2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-31 22:35:36 +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:
Dan
2020-08-22 08:05:05 +02:00
parent 2f0a1f4119
commit 538f1e3972
367 changed files with 12085 additions and 15090 deletions

View File

@@ -26,6 +26,7 @@ functions.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -1,78 +0,0 @@
RPC Errors
==========
All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.errors``.
The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram
follow the usual *PascalCase* convention.
.. code-block:: python
:emphasize-lines: 1, 5
from pyrogram.errors import FloodWait
try:
...
except FloodWait as e:
...
.. contents:: Contents
:backlinks: none
:local:
-----
303 - SeeOther
--------------
.. csv-table::
:file: ../../../compiler/error/source/303_SEE_OTHER.tsv
:delim: tab
:header-rows: 1
400 - BadRequest
----------------
.. csv-table::
:file: ../../../compiler/error/source/400_BAD_REQUEST.tsv
:delim: tab
:header-rows: 1
401 - Unauthorized
------------------
.. csv-table::
:file: ../../../compiler/error/source/401_UNAUTHORIZED.tsv
:delim: tab
:header-rows: 1
403 - Forbidden
---------------
.. csv-table::
:file: ../../../compiler/error/source/403_FORBIDDEN.tsv
:delim: tab
:header-rows: 1
406 - NotAcceptable
-------------------
.. csv-table::
:file: ../../../compiler/error/source/406_NOT_ACCEPTABLE.tsv
:delim: tab
:header-rows: 1
420 - Flood
-----------
.. csv-table::
:file: ../../../compiler/error/source/420_FLOOD.tsv
:delim: tab
:header-rows: 1
500 - InternalServerError
-------------------------
.. csv-table::
:file: ../../../compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
400 - BadRequest
----------------
.. csv-table::
:file: ../../../../compiler/error/source/400_BAD_REQUEST.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
420 - Flood
-----------
.. csv-table::
:file: ../../../../compiler/error/source/420_FLOOD.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
403 - Forbidden
---------------
.. csv-table::
:file: ../../../../compiler/error/source/403_FORBIDDEN.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,37 @@
RPC Errors
==========
All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.errors``.
The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram
follow the usual *PascalCase* convention.
.. code-block:: python
from pyrogram.errors import FloodWait
try:
...
except FloodWait as e:
...
.. hlist::
:columns: 1
- :doc:`see-other`
- :doc:`bad-request`
- :doc:`unauthorized`
- :doc:`forbidden`
- :doc:`not-acceptable`
- :doc:`flood`
- :doc:`internal-server-error`
.. toctree::
:hidden:
see-other
bad-request
unauthorized
forbidden
not-acceptable
flood
internal-server-error

View File

@@ -0,0 +1,7 @@
500 - InternalServerError
-------------------------
.. csv-table::
:file: ../../../../compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
406 - NotAcceptable
-------------------
.. csv-table::
:file: ../../../../compiler/error/source/406_NOT_ACCEPTABLE.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
303 - SeeOther
--------------
.. csv-table::
:file: ../../../../compiler/error/source/303_SEE_OTHER.tsv
:delim: tab
:header-rows: 1

View File

@@ -0,0 +1,7 @@
401 - Unauthorized
------------------
.. csv-table::
:file: ../../../../compiler/error/source/401_UNAUTHORIZED.tsv
:delim: tab
:header-rows: 1

View File

@@ -1,8 +1,11 @@
Update Filters
==============
Filters are objects that can be used to filter the content of incoming updates.
:doc:`Read more about how filters work <../topics/use-filters>`.
Details
-------
.. autoclass:: pyrogram.Filters
.. automodule:: pyrogram.filters
:members:

View File

@@ -7,7 +7,8 @@ For a much more convenient way of registering callback functions have a look at
.. code-block:: python
:emphasize-lines: 1, 10
from pyrogram import Client, MessageHandler
from pyrogram import Client
from pyrogram.handlers import MessageHandler
app = Client("my_account")
@@ -22,11 +23,12 @@ For a much more convenient way of registering callback functions have a look at
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
.. currentmodule:: pyrogram
.. currentmodule:: pyrogram.handlers
Index
-----

View File

@@ -12,6 +12,7 @@ This FAQ page provides answers to common questions about Pyrogram and, to some e
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -10,6 +10,7 @@ general. Some words may as well link to dedicated articles in case the topic is
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -1,6 +1,95 @@
Welcome to Pyrogram
===================
.. raw:: html
<div align="center">
<a href="/">
<div><img src="_static/pyrogram.png" alt="Pyrogram Logo" width="420"></div>
</a>
</div>
<p align="center">
<b>Telegram MTProto API Framework for Python</b>
<br>
<a href="https://github.com/pyrogram/pyrogram">
Source Code
</a>
<a href="https://github.com/pyrogram/pyrogram/releases">
Releases
</a>
<a href="https://t.me/Pyrogram">
Community
</a>
</p>
.. code-block:: python
from pyrogram import Client, filters
app = Client("my_account")
@app.on_message(filters.private)
async def hello(client, message):
await message.reply_text(f"Hello {message.from_user.mention}")
app.run()
**Pyrogram** is a modern, elegant and easy-to-use Telegram_ framework written from the ground up in Python and C.
It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the
:doc:`MTProto API <topics/mtproto-vs-botapi>`.
.. _Telegram: https://telegram.org
How the Documentation is Organized
----------------------------------
Contents are organized into sections composed of self-contained topics which can be all accessed from the sidebar, or by
following them in order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a
list of the most relevant pages for a quick access.
First Steps
^^^^^^^^^^^
.. hlist::
:columns: 2
- :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly.
- :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods.
- :doc:`Handling Updates <start/updates>`: How to handle Telegram updates.
- :doc:`Error Handling <start/errors>`: How to handle API errors correctly.
API Reference
^^^^^^^^^^^^^
.. hlist::
:columns: 2
- :doc:`Pyrogram Client <api/client>`: Reference details about the Client class.
- :doc:`Available Methods <api/methods/index>`: List of available high-level methods.
- :doc:`Available Types <api/types/index>`: List of available high-level types.
- :doc:`Bound Methods <api/bound-methods/index>`: List of convenient bound methods.
Meta
^^^^
.. hlist::
:columns: 2
- :doc:`Pyrogram FAQ <faq>`: Answers to common Pyrogram questions.
- :doc:`Pyrogram Glossary <glossary>`: List of words with brief explanations.
- :doc:`Powered by Pyrogram <powered-by>`: Collection of Pyrogram Projects.
- :doc:`Support Pyrogram <support-pyrogram>`: Ways to show your appreciation.
- :doc:`About the License <license>`: Information about the Project license.
- :doc:`Release Notes <releases/index>`: Release notes for Pyrogram releases.
Last updated on |today|
.. toctree::
:hidden:
:caption: Introduction
@@ -17,6 +106,7 @@ Welcome to Pyrogram
start/invoking
start/updates
start/errors
start/examples/index
.. toctree::
:hidden:
@@ -28,7 +118,7 @@ Welcome to Pyrogram
api/bound-methods/index
api/handlers
api/decorators
api/errors
api/errors/index
api/filters
.. toctree::
@@ -71,92 +161,4 @@ Welcome to Pyrogram
telegram/functions/index
telegram/types/index
.. raw:: html
<div align="center">
<a href="/">
<div><img src="_static/pyrogram.png" alt="Pyrogram Logo" width="420"></div>
</a>
</div>
<p align="center">
<b>Telegram MTProto API Framework for Python</b>
<br>
<a href="https://github.com/pyrogram/pyrogram">
Source Code
</a>
<a href="https://github.com/pyrogram/pyrogram/releases">
Releases
</a>
<a href="https://t.me/Pyrogram">
Community
</a>
</p>
.. code-block:: python
from pyrogram import Client, Filters
app = Client("my_account")
@app.on_message(Filters.private)
def hello(client, message):
message.reply_text(f"Hello {message.from_user.first_name}")
app.run()
**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and
C. It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the
:doc:`MTProto API <topics/mtproto-vs-botapi>`.
.. _Telegram: https://telegram.org
How the Documentation is Organized
----------------------------------
Contents are organized into self-contained topics and can be all accessed from the sidebar, or by following them in
order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a list of the most
relevant pages for a quick access.
First Steps
^^^^^^^^^^^
.. hlist::
:columns: 2
- :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly.
- :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods.
- :doc:`Handling Updates <start/updates>`: How to handle Telegram updates.
- :doc:`Error Handling <start/errors>`: How to handle API errors correctly.
API Reference
^^^^^^^^^^^^^
.. hlist::
:columns: 2
- :doc:`Pyrogram Client <api/client>`: Reference details about the Client class.
- :doc:`Available Methods <api/methods/index>`: List of available high-level methods.
- :doc:`Available Types <api/types/index>`: List of available high-level types.
- :doc:`Bound Methods <api/bound-methods/index>`: List of convenient bound methods.
Meta
^^^^
.. hlist::
:columns: 2
- :doc:`Pyrogram FAQ <faq>`: Answers to common Pyrogram questions.
- :doc:`Pyrogram Glossary <glossary>`: List of words with brief explanations.
- :doc:`Powered by Pyrogram <powered-by>`: Collection of Pyrogram Projects.
- :doc:`Support Pyrogram <support-pyrogram>`: Ways to show your appreciation.
- :doc:`About the License <license>`: Information about the Project license.
- :doc:`Release Notes <releases/index>`: Release notes for Pyrogram releases.
Last updated on |today|
telegram/base/index

View File

@@ -1,18 +1,19 @@
Install Guide
=============
Being a Python library, **Pyrogram** requires Python to be installed in your system.
Being a modern Python library, **Pyrogram** requires Python 3.6+ to be installed in your system.
We recommend using the latest versions of both Python 3 and pip.
- Get **Python 3** from https://www.python.org/downloads/ (or with your package manager)
- Get **Python 3** from https://www.python.org/downloads/ (or with your package manager).
- Get **pip** by following the instructions at https://pip.pypa.io/en/latest/installing/.
.. important::
Pyrogram supports **Python 3** only, starting from version 3.5.3. **PyPy** is supported too.
Pyrogram supports **Python 3** only, starting from version 3.6. **PyPy** is supported too.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -46,43 +47,6 @@ the link):
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/develop.zip
Asynchronous
------------
Pyrogram heavily depends on IO-bound network code (it's a cloud-based messaging framework after all), and here's
where asyncio shines the most by providing extra performance and efficiency while running on a single OS-level thread
only.
**A fully asynchronous variant of Pyrogram is therefore available** (Python 3.5.3 or higher is required).
Use this command to install (note "asyncio.zip" in the link):
.. code-block:: text
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/asyncio.zip
Pyrogram's API remains the same and features are kept up to date from the non-async, default develop branch, but you
are obviously required Python asyncio knowledge in order to take full advantage of it.
.. tip::
The idea to turn Pyrogram fully asynchronous is still under consideration, but is wise to expect that in future this
would be the one and only way to work with Pyrogram.
You can start using Pyrogram Async variant right now as an excuse to learn more about asynchronous programming and
do experiments with it!
.. raw:: html
<script async
src="https://telegram.org/js/telegram-widget.js?4"
data-telegram-post="Pyrogram/4"
data-width="100%">
</script>
.. centered:: Subscribe to `@Pyrogram <https://t.me/Pyrogram>`_ for news and announcements
Verifying
---------

View File

@@ -1,8 +1,8 @@
Quick Start
===========
The next few steps serve as a quick start for all new Pyrogrammers that want to get something done as fast as possible.
Let's go!
The next few steps serve as a quick start for all new Pyrogrammers that want to see Pyrogram in action as fast as
possible. Let's go!
Get Pyrogram Real Fast
----------------------

View File

@@ -6,6 +6,7 @@ project with the library. Let's see how it's done.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -11,6 +11,7 @@ This is a collection of remarkable projects made with Pyrogram.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -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::

View File

@@ -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

View 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"
)
]
]
)
)

View 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()

View 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()

View 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)

View 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)

View 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)

View 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")

View 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

View 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()

View 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()

View 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)

View 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()

View File

@@ -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())

View File

@@ -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")

View File

@@ -10,6 +10,7 @@ Telegram API with its functions and types.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -18,7 +19,7 @@ Telegram Raw API
----------------
If you can't find a high-level method for your needs or if you want complete, low-level access to the whole
Telegram API, you have to use the raw :mod:`~pyrogram.api.functions` and :mod:`~pyrogram.api.types`.
Telegram API, you have to use the raw :mod:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`.
As already hinted, raw functions and types can be really confusing, mainly because people don't realize soon enough they
accept *only* the right types and that all required parameters must be filled in. This section will therefore explain
@@ -41,7 +42,7 @@ Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which
functions to be invoked from the raw Telegram API have a different way of usage and are more complex.
First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>`
live in their respective packages (and sub-packages): ``pyrogram.api.functions``, ``pyrogram.api.types``. They all exist
live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist
as Python classes, meaning you need to create an instance of each every time you need them and fill them in with the
correct values using named arguments.
@@ -55,7 +56,7 @@ Here's some examples:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions
from pyrogram.raw import functions
with Client("my_account") as app:
app.send(
@@ -70,7 +71,7 @@ Here's some examples:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
from pyrogram.raw import functions, types
with Client("my_account") as app:
app.send(
@@ -85,7 +86,7 @@ Here's some examples:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
from pyrogram.raw import functions, types
with Client("my_account") as app:
app.send(
@@ -109,9 +110,9 @@ sending messages with IDs only thanks to cached access hashes.
There are three different InputPeer types, one for each kind of Telegram entity.
Whenever an InputPeer is needed you must pass one of these:
- :class:`~pyrogram.api.types.InputPeerUser` - Users
- :class:`~pyrogram.api.types.InputPeerChat` - Basic Chats
- :class:`~pyrogram.api.types.InputPeerChannel` - Either Channels or Supergroups
- :class:`~pyrogram.raw.types.InputPeerUser` - Users
- :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats
- :class:`~pyrogram.raw.types.InputPeerChannel` - Either Channels or Supergroups
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
:meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer

View File

@@ -5,6 +5,7 @@ Users can interact with other bots via plain text messages as well as inline que
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -6,6 +6,7 @@ This page explains how this file is structured, how to use it and why.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -1,16 +1,12 @@
Creating Filters
================
Pyrogram already provides lots of built-in :class:`~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 kind of handler,
for example) you can use :meth:`~pyrogram.Filters.create`.
.. note::
At the moment, the built-in filters are intended to be used with the :class:`~pyrogram.MessageHandler` only.
Pyrogram already provides lots of built-in :class:`~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 you can use :meth:`~pyrogram.filters.create`.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -19,14 +15,14 @@ Custom Filters
--------------
An example to demonstrate how custom filters work is to show how to create and use one for the
:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots as result of a
user pressing an inline button attached to the bot's message; create and :doc:`authorize your bot <../start/auth>`,
:class:`~pyrogram.handlers.CallbackQueryHandler`. Note that callback queries updates are only received by bots as result
of a user pressing an inline button attached to the bot's message; create and :doc:`authorize your bot <../start/auth>`,
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
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
app.send_message(
"username", # Change this to your username or id
@@ -39,7 +35,7 @@ button:
Basic Filters
-------------
For this basic filter we will be using only the first parameter of :meth:`~pyrogram.Filters.create`.
For this basic filter we will be using only the first parameter of :meth:`~pyrogram.filters.create`.
The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries
containing "pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data
@@ -47,17 +43,21 @@ equals to ``"pyrogram"``.
.. code-block:: python
static_data_filter = Filters.create(lambda _, query: query.data == "pyrogram")
from pyrogram import filters
static_data_filter = filters.create(lambda _, query: 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 scope:
could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope:
.. code-block:: python
from pyrogram import filters
def func(_, query):
return query.data == "pyrogram"
static_data_filter = Filters.create(func)
static_data_filter = filters.create(func)
The filter usage remains the same:
@@ -71,14 +71,16 @@ 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 named arguments for the :meth:`~pyrogram.Filters.create` method.
A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method.
This is how a dynamic custom filter looks like:
.. code-block:: python
from pyrogram import filters
def dynamic_data_filter(data):
return Filters.create(
return filters.create(
lambda flt, query: flt.data == query.data,
data=data # "data" kwarg is accessed with "flt.data" above
)

View File

@@ -6,6 +6,7 @@ to actually worry about -- that's normal -- and luckily for you, Pyrogram provid
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -6,6 +6,7 @@ Here we'll show some advanced usages when working with :doc:`update handlers <..
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -25,21 +26,21 @@ For example, take these two handlers:
.. code-block:: python
:emphasize-lines: 1, 6
@app.on_message(Filters.text | Filters.sticker)
@app.on_message(filters.text | filters.sticker)
def text_or_sticker(client, message):
print("Text or Sticker")
@app.on_message(Filters.text)
@app.on_message(filters.text)
def just_text(client, message):
print("Just Text")
Here, ``just_text`` is never executed because ``text_or_sticker``, which has been registered first, already handles
texts (``Filters.text`` is shared and conflicting). To enable it, register the handler using a different group:
texts (``filters.text`` is shared and conflicting). To enable it, register the handler using a different group:
.. code-block:: python
@app.on_message(Filters.text, group=1)
@app.on_message(filters.text, group=1)
def just_text(client, message):
print("Just Text")
@@ -47,7 +48,7 @@ Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note
.. code-block:: python
@app.on_message(Filters.text, group=-1)
@app.on_message(filters.text, group=-1)
def just_text(client, message):
print("Just Text")
@@ -55,7 +56,7 @@ With :meth:`~pyrogram.Client.add_handler` (without decorators) the same can be a
.. code-block:: python
app.add_handler(MessageHandler(just_text, Filters.text), -1)
app.add_handler(MessageHandler(just_text, filters.text), -1)
Update propagation
------------------
@@ -67,17 +68,17 @@ continue to propagate the same update to the next groups until all the handlers
.. code-block:: python
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(0)
@app.on_message(Filters.private, group=1)
@app.on_message(filters.private, group=1)
def _(client, message):
raise Exception("Unhandled exception!") # Simulate an unhandled exception
@app.on_message(Filters.private, group=2)
@app.on_message(filters.private, group=2)
def _(client, message):
print(2)
@@ -109,18 +110,18 @@ Example with ``stop_propagation()``:
.. code-block:: python
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(0)
@app.on_message(Filters.private, group=1)
@app.on_message(filters.private, group=1)
def _(client, message):
print(1)
message.stop_propagation()
@app.on_message(Filters.private, group=2)
@app.on_message(filters.private, group=2)
def _(client, message):
print(2)
@@ -130,18 +131,18 @@ Example with ``raise StopPropagation``:
from pyrogram import StopPropagation
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(0)
@app.on_message(Filters.private, group=1)
@app.on_message(filters.private, group=1)
def _(client, message):
print(1)
raise StopPropagation
@app.on_message(Filters.private, group=2)
@app.on_message(filters.private, group=2)
def _(client, message):
print(2)
@@ -177,19 +178,19 @@ Example with ``continue_propagation()``:
.. code-block:: python
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(0)
message.continue_propagation()
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(1)
message.continue_propagation()
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(2)
@@ -199,19 +200,19 @@ Example with ``raise ContinuePropagation``:
from pyrogram import ContinuePropagation
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(0)
raise ContinuePropagation
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(1)
raise ContinuePropagation
@app.on_message(Filters.private)
@app.on_message(filters.private)
def _(client, message):
print(2)

View File

@@ -8,6 +8,7 @@ actually is the MTProto and the Bot API.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -6,6 +6,7 @@ through an intermediate SOCKS5 proxy server.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -10,6 +10,7 @@ visit and learn from each library documentation.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -69,8 +70,7 @@ Using ``apscheduler``
scheduler.start()
app.run()
``apscheduler`` does also support async code, here's an example with
`Pyrogram Asyncio <https://docs.pyrogram.org/intro/install.html#asynchronous>`_:
``apscheduler`` does also support async code, here's an example:
.. code-block:: python

View File

@@ -7,6 +7,7 @@ humans and another more compact for machines that is able to recover the origina
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -22,6 +22,7 @@ That's how a session looks like on the Android app, showing the three main piece
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -11,6 +11,7 @@ different Pyrogram applications with **minimal boilerplate code**.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -51,7 +52,8 @@ after importing your modules, like this:
.. code-block:: python
from pyrogram import Client, MessageHandler, Filters
from pyrogram import Client, filters
from pyrogram.handlers import MessageHandler
from handlers import echo, echo_reversed
@@ -60,19 +62,19 @@ after importing your modules, like this:
app.add_handler(
MessageHandler(
echo,
Filters.text & Filters.private))
filters.text & filters.private))
app.add_handler(
MessageHandler(
echo_reversed,
Filters.text & Filters.private),
filters.text & filters.private),
group=1)
app.run()
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each
:class:`~pyrogram.MessageHandler` object because **you can't use those cool decorators** for your
:class:`~pyrogram.handlers.MessageHandler` object because **you can't use those cool decorators** for your
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
Using Smart Plugins
@@ -102,15 +104,15 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
.. code-block:: python
:emphasize-lines: 4, 9
from pyrogram import Client, Filters
from pyrogram import Client, filters
@Client.on_message(Filters.text & Filters.private)
@Client.on_message(filters.text & filters.private)
def echo(client, message):
message.reply(message.text)
@Client.on_message(Filters.text & Filters.private, group=1)
@Client.on_message(filters.text & filters.private, group=1)
def echo_reversed(client, message):
message.reply(message.text[::-1])
@@ -306,7 +308,7 @@ updates) will be modified in such a way that a special ``handler`` attribute poi
.. code-block:: python
:emphasize-lines: 5, 6
@Client.on_message(Filters.text & Filters.private)
@Client.on_message(filters.text & filters.private)
def echo(client, message):
message.reply(message.text)

View File

@@ -7,6 +7,7 @@ decide to manually terminate it) and is used to authorize a client to execute AP
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -20,6 +20,7 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -19,6 +19,7 @@ variety of decorations that can also be nested in order to combine multiple styl
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----

View File

@@ -1,14 +1,15 @@
Using Filters
=============
So far we've seen :doc:`how to register a callback function <../start/updates>` that executes every time a specific update
comes from the server, but there's much more than that to come.
So far we've seen :doc:`how to register a callback function <../start/updates>` that executes every time an update comes
from the server, but there's much more than that to come.
Here we'll discuss about :class:`~pyrogram.Filters`. Filters enable a fine-grain control over what kind of
Here we'll discuss about :obj:`~pyrogram.filters`. Filters enable a fine-grain control over what kind of
updates are allowed or not to be passed in your callback functions, based on their inner details.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
@@ -24,10 +25,10 @@ Let's start right away with a simple example:
.. code-block:: python
:emphasize-lines: 4
from pyrogram import Filters
from pyrogram import filters
@app.on_message(Filters.audio)
@app.on_message(filters.audio)
def my_handler(client, message):
print(message)
@@ -35,16 +36,17 @@ Let's start right away with a simple example:
callback function itself:
.. code-block:: python
:emphasize-lines: 8
:emphasize-lines: 9
from pyrogram import Filters, MessageHandler
from pyrogram import filters
from pyrogram.handlers import MessageHandler
def my_handler(client, message):
print(message)
app.add_handler(MessageHandler(my_handler, Filters.audio))
app.add_handler(MessageHandler(my_handler, filters.audio))
Combining Filters
-----------------
@@ -61,7 +63,7 @@ Here are some examples:
.. code-block:: python
@app.on_message(Filters.text & ~Filters.edited)
@app.on_message(filters.text & ~filters.edited)
def my_handler(client, message):
print(message)
@@ -69,21 +71,21 @@ Here are some examples:
.. code-block:: python
@app.on_message(Filters.sticker & (Filters.channel | Filters.private))
@app.on_message(filters.sticker & (filters.channel | filters.private))
def my_handler(client, message):
print(message)
Advanced Filters
----------------
Some filters, like :meth:`~pyrogram.Filters.command` or :meth:`~pyrogram.Filters.regex`
Some filters, like :meth:`~pyrogram.filters.command` or :meth:`~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"]))
@app.on_message(filters.command(["start", "help"]))
def my_handler(client, message):
print(message)
@@ -91,7 +93,7 @@ can also accept arguments:
.. code-block:: python
@app.on_message(Filters.regex("pyrogram"))
@app.on_message(filters.regex("pyrogram"))
def my_handler(client, message):
print(message)
@@ -99,16 +101,16 @@ More handlers using different filters can also live together.
.. code-block:: python
@app.on_message(Filters.command("start"))
@app.on_message(filters.command("start"))
def start_command(client, message):
print("This is the /start command")
@app.on_message(Filters.command("help"))
@app.on_message(filters.command("help"))
def help_command(client, message):
print("This is the /help command")
@app.on_message(Filters.chat("PyrogramChat"))
@app.on_message(filters.chat("PyrogramChat"))
def from_pyrogramchat(client, message):
print("New message in @PyrogramChat")