mirror of
https://github.com/pyrogram/pyrogram
synced 2025-09-01 23:05:15 +00:00
Deep rewrite: preparing for v1.0
- Pyrogram core is now fully asynchronous - Ditched Python 3.5, welcome 3.6 as minimum version. - Moved all types to pyrogram.types - Turned the Filters class into a module (filters) - Moved all filters to pyrogram.filters - Moved all handlers to pyrogram.handlers - Moved all emoji to pyrogram.emoji - Renamed pyrogram.api to pyrogram.raw - Clock is now synced with server's time - Telegram schema updated to Layer 117 - Greatly improved the TL compiler (proper type-constructor hierarchy) - Added "do not edit" warning in generated files - Crypto parts are executed in a thread pool to avoid blocking the event loop - idle() is now a separate function (it doesn't deal with Client instances) - Async storage, async filters and async progress callback (optional, can be sync too) - Added getpass back, for hidden password inputs
This commit is contained in:
@@ -6,6 +6,7 @@ API calls. This section provides all the information you need in order to author
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
@@ -41,7 +42,7 @@ keep the session alive, Pyrogram won't ask you again to enter your phone number.
|
||||
|
||||
.. important::
|
||||
|
||||
Your ``*.session`` files are personal and must be kept secret.
|
||||
Your ``*.session`` file is personal and must be kept secret.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@@ -10,6 +10,7 @@ to control the behaviour of your application. Pyrogram errors all live inside th
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
@@ -17,9 +18,8 @@ to control the behaviour of your application. Pyrogram errors all live inside th
|
||||
RPCError
|
||||
--------
|
||||
|
||||
The father of all errors is named ``RPCError``. This error exists in form of a Python exception which is directly
|
||||
subclass-ed from Python's main ``Exception`` and is able to catch all Telegram API related errors. This error is raised
|
||||
every time a method call against Telegram's API was unsuccessful.
|
||||
The father of all errors is named ``RPCError`` and is able to catch all Telegram API related errors.
|
||||
This error is raised every time a method call against Telegram's API was unsuccessful.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -34,19 +34,19 @@ Error Categories
|
||||
----------------
|
||||
|
||||
The ``RPCError`` packs together all the possible errors Telegram could raise, but to make things tidier, Pyrogram
|
||||
provides categories of errors, which are named after the common HTTP errors and are subclass-ed from the RPCError:
|
||||
provides categories of errors, which are named after the common HTTP errors and are subclass-ed from the ``RPCError``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram.errors import BadRequest, Forbidden, ...
|
||||
|
||||
- `303 - SeeOther <../api/errors#seeother>`_
|
||||
- `400 - BadRequest <../api/errors#badrequest>`_
|
||||
- `401 - Unauthorized <../api/errors#unauthorized>`_
|
||||
- `403 - Forbidden <../api/errors#forbidden>`_
|
||||
- `406 - NotAcceptable <../api/errors#notacceptable>`_
|
||||
- `420 - Flood <../api/errors#flood>`_
|
||||
- `500 - InternalServerError <../api/errors#internalservererror>`_
|
||||
- :doc:`303 - SeeOther <../api/errors/see-other>`
|
||||
- :doc:`400 - BadRequest <../api/errors/bad-request>`
|
||||
- :doc:`401 - Unauthorized <../api/errors/unauthorized>`
|
||||
- :doc:`403 - Forbidden <../api/errors/forbidden>`
|
||||
- :doc:`406 - NotAcceptable <../api/errors/not-acceptable>`
|
||||
- :doc:`420 - Flood <../api/errors/flood>`
|
||||
- :doc:`500 - InternalServerError <../api/errors/internal-server-error>`
|
||||
|
||||
Single Errors
|
||||
-------------
|
||||
@@ -59,7 +59,7 @@ issue. For example:
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
These errors subclass directly from the category of errors they belong to, which in turn subclass from the father
|
||||
RPCError, thus building a class of error hierarchy such as this:
|
||||
``RPCError``, thus building a class of error hierarchy such as this:
|
||||
|
||||
- RPCError
|
||||
- BadRequest
|
||||
|
61
docs/source/start/examples/bot_keyboards.rst
Normal file
61
docs/source/start/examples/bot_keyboards.rst
Normal file
@@ -0,0 +1,61 @@
|
||||
bot_keyboards
|
||||
=============
|
||||
|
||||
This example will show you how to send normal and inline keyboards (as bot).
|
||||
|
||||
You must log-in as a regular bot in order to send keyboards (use the token from @BotFather).
|
||||
Any attempt in sending keyboards with a user account will be simply ignored by the server.
|
||||
|
||||
send_message() is used as example, but a keyboard can be sent with any other send_* methods,
|
||||
like send_audio(), send_document(), send_location(), etc...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
# Create a client using your bot token
|
||||
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
|
||||
with app:
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a ReplyKeyboardMarkup example",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
[
|
||||
["A", "B", "C", "D"], # First row
|
||||
["E", "F", "G"], # Second row
|
||||
["H", "I"], # Third row
|
||||
["J"] # Fourth row
|
||||
],
|
||||
resize_keyboard=True # Make the keyboard smaller
|
||||
)
|
||||
)
|
||||
|
||||
app.send_message(
|
||||
"haskell", # Edit this
|
||||
"This is a InlineKeyboardMarkup example",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[ # First row
|
||||
InlineKeyboardButton( # Generates a callback query when pressed
|
||||
"Button",
|
||||
callback_data="data"
|
||||
),
|
||||
InlineKeyboardButton( # Opens a web URL
|
||||
"URL",
|
||||
url="https://docs.pyrogram.org"
|
||||
),
|
||||
],
|
||||
[ # Second row
|
||||
InlineKeyboardButton( # Opens the inline interface
|
||||
"Choose chat",
|
||||
switch_inline_query="pyrogram"
|
||||
),
|
||||
InlineKeyboardButton( # Opens the inline interface in the current chat
|
||||
"Inline here",
|
||||
switch_inline_query_current_chat="pyrogram"
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
)
|
19
docs/source/start/examples/callback_queries.rst
Normal file
19
docs/source/start/examples/callback_queries.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
callback_queries
|
||||
================
|
||||
|
||||
This example shows how to handle callback queries, i.e.: queries coming from inline button presses.
|
||||
It uses the @on_callback_query decorator to register a CallbackQueryHandler.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
|
||||
|
||||
@app.on_callback_query()
|
||||
def answer(client, callback_query):
|
||||
callback_query.answer(f"Button contains: '{callback_query.data}'", show_alert=True)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
21
docs/source/start/examples/echobot.rst
Normal file
21
docs/source/start/examples/echobot.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
echobot
|
||||
=======
|
||||
|
||||
This simple echo bot replies to every private text message.
|
||||
|
||||
It uses the @on_message decorator to register a MessageHandler and applies two filters on it:
|
||||
Filters.text and Filters.private to make sure it will reply to private text messages only.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, Filters
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message(Filters.text & Filters.private)
|
||||
def echo(client, message):
|
||||
message.reply(message.text)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
15
docs/source/start/examples/get_chat_members.rst
Normal file
15
docs/source/start/examples/get_chat_members.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
get_chat_members
|
||||
================
|
||||
|
||||
This example shows how to get all the members of a chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
target = "pyrogramchat" # Target channel/supergroup
|
||||
|
||||
with app:
|
||||
for member in app.iter_chat_members(target):
|
||||
print(member.user.first_name)
|
14
docs/source/start/examples/get_dialogs.rst
Normal file
14
docs/source/start/examples/get_dialogs.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
get_dialogs
|
||||
===========
|
||||
|
||||
This example shows how to get the full dialogs list (as user).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
for dialog in app.iter_dialogs():
|
||||
print(dialog.chat.title or dialog.chat.first_name)
|
15
docs/source/start/examples/get_history.rst
Normal file
15
docs/source/start/examples/get_history.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
get_history
|
||||
===========
|
||||
|
||||
This example shows how to get the full message history of a chat, starting from the latest message.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
target = "me" # "me" refers to your own chat (Saved Messages)
|
||||
|
||||
with app:
|
||||
for message in app.iter_history(target):
|
||||
print(message.text)
|
21
docs/source/start/examples/hello_world.rst
Normal file
21
docs/source/start/examples/hello_world.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
hello_world
|
||||
===========
|
||||
|
||||
This example demonstrates a basic API usage
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client instance
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
# Send a message, Markdown is enabled by default
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
|
||||
# Send a location
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
|
||||
# Send a sticker
|
||||
app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
|
46
docs/source/start/examples/index.rst
Normal file
46
docs/source/start/examples/index.rst
Normal file
@@ -0,0 +1,46 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
This page contains example scripts to show you how Pyrogram looks like.
|
||||
|
||||
Every script is working right away (provided you correctly set up your credentials), meaning you can simply copy-paste
|
||||
and run. The only things you have to change are session names and target chats, where applicable.
|
||||
|
||||
The examples listed below can be treated as building blocks for your own applications and are meant to be simple enough
|
||||
to give you a basic idea.
|
||||
|
||||
-----
|
||||
|
||||
.. csv-table::
|
||||
:header: Example, Description
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
:doc:`hello_world`, "Demonstration of basic API usage"
|
||||
:doc:`echobot`, "Echo every private text message"
|
||||
:doc:`welcomebot`, "The Welcome Bot in @PyrogramChat"
|
||||
:doc:`get_history`, "Get the full message history of a chat"
|
||||
:doc:`get_chat_members`, "Get all the members of a chat"
|
||||
:doc:`get_dialogs`, "Get all of your dialog chats"
|
||||
:doc:`callback_queries`, "Handle callback queries (as bot) coming from inline button presses"
|
||||
:doc:`inline_queries`, "Handle inline queries (as bot) and answer with results"
|
||||
:doc:`use_inline_bots`, "Query an inline bot (as user) and send a result to a chat"
|
||||
:doc:`bot_keyboards`, "Send normal and inline keyboards using regular bots"
|
||||
:doc:`raw_updates`, "Handle raw updates (old, should be avoided)"
|
||||
|
||||
For more advanced examples, see https://snippets.pyrogram.org.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
hello_world
|
||||
echobot
|
||||
welcomebot
|
||||
get_history
|
||||
get_chat_members
|
||||
get_dialogs
|
||||
callback_queries
|
||||
inline_queries
|
||||
use_inline_bots
|
||||
bot_keyboards
|
||||
raw_updates
|
61
docs/source/start/examples/inline_queries.rst
Normal file
61
docs/source/start/examples/inline_queries.rst
Normal file
@@ -0,0 +1,61 @@
|
||||
inline_queries
|
||||
==============
|
||||
|
||||
This example shows how to handle inline queries.
|
||||
|
||||
Two results are generated when users invoke the bot inline mode, e.g.: @pyrogrambot hi.
|
||||
It uses the @on_inline_query decorator to register an InlineQueryHandler.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import (
|
||||
Client, InlineQueryResultArticle, InputTextMessageContent, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
)
|
||||
|
||||
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||
|
||||
|
||||
@app.on_inline_query()
|
||||
def answer(client, inline_query):
|
||||
inline_query.answer(
|
||||
results=[
|
||||
InlineQueryResultArticle(
|
||||
title="Installation",
|
||||
input_message_content=InputTextMessageContent(
|
||||
"Here's how to install **Pyrogram**"
|
||||
),
|
||||
url="https://docs.pyrogram.org/intro/install",
|
||||
description="How to install Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton(
|
||||
"Open website",
|
||||
url="https://docs.pyrogram.org/intro/install"
|
||||
)]
|
||||
]
|
||||
)
|
||||
),
|
||||
InlineQueryResultArticle(
|
||||
title="Usage",
|
||||
input_message_content=InputTextMessageContent(
|
||||
"Here's how to use **Pyrogram**"
|
||||
),
|
||||
url="https://docs.pyrogram.org/start/invoking",
|
||||
description="How to use Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton(
|
||||
"Open website",
|
||||
url="https://docs.pyrogram.org/start/invoking"
|
||||
)]
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
cache_time=1
|
||||
)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
18
docs/source/start/examples/raw_updates.rst
Normal file
18
docs/source/start/examples/raw_updates.rst
Normal file
@@ -0,0 +1,18 @@
|
||||
raw_updates
|
||||
===========
|
||||
|
||||
This example shows how to handle raw updates.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_raw_update()
|
||||
def raw(client, update, users, chats):
|
||||
print(update)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
18
docs/source/start/examples/use_inline_bots.rst
Normal file
18
docs/source/start/examples/use_inline_bots.rst
Normal file
@@ -0,0 +1,18 @@
|
||||
use_inline_bots
|
||||
===============
|
||||
|
||||
This example shows how to query an inline bot (as user).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
# Get bot results for "Fuzz Universe" from the inline bot @vid
|
||||
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
|
||||
|
||||
# Send the first result (bot_results.results[0]) to your own chat (Saved Messages)
|
||||
app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id)
|
33
docs/source/start/examples/welcomebot.rst
Normal file
33
docs/source/start/examples/welcomebot.rst
Normal file
@@ -0,0 +1,33 @@
|
||||
welcomebot
|
||||
==========
|
||||
|
||||
This is the Welcome Bot in @PyrogramChat.
|
||||
|
||||
It uses the Emoji module to easily add emojis in your text messages and Filters
|
||||
to make it only work for specific messages in a specific chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, Emoji, Filters
|
||||
|
||||
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames
|
||||
MENTION = "[{}](tg://user?id={})" # User mention markup
|
||||
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!" # Welcome message
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
# Filter in only new_chat_members updates generated in TARGET chat
|
||||
@app.on_message(Filters.chat(TARGET) & Filters.new_chat_members)
|
||||
def welcome(client, message):
|
||||
# Build the new members list (with mentions) by using their first_name
|
||||
new_members = [MENTION.format(i.first_name, i.id) for i in message.new_chat_members]
|
||||
|
||||
# Build the welcome message by using an emoji and the list we built above
|
||||
text = MESSAGE.format(Emoji.SPARKLES, ", ".join(new_members))
|
||||
|
||||
# Send the welcome message, without the web page preview
|
||||
message.reply(text, disable_web_page_preview=True)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
@@ -6,6 +6,7 @@ account; we are now aiming towards the core of the library. It's time to start p
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
@@ -13,7 +14,8 @@ account; we are now aiming towards the core of the library. It's time to start p
|
||||
Basic Usage
|
||||
-----------
|
||||
|
||||
Making API method calls with Pyrogram is very simple. Here's an example we are going to examine:
|
||||
Making API method calls with Pyrogram is very simple. Here's a basic example we are going to examine step by step and
|
||||
then expand to explain what happens underneath:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -21,16 +23,13 @@ Making API method calls with Pyrogram is very simple. Here's an example we are g
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
app.start()
|
||||
with app:
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi, it's me!")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
Basic step-by-step
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
app.stop()
|
||||
|
||||
#. Let's begin by importing the Client class from the Pyrogram package:
|
||||
#. Let's begin by importing the Client class:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -42,35 +41,26 @@ Making API method calls with Pyrogram is very simple. Here's an example we are g
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
#. To actually make use of any method, the client has to be started first:
|
||||
#. The ``with`` context manager is a shortcut for starting, executing and stopping the Client:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.start()
|
||||
with app:
|
||||
|
||||
#. Now, you can call any method you like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(app.get_me()) # Print information about yourself
|
||||
|
||||
# Send messages to yourself:
|
||||
app.send_message("me", "Hi!") # Text message
|
||||
app.send_location("me", 51.500729, -0.124583) # Location
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") # Sticker
|
||||
|
||||
#. Finally, when done, simply stop the client:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.stop()
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
Context Manager
|
||||
---------------
|
||||
|
||||
You can also use Pyrogram's Client in a context manager with the ``with`` statement. The client will automatically
|
||||
:meth:`~pyrogram.Client.start` and :meth:`~pyrogram.Client.stop` gracefully, even in case of unhandled exceptions in
|
||||
your code. The example above can be therefore rewritten in a much nicer way:
|
||||
The ``with`` statement starts a context manager, which is used as a shortcut to automatically call
|
||||
:meth:`~pyrogram.Client.start` and :meth:`~pyrogram.Client.stop`, which are methods required for Pyrogram to work
|
||||
properly. The context manager does also gracefully stop the client, even in case of unhandled exceptions in your code.
|
||||
|
||||
This is how Pyrogram looks without the context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -78,10 +68,53 @@ your code. The example above can be therefore rewritten in a much nicer way:
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
app.start()
|
||||
app.send_message("me", "Hi!")
|
||||
app.stop()
|
||||
|
||||
More examples can be found on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_.
|
||||
Asynchronous Calls
|
||||
------------------
|
||||
|
||||
In case you want Pyrogram to run asynchronously (e.g.: if you are using third party libraries that require you to call
|
||||
them with ``await``), use the asynchronous context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
async def main():
|
||||
async with app:
|
||||
await app.send_message("me", "Hi!")
|
||||
|
||||
app.run(main())
|
||||
|
||||
Asynchronous step-by-step
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. Import the Client class and create an instance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
#. Async methods can't normally be executed at the top level, because they must be inside an async-defined function;
|
||||
here we define one and put our code inside; the context manager is also being used differently in asyncio and
|
||||
method calls require the await keyword:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def main():
|
||||
async with app:
|
||||
await app.send_message("me", "Hi!")
|
||||
|
||||
#. Finally, we tell Python to schedule our ``main()`` async function, which in turn will execute Pyrogram's code. Using
|
||||
:meth:`~pyrogram.Client.run` this way is a friendly alternative for the much more verbose
|
||||
``asyncio.get_event_loop().run_until_complete(main())``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.run(main())
|
||||
|
@@ -6,6 +6,7 @@ This page deals with updates and how to handle such events in Pyrogram. Let's ha
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
@@ -24,72 +25,14 @@ function will be called back by the framework and its body executed.
|
||||
Registering a Handler
|
||||
---------------------
|
||||
|
||||
To explain how handlers work let's have a look at the most used one, the :class:`~pyrogram.MessageHandler`, which will
|
||||
be in charge for handling :class:`~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.
|
||||
|
||||
Using add_handler()
|
||||
-------------------
|
||||
|
||||
The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback
|
||||
function and registers it in your Client. Here's a full example that prints out the content of a message as soon as it
|
||||
arrives:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, MessageHandler
|
||||
|
||||
|
||||
def my_function(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
app.add_handler(my_handler)
|
||||
|
||||
app.run()
|
||||
|
||||
Let's examine these four new pieces.
|
||||
|
||||
#. A callback function we defined which accepts two arguments -
|
||||
*(client, message)*. This will be the function that gets executed every time a new message arrives and Pyrogram will
|
||||
call that function by passing the client instance and the new message instance as argument.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def my_function(client, message):
|
||||
print(message)
|
||||
|
||||
#. The :class:`~pyrogram.MessageHandler`. This object tells Pyrogram the function we defined above must only handle
|
||||
updates that are in form of a :class:`~pyrogram.Message`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
|
||||
#. The method :meth:`~pyrogram.Client.add_handler`. This method is used to actually register the handler and let
|
||||
Pyrogram know it needs to be taken into consideration when new updates arrive and the internal dispatching phase
|
||||
begins.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.add_handler(my_handler)
|
||||
|
||||
#. The :meth:`~pyrogram.Client.run` method. What this does is simply call :meth:`~pyrogram.Client.start` and
|
||||
a special method :meth:`~pyrogram.Client.idle` that keeps your main scripts alive until you press ``CTRL+C``; the
|
||||
client will be automatically stopped after that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.run()
|
||||
To explain how handlers work let's examine the one which will be in charge for handling :class:`~pyrogram.types.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.
|
||||
|
||||
Using Decorators
|
||||
----------------
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
All of the above will become quite verbose, especially in case you have lots of handlers to register. A much nicer way
|
||||
to do so is by decorating your callback function with the :meth:`~pyrogram.Client.on_message` decorator.
|
||||
The most elegant way to register a message handler is by using the :meth:`~pyrogram.Client.on_message` decorator:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -100,7 +43,58 @@ to do so is by decorating your callback function with the :meth:`~pyrogram.Clien
|
||||
|
||||
@app.on_message()
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
message.forward("me")
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
The defined function ``my_handler``, which accepts the two arguments *(client, message)*, will be the function that gets
|
||||
executed every time a new message arrives.
|
||||
|
||||
Asynchronous handlers
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can also have asynchronous handlers; you only need to define the callback function using ``async def`` and call API
|
||||
methods by placing ``await`` in front of them:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message()
|
||||
async def my_handler(client, message):
|
||||
await message.forward("me")
|
||||
|
||||
.. note::
|
||||
|
||||
You can mix ``def`` and ``async def`` handlers as much as you need, Pyrogram will still work concurrently and
|
||||
efficiently regardless of what you choose.
|
||||
|
||||
Using add_handler()
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback
|
||||
function and registers it in your Client. It us useful in case you want to programmatically add handlers (or in case,
|
||||
for some reason, you don't like to use decorators).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.handlers import MessageHandler
|
||||
|
||||
|
||||
def my_function(client, message):
|
||||
message.forward("me")
|
||||
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
app.add_handler(my_handler)
|
||||
|
||||
app.run()
|
||||
|
||||
The same about asynchronous handlers applies for :meth:`~pyrogram.Client.add_handler`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def my_function(client, message):
|
||||
await message.forward("me")
|
||||
|
Reference in New Issue
Block a user