Merge pull request #1 from pyrogram/develop

merge
This commit is contained in:
YoilyL 2018-07-01 08:04:51 +03:00 committed by GitHub
commit 3ea7ea2c83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 362 additions and 81 deletions

View File

@ -26,7 +26,7 @@ Features
- **Easy to use**: You can easily install Pyrogram using pip and start building your app right away. - **Easy to use**: You can easily install Pyrogram using pip and start building your app right away.
- **High-level**: The low-level details of MTProto are abstracted and automatically handled. - **High-level**: The low-level details of MTProto are abstracted and automatically handled.
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. - **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
- **Updated** to the latest Telegram API version, currently Layer 79 on top of MTProto 2.0. - **Updated** to the latest Telegram API version, currently Layer 81 on top of MTProto 2.0.
- **Documented**: The Pyrogram API is well documented and resembles the Telegram Bot API. - **Documented**: The Pyrogram API is well documented and resembles the Telegram Bot API.
- **Full API**, allowing to execute any advanced action an official client is able to do, and more. - **Full API**, allowing to execute any advanced action an official client is able to do, and more.
@ -100,7 +100,7 @@ Copyright & License
</a> </a>
<br><br> <br><br>
<a href="compiler/api/source/main_api.tl"> <a href="compiler/api/source/main_api.tl">
<img src="https://img.shields.io/badge/SCHEME-LAYER%2079-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30" <img src="https://img.shields.io/badge/SCHEME-LAYER%2081-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
alt="Scheme Layer"> alt="Scheme Layer">
</a> </a>
<a href="https://github.com/pyrogram/tgcrypto"> <a href="https://github.com/pyrogram/tgcrypto">
@ -115,7 +115,7 @@ Copyright & License
.. |description| replace:: **Telegram MTProto API Client Library for Python** .. |description| replace:: **Telegram MTProto API Client Library for Python**
.. |scheme| image:: "https://img.shields.io/badge/SCHEME-LAYER%2079-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30" .. |scheme| image:: "https://img.shields.io/badge/SCHEME-LAYER%2081-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
:target: compiler/api/source/main_api.tl :target: compiler/api/source/main_api.tl
:alt: Scheme Layer :alt: Scheme Layer

View File

@ -494,17 +494,16 @@ def start():
f.write("\n 0xb0700015: \"pyrogram.client.types.ChatPhoto\",") f.write("\n 0xb0700015: \"pyrogram.client.types.ChatPhoto\",")
f.write("\n 0xb0700016: \"pyrogram.client.types.ChatMember\",") f.write("\n 0xb0700016: \"pyrogram.client.types.ChatMember\",")
f.write("\n 0xb0700017: \"pyrogram.client.types.Sticker\",") f.write("\n 0xb0700017: \"pyrogram.client.types.Sticker\",")
f.write("\n 0xb0700025: \"pyrogram.client.types.GIF\",")
f.write("\n 0xb0700026: \"pyrogram.client.types.Messages\",")
f.write("\n 0xb0700018: \"pyrogram.client.types.reply_markup.ForceReply\",") f.write("\n 0xb0700018: \"pyrogram.client.types.reply_markup.ForceReply\",")
f.write("\n 0xb0700019: \"pyrogram.client.types.reply_markup.InlineKeyboardButton\",") f.write("\n 0xb0700019: \"pyrogram.client.types.reply_markup.InlineKeyboardButton\",")
f.write("\n 0xb0700020: \"pyrogram.client.types.reply_markup.InlineKeyboardMarkup\",") f.write("\n 0xb0700020: \"pyrogram.client.types.reply_markup.InlineKeyboardMarkup\",")
f.write("\n 0xb0700021: \"pyrogram.client.types.reply_markup.KeyboardButton\",") f.write("\n 0xb0700021: \"pyrogram.client.types.reply_markup.KeyboardButton\",")
f.write("\n 0xb0700022: \"pyrogram.client.types.reply_markup.ReplyKeyboardMarkup\",") f.write("\n 0xb0700022: \"pyrogram.client.types.reply_markup.ReplyKeyboardMarkup\",")
f.write("\n 0xb0700023: \"pyrogram.client.types.reply_markup.ReplyKeyboardRemove\",") f.write("\n 0xb0700023: \"pyrogram.client.types.reply_markup.ReplyKeyboardRemove\",")
f.write("\n 0xb0700024: \"pyrogram.client.types.CallbackQuery\",")
f.write("\n 0xb0700024: \"pyrogram.client.types.CallbackQuery\"") f.write("\n 0xb0700025: \"pyrogram.client.types.GIF\",")
f.write("\n 0xb0700026: \"pyrogram.client.types.Messages\",")
f.write("\n 0xb0700027: \"pyrogram.client.types.Photo\",")
f.write("\n}\n") f.write("\n}\n")

View File

@ -60,6 +60,7 @@ inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation; inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation; inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation; inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation;
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent; inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
@ -149,6 +150,8 @@ messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDis
messageActionScreenshotTaken#4792929b = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction;
messageActionCustomAction#fae69f56 message:string = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction;
messageActionBotAllowed#abe9affe domain:string = MessageAction; messageActionBotAllowed#abe9affe domain:string = MessageAction;
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog; dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
@ -164,7 +167,7 @@ geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone; auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
auth.sentCode#5e002502 flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode; auth.sentCode#38faab5f flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int terms_of_service:flags.3?help.TermsOfService = auth.SentCode;
auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization; auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization;
@ -452,12 +455,12 @@ authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string s
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations; account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
account.noPassword#96dabc18 new_salt:bytes email_unconfirmed_pattern:string = account.Password; account.noPassword#5ea182f6 new_salt:bytes new_secure_salt:bytes secure_random:bytes email_unconfirmed_pattern:string = account.Password;
account.password#7c18141c current_salt:bytes new_salt:bytes hint:string has_recovery:Bool email_unconfirmed_pattern:string = account.Password; account.password#ca39b447 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true current_salt:bytes new_salt:bytes new_secure_salt:bytes secure_random:bytes hint:string email_unconfirmed_pattern:string = account.Password;
account.passwordSettings#b7b72ab3 email:string = account.PasswordSettings; account.passwordSettings#7bd9c3f1 email:string secure_salt:bytes secure_secret:bytes secure_secret_id:long = account.PasswordSettings;
account.passwordInputSettings#86916deb flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string = account.PasswordInputSettings; account.passwordInputSettings#21ffa60d flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_salt:flags.2?bytes new_secure_secret:flags.2?bytes new_secure_secret_id:flags.2?long = account.PasswordInputSettings;
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery; auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
@ -545,7 +548,7 @@ channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant; channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
help.termsOfService#f1ee3e90 text:string = help.TermsOfService; help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif; foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif; foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
@ -830,6 +833,56 @@ inputClientProxy#75588b3f address:string port:int = InputClientProxy;
help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData; help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData;
help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData; help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData;
help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
help.termsOfServiceUpdate#28ecf961 expires:int terms_of_service:help.TermsOfService = help.TermsOfServiceUpdate;
inputSecureFileUploaded#3334b0f0 id:long parts:int md5_checksum:string file_hash:bytes secret:bytes = InputSecureFile;
inputSecureFile#5367e5be id:long access_hash:long = InputSecureFile;
secureFileEmpty#64199744 = SecureFile;
secureFile#e0277a62 id:long access_hash:long size:int dc_id:int date:int file_hash:bytes secret:bytes = SecureFile;
secureData#8aeabec3 data:bytes data_hash:bytes secret:bytes = SecureData;
securePlainPhone#7d6099dd phone:string = SecurePlainData;
securePlainEmail#21ec5a5f email:string = SecurePlainData;
secureValueTypePersonalDetails#9d2a81e3 = SecureValueType;
secureValueTypePassport#3dac6a00 = SecureValueType;
secureValueTypeDriverLicense#6e425c4 = SecureValueType;
secureValueTypeIdentityCard#a0d0744b = SecureValueType;
secureValueTypeInternalPassport#99a48f23 = SecureValueType;
secureValueTypeAddress#cbe31e26 = SecureValueType;
secureValueTypeUtilityBill#fc36954e = SecureValueType;
secureValueTypeBankStatement#89137c0d = SecureValueType;
secureValueTypeRentalAgreement#8b883488 = SecureValueType;
secureValueTypePassportRegistration#99e3806a = SecureValueType;
secureValueTypeTemporaryRegistration#ea02ec33 = SecureValueType;
secureValueTypePhone#b320aadb = SecureValueType;
secureValueTypeEmail#8e3ca7ee = SecureValueType;
secureValue#b4b4b699 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?SecureFile reverse_side:flags.2?SecureFile selfie:flags.3?SecureFile files:flags.4?Vector<SecureFile> plain_data:flags.5?SecurePlainData hash:bytes = SecureValue;
inputSecureValue#67872e8 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?InputSecureFile reverse_side:flags.2?InputSecureFile selfie:flags.3?InputSecureFile files:flags.4?Vector<InputSecureFile> plain_data:flags.5?SecurePlainData = InputSecureValue;
secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash;
secureValueErrorData#e8a40bd9 type:SecureValueType data_hash:bytes field:string text:string = SecureValueError;
secureValueErrorFrontSide#be3dfa type:SecureValueType file_hash:bytes text:string = SecureValueError;
secureValueErrorReverseSide#868a2aa5 type:SecureValueType file_hash:bytes text:string = SecureValueError;
secureValueErrorSelfie#e537ced6 type:SecureValueType file_hash:bytes text:string = SecureValueError;
secureValueErrorFile#7a700873 type:SecureValueType file_hash:bytes text:string = SecureValueError;
secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector<bytes> text:string = SecureValueError;
secureCredentialsEncrypted#33f0ea47 data:bytes hash:bytes secret:bytes = SecureCredentialsEncrypted;
account.authorizationForm#cb976d53 flags:# selfie_required:flags.1?true required_types:Vector<SecureValueType> values:Vector<SecureValue> errors:Vector<SecureValueError> users:Vector<User> privacy_policy_url:flags.0?string = account.AuthorizationForm;
account.sentEmailCode#811f854f email_pattern:string length:int = account.SentEmailCode;
help.deepLinkInfoEmpty#66afa166 = help.DeepLinkInfo;
help.deepLinkInfo#6a4ee832 flags:# update_app:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = help.DeepLinkInfo;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -885,9 +938,20 @@ account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPass
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations; account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
account.resetWebAuthorization#2d01b9ef hash:long = Bool; account.resetWebAuthorization#2d01b9ef hash:long = Bool;
account.resetWebAuthorizations#682d2594 = Bool; account.resetWebAuthorizations#682d2594 = Bool;
account.getAllSecureValues#b288bc7d = Vector<SecureValue>;
account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>;
account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue;
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
account.verifyEmail#ecba39db email:string code:string = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>; users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull; users.getFullUser#ca30a5b1 id:InputUser = UserFull;
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>; contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#c023849f hash:int = contacts.Contacts; contacts.getContacts#c023849f hash:int = contacts.Contacts;
@ -1027,11 +1091,13 @@ help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#4d392343 = help.InviteText; help.getInviteText#4d392343 = help.InviteText;
help.getSupport#9cdf08cd = help.Support; help.getSupport#9cdf08cd = help.Support;
help.getAppChangelog#9010ef6f prev_app_version:string = Updates; help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
help.getTermsOfService#8e59b7e7 country_iso2:string = help.TermsOfService;
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
help.getCdnConfig#52029342 = CdnConfig; help.getCdnConfig#52029342 = CdnConfig;
help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls;
help.getProxyData#3d7758e1 = help.ProxyData; help.getProxyData#3d7758e1 = help.ProxyData;
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool; channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages; channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
@ -1095,4 +1161,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference; langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>; langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
// LAYER 79 // LAYER 81

View File

@ -77,7 +77,8 @@ def generate(source_path, base):
build(source_path) build(source_path)
for k, v in all_entities.items(): for k, v in sorted(all_entities.items()):
v = sorted(v)
entities = [] entities = []
for i in v: for i in v:

View File

@ -0,0 +1,2 @@
id message
AUTH_KEY_DUPLICATED Authorization error. You must log out and log in again with your phone number. We apologize for the inconvenience.
1 id message
2 AUTH_KEY_DUPLICATED Authorization error. You must log out and log in again with your phone number. We apologize for the inconvenience.

View File

@ -26,11 +26,11 @@ Welcome to Pyrogram
</a> </a>
<br><br> <br><br>
<a href="https://github.com/pyrogram/pyrogram/blob/master/compiler/api/source/main_api.tl"> <a href="https://github.com/pyrogram/pyrogram/blob/master/compiler/api/source/main_api.tl">
<img src="https://media.pyrogram.ml/images/scheme.svg" <img src="https://img.shields.io/badge/SCHEME-LAYER%2081-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
alt="Scheme Layer 75"> alt="Scheme Layer">
</a> </a>
<a href="https://github.com/pyrogram/tgcrypto"> <a href="https://github.com/pyrogram/tgcrypto">
<img src="https://media.pyrogram.ml/images/tgcrypto.svg" <img src="https://img.shields.io/badge/TGCRYPTO-V1.0.4-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
alt="TgCrypto"> alt="TgCrypto">
</a> </a>
</p> </p>
@ -56,7 +56,7 @@ button at the end of each page. But first, here's a brief overview of what is th
About About
----- -----
Pyrogram is a brand new Telegram_ Client Library written from the ground up in Python and C. It can be used for building **Pyrogram** is a brand new Telegram_ Client Library written from the ground up in Python and C. It can be used for building
custom Telegram applications that interact with the MTProto API as both User and Bot. custom Telegram applications that interact with the MTProto API as both User and Bot.
Features Features
@ -65,8 +65,8 @@ Features
- **Easy to use**: You can easily install Pyrogram using pip and start building your app right away. - **Easy to use**: You can easily install Pyrogram using pip and start building your app right away.
- **High-level**: The low-level details of MTProto are abstracted and automatically handled. - **High-level**: The low-level details of MTProto are abstracted and automatically handled.
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. - **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
- **Updated** to the latest Telegram API version, currently Layer 76 running on MTProto 2.0. - **Updated** to the latest Telegram API version, currently Layer 81 on top of MTProto 2.0.
- **Documented**: Pyrogram API methods are documented and resemble the Telegram Bot API. - **Documented**: The Pyrogram API is well documented and resembles the Telegram Bot API.
- **Full API**, allowing to execute any advanced action an official client is able to do, and more. - **Full API**, allowing to execute any advanced action an official client is able to do, and more.
To get started, press the Next button. To get started, press the Next button.
@ -84,10 +84,11 @@ To get started, press the Next button.
:caption: Resources :caption: Resources
resources/UpdateHandling resources/UpdateHandling
resources/SOCKS5Proxy
resources/TgCrypto
resources/AutoAuthorization resources/AutoAuthorization
resources/CustomizeSessions
resources/TgCrypto
resources/TextFormatting resources/TextFormatting
resources/SOCKS5Proxy
resources/BotsInteraction resources/BotsInteraction
resources/ErrorHandling resources/ErrorHandling

View File

@ -42,6 +42,7 @@ Client
send_chat_action send_chat_action
download_media download_media
get_user_profile_photos get_user_profile_photos
delete_profile_photos
edit_message_text edit_message_text
edit_message_caption edit_message_caption
edit_message_reply_markup edit_message_reply_markup
@ -62,6 +63,7 @@ Client
get_inline_bot_results get_inline_bot_results
send_inline_bot_result send_inline_bot_result
answer_callback_query answer_callback_query
request_callback_answer
get_users get_users
get_chat get_chat
get_messages get_messages

View File

@ -0,0 +1,5 @@
Photo
=====
.. autoclass:: pyrogram.Photo
:members:

View File

@ -9,6 +9,7 @@ Types
Message Message
MessageEntity MessageEntity
Messages Messages
Photo
PhotoSize PhotoSize
Audio Audio
Document Document

View File

@ -28,8 +28,12 @@ Inline Bots
.. code-block:: python .. code-block:: python
# Send the first result (bot_results.results[0]) to your own chat (Saved Messages) # Send the first result to your own chat
app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id) app.send_inline_bot_result(
"me",
bot_results.query_id,
bot_results.results[0].id
)
.. figure:: https://i.imgur.com/wwxr7B7.png .. figure:: https://i.imgur.com/wwxr7B7.png
:width: 90% :width: 90%

View File

@ -0,0 +1,66 @@
Customize Sessions
==================
As you may probably know, Telegram allows Users (and Bots) having more than one session (authorizations) registered
in the system at the same time.
Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official
app (or by invoking `GetAuthorizations <../functions/account/GetAuthorizations.html>`_ with Pyrogram) and store some useful
information about the client who generated them.
.. figure:: https://i.imgur.com/lzGPCdZ.png
:width: 70%
:align: center
A Pyrogram session running on Linux, Python 3.6.
That's how a session looks like on the Android app, showing the three main pieces of information.
- ``app_version``: **Pyrogram 🔥 0.7.5**
- ``device_model``: **CPython 3.6.5**
- ``system_version``: **Linux 4.15.0-23-generic**
Set Custom Values
-----------------
To set custom values, you can either make use of the ``config.ini`` file, this way:
.. code-block:: ini
[pyrogram]
app_version = 1.2.3
device_model = PC
system_version = Linux
Or, pass the arguments directly in the Client's constructor.
.. code-block:: python
app = Client(
"my_account",
app_version="1.2.3",
device_model="PC",
system_version="Linux"
)
Set Custom Languages
--------------------
To tell Telegram in which language should speak to you (terms of service, bots, service messages, ...) you can
set ``lang_code`` in `ISO 639-1 <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>`_ standard (defaults to "en",
English).
With the following code we make Telegram know we want it to speak in Italian (it):
.. code-block:: ini
[pyrogram]
lang_code = it
.. code-block:: python
app = Client(
"my_account",
lang_code="it",
)

View File

@ -9,6 +9,7 @@ from, one for each kind of update:
- `DeletedMessagesHandler <../pyrogram/handlers/DeletedMessagesHandler.html>`_ - `DeletedMessagesHandler <../pyrogram/handlers/DeletedMessagesHandler.html>`_
- `CallbackQueryHandler <../pyrogram/handlers/CallbackQueryHandler.html>`_ - `CallbackQueryHandler <../pyrogram/handlers/CallbackQueryHandler.html>`_
- `RawUpdateHandler <../pyrogram/handlers/RawUpdateHandler.html>`_ - `RawUpdateHandler <../pyrogram/handlers/RawUpdateHandler.html>`_
- `DisconnectHandler <../pyrogram/handlers/DisconnectHandler.html>`_
Registering an Handler Registering an Handler
---------------------- ----------------------

View File

@ -54,7 +54,7 @@ User Authorization
In order to use the API, Telegram requires that Users be authorized via their phone numbers. In order to use the API, Telegram requires that Users be authorized via their phone numbers.
Pyrogram automatically manages this access, all you need to do is create an instance of Pyrogram automatically manages this access, all you need to do is create an instance of
the :class:`Client <pyrogram.Client>` class by passing to it a ``session_name`` of your choice the :class:`Client <pyrogram.Client>` class by passing to it a ``session_name`` of your choice
(e.g.: "my_account") and call the :meth:`start() <pyrogram.Client.start>` method: (e.g.: "my_account") and call the :meth:`run() <pyrogram.Client.run>` method:
.. code-block:: python .. code-block:: python

View File

@ -10,10 +10,6 @@ High-level API
The easiest and recommended way to interact with Telegram is via the high-level Pyrogram methods_ and types_, which are The easiest and recommended way to interact with Telegram is via the high-level Pyrogram methods_ and types_, which are
named after the `Telegram Bot API`_. named after the `Telegram Bot API`_.
.. hint:: If you can't find an high-level method you want to use, chances are it's not implemented yet.
In this case, you must use the `Raw Functions`_. Meanwhile, feel free to join our Community_ if you get stuck
or want to propose a new method!
Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_): Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_):
- Get information about the authorized user: - Get information about the authorized user:
@ -34,10 +30,8 @@ Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/exa
app.send_photo("me", "/home/dan/perla.jpg", "Cute!") app.send_photo("me", "/home/dan/perla.jpg", "Cute!")
.. _using-raw-functions: Raw Functions
-------------
Using Raw Functions
-------------------
If you can't find a high-level method for your needs or if want complete, low-level access to the whole Telegram API, If you can't find a high-level method for your needs or if want complete, low-level access to the whole Telegram API,
you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`types <pyrogram.api.types>` exposed by the you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`types <pyrogram.api.types>` exposed by the
@ -45,8 +39,10 @@ you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`type
method provided by the Client class. method provided by the Client class.
.. hint:: Every high-level method mentioned in the section above is built on top of these raw functions. .. hint:: Every high-level method mentioned in the section above is built on top of these raw functions.
Nothing stops you from using the raw functions only, but they are rather complex and `plenty of them`_ are already Nothing stops you from using the raw functions only, but they are rather complex and `plenty of them`_ are already
re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API. re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API.
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_! If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_): Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_):

View File

@ -23,14 +23,14 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance
"e" if sys.getfilesystemencoding() != "utf-8" else "\xe8" "e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
) )
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
__version__ = "0.7.5.dev3" __version__ = "0.7.5"
from .api.errors import Error from .api.errors import Error
from .client.types import ( from .client.types import (
Audio, Chat, ChatMember, ChatPhoto, Contact, Document, InputMediaPhoto, Audio, Chat, ChatMember, ChatPhoto, Contact, Document, InputMediaPhoto,
InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity, InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity,
PhotoSize, Sticker, Update, User, UserProfilePhotos, Venue, GIF, Video, Photo, PhotoSize, Sticker, Update, User, UserProfilePhotos, Venue, GIF,
VideoNote, Voice, CallbackQuery, Messages Video, VideoNote, Voice, CallbackQuery, Messages
) )
from .client.types.reply_markup import ( from .client.types.reply_markup import (
ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,

View File

@ -86,10 +86,6 @@ class Client(Methods, BaseClient):
Operating System version. Defaults to *platform.system() + " " + platform.release()* Operating System version. Defaults to *platform.system() + " " + platform.release()*
This is an alternative way to set it if you don't want to use the *config.ini* file. This is an alternative way to set it if you don't want to use the *config.ini* file.
system_lang_code (``str``, *optional*):
Code of the language used on the system, in ISO 639-1 standard. Defaults to "en".
This is an alternative way to set it if you don't want to use the *config.ini* file.
lang_code (``str``, *optional*): lang_code (``str``, *optional*):
Code of the language used on the client, in ISO 639-1 standard. Defaults to "en". Code of the language used on the client, in ISO 639-1 standard. Defaults to "en".
This is an alternative way to set it if you don't want to use the *config.ini* file. This is an alternative way to set it if you don't want to use the *config.ini* file.
@ -149,7 +145,6 @@ class Client(Methods, BaseClient):
app_version: str = None, app_version: str = None,
device_model: str = None, device_model: str = None,
system_version: str = None, system_version: str = None,
system_lang_code: str = None,
lang_code: str = None, lang_code: str = None,
proxy: dict = None, proxy: dict = None,
test_mode: bool = False, test_mode: bool = False,
@ -170,7 +165,6 @@ class Client(Methods, BaseClient):
self.app_version = app_version self.app_version = app_version
self.device_model = device_model self.device_model = device_model
self.system_version = system_version self.system_version = system_version
self.system_lang_code = system_lang_code
self.lang_code = lang_code self.lang_code = lang_code
# TODO: Make code consistent, use underscore for private/protected fields # TODO: Make code consistent, use underscore for private/protected fields
self._proxy = proxy self._proxy = proxy
@ -475,6 +469,10 @@ class Client(Methods, BaseClient):
phone_registered = r.phone_registered phone_registered = r.phone_registered
phone_code_hash = r.phone_code_hash phone_code_hash = r.phone_code_hash
terms_of_service = r.terms_of_service
if terms_of_service:
print("\n" + terms_of_service.text + "\n")
if self.force_sms: if self.force_sms:
self.send( self.send(
@ -581,9 +579,14 @@ class Client(Methods, BaseClient):
else: else:
break break
if terms_of_service:
assert self.send(functions.help.AcceptTermsOfService(terms_of_service.id))
self.password = None self.password = None
self.user_id = r.user.id self.user_id = r.user.id
print("Login successful")
def fetch_peers(self, entities: list): def fetch_peers(self, entities: list):
for entity in entities: for entity in entities:
if isinstance(entity, types.User): if isinstance(entity, types.User):
@ -882,7 +885,7 @@ class Client(Methods, BaseClient):
"More info: https://docs.pyrogram.ml/start/ProjectSetup#configuration" "More info: https://docs.pyrogram.ml/start/ProjectSetup#configuration"
) )
for option in {"app_version", "device_model", "system_version", "system_lang_code", "lang_code"}: for option in {"app_version", "device_model", "system_version", "lang_code"}:
if getattr(self, option): if getattr(self, option):
pass pass
else: else:

View File

@ -329,13 +329,23 @@ def parse_messages(
), ),
width=size.w, width=size.w,
height=size.h, height=size.h,
file_size=file_size, file_size=file_size
date=photo.date
) )
photo_sizes.append(photo_size) photo_sizes.append(photo_size)
photo = photo_sizes photo = pyrogram_types.Photo(
id=b64encode(
pack(
"<qq",
photo.id,
photo.access_hash
),
b"-_"
).decode().rstrip("="),
date=photo.date,
sizes=photo_sizes
)
elif isinstance(media, types.MessageMediaGeo): elif isinstance(media, types.MessageMediaGeo):
geo_point = media.geo geo_point = media.geo
@ -664,13 +674,23 @@ def parse_messages(
), ),
width=size.w, width=size.w,
height=size.h, height=size.h,
file_size=file_size, file_size=file_size
date=photo.date
) )
photo_sizes.append(photo_size) photo_sizes.append(photo_size)
new_chat_photo = photo_sizes new_chat_photo = pyrogram_types.Photo(
id=b64encode(
pack(
"<qq",
photo.id,
photo.access_hash
),
b"-_"
).decode().rstrip("="),
date=photo.date,
sizes=photo_sizes
)
m = pyrogram_types.Message( m = pyrogram_types.Message(
message_id=message.id, message_id=message.id,
@ -757,7 +777,7 @@ def get_offset_date(dialogs):
return 0 return 0
def parse_photos(photos): def parse_profile_photos(photos):
if isinstance(photos, types.photos.Photos): if isinstance(photos, types.photos.Photos):
total_count = len(photos.photos) total_count = len(photos.photos)
else: else:
@ -795,13 +815,25 @@ def parse_photos(photos):
), ),
width=size.w, width=size.w,
height=size.h, height=size.h,
file_size=file_size, file_size=file_size
date=photo.date
) )
photo_sizes.append(photo_size) photo_sizes.append(photo_size)
user_profile_photos.append(photo_sizes) user_profile_photos.append(
pyrogram_types.Photo(
id=b64encode(
pack(
"<qq",
photo.id,
photo.access_hash
),
b"-_"
).decode().rstrip("="),
date=photo.date,
sizes=photo_sizes
)
)
return pyrogram_types.UserProfilePhotos( return pyrogram_types.UserProfilePhotos(
total_count=total_count, total_count=total_count,

View File

@ -77,7 +77,7 @@ class DownloadMedia(BaseClient):
""" """
if isinstance(message, pyrogram_types.Message): if isinstance(message, pyrogram_types.Message):
if message.photo: if message.photo:
media = message.photo[-1] media = message.photo.sizes[-1]
elif message.audio: elif message.audio:
media = message.audio media = message.audio
elif message.document: elif message.document:
@ -95,7 +95,7 @@ class DownloadMedia(BaseClient):
else: else:
return return
elif isinstance(message, ( elif isinstance(message, (
pyrogram_types.PhotoSize, pyrogram_types.Photo,
pyrogram_types.Audio, pyrogram_types.Audio,
pyrogram_types.Document, pyrogram_types.Document,
pyrogram_types.Video, pyrogram_types.Video,

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .delete_profile_photos import DeleteProfilePhotos
from .get_me import GetMe from .get_me import GetMe
from .get_user_profile_photos import GetUserProfilePhotos from .get_user_profile_photos import GetUserProfilePhotos
from .get_users import GetUsers from .get_users import GetUsers
@ -23,6 +24,7 @@ from .get_users import GetUsers
class Users( class Users(
GetUserProfilePhotos, GetUserProfilePhotos,
DeleteProfilePhotos,
GetUsers, GetUsers,
GetMe GetMe
): ):

View File

@ -0,0 +1,58 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from base64 import b64decode
from struct import unpack
from pyrogram.api import functions, types
from ...ext import BaseClient
class DeleteProfilePhotos(BaseClient):
def delete_profile_photos(self, id: str or list):
"""Use this method to delete your own profile photos
Args:
id (``str`` | ``list``):
A single :obj:`Photo <pyrogram.Photo>` id as string or multiple ids as list of strings for deleting
more than one photos at once.
Returns:
True on success.
Raises:
:class:`Error <pyrogram.Error>`
"""
id = id if isinstance(id, list) else [id]
input_photos = []
for i in id:
s = unpack("<qq", b64decode(i + "=" * (-len(i) % 4), "-_"))
input_photos.append(
types.InputPhoto(
id=s[0],
access_hash=s[1]
)
)
return bool(self.send(
functions.photos.DeletePhotos(
id=input_photos
)
))

View File

@ -48,7 +48,7 @@ class GetUserProfilePhotos(BaseClient):
Raises: Raises:
:class:`Error <pyrogram.Error>` :class:`Error <pyrogram.Error>`
""" """
return utils.parse_photos( return utils.parse_profile_photos(
self.send( self.send(
functions.photos.GetUserPhotos( functions.photos.GetUserPhotos(
user_id=self.resolve_peer(user_id), user_id=self.resolve_peer(user_id),

View File

@ -31,6 +31,7 @@ from .location import Location
from .message import Message from .message import Message
from .message_entity import MessageEntity from .message_entity import MessageEntity
from .messages import Messages from .messages import Messages
from .photo import Photo
from .photo_size import PhotoSize from .photo_size import PhotoSize
from .reply_markup import ( from .reply_markup import (
ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,

View File

@ -89,8 +89,8 @@ class Message(Object):
game (:obj:`Game <pyrogram.Game>`, *optional*): game (:obj:`Game <pyrogram.Game>`, *optional*):
Message is a game, information about the game. More about games. Message is a game, information about the game. More about games.
photo (List of :obj:`PhotoSize <pyrogram.PhotoSize>`, *optional*): photo (:obj:`Photo <pyrogram.Photo>`, *optional*):
Message is a photo, available sizes of the photo. Message is a photo, information about the photo.
sticker (:obj:`Sticker <pyrogram.Sticker>`, *optional*): sticker (:obj:`Sticker <pyrogram.Sticker>`, *optional*):
Message is a sticker, information about the sticker. Message is a sticker, information about the sticker.
@ -132,7 +132,7 @@ class Message(Object):
new_chat_title (``str``, *optional*): new_chat_title (``str``, *optional*):
A chat title was changed to this value. A chat title was changed to this value.
new_chat_photo (List of :obj:`PhotoSize <pyrogram.PhotoSize>`, *optional*): new_chat_photo (:obj:`Photo <pyrogram.Photo>`, *optional*):
A chat photo was change to this value. A chat photo was change to this value.
delete_chat_photo (``bool``, *optional*): delete_chat_photo (``bool``, *optional*):
@ -516,7 +516,8 @@ class Message(Object):
Raises: Raises:
:class:`Error <pyrogram.Error>` :class:`Error <pyrogram.Error>`
``ValueError``: If the provided index or position is out of range or the button label was not found. ``ValueError``: If the provided index or position is out of range or the button label was not found
``TimeoutError``: If, after clicking an inline button, the bot fails to answer within 10 seconds
""" """
if isinstance(self.reply_markup, ReplyKeyboardMarkup): if isinstance(self.reply_markup, ReplyKeyboardMarkup):
if quote is None: if quote is None:
@ -561,7 +562,7 @@ class Message(Object):
return self._client.request_callback_answer( return self._client.request_callback_answer(
chat_id=self.chat.id, chat_id=self.chat.id,
message_id=self.message_id, message_id=self.message_id,
data=button.callback_data callback_data=button.callback_data
) )
elif button.url: elif button.url:
return button.url return button.url

View File

@ -0,0 +1,41 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api.core import Object
class Photo(Object):
"""This object represents a Photo
Args:
id (``str``):
Unique identifier for this photo.
date (``int``):
Date the photo was sent in Unix time
sizes (List of :obj:`PhotoSize <pyrogram.PhotoSize>`):
Available sizes of this photo
"""
ID = 0xb0700027
def __init__(self, id: str, date: int, sizes: list):
self.id = id
self.date = date
self.sizes = sizes

View File

@ -32,18 +32,14 @@ class PhotoSize(Object):
height (``int``): height (``int``):
Photo height. Photo height.
file_size (``int``, *optional*): file_size (``int``):
File size. File size.
date (``int``, *optional*):
Date the photo was sent in Unix time
""" """
ID = 0xb0700005 ID = 0xb0700005
def __init__(self, file_id, width, height, file_size=None, date=None): def __init__(self, file_id: str, width: int, height: int, file_size: int):
self.file_id = file_id # string self.file_id = file_id
self.width = width # int self.width = width
self.height = height # int self.height = height
self.file_size = file_size # flags.0?int self.file_size = file_size
self.date = date

View File

@ -35,7 +35,7 @@ class ReplyKeyboardRemove(Object):
keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
""" """
ID = 0xb0700002 ID = 0xb0700023
def __init__(self, selective: bool = None): def __init__(self, selective: bool = None):
self.selective = selective self.selective = selective

View File

@ -26,12 +26,12 @@ class UserProfilePhotos(Object):
total_count (``int``): total_count (``int``):
Total number of profile pictures the target user has. Total number of profile pictures the target user has.
photos (List of List of :obj:`PhotoSize <pyrogram.PhotoSize>`): photos (List of :obj:`Photo <pyrogram.Photo>`):
Requested profile pictures (in up to 4 sizes each). Requested profile pictures.
""" """
ID = 0xb0700014 ID = 0xb0700014
def __init__(self, total_count: int, photos: list): def __init__(self, total_count: int, photos: list):
self.total_count = total_count # int self.total_count = total_count
self.photos = photos # Vector<Vector<PhotoSize>> self.photos = photos

View File

@ -31,7 +31,7 @@ from pyrogram import __copyright__, __license__, __version__
from pyrogram.api import functions, types, core from pyrogram.api import functions, types, core
from pyrogram.api.all import layer from pyrogram.api.all import layer
from pyrogram.api.core import Message, Object, MsgContainer, Long, FutureSalt, Int from pyrogram.api.core import Message, Object, MsgContainer, Long, FutureSalt, Int
from pyrogram.api.errors import Error, InternalServerError from pyrogram.api.errors import Error, InternalServerError, AuthKeyDuplicated
from pyrogram.connection import Connection from pyrogram.connection import Connection
from pyrogram.crypto import AES, KDF from pyrogram.crypto import AES, KDF
from .internals import MsgId, MsgFactory, DataCenter from .internals import MsgId, MsgFactory, DataCenter
@ -145,7 +145,7 @@ class Session:
app_version=self.client.app_version, app_version=self.client.app_version,
device_model=self.client.device_model, device_model=self.client.device_model,
system_version=self.client.system_version, system_version=self.client.system_version,
system_lang_code=self.client.system_lang_code, system_lang_code=self.client.lang_code,
lang_code=self.client.lang_code, lang_code=self.client.lang_code,
lang_pack="", lang_pack="",
query=functions.help.GetConfig(), query=functions.help.GetConfig(),
@ -157,6 +157,9 @@ class Session:
self.ping_thread.start() self.ping_thread.start()
log.info("Connection inited: Layer {}".format(layer)) log.info("Connection inited: Layer {}".format(layer))
except AuthKeyDuplicated as e:
self.stop()
raise e
except (OSError, TimeoutError, Error): except (OSError, TimeoutError, Error):
self.stop() self.stop()
except Exception as e: except Exception as e: