Merge branch 'develop' into inline-mode
# Conflicts: # compiler/api/compiler.py # compiler/error/source/400_BAD_REQUEST.tsv # pyrogram/__init__.py # pyrogram/client/dispatcher/dispatcher.py # pyrogram/client/ext/utils.py # pyrogram/client/methods/bots/__init__.py # pyrogram/client/types/__init__.py
This commit is contained in:
commit
acbbfabb27
2
NOTICE
2
NOTICE
@ -1,5 +1,5 @@
|
||||
Pyrogram - Telegram MTProto API Client Library for Python
|
||||
Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
|
||||
This file is part of Pyrogram.
|
||||
|
||||
|
56
README.rst
56
README.rst
@ -17,18 +17,24 @@ Pyrogram
|
||||
|
||||
app.run()
|
||||
|
||||
**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.
|
||||
**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C.
|
||||
It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the `MTProto API`_.
|
||||
|
||||
`Pyrogram in fully-asynchronous mode is also available » <https://github.com/pyrogram/pyrogram/issues/181>`_
|
||||
|
||||
`Working PoC of Telegram voice calls using Pyrogram » <https://github.com/bakatrouble/pytgvoip>`_
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- **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.
|
||||
- **Easy**: You can install Pyrogram with pip and start building your applications right away.
|
||||
- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way.
|
||||
- **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 82 on top of MTProto 2.0.
|
||||
- **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.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **Updated**, to the latest Telegram API version, currently Layer 95 on top of `MTProto 2.0`_.
|
||||
- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code.
|
||||
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
@ -43,11 +49,11 @@ Installing
|
||||
|
||||
pip3 install pyrogram
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
Resources
|
||||
---------
|
||||
|
||||
- The Docs contain lots of resources to help you getting started with Pyrogram: https://docs.pyrogram.ml.
|
||||
- Reading Examples_ in this repository is also a good way for learning how things work.
|
||||
- Reading `Examples in this repository`_ is also a good way for learning how Pyrogram works.
|
||||
- Seeking extra help? Don't be shy, come join and ask our Community_!
|
||||
- For other requests you can send an Email_ or a Message_.
|
||||
|
||||
@ -61,17 +67,19 @@ and documentation. Any help is appreciated!
|
||||
Copyright & License
|
||||
-------------------
|
||||
|
||||
- Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
- Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
- Licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_
|
||||
|
||||
.. _`Telegram`: https://telegram.org/
|
||||
.. _`MTProto API`: https://core.telegram.org/api#telegram-api
|
||||
.. _`Telegram API key`: https://docs.pyrogram.ml/start/ProjectSetup#api-keys
|
||||
.. _`Community`: https://t.me/PyrogramChat
|
||||
.. _`Examples`: https://github.com/pyrogram/pyrogram/tree/master/examples
|
||||
.. _`Examples in this repository`: https://github.com/pyrogram/pyrogram/tree/master/examples
|
||||
.. _`GitHub`: https://github.com/pyrogram/pyrogram/issues
|
||||
.. _`Email`: admin@pyrogram.ml
|
||||
.. _`Message`: https://t.me/haskell
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
.. _`MTProto 2.0`: https://core.telegram.org/mtproto
|
||||
.. _`GNU Lesser General Public License v3 or later (LGPLv3+)`: COPYING.lesser
|
||||
|
||||
.. |header| raw:: html
|
||||
@ -83,28 +91,28 @@ Copyright & License
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<b>Telegram MTProto API Client Library for Python</b>
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
|
||||
<br>
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases/latest">
|
||||
Download
|
||||
</a>
|
||||
•
|
||||
<a href="https://docs.pyrogram.ml">
|
||||
Documentation
|
||||
</a>
|
||||
•
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Changelog
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/PyrogramChat">
|
||||
Community
|
||||
</a>
|
||||
<br>
|
||||
<a href="compiler/api/source/main_api.tl">
|
||||
<img src="https://img.shields.io/badge/schema-layer%2082-eda738.svg?longCache=true&colorA=262b30"
|
||||
<img src="https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="Schema Layer">
|
||||
</a>
|
||||
<a href="https://github.com/pyrogram/tgcrypto">
|
||||
<img src="https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="TgCrypto">
|
||||
alt="TgCrypto Version">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -112,12 +120,12 @@ Copyright & License
|
||||
:target: https://pyrogram.ml
|
||||
:alt: Pyrogram
|
||||
|
||||
.. |description| replace:: **Telegram MTProto API Client Library for Python**
|
||||
.. |description| replace:: **Telegram MTProto API Framework for Python**
|
||||
|
||||
.. |scheme| image:: "https://img.shields.io/badge/SCHEME-LAYER%2082-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
.. |schema| image:: https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30
|
||||
:target: compiler/api/source/main_api.tl
|
||||
:alt: Scheme Layer
|
||||
:alt: Schema Layer
|
||||
|
||||
.. |tgcrypto| image:: "https://img.shields.io/badge/TGCRYPTO-V1.1.1-eda738.svg?longCache=true&style=for-the-badge&colorA=262b30"
|
||||
.. |tgcrypto| image:: https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30
|
||||
:target: https://github.com/pyrogram/tgcrypto
|
||||
:alt: TgCrypto
|
||||
:alt: TgCrypto Version
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -26,7 +26,7 @@ NOTICE_PATH = "NOTICE"
|
||||
SECTION_RE = re.compile(r"---(\w+)---")
|
||||
LAYER_RE = re.compile(r"//\sLAYER\s(\d+)")
|
||||
COMBINATOR_RE = re.compile(r"^([\w.]+)#([0-9a-f]+)\s(?:.*)=\s([\w<>.]+);(?: // Docs: (.+))?$", re.MULTILINE)
|
||||
ARGS_RE = re.compile("[^{](\w+):([\w?!.<>]+)")
|
||||
ARGS_RE = re.compile("[^{](\w+):([\w?!.<>#]+)")
|
||||
FLAGS_RE = re.compile(r"flags\.(\d+)\?")
|
||||
FLAGS_RE_2 = re.compile(r"flags\.(\d+)\?([\w<>.]+)")
|
||||
FLAGS_RE_3 = re.compile(r"flags:#")
|
||||
@ -287,18 +287,23 @@ def start():
|
||||
|
||||
sorted_args = sort_args(c.args)
|
||||
|
||||
arguments = ", " + ", ".join(
|
||||
[get_argument_type(i) for i in sorted_args]
|
||||
) if c.args else ""
|
||||
arguments = (
|
||||
", "
|
||||
+ ("*, " if c.args else "")
|
||||
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
|
||||
)
|
||||
|
||||
fields = "\n ".join(
|
||||
["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args]
|
||||
["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")]
|
||||
) if c.args else "pass"
|
||||
|
||||
docstring_args = []
|
||||
docs = c.docs.split("|")[1:] if c.docs else None
|
||||
|
||||
for i, arg in enumerate(sorted_args):
|
||||
if arg == ("flags", "#"):
|
||||
continue
|
||||
|
||||
arg_name, arg_type = arg
|
||||
is_optional = FLAGS_RE.match(arg_type)
|
||||
flag_number = is_optional.group(1) if is_optional else -1
|
||||
@ -338,27 +343,30 @@ def start():
|
||||
if references:
|
||||
docstring_args += "\n\n See Also:\n This object can be returned by " + references + "."
|
||||
|
||||
if c.has_flags:
|
||||
write_types = read_types = "" if c.has_flags else "# No flags\n "
|
||||
|
||||
for arg_name, arg_type in c.args:
|
||||
flag = FLAGS_RE_2.findall(arg_type)
|
||||
|
||||
if arg_name == "flags" and arg_type == "#":
|
||||
write_flags = []
|
||||
|
||||
for i in c.args:
|
||||
flag = FLAGS_RE.match(i[1])
|
||||
if flag:
|
||||
write_flags.append("flags |= (1 << {}) if self.{} is not None else 0".format(flag.group(1), i[0]))
|
||||
write_flags.append(
|
||||
"flags |= (1 << {}) if self.{} is not None else 0".format(flag.group(1), i[0]))
|
||||
|
||||
write_flags = "\n ".join([
|
||||
"flags = 0",
|
||||
"\n ".join(write_flags),
|
||||
"b.write(Int(flags))"
|
||||
"b.write(Int(flags))\n "
|
||||
])
|
||||
else:
|
||||
write_flags = "# No flags"
|
||||
|
||||
read_flags = "flags = Int.read(b)" if c.has_flags else "# No flags"
|
||||
write_types += write_flags
|
||||
read_types += "flags = Int.read(b)\n "
|
||||
|
||||
write_types = read_types = ""
|
||||
|
||||
for arg_name, arg_type in c.args:
|
||||
flag = FLAGS_RE_2.findall(arg_type)
|
||||
continue
|
||||
|
||||
if flag:
|
||||
index, flag_type = flag[0]
|
||||
@ -448,11 +456,13 @@ def start():
|
||||
object_id=c.id,
|
||||
arguments=arguments,
|
||||
fields=fields,
|
||||
read_flags=read_flags,
|
||||
read_types=read_types,
|
||||
write_flags=write_flags,
|
||||
write_types=write_types,
|
||||
return_arguments=", ".join([i[0] for i in sorted_args])
|
||||
return_arguments=", ".join(
|
||||
["{0}={0}".format(i[0]) for i in sorted_args if i != ("flags", "#")]
|
||||
),
|
||||
slots=", ".join(['"{}"'.format(i[0]) for i in sorted_args if i != ("flags", "#")]),
|
||||
qualname="{}{}".format("{}.".format(c.namespace) if c.namespace else "", c.name)
|
||||
)
|
||||
)
|
||||
|
||||
@ -475,40 +485,6 @@ def start():
|
||||
f.write("\n 0x3072cfa1: \"pyrogram.api.core.GzipPacked\",")
|
||||
f.write("\n 0x5bb8e511: \"pyrogram.api.core.Message\",")
|
||||
|
||||
f.write("\n 0xb0700000: \"pyrogram.client.types.Update\",")
|
||||
f.write("\n 0xb0700001: \"pyrogram.client.types.User\",")
|
||||
f.write("\n 0xb0700002: \"pyrogram.client.types.Chat\",")
|
||||
f.write("\n 0xb0700003: \"pyrogram.client.types.Message\",")
|
||||
f.write("\n 0xb0700004: \"pyrogram.client.types.MessageEntity\",")
|
||||
f.write("\n 0xb0700005: \"pyrogram.client.types.PhotoSize\",")
|
||||
f.write("\n 0xb0700006: \"pyrogram.client.types.Audio\",")
|
||||
f.write("\n 0xb0700007: \"pyrogram.client.types.Document\",")
|
||||
f.write("\n 0xb0700008: \"pyrogram.client.types.Video\",")
|
||||
f.write("\n 0xb0700009: \"pyrogram.client.types.Voice\",")
|
||||
f.write("\n 0xb0700010: \"pyrogram.client.types.VideoNote\",")
|
||||
f.write("\n 0xb0700011: \"pyrogram.client.types.Contact\",")
|
||||
f.write("\n 0xb0700012: \"pyrogram.client.types.Location\",")
|
||||
f.write("\n 0xb0700013: \"pyrogram.client.types.Venue\",")
|
||||
f.write("\n 0xb0700014: \"pyrogram.client.types.UserProfilePhotos\",")
|
||||
f.write("\n 0xb0700015: \"pyrogram.client.types.ChatPhoto\",")
|
||||
f.write("\n 0xb0700016: \"pyrogram.client.types.ChatMember\",")
|
||||
f.write("\n 0xb0700017: \"pyrogram.client.types.Sticker\",")
|
||||
f.write("\n 0xb0700018: \"pyrogram.client.types.bots.ForceReply\",")
|
||||
f.write("\n 0xb0700019: \"pyrogram.client.types.bots.InlineKeyboardButton\",")
|
||||
f.write("\n 0xb0700020: \"pyrogram.client.types.bots.InlineKeyboardMarkup\",")
|
||||
f.write("\n 0xb0700021: \"pyrogram.client.types.bots.KeyboardButton\",")
|
||||
f.write("\n 0xb0700022: \"pyrogram.client.types.bots.ReplyKeyboardMarkup\",")
|
||||
f.write("\n 0xb0700023: \"pyrogram.client.types.bots.ReplyKeyboardRemove\",")
|
||||
f.write("\n 0xb0700024: \"pyrogram.client.types.CallbackQuery\",")
|
||||
f.write("\n 0xb0700025: \"pyrogram.client.types.Animation\",")
|
||||
f.write("\n 0xb0700026: \"pyrogram.client.types.Messages\",")
|
||||
f.write("\n 0xb0700027: \"pyrogram.client.types.Photo\",")
|
||||
f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",")
|
||||
f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",")
|
||||
f.write("\n 0xb0700030: \"pyrogram.client.types.ChatMembers\",")
|
||||
f.write("\n 0xb0700031: \"pyrogram.client.types.UserStatus\",")
|
||||
f.write("\n 0xb0700032: \"pyrogram.client.types.InlineQuery\"")
|
||||
|
||||
f.write("\n}\n")
|
||||
|
||||
for k, v in namespaces.items():
|
||||
|
@ -45,7 +45,8 @@ inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = In
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia;
|
||||
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
|
||||
inputMediaPoll#6b3765b poll:Poll = InputMedia;
|
||||
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
|
||||
@ -55,16 +56,14 @@ inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
|
||||
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
|
||||
|
||||
inputPhotoEmpty#1cd7bf0d = InputPhoto;
|
||||
inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
|
||||
inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
|
||||
|
||||
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
|
||||
inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation;
|
||||
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
|
||||
inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation;
|
||||
inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes = InputFileLocation;
|
||||
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
|
||||
inputTakeoutFileLocation#29be5899 = InputFileLocation;
|
||||
|
||||
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
|
||||
|
||||
peerUser#9db1bc6d user_id:int = Peer;
|
||||
peerChat#bad0e5bb chat_id:int = Peer;
|
||||
peerChannel#bddde532 channel_id:int = Peer;
|
||||
@ -81,10 +80,10 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
|
||||
storage.fileWebp#1081464c = storage.FileType;
|
||||
|
||||
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
|
||||
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||
fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
|
||||
@ -97,13 +96,13 @@ userStatusLastWeek#7bf09fc = UserStatus;
|
||||
userStatusLastMonth#77ebc742 = UserStatus;
|
||||
|
||||
chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||
chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||
channelFull#76af5481 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
|
||||
chatFull#22a235da flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int = ChatFull;
|
||||
channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
|
||||
|
||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
||||
@ -116,7 +115,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -130,6 +129,7 @@ messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:str
|
||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
||||
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
||||
@ -153,15 +153,17 @@ messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
|
||||
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
|
||||
messageActionContactSignUp#f3f25f76 = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?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;
|
||||
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
photo#9288dd29 flags:# has_stickers:flags.0?true id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
|
||||
photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> = Photo;
|
||||
|
||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
|
||||
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
|
||||
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
|
||||
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
|
||||
@ -177,6 +179,7 @@ auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorizat
|
||||
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
|
||||
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
||||
|
||||
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
|
||||
|
||||
@ -184,15 +187,16 @@ peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bo
|
||||
|
||||
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
|
||||
|
||||
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
||||
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
||||
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
||||
|
||||
inputReportReasonSpam#58dbcab8 = ReportReason;
|
||||
inputReportReasonViolence#1e22c78d = ReportReason;
|
||||
inputReportReasonPornography#2e59d922 = ReportReason;
|
||||
inputReportReasonChildAbuse#adf44ee3 = ReportReason;
|
||||
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||
inputReportReasonCopyright#9b89f93a = ReportReason;
|
||||
|
||||
userFull#f220f3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo common_chats_count:int = UserFull;
|
||||
userFull#8ea4a881 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int = UserFull;
|
||||
|
||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||
|
||||
@ -217,8 +221,8 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
|
||||
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesNotModified#74535f21 count:int = messages.Messages;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
@ -254,7 +258,6 @@ updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
|
||||
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
|
||||
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
|
||||
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
|
||||
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
||||
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
|
||||
@ -278,7 +281,6 @@ updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
|
||||
updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update;
|
||||
updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
|
||||
updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update;
|
||||
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
|
||||
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
|
||||
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector<long> = Update;
|
||||
@ -305,13 +307,17 @@ updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Upd
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
updateBotPrecheckoutQuery#5d2f3aa9 flags:# query_id:long user_id:int payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string currency:string total_amount:long = Update;
|
||||
updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
|
||||
updateLangPackTooLong#10c2404b = Update;
|
||||
updateLangPackTooLong#46560264 lang_code:string = Update;
|
||||
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
||||
updateFavedStickers#e511996d = Update;
|
||||
updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> = Update;
|
||||
updateContactsReset#7084a7be = Update;
|
||||
updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
|
||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
||||
updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
|
||||
updateChatPinnedMessage#22893b26 chat_id:int id:int = Update;
|
||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -338,11 +344,11 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
|
||||
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#3213dbba flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
|
||||
config#e6ca25f6 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
help.appUpdate#8987f311 id:int critical:Bool url:string text:string = help.AppUpdate;
|
||||
help.appUpdate#1da7158f flags:# popup:flags.0?true id:int version:string text:string entities:Vector<MessageEntity> document:flags.1?Document url:flags.2?string = help.AppUpdate;
|
||||
help.noAppUpdate#c45a6536 = help.AppUpdate;
|
||||
|
||||
help.inviteText#18cb9f78 message:string = help.InviteText;
|
||||
@ -373,16 +379,17 @@ messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
|
||||
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
|
||||
|
||||
inputDocumentEmpty#72f0eaae = InputDocument;
|
||||
inputDocument#18798952 id:long access_hash:long = InputDocument;
|
||||
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
|
||||
|
||||
documentEmpty#36f8c871 id:long = Document;
|
||||
document#87232bc7 id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int version:int attributes:Vector<DocumentAttribute> = Document;
|
||||
document#9ba29cc1 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
||||
|
||||
help.support#17c6b5f6 phone_number:string user:User = help.Support;
|
||||
|
||||
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
|
||||
notifyUsers#b4c83b4c = NotifyPeer;
|
||||
notifyChats#c007cec3 = NotifyPeer;
|
||||
notifyBroadcasts#d612e8ef = NotifyPeer;
|
||||
|
||||
sendMessageTypingAction#16bf744e = SendMessageAction;
|
||||
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
|
||||
@ -403,10 +410,12 @@ contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vecto
|
||||
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
||||
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey;
|
||||
|
||||
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
||||
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
||||
privacyKeyPhoneCall#3d662b7b = PrivacyKey;
|
||||
privacyKeyPhoneP2P#39491cc8 = PrivacyKey;
|
||||
|
||||
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
|
||||
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
|
||||
@ -454,16 +463,15 @@ webPagePending#c586da1c id:long date:int = WebPage;
|
||||
webPage#5f07b4bc flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page = WebPage;
|
||||
webPageNotModified#85849473 = WebPage;
|
||||
|
||||
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
|
||||
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
|
||||
|
||||
account.noPassword#5ea182f6 new_salt:bytes new_secure_salt:bytes secure_random:bytes 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.password#ad2641f8 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes = account.Password;
|
||||
|
||||
account.passwordSettings#7bd9c3f1 email:string secure_salt:bytes secure_secret:bytes secure_secret_id:long = account.PasswordSettings;
|
||||
account.passwordSettings#9a5c33e5 flags:# email:flags.0?string secure_settings:flags.1?SecureSecretSettings = account.PasswordSettings;
|
||||
|
||||
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;
|
||||
account.passwordInputSettings#c23727c9 flags:# new_algo:flags.0?PasswordKdfAlgo new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_settings:flags.2?SecureSecretSettings = account.PasswordInputSettings;
|
||||
|
||||
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
||||
|
||||
@ -536,8 +544,8 @@ channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:
|
||||
channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
|
||||
channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
|
||||
channelParticipantCreator#e3e2e1f9 user_id:int = ChannelParticipant;
|
||||
channelParticipantAdmin#a82fa898 flags:# can_edit:flags.0?true user_id:int inviter_id:int promoted_by:int date:int admin_rights:ChannelAdminRights = ChannelParticipant;
|
||||
channelParticipantBanned#222c1886 flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChannelBannedRights = ChannelParticipant;
|
||||
channelParticipantAdmin#5daa6e23 flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights = ChannelParticipant;
|
||||
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
|
||||
|
||||
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
|
||||
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
|
||||
@ -545,6 +553,7 @@ channelParticipantsKicked#a3b54985 q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
|
||||
channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
|
||||
|
||||
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
|
||||
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
|
||||
@ -663,6 +672,12 @@ textFixed#6c3f19b9 text:RichText = RichText;
|
||||
textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
|
||||
textEmail#de5a0dd6 text:RichText email:string = RichText;
|
||||
textConcat#7e6260d7 texts:Vector<RichText> = RichText;
|
||||
textSubscript#ed6a8504 text:RichText = RichText;
|
||||
textSuperscript#c7fb5e01 text:RichText = RichText;
|
||||
textMarked#34b8621 text:RichText = RichText;
|
||||
textPhone#1ccb966a text:RichText phone:string = RichText;
|
||||
textImage#81ccf4f document_id:long w:int h:int = RichText;
|
||||
textAnchor#35553762 text:RichText name:string = RichText;
|
||||
|
||||
pageBlockUnsupported#13567e8a = PageBlock;
|
||||
pageBlockTitle#70abc3fd text:RichText = PageBlock;
|
||||
@ -675,21 +690,24 @@ pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
|
||||
pageBlockFooter#48870999 text:RichText = PageBlock;
|
||||
pageBlockDivider#db20b188 = PageBlock;
|
||||
pageBlockAnchor#ce0d37b0 name:string = PageBlock;
|
||||
pageBlockList#3a58c7f4 ordered:Bool items:Vector<RichText> = PageBlock;
|
||||
pageBlockList#e4e88011 items:Vector<PageListItem> = PageBlock;
|
||||
pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPhoto#e9c69982 photo_id:long caption:RichText = PageBlock;
|
||||
pageBlockVideo#d9d71866 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:RichText = PageBlock;
|
||||
pageBlockPhoto#1759c560 flags:# photo_id:long caption:PageCaption url:flags.0?string webpage_id:flags.0?long = PageBlock;
|
||||
pageBlockVideo#7c8fe7b6 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:PageCaption = PageBlock;
|
||||
pageBlockCover#39f23300 cover:PageBlock = PageBlock;
|
||||
pageBlockEmbed#cde200d1 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:int h:int caption:RichText = PageBlock;
|
||||
pageBlockEmbedPost#292c7be9 url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockCollage#8b31c4f items:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockSlideshow#130c8963 items:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockEmbed#a8718dc5 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:flags.5?int h:flags.5?int caption:PageCaption = PageBlock;
|
||||
pageBlockEmbedPost#f259a80b url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockCollage#65a0fa4d items:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockSlideshow#31f9590 items:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockChannel#ef1751b5 channel:Chat = PageBlock;
|
||||
pageBlockAudio#31b81a7f audio_id:long caption:RichText = PageBlock;
|
||||
|
||||
pagePart#8e3f9ebe blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
pageFull#556ec7aa blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
pageBlockAudio#804361ea audio_id:long caption:PageCaption = PageBlock;
|
||||
pageBlockKicker#1e148390 text:RichText = PageBlock;
|
||||
pageBlockTable#bf4dea82 flags:# bordered:flags.0?true striped:flags.1?true title:RichText rows:Vector<PageTableRow> = PageBlock;
|
||||
pageBlockOrderedList#9a8ae1e1 items:Vector<PageListOrderedItem> = PageBlock;
|
||||
pageBlockDetails#76768bed flags:# open:flags.0?true blocks:Vector<PageBlock> title:RichText = PageBlock;
|
||||
pageBlockRelatedArticles#16115a96 title:RichText articles:Vector<PageRelatedArticle> = PageBlock;
|
||||
pageBlockMap#a44f3ef6 geo:GeoPoint zoom:int w:int h:int caption:PageCaption = PageBlock;
|
||||
|
||||
phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
|
||||
@ -748,7 +766,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall;
|
||||
phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
|
||||
phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCall#ffe6ab67 id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
|
||||
|
||||
phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
|
||||
@ -770,11 +788,7 @@ langPackStringDeleted#2979eeb2 key:string = LangPackString;
|
||||
|
||||
langPackDifference#f385c1f6 lang_code:string from_version:int version:int strings:Vector<LangPackString> = LangPackDifference;
|
||||
|
||||
langPackLanguage#117698f1 name:string native_name:string lang_code:string = LangPackLanguage;
|
||||
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true manage_call:flags.10?true = ChannelAdminRights;
|
||||
|
||||
channelBannedRights#58cf4249 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true until_date:int = ChannelBannedRights;
|
||||
langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:flags.3?true name:string native_name:string lang_code:string base_lang_code:flags.1?string plural_code:string strings_count:int translated_count:int translations_url:string = LangPackLanguage;
|
||||
|
||||
channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
@ -792,6 +806,8 @@ channelAdminLogEventActionParticipantToggleBan#e6d83d7e prev_participant:Channel
|
||||
channelAdminLogEventActionParticipantToggleAdmin#d5676710 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@ -864,9 +880,9 @@ 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;
|
||||
secureValue#187fa0ca flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?SecureFile reverse_side:flags.2?SecureFile selfie:flags.3?SecureFile translation:flags.6?Vector<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;
|
||||
inputSecureValue#db21d0a7 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?InputSecureFile reverse_side:flags.2?InputSecureFile selfie:flags.3?InputSecureFile translation:flags.6?Vector<InputSecureFile> files:flags.4?Vector<InputSecureFile> plain_data:flags.5?SecurePlainData = InputSecureValue;
|
||||
|
||||
secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash;
|
||||
|
||||
@ -876,10 +892,13 @@ secureValueErrorReverseSide#868a2aa5 type:SecureValueType file_hash:bytes text:s
|
||||
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;
|
||||
secureValueError#869d758f type:SecureValueType hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorTranslationFile#a1144770 type:SecureValueType file_hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorTranslationFiles#34636dd8 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.authorizationForm#ad2e1cd8 flags:# required_types:Vector<SecureRequiredType> 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;
|
||||
|
||||
@ -890,6 +909,82 @@ savedPhoneContact#1142bd56 phone:string first_name:string last_name:string date:
|
||||
|
||||
account.takeout#4dba4501 id:long = account.Takeout;
|
||||
|
||||
passwordKdfAlgoUnknown#d45ab096 = PasswordKdfAlgo;
|
||||
passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow#3a912d4a salt1:bytes salt2:bytes g:int p:bytes = PasswordKdfAlgo;
|
||||
|
||||
securePasswordKdfAlgoUnknown#4a8537 = SecurePasswordKdfAlgo;
|
||||
securePasswordKdfAlgoPBKDF2HMACSHA512iter100000#bbf2dda0 salt:bytes = SecurePasswordKdfAlgo;
|
||||
securePasswordKdfAlgoSHA512#86471d92 salt:bytes = SecurePasswordKdfAlgo;
|
||||
|
||||
secureSecretSettings#1527bcac secure_algo:SecurePasswordKdfAlgo secure_secret:bytes secure_secret_id:long = SecureSecretSettings;
|
||||
|
||||
inputCheckPasswordEmpty#9880f658 = InputCheckPasswordSRP;
|
||||
inputCheckPasswordSRP#d27ff082 srp_id:long A:bytes M1:bytes = InputCheckPasswordSRP;
|
||||
|
||||
secureRequiredType#829d99da flags:# native_names:flags.0?true selfie_required:flags.1?true translation_required:flags.2?true type:SecureValueType = SecureRequiredType;
|
||||
secureRequiredTypeOneOf#27477b4 types:Vector<SecureRequiredType> = SecureRequiredType;
|
||||
|
||||
help.passportConfigNotModified#bfb9f457 = help.PassportConfig;
|
||||
help.passportConfig#a098d6af hash:int countries_langs:DataJSON = help.PassportConfig;
|
||||
|
||||
inputAppEvent#1d1b1245 time:double type:string peer:long data:JSONValue = InputAppEvent;
|
||||
|
||||
jsonObjectValue#c0de1bd9 key:string value:JSONValue = JSONObjectValue;
|
||||
|
||||
jsonNull#3f6d7b68 = JSONValue;
|
||||
jsonBool#c7345e6a value:Bool = JSONValue;
|
||||
jsonNumber#2be0dfa4 value:double = JSONValue;
|
||||
jsonString#b71e767a value:string = JSONValue;
|
||||
jsonArray#f7444763 value:Vector<JSONValue> = JSONValue;
|
||||
jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;
|
||||
|
||||
pageTableCell#34566b6a flags:# header:flags.0?true align_center:flags.3?true align_right:flags.4?true valign_middle:flags.5?true valign_bottom:flags.6?true text:flags.7?RichText colspan:flags.1?int rowspan:flags.2?int = PageTableCell;
|
||||
|
||||
pageTableRow#e0c0c5e5 cells:Vector<PageTableCell> = PageTableRow;
|
||||
|
||||
pageCaption#6f747657 text:RichText credit:RichText = PageCaption;
|
||||
|
||||
pageListItemText#b92fb6cd text:RichText = PageListItem;
|
||||
pageListItemBlocks#25e073fc blocks:Vector<PageBlock> = PageListItem;
|
||||
|
||||
pageListOrderedItemText#5e068047 num:string text:RichText = PageListOrderedItem;
|
||||
pageListOrderedItemBlocks#98dd8936 num:string blocks:Vector<PageBlock> = PageListOrderedItem;
|
||||
|
||||
pageRelatedArticle#b390dc08 flags:# url:string webpage_id:long title:flags.0?string description:flags.1?string photo_id:flags.2?long author:flags.3?string published_date:flags.4?int = PageRelatedArticle;
|
||||
|
||||
page#ae891bec flags:# part:flags.0?true rtl:flags.1?true v2:flags.2?true url:string blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
|
||||
help.supportName#8c05f1c9 name:string = help.SupportName;
|
||||
|
||||
help.userInfoEmpty#f3ae2eed = help.UserInfo;
|
||||
help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:string date:int = help.UserInfo;
|
||||
|
||||
pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
|
||||
|
||||
poll#d5529d06 id:long flags:# closed:flags.0?true question:string answers:Vector<PollAnswer> = Poll;
|
||||
|
||||
pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true option:bytes voters:int = PollAnswerVoters;
|
||||
|
||||
pollResults#5755785a flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int = PollResults;
|
||||
|
||||
chatOnlines#f041e250 onlines:int = ChatOnlines;
|
||||
|
||||
statsURL#47a971e0 url:string = StatsURL;
|
||||
|
||||
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true = ChatAdminRights;
|
||||
|
||||
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
|
||||
|
||||
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
|
||||
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
|
||||
|
||||
account.wallPapersNotModified#1c199183 = account.WallPapers;
|
||||
account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers;
|
||||
|
||||
codeSettings#302f59f3 flags:# allow_flashcall:flags.0?true current_number:flags.1?true app_hash_persistent:flags.2?true app_hash:flags.3?string = CodeSettings;
|
||||
|
||||
wallPaperSettings#a12f40b8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int intensity:flags.3?int = WallPaperSettings;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -900,7 +995,7 @@ invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
|
||||
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
auth.logOut#5717da40 = Bool;
|
||||
@ -909,7 +1004,7 @@ auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
|
||||
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
|
||||
auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
|
||||
auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_auth_token:string = auth.Authorization;
|
||||
auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
|
||||
auth.checkPassword#d18b4d16 password:InputCheckPasswordSRP = auth.Authorization;
|
||||
auth.requestPasswordRecovery#d897bc66 = auth.PasswordRecovery;
|
||||
auth.recoverPassword#4ea56e92 code:string = auth.Authorization;
|
||||
auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentCode;
|
||||
@ -923,7 +1018,7 @@ account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
account.resetNotifySettings#db7e1747 = Bool;
|
||||
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
|
||||
account.updateStatus#6628562c offline:Bool = Bool;
|
||||
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
||||
account.getWallPapers#aabb1763 hash:int = account.WallPapers;
|
||||
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
|
||||
account.checkUsername#2714d86c username:string = Bool;
|
||||
account.updateUsername#3e0bdd7c username:string = User;
|
||||
@ -932,17 +1027,17 @@ account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> =
|
||||
account.deleteAccount#418d4e0b reason:string = Bool;
|
||||
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
||||
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
||||
account.sendChangePhoneCode#8e57deb flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode;
|
||||
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
|
||||
account.updateDeviceLocked#38df3532 period:int = Bool;
|
||||
account.getAuthorizations#e320c158 = account.Authorizations;
|
||||
account.resetAuthorization#df77f3bc hash:long = Bool;
|
||||
account.getPassword#548a30f5 = account.Password;
|
||||
account.getPasswordSettings#bc8d11bb current_password_hash:bytes = account.PasswordSettings;
|
||||
account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings:account.PasswordInputSettings = Bool;
|
||||
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.getPasswordSettings#9cd4eaf9 password:InputCheckPasswordSRP = account.PasswordSettings;
|
||||
account.updatePasswordSettings#a59b102f password:InputCheckPasswordSRP new_settings:account.PasswordInputSettings = Bool;
|
||||
account.sendConfirmPhoneCode#1b3faa88 hash:string settings:CodeSettings = auth.SentCode;
|
||||
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
|
||||
account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword;
|
||||
account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;
|
||||
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
|
||||
account.resetWebAuthorization#2d01b9ef hash:long = Bool;
|
||||
account.resetWebAuthorizations#682d2594 = Bool;
|
||||
@ -952,27 +1047,38 @@ account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long =
|
||||
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.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = 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;
|
||||
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
|
||||
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
|
||||
account.confirmPasswordEmail#8fdf1920 code:string = Bool;
|
||||
account.resendPasswordEmail#7a7f2a15 = Bool;
|
||||
account.cancelPasswordEmail#c1cbd5b6 = Bool;
|
||||
account.getContactSignUpNotification#9f07c728 = Bool;
|
||||
account.setContactSignUpNotification#cff43f61 silent:Bool = Bool;
|
||||
account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates;
|
||||
account.getWallPaper#fc8ddbea wallpaper:InputWallPaper = WallPaper;
|
||||
account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
|
||||
account.saveWallPaper#6c5a5b37 wallpaper:InputWallPaper unsave:Bool settings:WallPaperSettings = Bool;
|
||||
account.installWallPaper#feed5769 wallpaper:InputWallPaper settings:WallPaperSettings = Bool;
|
||||
account.resetWallPapers#bb3b9804 = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
|
||||
|
||||
contacts.getContactIDs#2caa4a42 hash:int = Vector<int>;
|
||||
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
|
||||
contacts.getContacts#c023849f hash:int = contacts.Contacts;
|
||||
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
|
||||
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
|
||||
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
|
||||
contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
|
||||
contacts.block#332b49fc id:InputUser = Bool;
|
||||
contacts.unblock#e54100bd id:InputUser = Bool;
|
||||
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
|
||||
contacts.exportCard#84e53737 = Vector<int>;
|
||||
contacts.importCard#4fe196fe export_card:Vector<int> = User;
|
||||
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
||||
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||
@ -1019,7 +1125,7 @@ messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages
|
||||
messages.getStickers#43d4f2c emoticon:string hash:int = messages.Stickers;
|
||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
messages.exportChatInvite#df7534c peer:InputPeer = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
|
||||
@ -1027,7 +1133,6 @@ messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = m
|
||||
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
|
||||
messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
|
||||
messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>;
|
||||
messages.toggleChatAdmins#ec8bd9e1 chat_id:int enabled:Bool = Updates;
|
||||
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
|
||||
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
|
||||
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
@ -1038,10 +1143,10 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
|
||||
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
|
||||
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
|
||||
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
||||
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
|
||||
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
|
||||
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
||||
messages.editMessage#c000e4c8 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Updates;
|
||||
messages.editInlineBotMessage#adc3e828 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.editMessage#d116f31e flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||
@ -1080,6 +1185,14 @@ messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:stri
|
||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
|
||||
messages.clearAllDrafts#7e58ee9c = Bool;
|
||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
|
||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
|
||||
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
||||
messages.getStatsURL#83f6c0cd peer:InputPeer = StatsURL;
|
||||
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
||||
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1101,8 +1214,7 @@ upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<Fil
|
||||
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
help.getAppUpdate#ae2de196 = help.AppUpdate;
|
||||
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getAppUpdate#522d5a7d source:string = help.AppUpdate;
|
||||
help.getInviteText#4d392343 = help.InviteText;
|
||||
help.getSupport#9cdf08cd = help.Support;
|
||||
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
|
||||
@ -1113,6 +1225,12 @@ help.getProxyData#3d7758e1 = help.ProxyData;
|
||||
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
|
||||
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
|
||||
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
|
||||
help.getAppConfig#98914110 = JSONValue;
|
||||
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getPassportConfig#c661ad08 hash:int = help.PassportConfig;
|
||||
help.getSupportName#d360e72c = help.SupportName;
|
||||
help.getUserInfo#38a08d3 user_id:InputUser = help.UserInfo;
|
||||
help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
@ -1124,8 +1242,7 @@ channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channe
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
|
||||
channels.createChannel#f4893d7f flags:# broadcast:flags.0?true megagroup:flags.1?true title:string about:string = Updates;
|
||||
channels.editAbout#13e27f1e channel:InputChannel about:string = Bool;
|
||||
channels.editAdmin#20b88214 channel:InputChannel user_id:InputUser admin_rights:ChannelAdminRights = Updates;
|
||||
channels.editAdmin#70f893ba channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights = Updates;
|
||||
channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
|
||||
channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
|
||||
channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
|
||||
@ -1133,14 +1250,11 @@ channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
|
||||
channels.joinChannel#24b524c5 channel:InputChannel = Updates;
|
||||
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
||||
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
|
||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
channels.editBanned#bfd915cd channel:InputChannel user_id:InputUser banned_rights:ChannelBannedRights = Updates;
|
||||
channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
|
||||
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
|
||||
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
|
||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||
@ -1172,9 +1286,10 @@ phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDisc
|
||||
phone.setCallRating#1c536a34 peer:InputPhoneCall rating:int comment:string = Updates;
|
||||
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
|
||||
|
||||
langpack.getLangPack#9ab5c58e lang_code:string = LangPackDifference;
|
||||
langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangPackString>;
|
||||
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
|
||||
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
|
||||
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
|
||||
langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
|
||||
langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
|
||||
|
||||
// LAYER 82
|
||||
// LAYER 95
|
||||
|
@ -9,14 +9,16 @@ class {class_name}(Object):
|
||||
"""{docstring_args}
|
||||
"""
|
||||
|
||||
__slots__ = [{slots}]
|
||||
|
||||
ID = {object_id}
|
||||
QUALNAME = "{qualname}"
|
||||
|
||||
def __init__(self{arguments}):
|
||||
{fields}
|
||||
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args) -> "{class_name}":
|
||||
{read_flags}
|
||||
{read_types}
|
||||
return {class_name}({return_arguments})
|
||||
|
||||
@ -24,6 +26,5 @@ class {class_name}(Object):
|
||||
b = BytesIO()
|
||||
b.write(Int(self.ID, False))
|
||||
|
||||
{write_flags}
|
||||
{write_types}
|
||||
return b.getvalue()
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -51,7 +51,7 @@ BOT_INLINE_DISABLED The inline feature of the bot is disabled
|
||||
INLINE_RESULT_EXPIRED The inline bot query expired
|
||||
INVITE_HASH_INVALID The invite link hash is invalid
|
||||
USER_ALREADY_PARTICIPANT The user is already a participant of this chat
|
||||
TTL_MEDIA_INVALID This kind of media does not support self-destruction
|
||||
TTL_MEDIA_INVALID The media does not support self-destruction
|
||||
MAX_ID_INVALID The max_id parameter is invalid
|
||||
CHANNEL_INVALID The channel parameter is invalid
|
||||
DC_ID_INVALID The dc_id parameter is invalid
|
||||
@ -59,15 +59,40 @@ LIMIT_INVALID The limit parameter is invalid
|
||||
OFFSET_INVALID The offset parameter is invalid
|
||||
EMAIL_INVALID The email provided is invalid
|
||||
USER_IS_BOT A bot cannot send messages to other bots or to itself
|
||||
WEBPAGE_CURL_FAILED Telegram could not fetch the provided URL
|
||||
WEBPAGE_CURL_FAILED Telegram server could not fetch the provided URL
|
||||
STICKERSET_INVALID The requested sticker set is invalid
|
||||
PEER_FLOOD The method can't be used because your account is limited
|
||||
MEDIA_CAPTION_TOO_LONG The media caption is longer than 200 characters
|
||||
MEDIA_CAPTION_TOO_LONG The media caption is longer than 1024 characters
|
||||
USER_NOT_MUTUAL_CONTACT The user is not a mutual contact
|
||||
USER_CHANNELS_TOO_MUCH The user is already in too many channels or supergroups
|
||||
API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side
|
||||
USER_NOT_PARTICIPANT The user is not a member of this chat
|
||||
CHANNEL_PRIVATE The channel/supergroup is not accessible
|
||||
MESSAGE_IDS_EMPTY The requested message doesn't exist
|
||||
WEBPAGE_MEDIA_EMPTY The URL doesn't contain any valid media
|
||||
QUERY_ID_INVALID The callback query id is invalid
|
||||
MEDIA_EMPTY The media is invalid
|
||||
USER_IS_BLOCKED The user blocked you
|
||||
YOU_BLOCKED_USER You blocked this user
|
||||
ADMINS_TOO_MUCH The chat has too many administrators
|
||||
BOTS_TOO_MUCH The chat has too many bots
|
||||
USER_ADMIN_INVALID The action requires admin privileges
|
||||
INPUT_USER_DEACTIVATED The target user has been deactivated
|
||||
PASSWORD_RECOVERY_NA The password recovery e-mail is not available
|
||||
PASSWORD_EMPTY The password entered is empty
|
||||
PHONE_NUMBER_FLOOD This number has tried to login too many times
|
||||
TAKEOUT_INVALID The takeout id is invalid
|
||||
TAKEOUT_REQUIRED The method must be invoked inside a takeout session
|
||||
MESSAGE_POLL_CLOSED You can't interact with a closed poll
|
||||
MEDIA_INVALID The media is invalid
|
||||
BOT_SCORE_NOT_MODIFIED The bot score was not modified
|
||||
USER_BOT_REQUIRED The method can be used by bots only
|
||||
IMAGE_PROCESS_FAILED The server failed to process your image
|
||||
USERNAME_NOT_MODIFIED The username was not modified
|
||||
CALL_ALREADY_ACCEPTED The call is already accepted
|
||||
CALL_ALREADY_DECLINED The call is already declined
|
||||
PHOTO_EXT_INVALID The photo extension is invalid
|
||||
EXTERNAL_URL_INVALID The external media URL is invalid
|
||||
CHAT_NOT_MODIFIED The chat settings were not modified
|
||||
RESULTS_TOO_MUCH The result contains too many items
|
||||
RESULT_ID_DUPLICATE The result contains items with duplicated identifiers
|
|
@ -1,2 +1,3 @@
|
||||
id message
|
||||
AUTH_KEY_DUPLICATED Authorization error. You must log out and log in again with your phone number. We apologize for the inconvenience.
|
||||
AUTH_KEY_DUPLICATED Authorization error - you must delete your session file and log in again with your phone number
|
||||
FILEREF_UPGRADE_NEEDED The file reference has expired - you must obtain the original media message
|
|
@ -1,2 +1,3 @@
|
||||
id message
|
||||
FLOOD_WAIT_X A wait of {x} seconds is required
|
||||
TAKEOUT_INIT_DELAY_X You have to confirm the data export request using one of your mobile devices or wait {x} seconds
|
||||
|
|
@ -5,3 +5,4 @@ RPC_MCGET_FAIL Telegram is having internal problems. Please try again later
|
||||
PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later
|
||||
HISTORY_GET_FAILED Telegram is having internal problems. Please try again later
|
||||
REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later
|
||||
RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later
|
|
@ -1,5 +1,5 @@
|
||||
Bad Request
|
||||
===========
|
||||
400 - Bad Request
|
||||
=================
|
||||
|
||||
.. module:: pyrogram.api.errors.BadRequest
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Flood
|
||||
=====
|
||||
420 - Flood
|
||||
===========
|
||||
|
||||
.. module:: pyrogram.api.errors.Flood
|
||||
|
||||
|
8
docs/source/errors/Forbidden.rst
Normal file
8
docs/source/errors/Forbidden.rst
Normal file
@ -0,0 +1,8 @@
|
||||
403 - Forbidden
|
||||
===============
|
||||
|
||||
.. module:: pyrogram.api.errors.Forbidden
|
||||
|
||||
.. automodule:: pyrogram.api.errors.exceptions.forbidden_403
|
||||
:members:
|
||||
:show-inheritance:
|
@ -1,5 +1,5 @@
|
||||
Internal Server Error
|
||||
=====================
|
||||
500 - Internal Server Error
|
||||
===========================
|
||||
|
||||
.. module:: pyrogram.api.errors.InternalServerError
|
||||
|
||||
|
8
docs/source/errors/NotAcceptable.rst
Normal file
8
docs/source/errors/NotAcceptable.rst
Normal file
@ -0,0 +1,8 @@
|
||||
406 - Not Acceptable
|
||||
====================
|
||||
|
||||
.. module:: pyrogram.api.errors.NotAcceptable
|
||||
|
||||
.. automodule:: pyrogram.api.errors.exceptions.not_acceptable_406
|
||||
:members:
|
||||
:show-inheritance:
|
@ -1,5 +1,5 @@
|
||||
See Other
|
||||
=========
|
||||
303 - See Other
|
||||
===============
|
||||
|
||||
.. module:: pyrogram.api.errors.SeeOther
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Unauthorized
|
||||
============
|
||||
401 - Unauthorized
|
||||
==================
|
||||
|
||||
.. module:: pyrogram.api.errors.Unauthorized
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Unknown Error
|
||||
=============
|
||||
520 - Unknown Error
|
||||
===================
|
||||
|
||||
.. module:: pyrogram.api.errors.UnknownError
|
||||
|
||||
|
@ -10,27 +10,28 @@ Welcome to Pyrogram
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
<b>Telegram MTProto API Client Library for Python</b>
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
|
||||
<br>
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases/latest">
|
||||
Download
|
||||
<a href="https://docs.pyrogram.ml">
|
||||
Documentation
|
||||
</a>
|
||||
•
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
Source code
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Changelog
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/PyrogramChat">
|
||||
Community
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://github.com/pyrogram/pyrogram/blob/master/compiler/api/source/main_api.tl">
|
||||
<img src="https://img.shields.io/badge/schema-layer%2082-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="Scheme Layer">
|
||||
<a href="compiler/api/source/main_api.tl">
|
||||
<img src="https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="Schema Layer">
|
||||
</a>
|
||||
<a href="https://github.com/pyrogram/tgcrypto">
|
||||
<img src="https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="TgCrypto">
|
||||
alt="TgCrypto Version">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -48,25 +49,27 @@ Welcome to Pyrogram
|
||||
|
||||
app.run()
|
||||
|
||||
Welcome to Pyrogram's Documentation! Here you can find resources for learning how to use the library.
|
||||
Welcome to Pyrogram's Documentation! Here you can find resources for learning how to use the framework.
|
||||
Contents are organized into self-contained topics and can be accessed from the sidebar, or by following them in order
|
||||
using the Next button at the end of each page. But first, here's a brief overview of what is this all 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 custom Telegram applications that interact with the MTProto API as both User and Bot.
|
||||
**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C.
|
||||
It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the `MTProto API`_.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- **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.
|
||||
- **Easy**: You can install Pyrogram with pip and start building your applications right away.
|
||||
- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way.
|
||||
- **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 82 on top of MTProto 2.0.
|
||||
- **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.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **Updated**, to the latest Telegram API version, currently Layer 95 on top of `MTProto 2.0`_.
|
||||
- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code.
|
||||
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more.
|
||||
|
||||
To get started, press the Next button.
|
||||
|
||||
@ -84,6 +87,8 @@ To get started, press the Next button.
|
||||
|
||||
resources/UpdateHandling
|
||||
resources/UsingFilters
|
||||
resources/MoreOnUpdates
|
||||
resources/ConfigurationFile
|
||||
resources/SmartPlugins
|
||||
resources/AutoAuthorization
|
||||
resources/CustomizeSessions
|
||||
@ -92,6 +97,10 @@ To get started, press the Next button.
|
||||
resources/SOCKS5Proxy
|
||||
resources/BotsInteraction
|
||||
resources/ErrorHandling
|
||||
resources/TestServers
|
||||
resources/AdvancedUsage
|
||||
resources/VoiceCalls
|
||||
resources/Changelog
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
@ -108,3 +117,5 @@ To get started, press the Next button.
|
||||
|
||||
.. _`Telegram`: https://telegram.org/
|
||||
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto/
|
||||
.. _`MTProto API`: https://core.telegram.org/api#telegram-api
|
||||
.. _`MTProto 2.0`: https://core.telegram.org/mtproto
|
@ -13,13 +13,15 @@ Utilities
|
||||
|
||||
start
|
||||
stop
|
||||
restart
|
||||
idle
|
||||
run
|
||||
add_handler
|
||||
remove_handler
|
||||
send
|
||||
resolve_peer
|
||||
download_media
|
||||
save_file
|
||||
stop_transmission
|
||||
|
||||
Decorators
|
||||
----------
|
||||
@ -62,6 +64,11 @@ Messages
|
||||
delete_messages
|
||||
get_messages
|
||||
get_history
|
||||
iter_history
|
||||
send_poll
|
||||
vote_poll
|
||||
retract_vote
|
||||
download_media
|
||||
|
||||
Chats
|
||||
-----
|
||||
@ -83,10 +90,13 @@ Chats
|
||||
pin_chat_message
|
||||
unpin_chat_message
|
||||
get_chat
|
||||
get_chat_preview
|
||||
get_chat_member
|
||||
get_chat_members
|
||||
get_chat_members_count
|
||||
iter_chat_members
|
||||
get_dialogs
|
||||
iter_dialogs
|
||||
|
||||
Users
|
||||
-----
|
||||
@ -130,6 +140,9 @@ Bots
|
||||
send_inline_bot_result
|
||||
answer_callback_query
|
||||
request_callback_answer
|
||||
send_game
|
||||
set_game_score
|
||||
get_game_high_scores
|
||||
|
||||
|
||||
.. autoclass:: pyrogram.Client
|
||||
|
@ -9,6 +9,8 @@ Error
|
||||
../errors/SeeOther
|
||||
../errors/BadRequest
|
||||
../errors/Unauthorized
|
||||
../errors/Forbidden
|
||||
../errors/NotAcceptable
|
||||
../errors/Flood
|
||||
../errors/InternalServerError
|
||||
../errors/UnknownError
|
||||
|
@ -12,9 +12,11 @@ Users & Chats
|
||||
User
|
||||
UserStatus
|
||||
Chat
|
||||
ChatPreview
|
||||
ChatPhoto
|
||||
ChatMember
|
||||
ChatMembers
|
||||
ChatPermissions
|
||||
Dialog
|
||||
Dialogs
|
||||
|
||||
@ -40,6 +42,8 @@ Messages & Media
|
||||
Location
|
||||
Venue
|
||||
Sticker
|
||||
Poll
|
||||
PollOption
|
||||
|
||||
Bots
|
||||
----
|
||||
@ -54,6 +58,7 @@ Bots
|
||||
InlineKeyboardButton
|
||||
ForceReply
|
||||
CallbackQuery
|
||||
Game
|
||||
|
||||
Input Media
|
||||
-----------
|
||||
@ -91,6 +96,9 @@ Inline Mode
|
||||
.. autoclass:: Chat
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPreview
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPhoto
|
||||
:members:
|
||||
|
||||
@ -157,6 +165,12 @@ Inline Mode
|
||||
.. autoclass:: Sticker
|
||||
:members:
|
||||
|
||||
.. autoclass:: Poll
|
||||
:members:
|
||||
|
||||
.. autoclass:: PollOption
|
||||
:members:
|
||||
|
||||
.. Bots
|
||||
----
|
||||
|
||||
@ -181,6 +195,15 @@ Inline Mode
|
||||
.. autoclass:: CallbackQuery
|
||||
:members:
|
||||
|
||||
.. autoclass:: Game
|
||||
:members:
|
||||
|
||||
.. autoclass:: GameHighScore
|
||||
:members:
|
||||
|
||||
.. autoclass:: GameHighScores
|
||||
:members:
|
||||
|
||||
.. Input Media
|
||||
-----------
|
||||
|
||||
|
121
docs/source/resources/AdvancedUsage.rst
Normal file
121
docs/source/resources/AdvancedUsage.rst
Normal file
@ -0,0 +1,121 @@
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main Telegram
|
||||
API with its raw functions and types.
|
||||
|
||||
Telegram Raw API
|
||||
----------------
|
||||
|
||||
If you can't find a high-level method for your needs or if you 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 ``pyrogram.api`` package and call any Telegram API method you wish using the
|
||||
:meth:`send() <pyrogram.Client.send>` method provided by the Client class.
|
||||
|
||||
.. hint::
|
||||
|
||||
Every available high-level method mentioned in the previous page 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
|
||||
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_!
|
||||
|
||||
Caveats
|
||||
-------
|
||||
|
||||
As hinted before, raw functions and types can be confusing, mainly because people don't realize they must accept
|
||||
*exactly* the right values, but also because most of them don't have enough Python experience to fully grasp how things
|
||||
work.
|
||||
|
||||
This section will therefore explain some pitfalls to take into consideration when working with the raw API.
|
||||
|
||||
Chat IDs
|
||||
^^^^^^^^
|
||||
|
||||
The way Telegram works makes it impossible to directly send a message to a user or a chat by using their IDs only.
|
||||
Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed.
|
||||
|
||||
There are three different InputPeer types, one for each kind of Telegram entity.
|
||||
Whenever an InputPeer is needed you must pass one of these:
|
||||
|
||||
- `InputPeerUser <https://docs.pyrogram.ml/types/InputPeerUser>`_ - Users
|
||||
- `InputPeerChat <https://docs.pyrogram.ml/types/InputPeerChat>`_ - Basic Chats
|
||||
- `InputPeerChannel <https://docs.pyrogram.ml/types/InputPeerChannel>`_ - Either Channels or Supergroups
|
||||
|
||||
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
|
||||
:meth:`resolve_peer() <pyrogram.Client.resolve_peer>` as a convenience utility method that returns the correct InputPeer
|
||||
by accepting a peer ID only.
|
||||
|
||||
Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and
|
||||
all positive within their respective raw types.
|
||||
|
||||
Things are different when working with Pyrogram's API because having them in the same space can theoretically lead to
|
||||
collisions, and that's why Pyrogram (as well as the official Bot API) uses a slightly different representation for each
|
||||
kind of ID.
|
||||
|
||||
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:
|
||||
|
||||
- ``+ID`` - User: *123456789*
|
||||
- ``-ID`` - Chat: *-123456789*
|
||||
- ``-100ID`` - Channel (and Supergroup): *-100123456789*
|
||||
|
||||
So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an
|
||||
high-level method.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
- Update first name, last name and bio:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.account.UpdateProfile(
|
||||
first_name="Dan", last_name="Tès",
|
||||
about="Bio written from Pyrogram"
|
||||
)
|
||||
)
|
||||
|
||||
- Share your Last Seen time only with your contacts:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.account.SetPrivacy(
|
||||
key=types.InputPrivacyKeyStatusTimestamp(),
|
||||
rules=[types.InputPrivacyValueAllowContacts()]
|
||||
)
|
||||
)
|
||||
|
||||
- Invite users to your channel/supergroup:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.channels.InviteToChannel(
|
||||
channel=app.resolve_peer(123456789), # ID or Username
|
||||
users=[ # The users you want to invite
|
||||
app.resolve_peer(23456789), # By ID
|
||||
app.resolve_peer("username"), # By username
|
||||
app.resolve_peer("393281234567"), # By phone number
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
.. _plenty of them: ../pyrogram/Client.html#messages
|
||||
.. _Raw Functions: Usage.html#using-raw-functions
|
||||
.. _Community: https://t.me/PyrogramChat
|
11
docs/source/resources/Changelog.rst
Normal file
11
docs/source/resources/Changelog.rst
Normal file
@ -0,0 +1,11 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Currently, all Pyrogram release notes live inside the GitHub repository web page:
|
||||
https://github.com/pyrogram/pyrogram/releases
|
||||
|
||||
(You will be automatically redirected in 10 seconds.)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<meta http-equiv="refresh" content="10; URL=https://github.com/pyrogram/pyrogram/releases"/>
|
90
docs/source/resources/ConfigurationFile.rst
Normal file
90
docs/source/resources/ConfigurationFile.rst
Normal file
@ -0,0 +1,90 @@
|
||||
Configuration File
|
||||
==================
|
||||
|
||||
As already mentioned in previous sections, Pyrogram can also be configured by the use of an INI file.
|
||||
This page explains how this file is structured in Pyrogram, how to use it and why.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The idea behind using a configuration file is to help keeping your code free of settings (private) information such as
|
||||
the API Key and Proxy without having you to even deal with how to load such settings. The configuration file, usually
|
||||
referred as ``config.ini`` file, is automatically loaded from the root of your working directory; all you need to do is
|
||||
fill in the necessary parts.
|
||||
|
||||
.. note::
|
||||
|
||||
The configuration file is optional, but recommended. If, for any reason, you prefer not to use it, there's always an
|
||||
alternative way to configure Pyrogram via Client's parameters. Doing so, you can have full control on how to store
|
||||
and load your settings (e.g.: from environment variables).
|
||||
|
||||
Settings specified via Client's parameter have higher priority and will override any setting stored in the
|
||||
configuration file.
|
||||
|
||||
|
||||
The config.ini File
|
||||
-------------------
|
||||
|
||||
By default, Pyrogram will look for a file named ``config.ini`` placed at the root of your working directory, that is,
|
||||
the same folder of your running script. You can change the name or location of your configuration file by specifying it
|
||||
in your Client's parameter *config_file*.
|
||||
|
||||
- Replace the default *config.ini* file with *my_configuration.ini*:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account", config_file="my_configuration.ini")
|
||||
|
||||
|
||||
Configuration Sections
|
||||
----------------------
|
||||
|
||||
These are all the sections Pyrogram uses in its configuration file:
|
||||
|
||||
Pyrogram
|
||||
^^^^^^^^
|
||||
|
||||
The ``[pyrogram]`` section contains your Telegram API credentials *api_id* and *api_hash*.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pyrogram]
|
||||
api_id = 12345
|
||||
api_hash = 0123456789abcdef0123456789abcdef
|
||||
|
||||
`More info about API Key. <../start/Setup.html#configuration>`_
|
||||
|
||||
Proxy
|
||||
^^^^^
|
||||
|
||||
The ``[proxy]`` section contains settings about your SOCKS5 proxy.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[proxy]
|
||||
enabled = True
|
||||
hostname = 11.22.33.44
|
||||
port = 1080
|
||||
username = <your_username>
|
||||
password = <your_password>
|
||||
|
||||
`More info about SOCKS5 Proxy. <SOCKS5Proxy.html>`_
|
||||
|
||||
Plugins
|
||||
^^^^^^^
|
||||
|
||||
The ``[plugins]`` section contains settings about Smart Plugins.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
include =
|
||||
module
|
||||
folder.module
|
||||
exclude =
|
||||
module fn2
|
||||
|
||||
`More info about Smart Plugins. <SmartPlugins.html>`_
|
@ -1,17 +1,18 @@
|
||||
Error Handling
|
||||
==============
|
||||
|
||||
Errors are inevitable when working with the API, and they must be correctly handled by
|
||||
the use of ``try..except`` blocks.
|
||||
Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks.
|
||||
|
||||
There are many errors that Telegram could return, but they all fall in one of these five exception categories
|
||||
There are many errors that Telegram could return, but they all fall in one of these categories
|
||||
(which are in turn children of the :obj:`pyrogram.Error` superclass)
|
||||
|
||||
- :obj:`303 See Other <pyrogram.api.errors.SeeOther>`
|
||||
- :obj:`400 Bad Request <pyrogram.api.errors.BadRequest>`
|
||||
- :obj:`401 Unauthorized <pyrogram.api.errors.Unauthorized>`
|
||||
- :obj:`420 Flood <pyrogram.api.errors.Flood>`
|
||||
- :obj:`500 Internal Server Error <pyrogram.api.errors.InternalServerError>`
|
||||
- :obj:`303 - See Other <pyrogram.api.errors.SeeOther>`
|
||||
- :obj:`400 - Bad Request <pyrogram.api.errors.BadRequest>`
|
||||
- :obj:`401 - Unauthorized <pyrogram.api.errors.Unauthorized>`
|
||||
- :obj:`403 - Forbidden <pyrogram.api.errors.Forbidden>`
|
||||
- :obj:`406 - Not Acceptable <pyrogram.api.errors.NotAcceptable>`
|
||||
- :obj:`420 - Flood <pyrogram.api.errors.Flood>`
|
||||
- :obj:`500 - Internal Server Error <pyrogram.api.errors.InternalServerError>`
|
||||
|
||||
As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a
|
||||
specific one, it raises a special :obj:`520 Unknown Error <pyrogram.api.errors.UnknownError>` exception and logs it
|
||||
@ -56,5 +57,3 @@ before you can try again. The value is always stored in the ``x`` field of the r
|
||||
...
|
||||
except FloodWait as e:
|
||||
time.sleep(e.x)
|
||||
|
||||
**TODO: Better explanation on how to deal with exceptions**
|
221
docs/source/resources/MoreOnUpdates.rst
Normal file
221
docs/source/resources/MoreOnUpdates.rst
Normal file
@ -0,0 +1,221 @@
|
||||
More on Updates
|
||||
===============
|
||||
|
||||
Here we'll show some advanced usages when working with updates.
|
||||
|
||||
.. note::
|
||||
This page makes use of Handlers and Filters to show you how to handle updates.
|
||||
Learn more at `Update Handling <UpdateHandling.html>`_ and `Using Filters <UsingFilters.html>`_.
|
||||
|
||||
Handler Groups
|
||||
--------------
|
||||
|
||||
If you register handlers with overlapping filters, only the first one is executed and any other handler will be ignored.
|
||||
|
||||
In order to process the same update more than once, you can register your handler in a different group.
|
||||
Groups are identified by a number (number 0 being the default) and are sorted, that is, a lower group number has a
|
||||
higher priority.
|
||||
|
||||
For example, in:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text | Filters.sticker)
|
||||
def text_or_sticker(client, message):
|
||||
print("Text or Sticker")
|
||||
|
||||
|
||||
@app.on_message(Filters.text)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
``just_text`` is never executed because ``text_or_sticker`` already handles texts. To enable it, simply register the
|
||||
function using a different group:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text, group=1)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text, group=-1)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
With :meth:`add_handler() <pyrogram.Client.add_handler>` (without decorators) the same can be achieved with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.add_handler(MessageHandler(just_text, Filters.text), -1)
|
||||
|
||||
Update propagation
|
||||
------------------
|
||||
|
||||
Registering multiple handlers, each in a different group, becomes useful when you want to handle the same update more
|
||||
than once. Any incoming update will be sequentially processed by all of your registered functions by respecting the
|
||||
groups priority policy described above. Even in case any handler raises an unhandled exception, Pyrogram will still
|
||||
continue to propagate the same update to the next groups until all the handlers are done. Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(0)
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=1)
|
||||
def _(client, message):
|
||||
print(1 / 0) # Unhandled exception: ZeroDivisionError
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=2)
|
||||
def _(client, message):
|
||||
print(2)
|
||||
|
||||
All these handlers will handle the same kind of messages, that are, messages sent or received in private chats.
|
||||
The output for each incoming update will therefore be:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
0
|
||||
ZeroDivisionError: division by zero
|
||||
2
|
||||
|
||||
Stop Propagation
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to prevent further propagation of an update in the dispatching phase, you can do *one* of the following:
|
||||
|
||||
- Call the update's bound-method ``.stop_propagation()`` (preferred way).
|
||||
- Manually ``raise StopPropagation`` exception (more suitable for raw updates only).
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, the propagation is stopped by handling a custom exception. ``.stop_propagation()`` is just an elegant
|
||||
and intuitive way to ``raise StopPropagation``; this also means that any code coming *after* calling the method
|
||||
won't be executed as your function just raised an exception to signal the dispatcher not to propagate the
|
||||
update anymore.
|
||||
|
||||
Example with ``stop_propagation()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(0)
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=1)
|
||||
def _(client, message):
|
||||
print(1)
|
||||
message.stop_propagation()
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=2)
|
||||
def _(client, message):
|
||||
print(2)
|
||||
|
||||
Example with ``raise StopPropagation``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import StopPropagation
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(0)
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=1)
|
||||
def _(client, message):
|
||||
print(1)
|
||||
raise StopPropagation
|
||||
|
||||
|
||||
@app.on_message(Filters.private, group=2)
|
||||
def _(client, message):
|
||||
print(2)
|
||||
|
||||
Each handler is registered in a different group, but the handler in group number 2 will never be executed because the
|
||||
propagation was stopped earlier. The output of both (equivalent) examples will be:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
0
|
||||
1
|
||||
|
||||
Continue Propagation
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As opposed to `stopping the update propagation <#stop-propagation>`_ and also as an alternative to the
|
||||
`handler groups <#handler-groups>`_, you can signal the internal dispatcher to continue the update propagation within
|
||||
the group regardless of the next handler's filters. This allows you to register multiple handlers with overlapping
|
||||
filters in the same group; to let the dispatcher process the next handler you can do *one* of the following in each
|
||||
handler you want to grant permission to continue:
|
||||
|
||||
- Call the update's bound-method ``.continue_propagation()`` (preferred way).
|
||||
- Manually ``raise ContinuePropagation`` exception (more suitable for raw updates only).
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, the propagation is continued by handling a custom exception. ``.continue_propagation()`` is just an
|
||||
elegant and intuitive way to ``raise ContinuePropagation``; this also means that any code coming *after* calling the
|
||||
method won't be executed as your function just raised an exception to signal the dispatcher to continue with the
|
||||
next available handler.
|
||||
|
||||
|
||||
Example with ``continue_propagation()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(0)
|
||||
message.continue_propagation()
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(1)
|
||||
message.continue_propagation()
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(2)
|
||||
|
||||
Example with ``raise ContinuePropagation``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import ContinuePropagation
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(0)
|
||||
raise ContinuePropagation
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(1)
|
||||
raise ContinuePropagation
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def _(client, message):
|
||||
print(2)
|
||||
|
||||
Three handlers are registered in the same group, and all of them will be executed because the propagation was continued
|
||||
in each handler (except in the last one, where is useless to do so since there is no more handlers after).
|
||||
The output of both (equivalent) examples will be:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
0
|
||||
1
|
||||
2
|
@ -1,9 +1,9 @@
|
||||
Smart Plugins
|
||||
=============
|
||||
|
||||
Pyrogram embeds a **smart** (automatic) and lightweight plugin system that is meant to further simplify the organization
|
||||
of large projects and to provide a way for creating pluggable components that can be **easily shared** across different
|
||||
Pyrogram applications with **minimal boilerplate code**.
|
||||
Pyrogram embeds a **smart**, lightweight yet powerful plugin system that is meant to further simplify the organization
|
||||
of large projects and to provide a way for creating pluggable (modular) components that can be **easily shared** across
|
||||
different Pyrogram applications with **minimal boilerplate code**.
|
||||
|
||||
.. tip::
|
||||
|
||||
@ -13,7 +13,8 @@ Introduction
|
||||
------------
|
||||
|
||||
Prior to the Smart Plugin system, pluggable handlers were already possible. For example, if you wanted to modularize
|
||||
your applications, you had to do something like this...
|
||||
your applications, you had to put your function definitions in separate files and register them inside your main script,
|
||||
like this:
|
||||
|
||||
.. note::
|
||||
|
||||
@ -63,19 +64,19 @@ your applications, you had to do something like this...
|
||||
|
||||
app.run()
|
||||
|
||||
...which is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
|
||||
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
|
||||
manually ``import``, manually :meth:`add_handler <pyrogram.Client.add_handler>` and manually instantiate each
|
||||
:obj:`MessageHandler <pyrogram.MessageHandler>` object because **you can't use those cool decorators** for your
|
||||
functions. So... What if you could?
|
||||
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
|
||||
|
||||
Using Smart Plugins
|
||||
-------------------
|
||||
|
||||
Setting up your Pyrogram project to accommodate Smart Plugins is pretty straightforward:
|
||||
Setting up your Pyrogram project to accommodate Smart Plugins is straightforward:
|
||||
|
||||
#. Create a new folder to store all the plugins (e.g.: "plugins").
|
||||
#. Put your files full of plugins inside.
|
||||
#. Enable plugins in your Client.
|
||||
#. Create a new folder to store all the plugins (e.g.: "plugins", "handlers", ...).
|
||||
#. Put your python files full of plugins inside. Organize them as you wish.
|
||||
#. Enable plugins in your Client or via the *config.ini* file.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -107,20 +108,252 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
def echo_reversed(client, message):
|
||||
message.reply(message.text[::-1])
|
||||
|
||||
- ``config.ini``
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
Client("my_account", plugins_dir="plugins").run()
|
||||
Client("my_account").run()
|
||||
|
||||
The first important thing to note is the new ``plugins`` folder, whose name is passed to the the ``plugins_dir``
|
||||
parameter when creating a :obj:`Client <pyrogram.Client>` in the ``main.py`` file — you can put *any python file* in
|
||||
there and each file can contain *any decorated function* (handlers) with only one limitation: within a single plugin
|
||||
file you must use different names for each decorated function. Your Pyrogram Client instance will **automatically**
|
||||
scan the folder upon creation to search for valid handlers and register them for you.
|
||||
Alternatively, without using the *config.ini* file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
plugins = dict(
|
||||
root="plugins"
|
||||
)
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
The first important thing to note is the new ``plugins`` folder. You can put *any python file* in *any subfolder* and
|
||||
each file can contain *any decorated function* (handlers) with one limitation: within a single module (file) you must
|
||||
use different names for each decorated function.
|
||||
|
||||
The second thing is telling Pyrogram where to look for your plugins: you can either use the *config.ini* file or
|
||||
the Client parameter "plugins"; the *root* value must match the name of your plugins folder. Your Pyrogram Client
|
||||
instance will **automatically** scan the folder upon starting to search for valid handlers and register them for you.
|
||||
|
||||
Then you'll notice you can now use decorators. That's right, you can apply the usual decorators to your callback
|
||||
functions in a static way, i.e. **without having the Client instance around**: simply use ``@Client`` (Client class)
|
||||
instead of the usual ``@app`` (Client instance) namespace and things will work just the same.
|
||||
instead of the usual ``@app`` (Client instance) and things will work just the same.
|
||||
|
||||
Specifying the Plugins to include
|
||||
---------------------------------
|
||||
|
||||
By default, if you don't explicitly supply a list of plugins, every valid one found inside your plugins root folder will
|
||||
be included by following the alphabetical order of the directory structure (files and subfolders); the single handlers
|
||||
found inside each module will be, instead, loaded in the order they are defined, from top to bottom.
|
||||
|
||||
.. note::
|
||||
|
||||
Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping
|
||||
filters included a second time will not work. Learn more at `More on Updates <MoreOnUpdates.html>`_.
|
||||
|
||||
This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or
|
||||
exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude``
|
||||
keys, either in the *config.ini* file or in the dictionary passed as Client argument. Here's how they work:
|
||||
|
||||
- If both ``include`` and ``exclude`` are omitted, all plugins are loaded as described above.
|
||||
- If ``include`` is given, only the specified plugins will be loaded, in the order they are passed.
|
||||
- If ``exclude`` is given, the plugins specified here will be unloaded.
|
||||
|
||||
The ``include`` and ``exclude`` value is a **list of strings**. Each string containing the path of the module relative
|
||||
to the plugins root folder, in Python notation (dots instead of slashes).
|
||||
|
||||
E.g.: ``subfolder.module`` refers to ``plugins/subfolder/module.py``, with ``root="plugins"``.
|
||||
|
||||
You can also choose the order in which the single handlers inside a module are loaded, thus overriding the default
|
||||
top-to-bottom loading policy. You can do this by appending the name of the functions to the module path, each one
|
||||
separated by a blank space.
|
||||
|
||||
E.g.: ``subfolder.module fn2 fn1 fn3`` will load *fn2*, *fn1* and *fn3* from *subfolder.module*, in this order.
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
Given this plugins folder structure with three modules, each containing their own handlers (fn1, fn2, etc...), which are
|
||||
also organized in subfolders:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
myproject/
|
||||
plugins/
|
||||
subfolder1/
|
||||
plugins1.py
|
||||
- fn1
|
||||
- fn2
|
||||
- fn3
|
||||
subfolder2/
|
||||
plugins2.py
|
||||
...
|
||||
plugins0.py
|
||||
...
|
||||
...
|
||||
|
||||
- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order
|
||||
(files) and definition order (handlers inside files):
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
|
||||
Using *Client*'s parameter:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
plugins = dict(
|
||||
root="plugins"
|
||||
)
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
include =
|
||||
subfolder2.plugins2
|
||||
plugins0
|
||||
|
||||
Using *Client*'s parameter:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
plugins = dict(
|
||||
root="plugins",
|
||||
include=[
|
||||
"subfolder2.plugins2",
|
||||
"plugins0"
|
||||
]
|
||||
)
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load everything except the handlers inside *plugins2.py*:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
exclude = subfolder2.plugins2
|
||||
|
||||
Using *Client*'s parameter:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
plugins = dict(
|
||||
root="plugins",
|
||||
exclude=["subfolder2.plugins2"]
|
||||
)
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
include = subfolder1.plugins1 fn3 fn1 fn2
|
||||
|
||||
Using *Client*'s parameter:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
plugins = dict(
|
||||
root="plugins",
|
||||
include=["subfolder1.plugins1 fn3 fn1 fn2"]
|
||||
)
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
Load/Unload Plugins at Runtime
|
||||
------------------------------
|
||||
|
||||
In the `previous section <#specifying-the-plugins-to-include>`_ we've explained how to specify which plugins to load and
|
||||
which to ignore before your Client starts. Here we'll show, instead, how to unload and load again a previously
|
||||
registered plugins at runtime.
|
||||
|
||||
Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram updates
|
||||
) will be modified in such a way that, when you reference them later on, they will be actually pointing to a tuple of
|
||||
*(handler: Handler, group: int)*. The actual callback function is therefore stored inside the handler's *callback*
|
||||
attribute. Here's an example:
|
||||
|
||||
- ``plugins/handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 5, 6
|
||||
|
||||
@Client.on_message(Filters.text & Filters.private)
|
||||
def echo(client, message):
|
||||
message.reply(message.text)
|
||||
|
||||
print(echo)
|
||||
print(echo[0].callback)
|
||||
|
||||
- Printing ``echo`` will show something like ``(<MessageHandler object at 0x10e3abc50>, 0)``.
|
||||
|
||||
- Printing ``echo[0].callback``, that is, the *callback* attribute of the first eleent of the tuple, which is an
|
||||
Handler, will reveal the actual callback ``<function echo at 0x10e3b6598>``.
|
||||
|
||||
Unloading
|
||||
^^^^^^^^^
|
||||
|
||||
In order to unload a plugin, or any other handler, all you need to do is obtain a reference to it (by importing the
|
||||
relevant module) and call :meth:`remove_handler <pyrogram.Client.remove_handler>` Client's method with your function
|
||||
name preceded by the star ``*`` operator as argument. Example:
|
||||
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from plugins.handlers import echo
|
||||
|
||||
...
|
||||
|
||||
app.remove_handler(*echo)
|
||||
|
||||
The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive
|
||||
exactly what is needed. The same could have been achieved with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
handler, group = echo
|
||||
app.remove_handler(handler, group)
|
||||
|
||||
Loading
|
||||
^^^^^^^
|
||||
|
||||
Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time
|
||||
using :meth:`add_handler <pyrogram.Client.add_handler>` instead. Example:
|
||||
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from plugins.handlers import echo
|
||||
|
||||
...
|
||||
|
||||
app.add_handler(*echo)
|
39
docs/source/resources/TestServers.rst
Normal file
39
docs/source/resources/TestServers.rst
Normal file
@ -0,0 +1,39 @@
|
||||
Test Servers
|
||||
============
|
||||
|
||||
If you wish to test your application in a separate environment, Pyrogram is able to authorize your account into
|
||||
Telegram's test servers without hassle. All you need to do is start a new session (e.g.: "my_account_test") using
|
||||
``test_mode=True``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
with Client("my_account_test", test_mode=True) as app:
|
||||
print(app.get_me())
|
||||
|
||||
.. note::
|
||||
|
||||
If this is the first time you login into test servers, you will be asked to register your account first.
|
||||
Don't worry about your contacts and chats, they will be kept untouched inside the production environment;
|
||||
accounts authorized on test servers reside in a different, parallel instance of a Telegram database.
|
||||
|
||||
Test Mode in Official Apps
|
||||
--------------------------
|
||||
|
||||
You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop:
|
||||
|
||||
- **Webogram**: Login here: https://web.telegram.org/?test=1
|
||||
- **TDesktop**: Open settings and type ``testmode``.
|
||||
|
||||
Test Numbers
|
||||
------------
|
||||
|
||||
Beside normal numbers, the test environment allows you to login with reserved test numbers.
|
||||
Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random
|
||||
numbers. Users with such numbers always get ``XXXXX`` as the confirmation code (the DC number, repeated five times).
|
||||
|
||||
.. important::
|
||||
|
||||
Do not store any important or private information in such test users' accounts; anyone can make use of the
|
||||
simplified authorization mechanism and login at any time.
|
@ -1,5 +1,5 @@
|
||||
TgCrypto
|
||||
========
|
||||
Fast Crypto
|
||||
===========
|
||||
|
||||
Pyrogram's speed can be *dramatically* boosted up by TgCrypto_, a high-performance, easy-to-install Telegram Crypto
|
||||
Library specifically written in C for Pyrogram [#f1]_ as a Python extension.
|
||||
|
@ -5,7 +5,8 @@ For a finer grained control over what kind of messages will be allowed or not in
|
||||
:class:`Filters <pyrogram.Filters>`.
|
||||
|
||||
.. note::
|
||||
This section makes use of Handlers to handle updates. Learn more at `Update Handling <UpdateHandling.html>`_.
|
||||
This page makes use of Handlers to show you how to handle updates.
|
||||
Learn more at `Update Handling <UpdateHandling.html>`_.
|
||||
|
||||
- This example will show you how to **only** handle messages containing an :obj:`Audio <pyrogram.Audio>` object and
|
||||
ignore any other message:
|
||||
@ -99,45 +100,6 @@ More handlers using different filters can also live together.
|
||||
def from_pyrogramchat(client, message):
|
||||
print("New message in @PyrogramChat")
|
||||
|
||||
Handler Groups
|
||||
--------------
|
||||
|
||||
If you register handlers with overlapping filters, only the first one is executed and any other handler will be ignored.
|
||||
|
||||
In order to process the same message more than once, you can register your handler in a different group.
|
||||
Groups are identified by a number (number 0 being the default) and are sorted. This means that a lower group number has
|
||||
a higher priority.
|
||||
|
||||
For example, in:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text | Filters.sticker)
|
||||
def text_or_sticker(client, message):
|
||||
print("Text or Sticker")
|
||||
|
||||
|
||||
@app.on_message(Filters.text)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
``just_text`` is never executed because ``text_or_sticker`` already handles texts. To enable it, simply register the
|
||||
function using a different group:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text, group=1)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text, group=-1)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
Custom Filters
|
||||
--------------
|
||||
|
||||
@ -162,7 +124,7 @@ yourself. This allows you to test your filter by pressing the inline button:
|
||||
"username", # Change this to your username or id
|
||||
"Pyrogram's custom filter test",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[[InlineKeyboardButton("Press me", "pyrogram")]]
|
||||
[[InlineKeyboardButton("Press me", b"pyrogram")]]
|
||||
)
|
||||
)
|
||||
|
||||
@ -178,7 +140,7 @@ containing "pyrogram" as data:
|
||||
|
||||
hardcoded_data = Filters.create(
|
||||
name="HardcodedData",
|
||||
func=lambda filter, callback_query: callback_query.data == "pyrogram"
|
||||
func=lambda filter, callback_query: callback_query.data == b"pyrogram"
|
||||
)
|
||||
|
||||
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same
|
||||
@ -187,7 +149,7 @@ could be achieved with a normal function, but we don't really need it as it make
|
||||
.. code-block:: python
|
||||
|
||||
def func(filter, callback_query):
|
||||
return callback_query.data == "pyrogram"
|
||||
return callback_query.data == b"pyrogram"
|
||||
|
||||
hardcoded_data = Filters.create(
|
||||
name="HardcodedData",
|
||||
@ -223,6 +185,6 @@ And its usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(dynamic_data("pyrogram"))
|
||||
@app.on_callback_query(dynamic_data(b"pyrogram"))
|
||||
def pyrogram_data(client, callback_query):
|
||||
client.answer_callback_query(callback_query.id, "it works!")
|
10
docs/source/resources/VoiceCalls.rst
Normal file
10
docs/source/resources/VoiceCalls.rst
Normal file
@ -0,0 +1,10 @@
|
||||
Voice Calls
|
||||
===========
|
||||
|
||||
A working proof-of-concept of Telegram voice calls using Pyrogram can be found here:
|
||||
https://github.com/bakatrouble/pylibtgvoip. Thanks to `@bakatrouble <https://t.me/bakatrouble>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
This page will be updated with more information once voice calls become eventually more usable and more integrated
|
||||
in Pyrogram itself.
|
@ -18,23 +18,23 @@ Install Pyrogram
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ pip3 install --upgrade pyrogram
|
||||
$ pip3 install -U pyrogram
|
||||
|
||||
- or, with TgCrypto_ as extra requirement (recommended):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ pip3 install --upgrade pyrogram[fast]
|
||||
$ pip3 install -U pyrogram[fast]
|
||||
|
||||
Bleeding Edge
|
||||
-------------
|
||||
|
||||
If you want the latest development version of Pyrogram, you can install it straight from the develop_
|
||||
branch using this command (you might need to install **git** first):
|
||||
branch using this command (note "develop.zip" in the link):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ pip3 install --upgrade git+https://github.com/pyrogram/pyrogram.git
|
||||
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/develop.zip
|
||||
|
||||
Asynchronous
|
||||
------------
|
||||
@ -43,11 +43,11 @@ Pyrogram heavily depends on IO-bound network code (it's a cloud-based messaging
|
||||
where asyncio shines the most by providing extra performance while running on a single OS-level thread only.
|
||||
|
||||
**A fully asynchronous variant of Pyrogram is therefore available** (Python 3.5+ required).
|
||||
Use this command to install:
|
||||
Use this command to install (note "asyncio.zip" in the link):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ pip3 install --upgrade git+https://github.com/pyrogram/pyrogram.git@asyncio
|
||||
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/asyncio.zip
|
||||
|
||||
|
||||
Pyrogram API remains the same and features are kept up to date from the non-async, default develop branch, but you
|
||||
@ -82,7 +82,7 @@ If no error shows up you are good to go.
|
||||
|
||||
>>> import pyrogram
|
||||
>>> pyrogram.__version__
|
||||
'0.9.1'
|
||||
'0.12.0'
|
||||
|
||||
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
|
||||
.. _develop: http://github.com/pyrogram/pyrogram
|
||||
|
@ -1,8 +1,7 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
Having your `project set up`_ and your account authorized_, it's time to play with the API.
|
||||
In this section, you'll be shown two ways of communicating with Telegram using Pyrogram. Let's start!
|
||||
Having your `project set up`_ and your account authorized_, it's time to play with the API. Let's start!
|
||||
|
||||
High-level API
|
||||
--------------
|
||||
@ -43,79 +42,8 @@ exceptions in your code:
|
||||
|
||||
More examples on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_.
|
||||
|
||||
Raw Functions
|
||||
-------------
|
||||
|
||||
If you can't find a high-level method for your needs or if you 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
|
||||
``pyrogram.api`` package and call any Telegram API method you wish using the :meth:`send() <pyrogram.Client.send>`
|
||||
method provided by the Client class.
|
||||
|
||||
.. 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
|
||||
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_!
|
||||
|
||||
Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_):
|
||||
|
||||
- Update first name, last name and bio:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.account.UpdateProfile(
|
||||
first_name="Dan", last_name="Tès",
|
||||
about="Bio written from Pyrogram"
|
||||
)
|
||||
)
|
||||
|
||||
- Share your Last Seen time only with your contacts:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.account.SetPrivacy(
|
||||
key=types.InputPrivacyKeyStatusTimestamp(),
|
||||
rules=[types.InputPrivacyValueAllowContacts()]
|
||||
)
|
||||
)
|
||||
|
||||
- Invite users to your channel/supergroup:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.channels.InviteToChannel(
|
||||
channel=app.resolve_peer(123456789), # ID or Username
|
||||
users=[ # The users you want to invite
|
||||
app.resolve_peer(23456789), # By ID
|
||||
app.resolve_peer("username"), # By username
|
||||
app.resolve_peer("393281234567"), # By phone number
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
.. _methods: ../pyrogram/Client.html#messages
|
||||
.. _plenty of them: ../pyrogram/Client.html#messages
|
||||
.. _types: ../pyrogram/Types.html
|
||||
.. _Raw Functions: Usage.html#using-raw-functions
|
||||
.. _Community: https://t.me/PyrogramChat
|
||||
.. _project set up: Setup.html
|
||||
.. _authorized: Setup.html#user-authorization
|
||||
.. _Telegram Bot API: https://core.telegram.org/bots/api
|
||||
.. _methods: ../pyrogram/Client.html#messages
|
||||
.. _types: ../pyrogram/Types.html
|
@ -2,21 +2,21 @@
|
||||
|
||||
This folder contains example scripts to show you how **Pyrogram** looks like.
|
||||
|
||||
Every script is working right away (provided you correctly set up your credentials), meaning
|
||||
you can simply copy-paste and run. The only things you have to change are session names and target chats.
|
||||
Every script is working right away (provided you correctly set up your credentials), meaning you can simply copy-paste
|
||||
and run. The only things you have to change are session names and target chats.
|
||||
|
||||
All the examples listed in this directory are licensed under the terms of the [CC0 1.0 Universal](LICENSE) license and
|
||||
can be freely used as basic building blocks for your own applications without worrying about copyrights.
|
||||
|
||||
Example | Description
|
||||
---: | :---
|
||||
[**hello_world**](hello_world.py) | Demonstration of basic API usages
|
||||
[**echo_bot**](echo_bot.py) | Echo bot that replies to every private text message
|
||||
[**welcome_bot**](welcome_bot.py) | The Welcome Bot source code in [@PyrogramChat](https://t.me/pyrogramchat)
|
||||
[**get_history**](get_history.py) | How to retrieve the full message history of a chat
|
||||
[**get_chat_members**](get_chat_members.py) | How to get the first 10.000 members of a supergroup/channel
|
||||
[**get_chat_members2**](get_chat_members2.py) | Improved version to get more than 10.000 members
|
||||
[**query_inline_bots**](query_inline_bots.py) | How to query an inline bot and send a result to a chat
|
||||
[**send_bot_keyboards**](send_bot_keyboards.py) | How to send normal and inline keyboards using regular bots
|
||||
[**callback_query_handler**](callback_query_handler.py) | How to handle queries coming from inline button presses
|
||||
[**raw_update_handler**](raw_update_handler.py) | How to handle raw updates (old, should be avoided)
|
||||
[**hello**](hello.py) | Demonstration of basic API usage
|
||||
[**echo**](echo.py) | Reply to every private text message
|
||||
[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat)
|
||||
[**history**](history.py) | Get the full message history of a chat
|
||||
[**chat_members**](chat_members.py) | Get all the members of a chat
|
||||
[**dialogs**](dialogs.py) | Get all of your dialog chats
|
||||
[**inline_bots**](inline_bots.py) | Query an inline bot and send a result to a chat
|
||||
[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots
|
||||
[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses
|
||||
[**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided)
|
||||
|
10
examples/chat_members.py
Normal file
10
examples/chat_members.py
Normal file
@ -0,0 +1,10 @@
|
||||
"""This example shows how to get all the members of a chat."""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_count")
|
||||
target = "pyrogramchat" # Target channel/supergroup
|
||||
|
||||
with app:
|
||||
for member in app.iter_chat_members(target):
|
||||
print(member.user.first_name)
|
9
examples/dialogs.py
Normal file
9
examples/dialogs.py
Normal file
@ -0,0 +1,9 @@
|
||||
"""This example shows how to get the full dialogs list of a user."""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
for dialog in app.iter_dialogs():
|
||||
print(dialog.chat.title or dialog.chat.first_name)
|
@ -11,7 +11,7 @@ app = Client("my_account")
|
||||
|
||||
@app.on_message(Filters.text & Filters.private)
|
||||
def echo(client, message):
|
||||
message.reply(message.text, quote=True)
|
||||
message.reply(message.text)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
@ -1,31 +0,0 @@
|
||||
"""This example shows you how to get the first 10.000 members of a chat.
|
||||
Refer to get_chat_members2.py for more than 10.000 members.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api.errors import FloodWait
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
target = "pyrogramchat" # Target channel/supergroup
|
||||
members = [] # List that will contain all the members of the target chat
|
||||
offset = 0 # Offset starts at 0
|
||||
limit = 200 # Amount of users to retrieve for each API call (max 200)
|
||||
|
||||
with app:
|
||||
while True:
|
||||
try:
|
||||
chunk = app.get_chat_members(target, offset)
|
||||
except FloodWait as e: # Very large chats could trigger FloodWait
|
||||
time.sleep(e.x) # When it happens, wait X seconds and try again
|
||||
continue
|
||||
|
||||
if not chunk.chat_members:
|
||||
break # No more members left
|
||||
|
||||
members.extend(chunk.chat_members)
|
||||
offset += len(chunk.chat_members)
|
||||
|
||||
# Now the "members" list contains all the members of the target chat
|
@ -1,50 +0,0 @@
|
||||
"""This is an improved version of get_chat_members.py
|
||||
|
||||
Since Telegram will return at most 10.000 members for a single query, this script
|
||||
repeats the search using numbers ("0" to "9") and all the available ascii letters ("a" to "z").
|
||||
|
||||
This can be further improved by also searching for non-ascii characters (e.g.: Japanese script),
|
||||
as some user names may not contain ascii letters at all.
|
||||
"""
|
||||
|
||||
import time
|
||||
from string import ascii_lowercase
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api.errors import FloodWait
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
target = "pyrogramchat" # Target channel/supergroup
|
||||
members = {} # List that will contain all the members of the target chat
|
||||
limit = 200 # Amount of users to retrieve for each API call (max 200)
|
||||
|
||||
# "" + "0123456789" + "abcdefghijklmnopqrstuvwxyz" (as list)
|
||||
queries = [""] + [str(i) for i in range(10)] + list(ascii_lowercase)
|
||||
|
||||
with app:
|
||||
for q in queries:
|
||||
print('Searching for "{}"'.format(q))
|
||||
offset = 0 # For each query, offset restarts from 0
|
||||
|
||||
while True:
|
||||
try:
|
||||
chunk = app.get_chat_members(target, offset, query=q)
|
||||
except FloodWait as e: # Very large chats could trigger FloodWait
|
||||
print("Flood wait: {} seconds".format(e.x))
|
||||
time.sleep(e.x) # When it happens, wait X seconds and try again
|
||||
continue
|
||||
|
||||
if not chunk.chat_members:
|
||||
print('Done searching for "{}"'.format(q))
|
||||
print()
|
||||
break # No more members left
|
||||
|
||||
members.update({i.user.id: i for i in chunk.chat_members})
|
||||
offset += len(chunk.chat_members)
|
||||
|
||||
print("Total members: {}".format(len(members)))
|
||||
|
||||
print("Grand total: {}".format(len(members)))
|
||||
|
||||
# Now the "members" list contains all the members of the target chat
|
@ -1,31 +0,0 @@
|
||||
"""This example shows how to retrieve the full message history of a chat"""
|
||||
|
||||
import time
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.api.errors import FloodWait
|
||||
|
||||
app = Client("my_account")
|
||||
target = "me" # "me" refers to your own chat (Saved Messages)
|
||||
messages = [] # List that will contain all the messages of the target chat
|
||||
offset_id = 0 # ID of the last message of the chunk
|
||||
|
||||
with app:
|
||||
while True:
|
||||
try:
|
||||
m = app.get_history(target, offset_id=offset_id)
|
||||
except FloodWait as e: # For very large chats the method call can raise a FloodWait
|
||||
print("waiting {}".format(e.x))
|
||||
time.sleep(e.x) # Sleep X seconds before continuing
|
||||
continue
|
||||
|
||||
if not m.messages:
|
||||
break
|
||||
|
||||
messages += m.messages
|
||||
offset_id = m.messages[-1].message_id
|
||||
|
||||
print("Messages: {}".format(len(messages)))
|
||||
|
||||
# Now the "messages" list contains all the messages sorted by date in
|
||||
# descending order (from the most recent to the oldest one)
|
16
examples/hello.py
Normal file
16
examples/hello.py
Normal file
@ -0,0 +1,16 @@
|
||||
"""This example demonstrates a basic API usage"""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client instance
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
# Send a message, Markdown is enabled by default
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
|
||||
# Send a location
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
|
||||
# Send a sticker
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
@ -1,18 +0,0 @@
|
||||
"""This example demonstrates a basic API usage"""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client instance
|
||||
app = Client("my_account")
|
||||
|
||||
# Start the Client before calling any API method
|
||||
app.start()
|
||||
|
||||
# Send a message to yourself, Markdown is enabled by default
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
|
||||
# Send a location to yourself
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
|
||||
# Stop the client when you're done
|
||||
app.stop()
|
10
examples/history.py
Normal file
10
examples/history.py
Normal file
@ -0,0 +1,10 @@
|
||||
"""This example shows how to get the full message history of a chat, starting from the latest message"""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
target = "me" # "me" refers to your own chat (Saved Messages)
|
||||
|
||||
with app:
|
||||
for message in app.iter_history(target):
|
||||
print(message.text)
|
59
examples/keyboards.py
Normal file
59
examples/keyboards.py
Normal file
@ -0,0 +1,59 @@
|
||||
"""This example will show you how to send normal and inline keyboards.
|
||||
|
||||
You must log-in as a regular bot in order to send keyboards (use the token from @BotFather).
|
||||
Any attempt in sending keyboards with a user account will be simply ignored by the server.
|
||||
|
||||
send_message() is used as example, but a keyboard can be sent with any other send_* methods,
|
||||
like send_audio(), send_document(), send_location(), etc...
|
||||
"""
|
||||
|
||||
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
# Create a client using your bot token
|
||||
app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
|
||||
with app:
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a ReplyKeyboardMarkup example",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
[
|
||||
["A", "B", "C", "D"], # First row
|
||||
["E", "F", "G"], # Second row
|
||||
["H", "I"], # Third row
|
||||
["J"] # Fourth row
|
||||
],
|
||||
resize_keyboard=True # Make the keyboard smaller
|
||||
)
|
||||
)
|
||||
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a InlineKeyboardMarkup example",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[ # First row
|
||||
|
||||
InlineKeyboardButton( # Generates a callback query when pressed
|
||||
"Button",
|
||||
callback_data=b"data"
|
||||
), # Note how callback_data must be bytes
|
||||
InlineKeyboardButton( # Opens a web URL
|
||||
"URL",
|
||||
url="https://docs.pyrogram.ml"
|
||||
),
|
||||
],
|
||||
[ # Second row
|
||||
# Opens the inline interface
|
||||
InlineKeyboardButton(
|
||||
"Choose chat",
|
||||
switch_inline_query="pyrogram"
|
||||
),
|
||||
InlineKeyboardButton( # Opens the inline interface in the current chat
|
||||
"Inline here",
|
||||
switch_inline_query_current_chat="pyrogram"
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
)
|
@ -1,51 +0,0 @@
|
||||
"""This example will show you how to send normal and inline keyboards.
|
||||
|
||||
You must log-in as a regular bot in order to send keyboards (use the token from @BotFather).
|
||||
Any attempt in sending keyboards with a user account will be simply ignored by the server.
|
||||
|
||||
send_message() is used as example, but a keyboard can be sent with any other send_* methods,
|
||||
like send_audio(), send_document(), send_location(), etc...
|
||||
"""
|
||||
|
||||
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
# Create a client using your bot token
|
||||
app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
app.start()
|
||||
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a ReplyKeyboardMarkup example",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
[
|
||||
["A", "B", "C", "D"], # First row
|
||||
["E", "F", "G"], # Second row
|
||||
["H", "I"], # Third row
|
||||
["J"] # Fourth row
|
||||
],
|
||||
resize_keyboard=True # Make the keyboard smaller
|
||||
)
|
||||
)
|
||||
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a InlineKeyboardMarkup example",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[ # First row
|
||||
# Generates a callback query when pressed
|
||||
InlineKeyboardButton("Button", callback_data="data"),
|
||||
# Opens a web URL
|
||||
InlineKeyboardButton("URL", url="https://docs.pyrogram.ml"),
|
||||
],
|
||||
[ # Second row
|
||||
# Opens the inline interface of a bot in another chat with a pre-defined query
|
||||
InlineKeyboardButton("Choose chat", switch_inline_query="pyrogram"),
|
||||
# Same as the button above, but the inline interface is opened in the current chat
|
||||
InlineKeyboardButton("Inline here", switch_inline_query_current_chat="pyrogram"),
|
||||
]
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
app.stop()
|
@ -6,13 +6,15 @@ to make it only work for specific messages in a specific chat.
|
||||
|
||||
from pyrogram import Client, Emoji, Filters
|
||||
|
||||
MENTION = "[{}](tg://user?id={})"
|
||||
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {}!"
|
||||
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames
|
||||
MENTION = "[{}](tg://user?id={})" # User mention markup
|
||||
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {}!" # Welcome message
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message(Filters.chat("PyrogramChat") & Filters.new_chat_members)
|
||||
# Filter in only new_chat_members updates generated in TARGET chat
|
||||
@app.on_message(Filters.chat(TARGET) & Filters.new_chat_members)
|
||||
def welcome(client, message):
|
||||
# Build the new members list (with mentions) by using their first_name
|
||||
new_members = [MENTION.format(i.first_name, i.id) for i in message.new_chat_members]
|
||||
@ -20,7 +22,7 @@ def welcome(client, message):
|
||||
# Build the welcome message by using an emoji and the list we built above
|
||||
text = MESSAGE.format(Emoji.SPARKLES, ", ".join(new_members))
|
||||
|
||||
# Send the welcome message
|
||||
# Send the welcome message, without the web page preview
|
||||
message.reply(text, disable_web_page_preview=True)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -18,22 +18,30 @@
|
||||
|
||||
import sys
|
||||
|
||||
__copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>".replace(
|
||||
if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]:
|
||||
from .vendor import typing
|
||||
|
||||
# Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one.
|
||||
sys.modules["typing"] = typing
|
||||
|
||||
__copyright__ = "Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>".replace(
|
||||
"\xe8",
|
||||
"e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
|
||||
)
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__version__ = "0.9.2.dev1"
|
||||
__version__ = "0.12.0.develop"
|
||||
|
||||
from .api.errors import Error
|
||||
from .client.types import (
|
||||
Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto,
|
||||
InputMediaVideo, InputMediaDocument, InputMediaAudio, InputMediaAnimation, InputPhoneContact,
|
||||
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserStatus,
|
||||
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
|
||||
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
||||
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
|
||||
InlineQuery, InlineQueryResult, InlineQueryResultArticle, InlineQueryResultPhoto, InputTextMessageContent,
|
||||
InlineQueryResultCachedAudio, InputMessageContent
|
||||
InlineQueryResultCachedAudio, InputMessageContent, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton,
|
||||
ReplyKeyboardMarkup, ReplyKeyboardRemove, Poll, PollOption, ChatPreview, StopPropagation, ContinuePropagation,
|
||||
Game, CallbackGame, GameHighScore, GameHighScores, ChatPermissions
|
||||
)
|
||||
from .client import (
|
||||
Client, ChatAction, ParseMode, Emoji,
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -19,14 +19,16 @@
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from json import JSONEncoder, dumps
|
||||
|
||||
from ..all import objects
|
||||
from json import dumps
|
||||
|
||||
|
||||
class Object:
|
||||
all = {}
|
||||
|
||||
__slots__ = []
|
||||
|
||||
QUALNAME = "Base"
|
||||
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args):
|
||||
return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args)
|
||||
@ -35,7 +37,7 @@ class Object:
|
||||
pass
|
||||
|
||||
def __str__(self) -> str:
|
||||
return dumps(self, cls=Encoder, indent=4)
|
||||
return dumps(self, indent=4, default=default, ensure_ascii=False)
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return True
|
||||
@ -62,29 +64,18 @@ def remove_none(obj):
|
||||
return obj
|
||||
|
||||
|
||||
class Encoder(JSONEncoder):
|
||||
def default(self, o: Object):
|
||||
def default(o: "Object"):
|
||||
try:
|
||||
content = o.__dict__
|
||||
content = {i: getattr(o, i) for i in o.__slots__}
|
||||
|
||||
return remove_none(
|
||||
OrderedDict(
|
||||
[("_", o.QUALNAME)]
|
||||
+ [i for i in content.items()]
|
||||
)
|
||||
)
|
||||
except AttributeError:
|
||||
if isinstance(o, datetime):
|
||||
return o.strftime("%d-%b-%Y %H:%M:%S")
|
||||
else:
|
||||
return repr(o)
|
||||
|
||||
name = o.__class__.__name__
|
||||
o = objects.get(getattr(o, "ID", None), None)
|
||||
|
||||
if o is not None:
|
||||
if o.startswith("pyrogram.client"):
|
||||
r = remove_none(OrderedDict([("_", "pyrogram:" + name)] + [i for i in content.items()]))
|
||||
r.pop("_client", None)
|
||||
|
||||
return r
|
||||
else:
|
||||
return OrderedDict(
|
||||
[("_", o.replace("pyrogram.api.types.", "telegram:"))]
|
||||
+ [i for i in content.items()]
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -22,6 +22,7 @@ from collections import OrderedDict
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from ..ext import utils
|
||||
from ..handlers import (
|
||||
@ -43,7 +44,7 @@ class Dispatcher:
|
||||
types.UpdateEditChannelMessage
|
||||
)
|
||||
|
||||
DELETE_MESSAGE_UPDATES = (
|
||||
DELETE_MESSAGES_UPDATES = (
|
||||
types.UpdateDeleteMessages,
|
||||
types.UpdateDeleteChannelMessages
|
||||
)
|
||||
@ -55,34 +56,34 @@ class Dispatcher:
|
||||
|
||||
MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES
|
||||
|
||||
UPDATES = None
|
||||
|
||||
def __init__(self, client, workers: int):
|
||||
self.client = client
|
||||
self.workers = workers
|
||||
|
||||
self.workers_list = []
|
||||
self.updates = Queue()
|
||||
self.updates_queue = Queue()
|
||||
self.groups = OrderedDict()
|
||||
|
||||
Dispatcher.UPDATES = {
|
||||
self.update_parsers = {
|
||||
Dispatcher.MESSAGE_UPDATES:
|
||||
lambda upd, usr, cht: (utils.parse_messages(self.client, upd.message, usr, cht), MessageHandler),
|
||||
lambda upd, usr, cht: (pyrogram.Message._parse(self.client, upd.message, usr, cht), MessageHandler),
|
||||
|
||||
Dispatcher.DELETE_MESSAGE_UPDATES:
|
||||
lambda upd, usr, cht: (utils.parse_deleted_messages(upd), DeletedMessagesHandler),
|
||||
Dispatcher.DELETE_MESSAGES_UPDATES:
|
||||
lambda upd, usr, cht: (pyrogram.Messages._parse_deleted(self.client, upd), DeletedMessagesHandler),
|
||||
|
||||
Dispatcher.CALLBACK_QUERY_UPDATES:
|
||||
lambda upd, usr, cht: (utils.parse_callback_query(self.client, upd, usr), CallbackQueryHandler),
|
||||
lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler),
|
||||
|
||||
(types.UpdateUserStatus,):
|
||||
lambda upd, usr, cht: (utils.parse_user_status(upd.status, upd.user_id), UserStatusHandler),
|
||||
lambda upd, usr, cht: (
|
||||
pyrogram.UserStatus._parse(self.client, upd.status, upd.user_id), UserStatusHandler
|
||||
),
|
||||
|
||||
(types.UpdateBotInlineQuery,):
|
||||
lambda upd, usr, cht: (utils.parse_inline_query(self.client, upd, usr), InlineQueryHandler)
|
||||
}
|
||||
|
||||
Dispatcher.UPDATES = {key: value for key_tuple, value in Dispatcher.UPDATES.items() for key in key_tuple}
|
||||
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}
|
||||
|
||||
def start(self):
|
||||
for i in range(self.workers):
|
||||
@ -97,7 +98,7 @@ class Dispatcher:
|
||||
|
||||
def stop(self):
|
||||
for _ in range(self.workers):
|
||||
self.updates.put(None)
|
||||
self.updates_queue.put(None)
|
||||
|
||||
for worker in self.workers_list:
|
||||
worker.join()
|
||||
@ -122,7 +123,7 @@ class Dispatcher:
|
||||
log.debug("{} started".format(name))
|
||||
|
||||
while True:
|
||||
update = self.updates.get()
|
||||
update = self.updates_queue.get()
|
||||
|
||||
if update is None:
|
||||
break
|
||||
@ -132,32 +133,39 @@ class Dispatcher:
|
||||
chats = {i.id: i for i in update[2]}
|
||||
update = update[0]
|
||||
|
||||
parser = Dispatcher.UPDATES.get(type(update), None)
|
||||
parser = self.update_parsers.get(type(update), None)
|
||||
|
||||
if parser is None:
|
||||
continue
|
||||
|
||||
update, handler_type = parser(update, users, chats)
|
||||
parsed_update, handler_type = (
|
||||
parser(update, users, chats)
|
||||
if parser is not None
|
||||
else (None, type(None))
|
||||
)
|
||||
|
||||
for group in self.groups.values():
|
||||
for handler in group:
|
||||
args = None
|
||||
|
||||
if isinstance(handler, RawUpdateHandler):
|
||||
if isinstance(handler, handler_type):
|
||||
if handler.check(parsed_update):
|
||||
args = (parsed_update,)
|
||||
elif isinstance(handler, RawUpdateHandler):
|
||||
args = (update, users, chats)
|
||||
elif isinstance(handler, handler_type):
|
||||
if handler.check(update):
|
||||
args = (update,)
|
||||
|
||||
if args is None:
|
||||
continue
|
||||
|
||||
try:
|
||||
handler.callback(self.client, *args)
|
||||
except pyrogram.StopPropagation:
|
||||
raise
|
||||
except pyrogram.ContinuePropagation:
|
||||
continue
|
||||
except Exception as e:
|
||||
log.error(e, exc_info=True)
|
||||
finally:
|
||||
|
||||
break
|
||||
except pyrogram.StopPropagation:
|
||||
pass
|
||||
except Exception as e:
|
||||
log.error(e, exc_info=True)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -23,12 +23,13 @@ from threading import Lock
|
||||
|
||||
from pyrogram import __version__
|
||||
from ..style import Markdown, HTML
|
||||
from ...api.core import Object
|
||||
from ...session import Session
|
||||
from ...session.internals import MsgId
|
||||
|
||||
|
||||
class BaseClient:
|
||||
class StopTransmission(StopIteration):
|
||||
pass
|
||||
|
||||
APP_VERSION = "Pyrogram \U0001f525 {}".format(__version__)
|
||||
|
||||
DEVICE_MODEL = "{} {}".format(
|
||||
@ -67,7 +68,7 @@ class BaseClient:
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.bot_token = None
|
||||
self.is_bot = None
|
||||
self.dc_id = None
|
||||
self.auth_key = None
|
||||
self.user_id = None
|
||||
@ -90,6 +91,8 @@ class BaseClient:
|
||||
self.is_started = None
|
||||
self.is_idle = None
|
||||
|
||||
self.takeout_id = None
|
||||
|
||||
self.updates_queue = Queue()
|
||||
self.updates_workers_list = []
|
||||
self.download_queue = Queue()
|
||||
@ -97,30 +100,32 @@ class BaseClient:
|
||||
|
||||
self.disconnect_handler = None
|
||||
|
||||
def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT):
|
||||
def send(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def resolve_peer(self, peer_id: int or str):
|
||||
def resolve_peer(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def add_handler(self, handler, group: int = 0) -> tuple:
|
||||
def fetch_peers(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def save_file(
|
||||
self,
|
||||
path: str,
|
||||
file_id: int = None,
|
||||
file_part: int = 0,
|
||||
progress: callable = None,
|
||||
progress_args: tuple = ()
|
||||
):
|
||||
def add_handler(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_messages(
|
||||
self,
|
||||
chat_id: int or str,
|
||||
message_ids: int or list = None,
|
||||
reply_to_message_ids: int or list = None,
|
||||
replies: int = 1
|
||||
):
|
||||
def save_file(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_messages(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_history(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_dialogs(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_chat_members(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def get_chat_members_count(self, *args, **kwargs):
|
||||
pass
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -94,6 +94,7 @@ class Syncer:
|
||||
auth_key=auth_key,
|
||||
user_id=client.user_id,
|
||||
date=int(time.time()),
|
||||
is_bot=client.is_bot,
|
||||
peers_by_id={
|
||||
k: getattr(v, "access_hash", None)
|
||||
for k, v in client.peers_by_id.copy().items()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -61,14 +61,17 @@ class Filters:
|
||||
|
||||
create = create
|
||||
|
||||
me = create("Me", lambda _, m: bool(m.from_user and m.from_user.is_self))
|
||||
"""Filter messages generated by you yourself."""
|
||||
|
||||
bot = create("Bot", lambda _, m: bool(m.from_user and m.from_user.is_bot))
|
||||
"""Filter messages coming from bots"""
|
||||
"""Filter messages coming from bots."""
|
||||
|
||||
incoming = create("Incoming", lambda _, m: not m.outgoing)
|
||||
"""Filter incoming messages."""
|
||||
"""Filter incoming messages. Messages sent to your own chat (Saved Messages) are also recognised as incoming."""
|
||||
|
||||
outgoing = create("Outgoing", lambda _, m: m.outgoing)
|
||||
"""Filter outgoing messages."""
|
||||
"""Filter outgoing messages. Messages sent to your own chat (Saved Messages) are not recognized as outgoing."""
|
||||
|
||||
text = create("Text", lambda _, m: bool(m.text))
|
||||
"""Filter text messages."""
|
||||
@ -86,37 +89,49 @@ class Filters:
|
||||
"""Filter edited messages."""
|
||||
|
||||
audio = create("Audio", lambda _, m: bool(m.audio))
|
||||
"""Filter messages that contain :obj:`Audio <pyrogram.api.types.pyrogram.Audio>` objects."""
|
||||
"""Filter messages that contain :obj:`Audio <pyrogram.Audio>` objects."""
|
||||
|
||||
document = create("Document", lambda _, m: bool(m.document))
|
||||
"""Filter messages that contain :obj:`Document <pyrogram.api.types.pyrogram.Document>` objects."""
|
||||
"""Filter messages that contain :obj:`Document <pyrogram.Document>` objects."""
|
||||
|
||||
photo = create("Photo", lambda _, m: bool(m.photo))
|
||||
"""Filter messages that contain :obj:`Photo <pyrogram.api.types.pyrogram.PhotoSize>` objects."""
|
||||
"""Filter messages that contain :obj:`Photo <pyrogram.PhotoSize>` objects."""
|
||||
|
||||
sticker = create("Sticker", lambda _, m: bool(m.sticker))
|
||||
"""Filter messages that contain :obj:`Sticker <pyrogram.api.types.pyrogram.Sticker>` objects."""
|
||||
"""Filter messages that contain :obj:`Sticker <pyrogram.Sticker>` objects."""
|
||||
|
||||
animation = create("GIF", lambda _, m: bool(m.animation))
|
||||
"""Filter messages that contain :obj:`Animation <pyrogram.api.types.pyrogram.Animation>` objects."""
|
||||
animation = create("Animation", lambda _, m: bool(m.animation))
|
||||
"""Filter messages that contain :obj:`Animation <pyrogram.Animation>` objects."""
|
||||
|
||||
game = create("Game", lambda _, m: bool(m.game))
|
||||
"""Filter messages that contain :obj:`Game <pyrogram.Game>` objects."""
|
||||
|
||||
video = create("Video", lambda _, m: bool(m.video))
|
||||
"""Filter messages that contain :obj:`Video <pyrogram.api.types.pyrogram.Video>` objects."""
|
||||
"""Filter messages that contain :obj:`Video <pyrogram.Video>` objects."""
|
||||
|
||||
media_group = create("MediaGroup", lambda _, m: bool(m.media_group_id))
|
||||
"""Filter messages containing photos or videos being part of an album."""
|
||||
|
||||
voice = create("Voice", lambda _, m: bool(m.voice))
|
||||
"""Filter messages that contain :obj:`Voice <pyrogram.api.types.pyrogram.Voice>` note objects."""
|
||||
"""Filter messages that contain :obj:`Voice <pyrogram.Voice>` note objects."""
|
||||
|
||||
video_note = create("Voice", lambda _, m: bool(m.video_note))
|
||||
"""Filter messages that contain :obj:`VideoNote <pyrogram.api.types.pyrogram.VideoNote>` objects."""
|
||||
"""Filter messages that contain :obj:`VideoNote <pyrogram.VideoNote>` objects."""
|
||||
|
||||
contact = create("Contact", lambda _, m: bool(m.contact))
|
||||
"""Filter messages that contain :obj:`Contact <pyrogram.api.types.pyrogram.Contact>` objects."""
|
||||
"""Filter messages that contain :obj:`Contact <pyrogram.Contact>` objects."""
|
||||
|
||||
location = create("Location", lambda _, m: bool(m.location))
|
||||
"""Filter messages that contain :obj:`Location <pyrogram.api.types.pyrogram.Location>` objects."""
|
||||
"""Filter messages that contain :obj:`Location <pyrogram.Location>` objects."""
|
||||
|
||||
venue = create("Venue", lambda _, m: bool(m.venue))
|
||||
"""Filter messages that contain :obj:`Venue <pyrogram.api.types.pyrogram.Venue>` objects."""
|
||||
"""Filter messages that contain :obj:`Venue <pyrogram.Venue>` objects."""
|
||||
|
||||
web_page = create("WebPage", lambda _, m: m.web_page)
|
||||
"""Filter messages sent with a webpage preview."""
|
||||
|
||||
poll = create("Poll", lambda _, m: m.poll)
|
||||
"""Filter messages that contain :obj:`Poll <pyrogram.Poll>` objects."""
|
||||
|
||||
private = create("Private", lambda _, m: bool(m.chat and m.chat.type == "private"))
|
||||
"""Filter messages sent in private chats."""
|
||||
@ -160,6 +175,9 @@ class Filters:
|
||||
pinned_message = create("PinnedMessage", lambda _, m: bool(m.pinned_message))
|
||||
"""Filter service messages for pinned messages."""
|
||||
|
||||
game_high_score = create("GameHighScore", lambda _, m: bool(m.game_high_score))
|
||||
"""Filter service messages for game high scores."""
|
||||
|
||||
reply_keyboard = create("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
|
||||
"""Filter messages containing reply keyboard markups"""
|
||||
|
||||
@ -169,6 +187,9 @@ class Filters:
|
||||
mentioned = create("Mentioned", lambda _, m: bool(m.mentioned))
|
||||
"""Filter messages containing mentions"""
|
||||
|
||||
via_bot = create("ViaBot", lambda _, m: bool(m.via_bot))
|
||||
"""Filter messages sent via inline bots"""
|
||||
|
||||
service = create("Service", lambda _, m: bool(m.service))
|
||||
"""Filter service messages. A service message contains any of the following fields set
|
||||
|
||||
@ -181,7 +202,8 @@ class Filters:
|
||||
- channel_chat_created
|
||||
- migrate_to_chat_id
|
||||
- migrate_from_chat_id
|
||||
- pinned_message"""
|
||||
- pinned_message
|
||||
- game_score"""
|
||||
|
||||
media = create("Media", lambda _, m: bool(m.media))
|
||||
"""Filter media messages. A media message contains any of the following fields set
|
||||
@ -196,7 +218,8 @@ class Filters:
|
||||
- video_note
|
||||
- contact
|
||||
- location
|
||||
- venue"""
|
||||
- venue
|
||||
- poll"""
|
||||
|
||||
@staticmethod
|
||||
def command(command: str or list,
|
||||
@ -267,7 +290,7 @@ class Filters:
|
||||
"""
|
||||
|
||||
def f(_, m):
|
||||
m.matches = [i for i in _.p.finditer(m.text or "")]
|
||||
m.matches = [i for i in _.p.finditer(m.text or m.caption or "")]
|
||||
return bool(m.matches)
|
||||
|
||||
return create("Regex", f, p=re.compile(pattern, flags))
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -45,10 +45,3 @@ class CallbackQueryHandler(Handler):
|
||||
|
||||
def __init__(self, callback: callable, filters=None):
|
||||
super().__init__(callback, filters)
|
||||
|
||||
def check(self, callback_query):
|
||||
return (
|
||||
self.filters(callback_query)
|
||||
if callable(self.filters)
|
||||
else True
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -48,8 +48,4 @@ class DeletedMessagesHandler(Handler):
|
||||
super().__init__(callback, filters)
|
||||
|
||||
def check(self, messages):
|
||||
return (
|
||||
self.filters(messages.messages[0])
|
||||
if callable(self.filters)
|
||||
else True
|
||||
)
|
||||
return super().check(messages.messages[0])
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -21,3 +21,10 @@ class Handler:
|
||||
def __init__(self, callback: callable, filters=None):
|
||||
self.callback = callback
|
||||
self.filters = filters
|
||||
|
||||
def check(self, update):
|
||||
return (
|
||||
self.filters(update)
|
||||
if callable(self.filters)
|
||||
else True
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -46,10 +46,3 @@ class MessageHandler(Handler):
|
||||
|
||||
def __init__(self, callback: callable, filters=None):
|
||||
super().__init__(callback, filters)
|
||||
|
||||
def check(self, message):
|
||||
return (
|
||||
self.filters(message)
|
||||
if callable(self.filters)
|
||||
else True
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -45,10 +45,3 @@ class UserStatusHandler(Handler):
|
||||
|
||||
def __init__(self, callback: callable, filters=None):
|
||||
super().__init__(callback, filters)
|
||||
|
||||
def check(self, user_status):
|
||||
return (
|
||||
self.filters(user_status)
|
||||
if callable(self.filters)
|
||||
else True
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -23,7 +23,6 @@ from .decorators import Decorators
|
||||
from .messages import Messages
|
||||
from .password import Password
|
||||
from .users import Users
|
||||
from .utilities import Utilities
|
||||
|
||||
|
||||
class Methods(
|
||||
@ -32,7 +31,6 @@ class Methods(
|
||||
Password,
|
||||
Chats,
|
||||
Users,
|
||||
Utilities,
|
||||
Messages,
|
||||
Decorators
|
||||
):
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -18,9 +18,12 @@
|
||||
|
||||
from .answer_callback_query import AnswerCallbackQuery
|
||||
from .answer_inline_query import AnswerInlineQuery
|
||||
from .get_game_high_scores import GetGameHighScores
|
||||
from .get_inline_bot_results import GetInlineBotResults
|
||||
from .request_callback_answer import RequestCallbackAnswer
|
||||
from .send_game import SendGame
|
||||
from .send_inline_bot_result import SendInlineBotResult
|
||||
from .set_game_score import SetGameScore
|
||||
|
||||
|
||||
class Bots(
|
||||
@ -28,6 +31,9 @@ class Bots(
|
||||
AnswerInlineQuery,
|
||||
GetInlineBotResults,
|
||||
RequestCallbackAnswer,
|
||||
SendInlineBotResult
|
||||
SendInlineBotResult,
|
||||
SendGame,
|
||||
SetGameScore,
|
||||
GetGameHighScores
|
||||
):
|
||||
pass
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -21,12 +21,14 @@ from pyrogram.client.ext import BaseClient
|
||||
|
||||
|
||||
class AnswerCallbackQuery(BaseClient):
|
||||
def answer_callback_query(self,
|
||||
def answer_callback_query(
|
||||
self,
|
||||
callback_query_id: str,
|
||||
text: str = None,
|
||||
show_alert: bool = None,
|
||||
url: str = None,
|
||||
cache_time: int = 0):
|
||||
cache_time: int = 0
|
||||
):
|
||||
"""Use this method to send answers to callback queries sent from inline keyboards.
|
||||
The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
|
||||
|
||||
|
68
pyrogram/client/methods/bots/get_game_high_scores.py
Normal file
68
pyrogram/client/methods/bots/get_game_high_scores.py
Normal file
@ -0,0 +1,68 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2019 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 typing import Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import functions
|
||||
from pyrogram.client.ext import BaseClient
|
||||
|
||||
|
||||
class GetGameHighScores(BaseClient):
|
||||
def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
chat_id: Union[int, str],
|
||||
message_id: int = None
|
||||
):
|
||||
"""Use this method to get data for high score tables.
|
||||
|
||||
Args:
|
||||
user_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
chat_id (``int`` | ``str``, *optional*):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
Required if inline_message_id is not specified.
|
||||
|
||||
message_id (``int``, *optional*):
|
||||
Identifier of the sent message.
|
||||
Required if inline_message_id is not specified.
|
||||
|
||||
Returns:
|
||||
On success, a :obj:`GameHighScores <pyrogram.GameHighScores>` object is returned.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
|
||||
"""
|
||||
# TODO: inline_message_id
|
||||
|
||||
return pyrogram.GameHighScores._parse(
|
||||
self,
|
||||
self.send(
|
||||
functions.messages.GetGameHighScores(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
id=message_id,
|
||||
user_id=self.resolve_peer(user_id)
|
||||
)
|
||||
)
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user