mirror of
https://github.com/TeamPGM/pyrogram.git
synced 2024-11-18 13:34:54 +00:00
Merge branch 'develop' into asyncio
# Conflicts: # pyrogram/client/client.py # pyrogram/client/methods/chats/get_chat_members.py # pyrogram/client/methods/chats/get_dialogs.py # pyrogram/client/methods/messages/send_animation.py # pyrogram/client/methods/messages/send_venue.py
This commit is contained in:
commit
3f7b0b25af
@ -494,14 +494,14 @@ def start():
|
||||
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.reply_markup.ForceReply\",")
|
||||
f.write("\n 0xb0700019: \"pyrogram.client.types.reply_markup.InlineKeyboardButton\",")
|
||||
f.write("\n 0xb0700020: \"pyrogram.client.types.reply_markup.InlineKeyboardMarkup\",")
|
||||
f.write("\n 0xb0700021: \"pyrogram.client.types.reply_markup.KeyboardButton\",")
|
||||
f.write("\n 0xb0700022: \"pyrogram.client.types.reply_markup.ReplyKeyboardMarkup\",")
|
||||
f.write("\n 0xb0700023: \"pyrogram.client.types.reply_markup.ReplyKeyboardRemove\",")
|
||||
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.GIF\",")
|
||||
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\",")
|
||||
|
@ -66,3 +66,4 @@ MEDIA_CAPTION_TOO_LONG The media caption is longer than 200 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
|
|
@ -84,6 +84,7 @@ To get started, press the Next button.
|
||||
:caption: Resources
|
||||
|
||||
resources/UpdateHandling
|
||||
resources/UsingFilters
|
||||
resources/AutoAuthorization
|
||||
resources/CustomizeSessions
|
||||
resources/TgCrypto
|
||||
|
@ -1,15 +1,12 @@
|
||||
Client
|
||||
======
|
||||
|
||||
.. currentmodule:::: pyrogram.Client
|
||||
.. currentmodule:: pyrogram.Client
|
||||
|
||||
.. autoclass:: pyrogram.Client
|
||||
:inherited-members:
|
||||
:members:
|
||||
|
||||
.. _available-methods:
|
||||
|
||||
**Available methods**
|
||||
Utilities
|
||||
---------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
@ -18,14 +15,30 @@ Client
|
||||
stop
|
||||
idle
|
||||
run
|
||||
on_message
|
||||
on_callback_query
|
||||
on_raw_update
|
||||
add_handler
|
||||
remove_handler
|
||||
send
|
||||
resolve_peer
|
||||
get_me
|
||||
download_media
|
||||
|
||||
Decorators
|
||||
----------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
on_message
|
||||
on_callback_query
|
||||
on_deleted_messages
|
||||
on_disconnect
|
||||
on_raw_update
|
||||
|
||||
Messages
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
send_message
|
||||
forward_messages
|
||||
send_photo
|
||||
@ -33,6 +46,7 @@ Client
|
||||
send_document
|
||||
send_sticker
|
||||
send_video
|
||||
send_animation
|
||||
send_voice
|
||||
send_video_note
|
||||
send_media_group
|
||||
@ -40,37 +54,80 @@ Client
|
||||
send_venue
|
||||
send_contact
|
||||
send_chat_action
|
||||
download_media
|
||||
get_user_profile_photos
|
||||
delete_profile_photos
|
||||
edit_message_text
|
||||
edit_message_caption
|
||||
edit_message_reply_markup
|
||||
delete_messages
|
||||
get_messages
|
||||
get_history
|
||||
get_dialogs
|
||||
|
||||
Chats
|
||||
-----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
join_chat
|
||||
leave_chat
|
||||
export_chat_invite_link
|
||||
enable_cloud_password
|
||||
change_cloud_password
|
||||
remove_cloud_password
|
||||
kick_chat_member
|
||||
unban_chat_member
|
||||
restrict_chat_member
|
||||
promote_chat_member
|
||||
add_contacts
|
||||
get_contacts
|
||||
delete_contacts
|
||||
get_inline_bot_results
|
||||
send_inline_bot_result
|
||||
answer_callback_query
|
||||
request_callback_answer
|
||||
get_users
|
||||
get_chat
|
||||
get_messages
|
||||
get_history
|
||||
export_chat_invite_link
|
||||
set_chat_photo
|
||||
delete_chat_photo
|
||||
set_chat_title
|
||||
set_chat_description
|
||||
pin_chat_message
|
||||
unpin_chat_message
|
||||
get_chat
|
||||
get_chat_member
|
||||
get_chat_members
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
get_me
|
||||
get_users
|
||||
get_user_profile_photos
|
||||
delete_profile_photos
|
||||
|
||||
Contacts
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
add_contacts
|
||||
get_contacts
|
||||
delete_contacts
|
||||
|
||||
Password
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
enable_cloud_password
|
||||
change_cloud_password
|
||||
remove_cloud_password
|
||||
|
||||
Bots
|
||||
----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
get_inline_bot_results
|
||||
send_inline_bot_result
|
||||
answer_callback_query
|
||||
request_callback_answer
|
||||
|
||||
|
||||
.. autoclass:: pyrogram.Client
|
||||
:inherited-members:
|
||||
:members:
|
||||
|
@ -1,5 +1,3 @@
|
||||
:tocdepth: 1
|
||||
|
||||
Error
|
||||
=====
|
||||
|
||||
|
29
docs/source/pyrogram/Handlers.rst
Normal file
29
docs/source/pyrogram/Handlers.rst
Normal file
@ -0,0 +1,29 @@
|
||||
Handlers
|
||||
========
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
MessageHandler
|
||||
DeletedMessagesHandler
|
||||
CallbackQueryHandler
|
||||
DisconnectHandler
|
||||
RawUpdateHandler
|
||||
|
||||
.. autoclass:: MessageHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: DeletedMessagesHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: CallbackQueryHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: DisconnectHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: RawUpdateHandler
|
||||
:members:
|
||||
|
176
docs/source/pyrogram/Types.rst
Normal file
176
docs/source/pyrogram/Types.rst
Normal file
@ -0,0 +1,176 @@
|
||||
Types
|
||||
=====
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Users & Chats
|
||||
-------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
User
|
||||
Chat
|
||||
ChatPhoto
|
||||
ChatMember
|
||||
ChatMembers
|
||||
Dialog
|
||||
Dialogs
|
||||
|
||||
Messages & Media
|
||||
----------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
Message
|
||||
Messages
|
||||
MessageEntity
|
||||
Photo
|
||||
PhotoSize
|
||||
UserProfilePhotos
|
||||
Audio
|
||||
Document
|
||||
Animation
|
||||
Video
|
||||
Voice
|
||||
VideoNote
|
||||
Contact
|
||||
Location
|
||||
Venue
|
||||
Sticker
|
||||
|
||||
Bots
|
||||
----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
ReplyKeyboardMarkup
|
||||
KeyboardButton
|
||||
ReplyKeyboardRemove
|
||||
InlineKeyboardMarkup
|
||||
InlineKeyboardButton
|
||||
ForceReply
|
||||
CallbackQuery
|
||||
|
||||
Input Media
|
||||
-----------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
InputMediaPhoto
|
||||
InputMediaVideo
|
||||
InputPhoneContact
|
||||
|
||||
.. User & Chats
|
||||
------------
|
||||
|
||||
.. autoclass:: User
|
||||
:members:
|
||||
|
||||
.. autoclass:: Chat
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPhoto
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatMember
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatMembers
|
||||
:members:
|
||||
|
||||
.. autoclass:: Dialog
|
||||
:members:
|
||||
|
||||
.. autoclass:: Dialogs
|
||||
:members:
|
||||
|
||||
.. Messages & Media
|
||||
----------------
|
||||
|
||||
.. autoclass:: Message
|
||||
:members:
|
||||
|
||||
.. autoclass:: Messages
|
||||
:members:
|
||||
|
||||
.. autoclass:: MessageEntity
|
||||
:members:
|
||||
|
||||
.. autoclass:: Photo
|
||||
:members:
|
||||
|
||||
.. autoclass:: PhotoSize
|
||||
:members:
|
||||
|
||||
.. autoclass:: UserProfilePhotos
|
||||
:members:
|
||||
|
||||
.. autoclass:: Audio
|
||||
:members:
|
||||
|
||||
.. autoclass:: Document
|
||||
:members:
|
||||
|
||||
.. autoclass:: Animation
|
||||
:members:
|
||||
|
||||
.. autoclass:: Video
|
||||
:members:
|
||||
|
||||
.. autoclass:: Voice
|
||||
:members:
|
||||
|
||||
.. autoclass:: VideoNote
|
||||
:members:
|
||||
|
||||
.. autoclass:: Contact
|
||||
:members:
|
||||
|
||||
.. autoclass:: Location
|
||||
:members:
|
||||
|
||||
.. autoclass:: Venue
|
||||
:members:
|
||||
|
||||
.. autoclass:: Sticker
|
||||
:members:
|
||||
|
||||
.. Bots
|
||||
----
|
||||
|
||||
.. autoclass:: ReplyKeyboardMarkup
|
||||
:members:
|
||||
|
||||
.. autoclass:: KeyboardButton
|
||||
:members:
|
||||
|
||||
.. autoclass:: ReplyKeyboardRemove
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineKeyboardMarkup
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineKeyboardButton
|
||||
:members:
|
||||
|
||||
.. autoclass:: ForceReply
|
||||
:members:
|
||||
|
||||
.. autoclass:: CallbackQuery
|
||||
:members:
|
||||
|
||||
.. Input Media
|
||||
-----------
|
||||
|
||||
.. autoclass:: InputMediaPhoto
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaVideo
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputPhoneContact
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
CallbackQueryHandler
|
||||
====================
|
||||
|
||||
.. autoclass:: pyrogram.CallbackQueryHandler
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,6 +0,0 @@
|
||||
DeletedMessagesHandler
|
||||
======================
|
||||
|
||||
.. autoclass:: pyrogram.DeletedMessagesHandler
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,6 +0,0 @@
|
||||
DisconnectHandler
|
||||
=================
|
||||
|
||||
.. autoclass:: pyrogram.DisconnectHandler
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,6 +0,0 @@
|
||||
MessageHandler
|
||||
==============
|
||||
|
||||
.. autoclass:: pyrogram.MessageHandler
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,6 +0,0 @@
|
||||
RawUpdateHandler
|
||||
================
|
||||
|
||||
.. autoclass:: pyrogram.RawUpdateHandler
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,11 +0,0 @@
|
||||
:tocdepth: 1
|
||||
|
||||
Handlers
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
MessageHandler
|
||||
DeletedMessagesHandler
|
||||
CallbackQueryHandler
|
||||
DisconnectHandler
|
||||
RawUpdateHandler
|
@ -7,9 +7,11 @@ In this section you can find a detailed description of the Pyrogram package and
|
||||
after the well established `Telegram Bot API`_ methods, thus offering a familiar look to Bot developers.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Client
|
||||
types/index
|
||||
handlers/index
|
||||
Types
|
||||
Handlers
|
||||
Filters
|
||||
ChatAction
|
||||
ParseMode
|
||||
|
@ -1,5 +0,0 @@
|
||||
Audio
|
||||
=====
|
||||
|
||||
.. autoclass:: pyrogram.Audio
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
CallbackQuery
|
||||
=============
|
||||
|
||||
.. autoclass:: pyrogram.CallbackQuery
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Chat
|
||||
====
|
||||
|
||||
.. autoclass:: pyrogram.Chat
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
ChatMember
|
||||
==========
|
||||
|
||||
.. autoclass:: pyrogram.ChatMember
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
ChatPhoto
|
||||
=========
|
||||
|
||||
.. autoclass:: pyrogram.ChatPhoto
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Contact
|
||||
=======
|
||||
|
||||
.. autoclass:: pyrogram.Contact
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Document
|
||||
========
|
||||
|
||||
.. autoclass:: pyrogram.Document
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
GIF
|
||||
===
|
||||
|
||||
.. autoclass:: pyrogram.GIF
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
InputMediaPhoto
|
||||
===============
|
||||
|
||||
.. autoclass:: pyrogram.InputMediaPhoto
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
InputMediaVideo
|
||||
===============
|
||||
|
||||
.. autoclass:: pyrogram.InputMediaVideo
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
InputPhoneContact
|
||||
=================
|
||||
|
||||
.. autoclass:: pyrogram.InputPhoneContact
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Location
|
||||
========
|
||||
|
||||
.. autoclass:: pyrogram.Location
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Message
|
||||
=======
|
||||
|
||||
.. autoclass:: pyrogram.Message
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
MessageEntity
|
||||
=============
|
||||
|
||||
.. autoclass:: pyrogram.MessageEntity
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Messages
|
||||
========
|
||||
|
||||
.. autoclass:: pyrogram.Messages
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Photo
|
||||
=====
|
||||
|
||||
.. autoclass:: pyrogram.Photo
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
PhotoSize
|
||||
=========
|
||||
|
||||
.. autoclass:: pyrogram.PhotoSize
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Sticker
|
||||
=======
|
||||
|
||||
.. autoclass:: pyrogram.Sticker
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Update
|
||||
======
|
||||
|
||||
.. autoclass:: pyrogram.Update
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
User
|
||||
====
|
||||
|
||||
.. autoclass:: pyrogram.User
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
UserProfilePhotos
|
||||
=================
|
||||
|
||||
.. autoclass:: pyrogram.UserProfilePhotos
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Venue
|
||||
=====
|
||||
|
||||
.. autoclass:: pyrogram.Venue
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Video
|
||||
=====
|
||||
|
||||
.. autoclass:: pyrogram.Video
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
VideoNote
|
||||
=========
|
||||
|
||||
.. autoclass:: pyrogram.VideoNote
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
Voice
|
||||
=====
|
||||
|
||||
.. autoclass:: pyrogram.Voice
|
||||
:members:
|
@ -1,36 +0,0 @@
|
||||
:tocdepth: 1
|
||||
|
||||
Types
|
||||
=====
|
||||
|
||||
.. toctree::
|
||||
User
|
||||
Chat
|
||||
Message
|
||||
MessageEntity
|
||||
Messages
|
||||
Photo
|
||||
PhotoSize
|
||||
Audio
|
||||
Document
|
||||
GIF
|
||||
Video
|
||||
Voice
|
||||
VideoNote
|
||||
Contact
|
||||
Location
|
||||
Venue
|
||||
UserProfilePhotos
|
||||
ChatPhoto
|
||||
ChatMember
|
||||
InputMediaPhoto
|
||||
InputMediaVideo
|
||||
InputPhoneContact
|
||||
Sticker
|
||||
reply_markup/ForceReply
|
||||
reply_markup/InlineKeyboardButton
|
||||
reply_markup/InlineKeyboardMarkup
|
||||
reply_markup/KeyboardButton
|
||||
reply_markup/ReplyKeyboardMarkup
|
||||
reply_markup/ReplyKeyboardRemove
|
||||
CallbackQuery
|
@ -1,5 +0,0 @@
|
||||
ForceReply
|
||||
==========
|
||||
|
||||
.. autoclass:: pyrogram.ForceReply
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
InlineKeyboardButton
|
||||
====================
|
||||
|
||||
.. autoclass:: pyrogram.InlineKeyboardButton
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
InlineKeyboardMarkup
|
||||
====================
|
||||
|
||||
.. autoclass:: pyrogram.InlineKeyboardMarkup
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
KeyboardButton
|
||||
==============
|
||||
|
||||
.. autoclass:: pyrogram.KeyboardButton
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
ReplyKeyboardMarkup
|
||||
===================
|
||||
|
||||
.. autoclass:: pyrogram.ReplyKeyboardMarkup
|
||||
:members:
|
@ -1,5 +0,0 @@
|
||||
ReplyKeyboardRemove
|
||||
===================
|
||||
|
||||
.. autoclass:: pyrogram.ReplyKeyboardRemove
|
||||
:members:
|
@ -1,8 +1,11 @@
|
||||
Text Formatting
|
||||
===============
|
||||
|
||||
Pyrogram, just like `Telegram Bot API`_, supports basic Markdown and HTML formatting styles for text messages and
|
||||
media captions; Markdown uses the same syntax as Telegram Desktop's and is enabled by default.
|
||||
Pyrogram, just like the `Telegram Bot API`_, natively supports basic Markdown and HTML formatting styles for text
|
||||
messages and media captions.
|
||||
|
||||
Markdown style uses the same syntax as Telegram Desktop's and is enabled by default.
|
||||
|
||||
Beside bold, italic, and pre-formatted code, **Pyrogram does also support inline URLs and inline mentions of users**.
|
||||
|
||||
Markdown Style
|
||||
@ -11,7 +14,7 @@ Markdown Style
|
||||
To use this mode, pass :obj:`MARKDOWN <pyrogram.ParseMode.MARKDOWN>` or "markdown" in the *parse_mode* field when using
|
||||
:obj:`send_message() <pyrogram.Client.send_message>`. Use the following syntax in your message:
|
||||
|
||||
.. code-block:: txt
|
||||
.. code-block:: text
|
||||
|
||||
**bold text**
|
||||
|
||||
@ -34,7 +37,7 @@ HTML Style
|
||||
To use this mode, pass :obj:`HTML <pyrogram.ParseMode.HTML>` or "html" in the *parse_mode* field when using
|
||||
:obj:`send_message() <pyrogram.Client.send_message>`. The following tags are currently supported:
|
||||
|
||||
.. code-block:: txt
|
||||
.. code-block:: text
|
||||
|
||||
<b>bold</b>, <strong>bold</strong>
|
||||
|
||||
@ -46,9 +49,7 @@ To use this mode, pass :obj:`HTML <pyrogram.ParseMode.HTML>` or "html" in the *p
|
||||
|
||||
<code>inline fixed-width code</code>
|
||||
|
||||
<pre>pre-formatted fixed-width
|
||||
code block
|
||||
</pre>
|
||||
<pre>pre-formatted fixed-width code block</pre>
|
||||
|
||||
.. note:: Mentions are only guaranteed to work if you have already met the user (in groups or private chats).
|
||||
|
||||
|
@ -2,22 +2,24 @@ Update Handling
|
||||
===============
|
||||
|
||||
Updates are events that happen in your Telegram account (incoming messages, new channel posts, new members join, ...)
|
||||
and are handled by registering one or more callback functions with an Handler. There are multiple Handlers to choose
|
||||
from, one for each kind of update:
|
||||
and can be handled by registering one or more callback functions in your app by using an `Handler <../pyrogram/Handlers.html>`_.
|
||||
|
||||
- `MessageHandler <../pyrogram/handlers/MessageHandler.html>`_
|
||||
- `DeletedMessagesHandler <../pyrogram/handlers/DeletedMessagesHandler.html>`_
|
||||
- `CallbackQueryHandler <../pyrogram/handlers/CallbackQueryHandler.html>`_
|
||||
- `RawUpdateHandler <../pyrogram/handlers/RawUpdateHandler.html>`_
|
||||
- `DisconnectHandler <../pyrogram/handlers/DisconnectHandler.html>`_
|
||||
To put it simply, whenever an update is received from Telegram it will be dispatched and your previously defined callback
|
||||
function(s) will be called back with the update itself as argument.
|
||||
|
||||
Registering an Handler
|
||||
----------------------
|
||||
|
||||
We shall examine the :obj:`MessageHandler <pyrogram.MessageHandler>`, which will be in charge for handling
|
||||
:obj:`Message <pyrogram.Message>` objects.
|
||||
To explain how `Handlers <../pyrogram/Handlers.html>`_ work let's have a look at the most used one, the
|
||||
:obj:`MessageHandler <pyrogram.MessageHandler>`, which will be in charge for handling :obj:`Message <pyrogram.Message>`
|
||||
updates coming from all around your chats. Every other handler shares the same setup logic; you should not have troubles
|
||||
settings them up once you learn from this section.
|
||||
|
||||
- The easiest and nicest way to register a MessageHandler is by decorating your function with the
|
||||
|
||||
Using Decorators
|
||||
----------------
|
||||
|
||||
The easiest and nicest way to register a MessageHandler is by decorating your function with the
|
||||
:meth:`on_message() <pyrogram.Client.on_message>` decorator. Here's a full example that prints out the content
|
||||
of a message as soon as it arrives.
|
||||
|
||||
@ -35,7 +37,10 @@ We shall examine the :obj:`MessageHandler <pyrogram.MessageHandler>`, which will
|
||||
|
||||
app.run()
|
||||
|
||||
- If you prefer not to use decorators, there is an alternative way for registering Handlers.
|
||||
Using add_handler()
|
||||
-------------------
|
||||
|
||||
If you prefer not to use decorators for any reason, there is an alternative way for registering Handlers.
|
||||
This is useful, for example, when you want to keep your callback functions in separate files.
|
||||
|
||||
.. code-block:: python
|
||||
@ -52,138 +57,3 @@ We shall examine the :obj:`MessageHandler <pyrogram.MessageHandler>`, which will
|
||||
app.add_handler(MessageHandler(my_handler))
|
||||
|
||||
app.run()
|
||||
|
||||
Using Filters
|
||||
-------------
|
||||
|
||||
For a finer grained control over what kind of messages will be allowed or not in your callback functions, you can use
|
||||
:class:`Filters <pyrogram.Filters>`.
|
||||
|
||||
- This example will show you how to **only** handle messages containing an
|
||||
:obj:`Audio <pyrogram.Audio>` object and filter out any other message:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Filters
|
||||
|
||||
|
||||
@app.on_message(Filters.audio)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- or, without decorators:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Filters, MessageHandler
|
||||
|
||||
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(my_handler, Filters.audio))
|
||||
|
||||
Combining Filters
|
||||
-----------------
|
||||
|
||||
Filters can also be used in a more advanced way by combining more filters together using bitwise operators:
|
||||
|
||||
- Use ``~`` to invert a filter (behaves like the ``not`` operator).
|
||||
- Use ``&`` and ``|`` to merge two filters (behave like ``and``, ``or`` operators respectively).
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- Message is a **text** message **and** is **not edited**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text & ~Filters.edited)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **sticker** **and** is coming from a **channel or** a **private** chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.sticker & (Filters.channel | Filters.private))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
Advanced Filters
|
||||
----------------
|
||||
|
||||
Some filters, like :obj:`command() <pyrogram.Filters.command>` or :obj:`regex() <pyrogram.Filters.regex>`
|
||||
can also accept arguments:
|
||||
|
||||
- Message is either a */start* or */help* **command**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command(["start", "help"]))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **text** message matching the given **regex** pattern.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.regex("pyrogram"))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
More handlers using different filters can also live together.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command("start"))
|
||||
def start_command(client, message):
|
||||
print("This is the /start command")
|
||||
|
||||
|
||||
@app.on_message(Filters.command("help"))
|
||||
def help_command(client, message):
|
||||
print("This is the /help command")
|
||||
|
||||
|
||||
@app.on_message(Filters.chat("PyrogramChat"))
|
||||
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. 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``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text, group=-1)
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
228
docs/source/resources/UsingFilters.rst
Normal file
228
docs/source/resources/UsingFilters.rst
Normal file
@ -0,0 +1,228 @@
|
||||
Using Filters
|
||||
=============
|
||||
|
||||
For a finer grained control over what kind of messages will be allowed or not in your callback functions, you can use
|
||||
:class:`Filters <pyrogram.Filters>`.
|
||||
|
||||
.. note::
|
||||
This section makes use of Handlers 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:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Filters
|
||||
|
||||
|
||||
@app.on_message(Filters.audio)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- or, without decorators:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Filters, MessageHandler
|
||||
|
||||
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(my_handler, Filters.audio))
|
||||
|
||||
Combining Filters
|
||||
-----------------
|
||||
|
||||
Filters can also be used in a more advanced way by inverting and combining more filters together using bitwise
|
||||
operators:
|
||||
|
||||
- Use ``~`` to invert a filter (behaves like the ``not`` operator).
|
||||
- Use ``&`` and ``|`` to merge two filters (behave like ``and``, ``or`` operators respectively).
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- Message is a **text** message **and** is **not edited**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text & ~Filters.edited)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **sticker** **and** is coming from a **channel or** a **private** chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.sticker & (Filters.channel | Filters.private))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
Advanced Filters
|
||||
----------------
|
||||
|
||||
Some filters, like :meth:`command() <pyrogram.Filters.command>` or :meth:`regex() <pyrogram.Filters.regex>`
|
||||
can also accept arguments:
|
||||
|
||||
- Message is either a */start* or */help* **command**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command(["start", "help"]))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **text** message matching the given **regex** pattern.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.regex("pyrogram"))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
More handlers using different filters can also live together.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command("start"))
|
||||
def start_command(client, message):
|
||||
print("This is the /start command")
|
||||
|
||||
|
||||
@app.on_message(Filters.command("help"))
|
||||
def help_command(client, message):
|
||||
print("This is the /help command")
|
||||
|
||||
|
||||
@app.on_message(Filters.chat("PyrogramChat"))
|
||||
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
|
||||
--------------
|
||||
|
||||
Pyrogram already provides lots of built-in :class:`Filters <pyrogram.Filters>` to work with, but in case you can't find
|
||||
a specific one for your needs or want to build a custom filter by yourself (to be used in a different handler, for
|
||||
example) you can use :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
.. note::
|
||||
At the moment, the built-in filters are intended to be used with the :obj:`MessageHandler <pyrogram.MessageHandler>`
|
||||
only.
|
||||
|
||||
An example to demonstrate how custom filters work is to show how to create and use one for the
|
||||
:obj:`CallbackQueryHandler <pyrogram.CallbackQueryHandler>`. Note that callback queries updates are only received by Bots;
|
||||
create and `authorize your bot <../start/Setup.html#bot-authorization>`_, then send a message with an inline keyboard to
|
||||
yourself. This allows you to test your filter by pressing the inline button:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
app.send_message(
|
||||
"username", # Change this to your username or id
|
||||
"Pyrogram's custom filter test",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[[InlineKeyboardButton("Press me", "pyrogram")]]
|
||||
)
|
||||
)
|
||||
|
||||
Basic Filters
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
For this basic filter we will be using only the first two parameters of :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
The code below creates a simple filter for hardcoded callback data. This filter will only allow callback queries
|
||||
containing "pyrogram" as data:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
hardcoded_data = Filters.create(
|
||||
name="HardcodedData",
|
||||
func=lambda filter, callback_query: callback_query.data == "pyrogram"
|
||||
)
|
||||
|
||||
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same
|
||||
could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter itself:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def func(filter, callback_query):
|
||||
return callback_query.data == "pyrogram"
|
||||
|
||||
hardcoded_data = Filters.create(
|
||||
name="HardcodedData",
|
||||
func=func
|
||||
)
|
||||
|
||||
The filter usage remains the same:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(hardcoded_data)
|
||||
def pyrogram_data(client, callback_query):
|
||||
client.answer_callback_query(callback_query.id, "it works!")
|
||||
|
||||
Filters with Arguments
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A much cooler filter would be one that accepts "pyrogram" or any other data as argument at usage time.
|
||||
A dynamic filter like this will make use of the third parameter of :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
This is how a dynamic custom filter looks like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def dynamic_data(data):
|
||||
return Filters.create(
|
||||
name="DynamicData",
|
||||
func=lambda filter, callback_query: filter.data == callback_query.data,
|
||||
data=data # "data" kwarg is accessed with "filter.data"
|
||||
)
|
||||
|
||||
And its usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(dynamic_data("pyrogram"))
|
||||
def pyrogram_data(client, callback_query):
|
||||
client.answer_callback_query(callback_query.id, "it works!")
|
@ -7,6 +7,7 @@ We recommend using the latest version of Python 3 and pip.
|
||||
Get Python 3 from https://www.python.org/downloads/ or with your package manager and pip
|
||||
by following the instructions at https://pip.pypa.io/en/latest/installing/.
|
||||
|
||||
.. note::
|
||||
Pyrogram supports Python 3 only, starting from version 3.4 and PyPy.
|
||||
|
||||
Install Pyrogram
|
||||
|
@ -8,22 +8,29 @@ with Pyrogram.
|
||||
API Keys
|
||||
--------
|
||||
|
||||
The very first step requires you to obtain a valid Telegram API key.
|
||||
The very first step requires you to obtain a valid Telegram API key (API id/hash pair).
|
||||
If you already have one you can skip this step, otherwise:
|
||||
|
||||
#. Visit https://my.telegram.org/apps and log in with your Telegram Account.
|
||||
#. Fill out the form to register a new Telegram application.
|
||||
#. Done. The Telegram API key consists of two parts: the **App api_id** and the **App api_hash**.
|
||||
#. Done. The API key consists of two parts: **App api_id** and **App api_hash**.
|
||||
|
||||
.. important:: This key should be kept secret.
|
||||
|
||||
.. important::
|
||||
|
||||
This API key is personal and should be kept secret.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
There are two ways to configure a Pyrogram application project, and you can choose the one that fits better for you:
|
||||
The API key obtained in the `previous step <#api-keys>`_ defines a token for your application allowing you to access
|
||||
the Telegram database using the MTProto API — **it is therefore required for all authorizations of both Users and Bots**.
|
||||
|
||||
Having it handy, it's time to configure your Pyrogram project. There are two ways to do so, and you can choose what
|
||||
fits better for you:
|
||||
|
||||
- Create a new ``config.ini`` file at the root of your working directory, copy-paste the following and replace the
|
||||
**api_id** and **api_hash** values with `your own <#api-keys>`_. This is the preferred method because allows you
|
||||
**api_id** and **api_hash** values with your own. This is the preferred method because allows you
|
||||
to keep your credentials out of your code without having to deal with how to load them:
|
||||
|
||||
.. code-block:: ini
|
||||
@ -45,7 +52,8 @@ There are two ways to configure a Pyrogram application project, and you can choo
|
||||
api_hash="0123456789abcdef0123456789abcdef"
|
||||
)
|
||||
|
||||
.. note:: The examples below assume you have created a ``config.ini`` file, thus they won't show the *api_id*
|
||||
.. note::
|
||||
The examples below assume you have created a ``config.ini`` file, thus they won't show the *api_id*
|
||||
and *api_hash* parameters usage.
|
||||
|
||||
User Authorization
|
||||
@ -76,16 +84,17 @@ After successfully authorizing yourself, a new file called ``my_account.session`
|
||||
Pyrogram executing API calls with your identity. This file will be loaded again when you restart your app,
|
||||
and as long as you keep the session alive, Pyrogram won't ask you again to enter your phone number.
|
||||
|
||||
.. important:: Your ``*.session`` file(s) must be kept secret.
|
||||
.. important:: Your ``*.session`` files are personal and must be kept secret.
|
||||
|
||||
Bot Authorization
|
||||
-----------------
|
||||
|
||||
Being written entirely from the ground up, Pyrogram is also able to authorize Bots.
|
||||
Bots are a special kind of users which also make use of MTProto, the underlying Telegram protocol.
|
||||
This means that you can use Pyrogram to execute API calls with a Bot identity.
|
||||
Bots are a special kind of users and are authorized via their tokens (instead of phone numbers), which are created by
|
||||
BotFather_. Bot tokens replace the Users' phone numbers only — you still need to
|
||||
`configure a Telegram API key <#configuration>`_ with Pyrogram, even when using Bots.
|
||||
|
||||
Instead of phone numbers, Bots are authorized via their tokens which are created by BotFather_:
|
||||
The authorization process is automatically managed. All you need to do is pass the bot token as ``session_name``.
|
||||
The session file will be named after the Bot user_id, which is ``123456.session`` for the example below.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -94,9 +103,6 @@ Instead of phone numbers, Bots are authorized via their tokens which are created
|
||||
app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
app.run()
|
||||
|
||||
That's all, no further action is needed. The session file will be named after the Bot user_id, which is
|
||||
``123456.session`` for the example above.
|
||||
|
||||
.. _installed Pyrogram: Installation.html
|
||||
.. _`Country Code`: https://en.wikipedia.org/wiki/List_of_country_calling_codes
|
||||
.. _BotFather: https://t.me/botfather
|
@ -108,9 +108,9 @@ Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/exa
|
||||
|
||||
app.stop()
|
||||
|
||||
.. _methods: ../pyrogram/Client.html#available-methods
|
||||
.. _plenty of them: ../pyrogram/Client.html#available-methods
|
||||
.. _types: ../pyrogram/types/index.html
|
||||
.. _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
|
||||
|
@ -36,11 +36,10 @@ __version__ = "0.8.0dev1"
|
||||
from .api.errors import Error
|
||||
from .client.types import (
|
||||
Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto,
|
||||
InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity,
|
||||
Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserProfilePhotos,
|
||||
Venue, GIF, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
||||
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup,
|
||||
ReplyKeyboardRemove
|
||||
InputMediaVideo, InputMediaDocument, InputMediaAudio, InputMediaAnimation, InputPhoneContact,
|
||||
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User,
|
||||
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
||||
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
|
||||
)
|
||||
from .client import (
|
||||
Client, ChatAction, ParseMode, Emoji,
|
||||
|
@ -1009,21 +1009,19 @@ class Client(Methods, BaseClient):
|
||||
await self.get_initial_dialogs_chunk()
|
||||
|
||||
async def resolve_peer(self, peer_id: int or str):
|
||||
"""Use this method to get the *InputPeer* of a known *peer_id*.
|
||||
"""Use this method to get the InputPeer of a known peer_id.
|
||||
|
||||
It is intended to be used when working with Raw Functions (i.e: a Telegram API method you wish to use which is
|
||||
not available yet in the Client class as an easy-to-use method).
|
||||
This is a utility method intended to be used only when working with Raw Functions (i.e: a Telegram API method
|
||||
you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an InputPeer
|
||||
type is required.
|
||||
|
||||
Args:
|
||||
peer_id (``int`` | ``str`` | ``Peer``):
|
||||
The Peer ID you want to extract the InputPeer from. Can be one of these types: ``int`` (direct ID),
|
||||
``str`` (@username), :obj:`PeerUser <pyrogram.api.types.PeerUser>`,
|
||||
:obj:`PeerChat <pyrogram.api.types.PeerChat>`, :obj:`PeerChannel <pyrogram.api.types.PeerChannel>`
|
||||
peer_id (``int`` | ``str``):
|
||||
The peer id you want to extract the InputPeer from.
|
||||
Can be a direct id (int), a username (str) or a phone number (str).
|
||||
|
||||
Returns:
|
||||
:obj:`InputPeerUser <pyrogram.api.types.InputPeerUser>` or
|
||||
:obj:`InputPeerChat <pyrogram.api.types.InputPeerChat>` or
|
||||
:obj:`InputPeerChannel <pyrogram.api.types.InputPeerChannel>` depending on the *peer_id*.
|
||||
On success, the resolved peer id is returned in form of an InputPeer object.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>`
|
||||
@ -1032,23 +1030,14 @@ class Client(Methods, BaseClient):
|
||||
if peer_id in ("self", "me"):
|
||||
return types.InputPeerSelf()
|
||||
|
||||
match = self.INVITE_LINK_RE.match(peer_id)
|
||||
|
||||
try:
|
||||
decoded = base64.b64decode(match.group(1) + "=" * (-len(match.group(1)) % 4), "-_")
|
||||
return await self.resolve_peer(struct.unpack(">2iq", decoded)[1])
|
||||
except (AttributeError, binascii.Error, struct.error):
|
||||
pass
|
||||
|
||||
peer_id = re.sub(r"[@+\s]", "", peer_id.lower())
|
||||
|
||||
try:
|
||||
int(peer_id)
|
||||
except ValueError:
|
||||
try:
|
||||
return self.peers_by_username[peer_id]
|
||||
except KeyError:
|
||||
if peer_id not in self.peers_by_username:
|
||||
await self.send(functions.contacts.ResolveUsername(peer_id))
|
||||
|
||||
return self.peers_by_username[peer_id]
|
||||
else:
|
||||
try:
|
||||
@ -1056,14 +1045,6 @@ class Client(Methods, BaseClient):
|
||||
except KeyError:
|
||||
raise PeerIdInvalid
|
||||
|
||||
if type(peer_id) is not int:
|
||||
if isinstance(peer_id, types.PeerUser):
|
||||
peer_id = peer_id.user_id
|
||||
elif isinstance(peer_id, types.PeerChat):
|
||||
peer_id = -peer_id.chat_id
|
||||
elif isinstance(peer_id, types.PeerChannel):
|
||||
peer_id = int("-100" + str(peer_id.channel_id))
|
||||
|
||||
try: # User
|
||||
return self.peers_by_id[peer_id]
|
||||
except KeyError:
|
||||
|
@ -40,7 +40,6 @@ class BaseClient:
|
||||
platform.release()
|
||||
)
|
||||
|
||||
SYSTEM_LANG_CODE = "en"
|
||||
LANG_CODE = "en"
|
||||
|
||||
INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/joinchat/)([\w-]+)$")
|
||||
@ -59,7 +58,7 @@ class BaseClient:
|
||||
5: "document",
|
||||
8: "sticker",
|
||||
9: "audio",
|
||||
10: "gif",
|
||||
10: "animation",
|
||||
13: "video_note"
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,8 @@ ENTITIES = {
|
||||
types.MessageEntityCode.ID: "code",
|
||||
types.MessageEntityPre.ID: "pre",
|
||||
types.MessageEntityTextUrl.ID: "text_link",
|
||||
types.MessageEntityMentionName.ID: "text_mention"
|
||||
types.MessageEntityMentionName.ID: "text_mention",
|
||||
types.MessageEntityPhone.ID: "phone_number"
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +93,8 @@ def parse_entities(entities: list, users: dict) -> list:
|
||||
entity_type = ENTITIES.get(entity.ID, None)
|
||||
|
||||
if entity_type:
|
||||
output_entities.append(pyrogram_types.MessageEntity(
|
||||
output_entities.append(
|
||||
pyrogram_types.MessageEntity(
|
||||
type=entity_type,
|
||||
offset=entity.offset,
|
||||
length=entity.length,
|
||||
@ -103,7 +105,8 @@ def parse_entities(entities: list, users: dict) -> list:
|
||||
None
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
return output_entities
|
||||
|
||||
@ -305,7 +308,7 @@ async def parse_messages(
|
||||
venue = None
|
||||
audio = None
|
||||
voice = None
|
||||
gif = None
|
||||
animation = None
|
||||
video = None
|
||||
video_note = None
|
||||
sticker = None
|
||||
@ -387,7 +390,8 @@ async def parse_messages(
|
||||
),
|
||||
title=media.title,
|
||||
address=media.address,
|
||||
foursquare_id=media.venue_id or None
|
||||
foursquare_id=media.venue_id or None,
|
||||
foursquare_type=media.venue_type
|
||||
)
|
||||
elif isinstance(media, types.MessageMediaDocument):
|
||||
doc = media.document
|
||||
@ -444,7 +448,7 @@ async def parse_messages(
|
||||
elif types.DocumentAttributeAnimated in attributes:
|
||||
video_attributes = attributes.get(types.DocumentAttributeVideo, None)
|
||||
|
||||
gif = pyrogram_types.GIF(
|
||||
animation = pyrogram_types.Animation(
|
||||
file_id=encode(
|
||||
pack(
|
||||
"<iiqq",
|
||||
@ -596,7 +600,7 @@ async def parse_messages(
|
||||
venue=venue,
|
||||
audio=audio,
|
||||
voice=voice,
|
||||
gif=gif,
|
||||
animation=animation,
|
||||
video=video,
|
||||
video_note=video_note,
|
||||
sticker=sticker,
|
||||
|
@ -19,10 +19,32 @@
|
||||
import re
|
||||
|
||||
from .filter import Filter
|
||||
from ..types.reply_markup import InlineKeyboardMarkup, ReplyKeyboardMarkup
|
||||
from ..types.bots import InlineKeyboardMarkup, ReplyKeyboardMarkup
|
||||
|
||||
|
||||
def build(name: str, func: callable, **kwargs) -> type:
|
||||
def create(name: str, func: callable, **kwargs) -> type:
|
||||
"""Use this method to create a Filter.
|
||||
|
||||
Custom filters give you extra control over which updates are allowed or not to be processed by your handlers.
|
||||
|
||||
Args:
|
||||
name (``str``):
|
||||
Your filter's name. Can be anything you like.
|
||||
|
||||
func (``callable``):
|
||||
A function that accepts two arguments *(filter, update)* and returns a Boolean: True if the update should be
|
||||
handled, False otherwise.
|
||||
The "update" argument type will vary depending on which `Handler <Handlers.html>`_ is coming from.
|
||||
For example, in a :obj:`MessageHandler <pyrogram.MessageHandler>` the update type will be
|
||||
a :obj:`Message <pyrogram.Message>`; in a :obj:`CallbackQueryHandler <pyrogram.CallbackQueryHandler>` the
|
||||
update type will be a :obj:`CallbackQuery <pyrogram.CallbackQuery>`. Your function body can then access the
|
||||
incoming update and decide whether to allow it or not.
|
||||
|
||||
**kwargs (``any``, *optional*):
|
||||
Any keyword argument you would like to pass. Useful for custom filters that accept parameters (e.g.:
|
||||
:meth:`Filters.command`, :meth:`Filters.regex`).
|
||||
"""
|
||||
# TODO: unpack kwargs using **kwargs into the dict itself. For Python 3.5+ only
|
||||
d = {"__call__": func}
|
||||
d.update(kwargs)
|
||||
|
||||
@ -30,112 +52,118 @@ def build(name: str, func: callable, **kwargs) -> type:
|
||||
|
||||
|
||||
class Filters:
|
||||
"""This class provides access to all Filters available in Pyrogram.
|
||||
Filters are intended to be used with the :obj:`MessageHandler <pyrogram.MessageHandler>`."""
|
||||
"""This class provides access to all library-defined Filters available in Pyrogram.
|
||||
|
||||
bot = build("Bot", lambda _, m: bool(m.from_user and m.from_user.is_bot))
|
||||
The Filters listed here are intended to be used with the :obj:`MessageHandler <pyrogram.MessageHandler>` only.
|
||||
At the moment, if you want to filter updates coming from different `Handlers <Handlers.html>`_ you have to create
|
||||
your own filters with :meth:`Filters.create` and use them in the same way.
|
||||
"""
|
||||
|
||||
create = create
|
||||
|
||||
bot = create("Bot", lambda _, m: bool(m.from_user and m.from_user.is_bot))
|
||||
"""Filter messages coming from bots"""
|
||||
|
||||
incoming = build("Incoming", lambda _, m: not m.outgoing)
|
||||
incoming = create("Incoming", lambda _, m: not m.outgoing)
|
||||
"""Filter incoming messages."""
|
||||
|
||||
outgoing = build("Outgoing", lambda _, m: m.outgoing)
|
||||
outgoing = create("Outgoing", lambda _, m: m.outgoing)
|
||||
"""Filter outgoing messages."""
|
||||
|
||||
text = build("Text", lambda _, m: bool(m.text))
|
||||
text = create("Text", lambda _, m: bool(m.text))
|
||||
"""Filter text messages."""
|
||||
|
||||
reply = build("Reply", lambda _, m: bool(m.reply_to_message))
|
||||
reply = create("Reply", lambda _, m: bool(m.reply_to_message))
|
||||
"""Filter messages that are replies to other messages."""
|
||||
|
||||
forwarded = build("Forwarded", lambda _, m: bool(m.forward_date))
|
||||
forwarded = create("Forwarded", lambda _, m: bool(m.forward_date))
|
||||
"""Filter messages that are forwarded."""
|
||||
|
||||
caption = build("Caption", lambda _, m: bool(m.caption))
|
||||
caption = create("Caption", lambda _, m: bool(m.caption))
|
||||
"""Filter media messages that contain captions."""
|
||||
|
||||
edited = build("Edited", lambda _, m: bool(m.edit_date))
|
||||
edited = create("Edited", lambda _, m: bool(m.edit_date))
|
||||
"""Filter edited messages."""
|
||||
|
||||
audio = build("Audio", lambda _, m: bool(m.audio))
|
||||
audio = create("Audio", lambda _, m: bool(m.audio))
|
||||
"""Filter messages that contain :obj:`Audio <pyrogram.api.types.pyrogram.Audio>` objects."""
|
||||
|
||||
document = build("Document", lambda _, m: bool(m.document))
|
||||
document = create("Document", lambda _, m: bool(m.document))
|
||||
"""Filter messages that contain :obj:`Document <pyrogram.api.types.pyrogram.Document>` objects."""
|
||||
|
||||
photo = build("Photo", lambda _, m: bool(m.photo))
|
||||
photo = create("Photo", lambda _, m: bool(m.photo))
|
||||
"""Filter messages that contain :obj:`Photo <pyrogram.api.types.pyrogram.PhotoSize>` objects."""
|
||||
|
||||
sticker = build("Sticker", lambda _, m: bool(m.sticker))
|
||||
sticker = create("Sticker", lambda _, m: bool(m.sticker))
|
||||
"""Filter messages that contain :obj:`Sticker <pyrogram.api.types.pyrogram.Sticker>` objects."""
|
||||
|
||||
gif = build("GIF", lambda _, m: bool(m.gif))
|
||||
"""Filter messages that contain :obj:`GIF <pyrogram.api.types.pyrogram.GIF>` objects."""
|
||||
animation = create("GIF", lambda _, m: bool(m.animation))
|
||||
"""Filter messages that contain :obj:`Animation <pyrogram.api.types.pyrogram.Animation>` objects."""
|
||||
|
||||
video = build("Video", lambda _, m: bool(m.video))
|
||||
video = create("Video", lambda _, m: bool(m.video))
|
||||
"""Filter messages that contain :obj:`Video <pyrogram.api.types.pyrogram.Video>` objects."""
|
||||
|
||||
voice = build("Voice", lambda _, m: bool(m.voice))
|
||||
voice = create("Voice", lambda _, m: bool(m.voice))
|
||||
"""Filter messages that contain :obj:`Voice <pyrogram.api.types.pyrogram.Voice>` note objects."""
|
||||
|
||||
video_note = build("Voice", lambda _, m: bool(m.video_note))
|
||||
video_note = create("Voice", lambda _, m: bool(m.video_note))
|
||||
"""Filter messages that contain :obj:`VideoNote <pyrogram.api.types.pyrogram.VideoNote>` objects."""
|
||||
|
||||
contact = build("Contact", lambda _, m: bool(m.contact))
|
||||
contact = create("Contact", lambda _, m: bool(m.contact))
|
||||
"""Filter messages that contain :obj:`Contact <pyrogram.api.types.pyrogram.Contact>` objects."""
|
||||
|
||||
location = build("Location", lambda _, m: bool(m.location))
|
||||
location = create("Location", lambda _, m: bool(m.location))
|
||||
"""Filter messages that contain :obj:`Location <pyrogram.api.types.pyrogram.Location>` objects."""
|
||||
|
||||
venue = build("Venue", lambda _, m: bool(m.venue))
|
||||
venue = create("Venue", lambda _, m: bool(m.venue))
|
||||
"""Filter messages that contain :obj:`Venue <pyrogram.api.types.pyrogram.Venue>` objects."""
|
||||
|
||||
private = build("Private", lambda _, m: bool(m.chat and m.chat.type == "private"))
|
||||
private = create("Private", lambda _, m: bool(m.chat and m.chat.type == "private"))
|
||||
"""Filter messages sent in private chats."""
|
||||
|
||||
group = build("Group", lambda _, m: bool(m.chat and m.chat.type in {"group", "supergroup"}))
|
||||
group = create("Group", lambda _, m: bool(m.chat and m.chat.type in {"group", "supergroup"}))
|
||||
"""Filter messages sent in group or supergroup chats."""
|
||||
|
||||
channel = build("Channel", lambda _, m: bool(m.chat and m.chat.type == "channel"))
|
||||
channel = create("Channel", lambda _, m: bool(m.chat and m.chat.type == "channel"))
|
||||
"""Filter messages sent in channels."""
|
||||
|
||||
new_chat_members = build("NewChatMembers", lambda _, m: bool(m.new_chat_members))
|
||||
new_chat_members = create("NewChatMembers", lambda _, m: bool(m.new_chat_members))
|
||||
"""Filter service messages for new chat members."""
|
||||
|
||||
left_chat_member = build("LeftChatMember", lambda _, m: bool(m.left_chat_member))
|
||||
left_chat_member = create("LeftChatMember", lambda _, m: bool(m.left_chat_member))
|
||||
"""Filter service messages for members that left the chat."""
|
||||
|
||||
new_chat_title = build("NewChatTitle", lambda _, m: bool(m.new_chat_title))
|
||||
new_chat_title = create("NewChatTitle", lambda _, m: bool(m.new_chat_title))
|
||||
"""Filter service messages for new chat titles."""
|
||||
|
||||
new_chat_photo = build("NewChatPhoto", lambda _, m: bool(m.new_chat_photo))
|
||||
new_chat_photo = create("NewChatPhoto", lambda _, m: bool(m.new_chat_photo))
|
||||
"""Filter service messages for new chat photos."""
|
||||
|
||||
delete_chat_photo = build("DeleteChatPhoto", lambda _, m: bool(m.delete_chat_photo))
|
||||
delete_chat_photo = create("DeleteChatPhoto", lambda _, m: bool(m.delete_chat_photo))
|
||||
"""Filter service messages for deleted photos."""
|
||||
|
||||
group_chat_created = build("GroupChatCreated", lambda _, m: bool(m.group_chat_created))
|
||||
group_chat_created = create("GroupChatCreated", lambda _, m: bool(m.group_chat_created))
|
||||
"""Filter service messages for group chat creations."""
|
||||
|
||||
supergroup_chat_created = build("SupergroupChatCreated", lambda _, m: bool(m.supergroup_chat_created))
|
||||
supergroup_chat_created = create("SupergroupChatCreated", lambda _, m: bool(m.supergroup_chat_created))
|
||||
"""Filter service messages for supergroup chat creations."""
|
||||
|
||||
channel_chat_created = build("ChannelChatCreated", lambda _, m: bool(m.channel_chat_created))
|
||||
channel_chat_created = create("ChannelChatCreated", lambda _, m: bool(m.channel_chat_created))
|
||||
"""Filter service messages for channel chat creations."""
|
||||
|
||||
migrate_to_chat_id = build("MigrateToChatId", lambda _, m: bool(m.migrate_to_chat_id))
|
||||
migrate_to_chat_id = create("MigrateToChatId", lambda _, m: bool(m.migrate_to_chat_id))
|
||||
"""Filter service messages that contain migrate_to_chat_id."""
|
||||
|
||||
migrate_from_chat_id = build("MigrateFromChatId", lambda _, m: bool(m.migrate_from_chat_id))
|
||||
migrate_from_chat_id = create("MigrateFromChatId", lambda _, m: bool(m.migrate_from_chat_id))
|
||||
"""Filter service messages that contain migrate_from_chat_id."""
|
||||
|
||||
pinned_message = build("PinnedMessage", lambda _, m: bool(m.pinned_message))
|
||||
pinned_message = create("PinnedMessage", lambda _, m: bool(m.pinned_message))
|
||||
"""Filter service messages for pinned messages."""
|
||||
|
||||
reply_keyboard = build("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
|
||||
reply_keyboard = create("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
|
||||
"""Filter messages containing reply keyboard markups"""
|
||||
|
||||
inline_keyboard = build("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup))
|
||||
inline_keyboard = create("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup))
|
||||
"""Filter messages containing inline keyboard markups"""
|
||||
|
||||
@staticmethod
|
||||
@ -174,7 +202,7 @@ class Filters:
|
||||
|
||||
return bool(m.command)
|
||||
|
||||
return build(
|
||||
return create(
|
||||
"Command",
|
||||
f,
|
||||
c={command if case_sensitive
|
||||
@ -206,7 +234,7 @@ class Filters:
|
||||
m.matches = [i for i in _.p.finditer(m.text or "")]
|
||||
return bool(m.matches)
|
||||
|
||||
return build("Regex", f, p=re.compile(pattern, flags))
|
||||
return create("Regex", f, p=re.compile(pattern, flags))
|
||||
|
||||
@staticmethod
|
||||
def user(user: int or str or list):
|
||||
@ -216,7 +244,7 @@ class Filters:
|
||||
user (``int`` | ``str`` | ``list``):
|
||||
The user or list of user IDs (int) or usernames (str) the filter should look for.
|
||||
"""
|
||||
return build(
|
||||
return create(
|
||||
"User",
|
||||
lambda _, m: bool(m.from_user
|
||||
and (m.from_user.id in _.u
|
||||
@ -237,7 +265,7 @@ class Filters:
|
||||
chat (``int`` | ``str`` | ``list``):
|
||||
The chat or list of chat IDs (int) or usernames (str) the filter should look for.
|
||||
"""
|
||||
return build(
|
||||
return create(
|
||||
"Chat",
|
||||
lambda _, m: bool(m.chat
|
||||
and (m.chat.id in _.c
|
||||
@ -250,7 +278,7 @@ class Filters:
|
||||
)
|
||||
)
|
||||
|
||||
service = build(
|
||||
service = create(
|
||||
"Service",
|
||||
lambda _, m: bool(
|
||||
Filters.new_chat_members(m)
|
||||
@ -268,7 +296,7 @@ class Filters:
|
||||
)
|
||||
"""Filter all service messages."""
|
||||
|
||||
media = build(
|
||||
media = create(
|
||||
"Media",
|
||||
lambda _, m: bool(
|
||||
Filters.audio(m)
|
||||
@ -276,7 +304,7 @@ class Filters:
|
||||
or Filters.photo(m)
|
||||
or Filters.sticker(m)
|
||||
or Filters.video(m)
|
||||
or Filters.gif(m)
|
||||
or Filters.animation(m)
|
||||
or Filters.voice(m)
|
||||
or Filters.video_note(m)
|
||||
or Filters.contact(m)
|
||||
|
@ -20,10 +20,10 @@ from .bots import Bots
|
||||
from .chats import Chats
|
||||
from .contacts import Contacts
|
||||
from .decorators import Decorators
|
||||
from .download_media import DownloadMedia
|
||||
from .messages import Messages
|
||||
from .password import Password
|
||||
from .users import Users
|
||||
from .utilities import Utilities
|
||||
|
||||
|
||||
class Methods(
|
||||
@ -32,7 +32,7 @@ class Methods(
|
||||
Password,
|
||||
Chats,
|
||||
Users,
|
||||
DownloadMedia,
|
||||
Utilities,
|
||||
Messages,
|
||||
Decorators
|
||||
):
|
||||
|
@ -33,7 +33,6 @@ class RequestCallbackAnswer(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_id (``int``):
|
||||
The message id the inline keyboard is attached on.
|
||||
|
@ -35,7 +35,6 @@ class SendInlineBotResult(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
query_id (``int``):
|
||||
Unique identifier for the answered query.
|
||||
|
@ -19,7 +19,9 @@
|
||||
from .delete_chat_photo import DeleteChatPhoto
|
||||
from .export_chat_invite_link import ExportChatInviteLink
|
||||
from .get_chat import GetChat
|
||||
from .get_chat_member import GetChatMember
|
||||
from .get_chat_members import GetChatMembers
|
||||
from .get_dialogs import GetDialogs
|
||||
from .join_chat import JoinChat
|
||||
from .kick_chat_member import KickChatMember
|
||||
from .leave_chat import LeaveChat
|
||||
@ -43,11 +45,13 @@ class Chats(
|
||||
RestrictChatMember,
|
||||
PromoteChatMember,
|
||||
GetChatMembers,
|
||||
GetChatMember,
|
||||
SetChatPhoto,
|
||||
DeleteChatPhoto,
|
||||
SetChatTitle,
|
||||
SetChatDescription,
|
||||
PinChatMessage,
|
||||
UnpinChatMessage
|
||||
UnpinChatMessage,
|
||||
GetDialogs
|
||||
):
|
||||
pass
|
||||
|
@ -33,7 +33,6 @@ class DeleteChatPhoto(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
Returns:
|
||||
True on success.
|
||||
|
@ -28,7 +28,6 @@ class GetChat(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
Returns:
|
||||
On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
|
||||
|
75
pyrogram/client/methods/chats/get_chat_member.py
Normal file
75
pyrogram/client/methods/chats/get_chat_member.py
Normal file
@ -0,0 +1,75 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram.api import functions, types, errors
|
||||
from ...ext import BaseClient, utils
|
||||
|
||||
|
||||
class GetChatMember(BaseClient):
|
||||
def get_chat_member(self,
|
||||
chat_id: int or str,
|
||||
user_id: int or str):
|
||||
"""Use this method to get information about one member of a chat.
|
||||
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
|
||||
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).
|
||||
|
||||
Returns:
|
||||
On success, a :obj:`ChatMember <pyrogram.ChatMember>` object is returned.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>`
|
||||
"""
|
||||
chat_id = self.resolve_peer(chat_id)
|
||||
user_id = self.resolve_peer(user_id)
|
||||
|
||||
if isinstance(chat_id, types.InputPeerChat):
|
||||
full_chat = self.send(
|
||||
functions.messages.GetFullChat(
|
||||
chat_id=chat_id.chat_id
|
||||
)
|
||||
)
|
||||
|
||||
for member in utils.parse_chat_members(full_chat).chat_members:
|
||||
if member.user.id == user_id.user_id:
|
||||
return member
|
||||
else:
|
||||
raise errors.UserNotParticipant
|
||||
elif isinstance(chat_id, types.InputPeerChannel):
|
||||
r = self.send(
|
||||
functions.channels.GetParticipant(
|
||||
channel=chat_id,
|
||||
user_id=user_id
|
||||
)
|
||||
)
|
||||
|
||||
return utils.parse_chat_members(
|
||||
types.channels.ChannelParticipants(
|
||||
count=1,
|
||||
participants=[r.participant],
|
||||
users=r.users
|
||||
)
|
||||
).chat_members[0]
|
||||
else:
|
||||
raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id))
|
@ -36,6 +36,42 @@ class GetChatMembers(BaseClient):
|
||||
limit: int = 200,
|
||||
query: str = "",
|
||||
filter: str = Filters.ALL):
|
||||
"""Use this method to get the members list of a chat.
|
||||
|
||||
A chat can be either a basic group, a supergroup or a channel.
|
||||
You must be admin to retrieve the members (also known as "subscribers") list of a channel.
|
||||
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
|
||||
offset (``int``, *optional*):
|
||||
Sequential number of the first member to be returned.
|
||||
Defaults to 0 [1]_.
|
||||
|
||||
limit (``int``, *optional*):
|
||||
Limits the number of members to be retrieved.
|
||||
Defaults to 200, which is also the maximum limit allowed per method call.
|
||||
|
||||
query (``str``, *optional*):
|
||||
Query string to filter members based on their display names and usernames.
|
||||
Defaults to "" (empty string) [2]_.
|
||||
|
||||
filter (``str``, *optional*):
|
||||
Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
|
||||
and channels. It can be any of the followings:
|
||||
*"all"* - all kind of members,
|
||||
*"kicked"* - kicked (banned) members only,
|
||||
*"restricted"* - restricted members only,
|
||||
*"bots"* - bots only,
|
||||
*"recent"* - recent members only,
|
||||
*"administrators"* - chat administrators only.
|
||||
Defaults to *"all"*.
|
||||
|
||||
.. [1] On supergroups and channels you can get up to 10,000 members for a single query string.
|
||||
|
||||
.. [2] A query string is applicable only for *"all"*, *"kicked"* and *"restricted"* filters only.
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
|
||||
if isinstance(peer, types.InputPeerChat):
|
||||
|
@ -22,19 +22,41 @@ from ...ext import BaseClient, utils
|
||||
|
||||
|
||||
class GetDialogs(BaseClient):
|
||||
# TODO docstrings
|
||||
|
||||
async def get_dialogs(self,
|
||||
def get_dialogs(self,
|
||||
offset_dialogs=None,
|
||||
limit: int = 100,
|
||||
pinned_only: bool = False,
|
||||
last_chunk=None):
|
||||
pinned_only: bool = False):
|
||||
"""Use this method to get the user's dialogs
|
||||
|
||||
You can get up to 100 dialogs at once.
|
||||
|
||||
Args:
|
||||
limit (``str``, *optional*):
|
||||
Limits the number of dialogs to be retrieved.
|
||||
Defaults to 100
|
||||
|
||||
pinned_only (``bool``, *optional*):
|
||||
Pass True if you want to get only pinned dialogs.
|
||||
Defaults to False.
|
||||
|
||||
offset_dialogs (:obj:`Dialogs`):
|
||||
Pass the previous dialogs object to retrieve the next dialogs chunk starting from the last dialog.
|
||||
Defaults to None (start from the beginning).
|
||||
|
||||
Returns:
|
||||
On success, a :obj:`Dialogs` object is returned.
|
||||
|
||||
Raises:
|
||||
:class:`Error`
|
||||
"""
|
||||
|
||||
if pinned_only:
|
||||
r = await self.send(functions.messages.GetPinnedDialogs())
|
||||
else:
|
||||
offset_date = 0
|
||||
|
||||
if last_chunk:
|
||||
for dialog in reversed(last_chunk.dialogs):
|
||||
if offset_dialogs:
|
||||
for dialog in reversed(offset_dialogs.dialogs):
|
||||
top_message = dialog.top_message
|
||||
|
||||
if top_message:
|
||||
@ -92,7 +114,8 @@ class GetDialogs(BaseClient):
|
||||
top_message=messages.get(chat_id),
|
||||
unread_messages_count=dialog.unread_count,
|
||||
unread_mentions_count=dialog.unread_mentions_count,
|
||||
unread_mark=dialog.unread_mark
|
||||
unread_mark=dialog.unread_mark,
|
||||
is_pinned=dialog.pinned
|
||||
)
|
||||
)
|
||||
|
@ -38,7 +38,6 @@ class KickChatMember(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
user_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
|
@ -29,7 +29,6 @@ class PinChatMessage(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_id (``int``):
|
||||
Identifier of a message to pin.
|
||||
|
@ -39,7 +39,6 @@ class PromoteChatMember(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
user_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
|
@ -36,7 +36,6 @@ class RestrictChatMember(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
user_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
|
@ -28,7 +28,6 @@ class SetChatDescription(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
description (``str``):
|
||||
New chat description, 0-255 characters.
|
||||
|
@ -37,7 +37,6 @@ class SetChatPhoto(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
photo (``str``):
|
||||
New chat photo. You can pass a :class:`Photo` id or a file path to upload a new photo.
|
||||
|
@ -33,7 +33,6 @@ class SetChatTitle(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
title (``str``):
|
||||
New chat title, 1-255 characters.
|
||||
|
@ -31,7 +31,6 @@ class UnbanChatMember(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
user_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
|
@ -29,7 +29,6 @@ class UnpinChatMessage(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
Returns:
|
||||
True on success.
|
||||
|
@ -18,17 +18,17 @@
|
||||
|
||||
from .delete_messages import DeleteMessages
|
||||
from .edit_message_caption import EditMessageCaption
|
||||
from .edit_message_media import EditMessageMedia
|
||||
from .edit_message_reply_markup import EditMessageReplyMarkup
|
||||
from .edit_message_text import EditMessageText
|
||||
from .forward_messages import ForwardMessages
|
||||
from .get_dialogs import GetDialogs
|
||||
from .get_history import GetHistory
|
||||
from .get_messages import GetMessages
|
||||
from .send_animation import SendAnimation
|
||||
from .send_audio import SendAudio
|
||||
from .send_chat_action import SendChatAction
|
||||
from .send_contact import SendContact
|
||||
from .send_document import SendDocument
|
||||
from .send_gif import SendGIF
|
||||
from .send_location import SendLocation
|
||||
from .send_media_group import SendMediaGroup
|
||||
from .send_message import SendMessage
|
||||
@ -44,16 +44,16 @@ class Messages(
|
||||
DeleteMessages,
|
||||
EditMessageCaption,
|
||||
EditMessageReplyMarkup,
|
||||
EditMessageMedia,
|
||||
EditMessageText,
|
||||
ForwardMessages,
|
||||
GetHistory,
|
||||
GetMessages,
|
||||
GetDialogs,
|
||||
SendAudio,
|
||||
SendChatAction,
|
||||
SendContact,
|
||||
SendDocument,
|
||||
SendGIF,
|
||||
SendAnimation,
|
||||
SendLocation,
|
||||
SendMediaGroup,
|
||||
SendMessage,
|
||||
|
@ -38,7 +38,6 @@ class DeleteMessages(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_ids (``iterable``):
|
||||
A list of Message identifiers to delete or a single message id.
|
||||
|
@ -34,7 +34,6 @@ class EditMessageCaption(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_id (``int``):
|
||||
Message identifier in the chat specified in chat_id.
|
||||
|
264
pyrogram/client/methods/messages/edit_message_media.py
Normal file
264
pyrogram/client/methods/messages/edit_message_media.py
Normal file
@ -0,0 +1,264 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import binascii
|
||||
import mimetypes
|
||||
import os
|
||||
import struct
|
||||
|
||||
from pyrogram.api import functions, types
|
||||
from pyrogram.api.errors import FileIdInvalid
|
||||
from pyrogram.client.ext import BaseClient, utils
|
||||
from pyrogram.client.types import (
|
||||
InputMediaPhoto, InputMediaVideo, InputMediaAudio,
|
||||
InputMediaAnimation
|
||||
)
|
||||
|
||||
|
||||
class EditMessageMedia(BaseClient):
|
||||
def edit_message_media(self,
|
||||
chat_id: int or str,
|
||||
message_id: int,
|
||||
media,
|
||||
reply_markup=None):
|
||||
style = self.html if media.parse_mode.lower() == "html" else self.markdown
|
||||
caption = media.caption
|
||||
|
||||
if isinstance(media, InputMediaPhoto):
|
||||
if os.path.exists(media.media):
|
||||
media = self.send(
|
||||
functions.messages.UploadMedia(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
media=types.InputMediaUploadedPhoto(
|
||||
file=self.save_file(media.media)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
media = types.InputMediaPhoto(
|
||||
id=types.InputPhoto(
|
||||
id=media.photo.id,
|
||||
access_hash=media.photo.access_hash
|
||||
)
|
||||
)
|
||||
elif media.media.startswith("http"):
|
||||
media = types.InputMediaPhotoExternal(
|
||||
url=media.media
|
||||
)
|
||||
else:
|
||||
try:
|
||||
decoded = utils.decode(media.media)
|
||||
fmt = "<iiqqqqi" if len(decoded) > 24 else "<iiqq"
|
||||
unpacked = struct.unpack(fmt, decoded)
|
||||
except (AssertionError, binascii.Error, struct.error):
|
||||
raise FileIdInvalid from None
|
||||
else:
|
||||
if unpacked[0] != 2:
|
||||
media_type = BaseClient.MEDIA_TYPE_ID.get(unpacked[0], None)
|
||||
|
||||
if media_type:
|
||||
raise FileIdInvalid("The file_id belongs to a {}".format(media_type))
|
||||
else:
|
||||
raise FileIdInvalid("Unknown media type: {}".format(unpacked[0]))
|
||||
|
||||
media = types.InputMediaPhoto(
|
||||
id=types.InputPhoto(
|
||||
id=unpacked[2],
|
||||
access_hash=unpacked[3]
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(media, InputMediaVideo):
|
||||
if os.path.exists(media.media):
|
||||
media = self.send(
|
||||
functions.messages.UploadMedia(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
media=types.InputMediaUploadedDocument(
|
||||
mime_type=mimetypes.types_map[".mp4"],
|
||||
file=self.save_file(media.media),
|
||||
attributes=[
|
||||
types.DocumentAttributeVideo(
|
||||
supports_streaming=media.supports_streaming or None,
|
||||
duration=media.duration,
|
||||
w=media.width,
|
||||
h=media.height
|
||||
),
|
||||
types.DocumentAttributeFilename(os.path.basename(media.media))
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=media.document.id,
|
||||
access_hash=media.document.access_hash
|
||||
)
|
||||
)
|
||||
elif media.media.startswith("http"):
|
||||
media = types.InputMediaDocumentExternal(
|
||||
url=media.media
|
||||
)
|
||||
else:
|
||||
try:
|
||||
decoded = utils.decode(media.media)
|
||||
fmt = "<iiqqqqi" if len(decoded) > 24 else "<iiqq"
|
||||
unpacked = struct.unpack(fmt, decoded)
|
||||
except (AssertionError, binascii.Error, struct.error):
|
||||
raise FileIdInvalid from None
|
||||
else:
|
||||
if unpacked[0] != 4:
|
||||
media_type = BaseClient.MEDIA_TYPE_ID.get(unpacked[0], None)
|
||||
|
||||
if media_type:
|
||||
raise FileIdInvalid("The file_id belongs to a {}".format(media_type))
|
||||
else:
|
||||
raise FileIdInvalid("Unknown media type: {}".format(unpacked[0]))
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=unpacked[2],
|
||||
access_hash=unpacked[3]
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(media, InputMediaAudio):
|
||||
if os.path.exists(media.media):
|
||||
media = self.send(
|
||||
functions.messages.UploadMedia(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
media=types.InputMediaUploadedDocument(
|
||||
mime_type=mimetypes.types_map.get("." + media.media.split(".")[-1], "audio/mpeg"),
|
||||
file=self.save_file(media.media),
|
||||
attributes=[
|
||||
types.DocumentAttributeAudio(
|
||||
duration=media.duration,
|
||||
performer=media.performer,
|
||||
title=media.title
|
||||
),
|
||||
types.DocumentAttributeFilename(os.path.basename(media.media))
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=media.document.id,
|
||||
access_hash=media.document.access_hash
|
||||
)
|
||||
)
|
||||
elif media.media.startswith("http"):
|
||||
media = types.InputMediaDocumentExternal(
|
||||
url=media.media
|
||||
)
|
||||
else:
|
||||
try:
|
||||
decoded = utils.decode(media.media)
|
||||
fmt = "<iiqqqqi" if len(decoded) > 24 else "<iiqq"
|
||||
unpacked = struct.unpack(fmt, decoded)
|
||||
except (AssertionError, binascii.Error, struct.error):
|
||||
raise FileIdInvalid from None
|
||||
else:
|
||||
if unpacked[0] != 9:
|
||||
media_type = BaseClient.MEDIA_TYPE_ID.get(unpacked[0], None)
|
||||
|
||||
if media_type:
|
||||
raise FileIdInvalid("The file_id belongs to a {}".format(media_type))
|
||||
else:
|
||||
raise FileIdInvalid("Unknown media type: {}".format(unpacked[0]))
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=unpacked[2],
|
||||
access_hash=unpacked[3]
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(media, InputMediaAnimation):
|
||||
if os.path.exists(media.media):
|
||||
media = self.send(
|
||||
functions.messages.UploadMedia(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
media=types.InputMediaUploadedDocument(
|
||||
mime_type=mimetypes.types_map[".mp4"],
|
||||
file=self.save_file(media.media),
|
||||
attributes=[
|
||||
types.DocumentAttributeVideo(
|
||||
supports_streaming=True,
|
||||
duration=media.duration,
|
||||
w=media.width,
|
||||
h=media.height
|
||||
),
|
||||
types.DocumentAttributeFilename(os.path.basename(media.media)),
|
||||
types.DocumentAttributeAnimated()
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=media.document.id,
|
||||
access_hash=media.document.access_hash
|
||||
)
|
||||
)
|
||||
elif media.media.startswith("http"):
|
||||
media = types.InputMediaDocumentExternal(
|
||||
url=media.media
|
||||
)
|
||||
else:
|
||||
try:
|
||||
decoded = utils.decode(media.media)
|
||||
fmt = "<iiqqqqi" if len(decoded) > 24 else "<iiqq"
|
||||
unpacked = struct.unpack(fmt, decoded)
|
||||
except (AssertionError, binascii.Error, struct.error):
|
||||
raise FileIdInvalid from None
|
||||
else:
|
||||
if unpacked[0] != 10:
|
||||
media_type = BaseClient.MEDIA_TYPE_ID.get(unpacked[0], None)
|
||||
|
||||
if media_type:
|
||||
raise FileIdInvalid("The file_id belongs to a {}".format(media_type))
|
||||
else:
|
||||
raise FileIdInvalid("Unknown media type: {}".format(unpacked[0]))
|
||||
|
||||
media = types.InputMediaDocument(
|
||||
id=types.InputDocument(
|
||||
id=unpacked[2],
|
||||
access_hash=unpacked[3]
|
||||
)
|
||||
)
|
||||
|
||||
r = self.send(
|
||||
functions.messages.EditMessage(
|
||||
peer=self.resolve_peer(chat_id),
|
||||
id=message_id,
|
||||
reply_markup=reply_markup.write() if reply_markup else None,
|
||||
media=media,
|
||||
**style.parse(caption)
|
||||
)
|
||||
)
|
||||
|
||||
for i in r.updates:
|
||||
if isinstance(i, (types.UpdateEditMessage, types.UpdateEditChannelMessage)):
|
||||
return utils.parse_messages(
|
||||
self, i.message,
|
||||
{i.id: i for i in r.users},
|
||||
{i.id: i for i in r.chats}
|
||||
)
|
@ -32,7 +32,6 @@ class EditMessageReplyMarkup(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_id (``int``):
|
||||
Message identifier in the chat specified in chat_id.
|
||||
|
@ -35,7 +35,6 @@ class EditMessageText(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_id (``int``):
|
||||
Message identifier in the chat specified in chat_id.
|
||||
|
@ -33,13 +33,11 @@ class ForwardMessages(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
from_chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the source chat where the original message was sent.
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_ids (``iterable``):
|
||||
A list of Message identifiers in the chat specified in *from_chat_id* or a single message id.
|
||||
|
@ -37,7 +37,6 @@ class GetHistory(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
offset (``int``, *optional*)
|
||||
Sequential number of the first message to be returned.
|
||||
|
@ -33,7 +33,6 @@ class GetMessages(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
message_ids (``iterable``):
|
||||
A list of Message identifiers in the chat specified in *chat_id* or a single message id, as integer.
|
||||
|
@ -26,10 +26,10 @@ from pyrogram.api.errors import FileIdInvalid, FilePartMissing
|
||||
from pyrogram.client.ext import BaseClient, utils
|
||||
|
||||
|
||||
class SendGIF(BaseClient):
|
||||
async def send_gif(self,
|
||||
class SendAnimation(BaseClient):
|
||||
asyncdef send_animation(self,
|
||||
chat_id: int or str,
|
||||
gif: str,
|
||||
animation: str,
|
||||
caption: str = "",
|
||||
parse_mode: str = "",
|
||||
duration: int = 0,
|
||||
@ -41,23 +41,22 @@ class SendGIF(BaseClient):
|
||||
reply_markup=None,
|
||||
progress: callable = None,
|
||||
progress_args: tuple = ()):
|
||||
"""Use this method to send GIF files.
|
||||
"""Use this method to send animation files(animation or H.264/MPEG-4 AVC video without sound).
|
||||
|
||||
Args:
|
||||
chat_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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
gif (``str``):
|
||||
GIF to send.
|
||||
Pass a file_id as string to send a GIF that exists on the Telegram servers,
|
||||
pass an HTTP URL as a string for Telegram to get a GIF from the Internet, or
|
||||
pass a file path as string to upload a new GIF that exists on your local machine.
|
||||
animation (``str``):
|
||||
Animation to send.
|
||||
Pass a file_id as string to send an animation that exists on the Telegram servers,
|
||||
pass an HTTP URL as a string for Telegram to get an animation from the Internet, or
|
||||
pass a file path as string to upload a new animation that exists on your local machine.
|
||||
|
||||
caption (``str``, *optional*):
|
||||
GIF caption, 0-200 characters.
|
||||
Animation caption, 0-200 characters.
|
||||
|
||||
parse_mode (``str``, *optional*):
|
||||
Use :obj:`MARKDOWN <pyrogram.ParseMode.MARKDOWN>` or :obj:`HTML <pyrogram.ParseMode.HTML>`
|
||||
@ -65,16 +64,16 @@ class SendGIF(BaseClient):
|
||||
Defaults to Markdown.
|
||||
|
||||
duration (``int``, *optional*):
|
||||
Duration of sent GIF in seconds.
|
||||
Duration of sent animation in seconds.
|
||||
|
||||
width (``int``, *optional*):
|
||||
GIF width.
|
||||
Animation width.
|
||||
|
||||
height (``int``, *optional*):
|
||||
GIF height.
|
||||
Animation height.
|
||||
|
||||
thumb (``str``, *optional*):
|
||||
GIF thumbnail.
|
||||
Animation thumbnail.
|
||||
Pass a file path as string to send an image that exists on your local machine.
|
||||
Thumbnail should have 90 or less pixels of width and 90 or less pixels of height.
|
||||
|
||||
@ -121,9 +120,9 @@ class SendGIF(BaseClient):
|
||||
file = None
|
||||
style = self.html if parse_mode.lower() == "html" else self.markdown
|
||||
|
||||
if os.path.exists(gif):
|
||||
if os.path.exists(animation):
|
||||
thumb = None if thumb is None else await self.save_file(thumb)
|
||||
file = await self.save_file(gif, progress=progress, progress_args=progress_args)
|
||||
file = await self.save_file(animation, progress=progress, progress_args=progress_args)
|
||||
media = types.InputMediaUploadedDocument(
|
||||
mime_type=mimetypes.types_map[".mp4"],
|
||||
file=file,
|
||||
@ -135,17 +134,17 @@ class SendGIF(BaseClient):
|
||||
w=width,
|
||||
h=height
|
||||
),
|
||||
types.DocumentAttributeFilename(os.path.basename(gif)),
|
||||
types.DocumentAttributeFilename(os.path.basename(animation)),
|
||||
types.DocumentAttributeAnimated()
|
||||
]
|
||||
)
|
||||
elif gif.startswith("http"):
|
||||
elif animation.startswith("http"):
|
||||
media = types.InputMediaDocumentExternal(
|
||||
url=gif
|
||||
url=animation
|
||||
)
|
||||
else:
|
||||
try:
|
||||
decoded = utils.decode(gif)
|
||||
decoded = utils.decode(animation)
|
||||
fmt = "<iiqqqqi" if len(decoded) > 24 else "<iiqq"
|
||||
unpacked = struct.unpack(fmt, decoded)
|
||||
except (AssertionError, binascii.Error, struct.error):
|
||||
@ -180,7 +179,7 @@ class SendGIF(BaseClient):
|
||||
)
|
||||
)
|
||||
except FilePartMissing as e:
|
||||
await self.save_file(gif, file_id=file.id, file_part=e.x)
|
||||
await self.save_file(animation, file_id=file.id, file_part=e.x)
|
||||
else:
|
||||
for i in r.updates:
|
||||
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
|
@ -49,7 +49,6 @@ class SendAudio(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
audio (``str``):
|
||||
Audio file to send.
|
||||
|
@ -32,7 +32,6 @@ class SendChatAction(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
action (:obj:`ChatAction <pyrogram.ChatAction>` | ``str``):
|
||||
Type of action to broadcast.
|
||||
|
@ -36,7 +36,6 @@ class SendContact(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
phone_number (``str``):
|
||||
Contact's phone number.
|
||||
@ -48,7 +47,7 @@ class SendContact(BaseClient):
|
||||
Contact's last name.
|
||||
|
||||
vcard (``str``, *optional*):
|
||||
Contact's vCard information.
|
||||
Additional data about the contact in the form of a vCard, 0-2048 bytes
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
|
@ -44,7 +44,6 @@ class SendDocument(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
document (``str``):
|
||||
File to send.
|
||||
|
@ -35,7 +35,6 @@ class SendLocation(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
latitude (``float``):
|
||||
Latitude of the location.
|
||||
|
@ -44,7 +44,6 @@ class SendMediaGroup(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
media (``list``):
|
||||
A list containing either :obj:`InputMediaPhoto <pyrogram.InputMediaPhoto>` or
|
||||
|
@ -37,7 +37,6 @@ class SendMessage(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
text (``str``):
|
||||
Text of the message to be sent.
|
||||
@ -62,7 +61,7 @@ class SendMessage(BaseClient):
|
||||
instructions to remove reply keyboard or to force a reply from the user.
|
||||
|
||||
Returns:
|
||||
On success, the sent Message is returned.
|
||||
On success, the sent :obj:`Message` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>`
|
||||
|
@ -44,7 +44,6 @@ class SendPhoto(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
photo (``str``):
|
||||
Photo to send.
|
||||
|
@ -41,7 +41,6 @@ class SendSticker(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
sticker (``str``):
|
||||
Sticker to send.
|
||||
|
@ -28,7 +28,7 @@ class SendVenue(BaseClient):
|
||||
title: str,
|
||||
address: str,
|
||||
foursquare_id: str = "",
|
||||
disable_notification: bool = None,
|
||||
foursquare_type: str = "",disable_notification: bool = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup=None):
|
||||
"""Use this method to send information about a venue.
|
||||
@ -38,7 +38,6 @@ class SendVenue(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
latitude (``float``):
|
||||
Latitude of the venue.
|
||||
@ -55,6 +54,10 @@ class SendVenue(BaseClient):
|
||||
foursquare_id (``str``, *optional*):
|
||||
Foursquare identifier of the venue.
|
||||
|
||||
foursquare_type (``str``, *optional*):
|
||||
Foursquare type of the venue, if known.
|
||||
(For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".)
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
Users will receive a notification with no sound.
|
||||
@ -84,7 +87,7 @@ class SendVenue(BaseClient):
|
||||
address=address,
|
||||
provider="",
|
||||
venue_id=foursquare_id,
|
||||
venue_type=""
|
||||
venue_type=foursquare_type
|
||||
),
|
||||
message="",
|
||||
silent=disable_notification or None,
|
||||
|
@ -49,7 +49,6 @@ class SendVideo(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
video (``str``):
|
||||
Video to send.
|
||||
|
@ -44,7 +44,6 @@ class SendVideoNote(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
video_note (``str``):
|
||||
Video note to send.
|
||||
|
@ -45,7 +45,6 @@ class SendVoice(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
voice (``str``):
|
||||
Audio file to send.
|
||||
|
@ -32,7 +32,6 @@ class GetUserProfilePhotos(BaseClient):
|
||||
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).
|
||||
For a private channel/supergroup you can use its *t.me/joinchat/* link.
|
||||
|
||||
offset (``int``, *optional*):
|
||||
Sequential number of the first photo to be returned.
|
||||
|
25
pyrogram/client/methods/utilities/__init__.py
Normal file
25
pyrogram/client/methods/utilities/__init__.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .download_media import DownloadMedia
|
||||
|
||||
|
||||
class Utilities(
|
||||
DownloadMedia
|
||||
):
|
||||
pass
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user