mirror of
https://github.com/pyrogram/pyrogram
synced 2025-08-31 06:16:06 +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:
@@ -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
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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
|
||||
)
|
||||
|
@@ -6,6 +6,7 @@ to actually worry about -- that's normal -- and luckily for you, Pyrogram provid
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -8,6 +8,7 @@ actually is the MTProto and the Bot API.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
@@ -6,6 +6,7 @@ through an intermediate SOCKS5 proxy server.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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:
|
||||
|
||||
-----
|
||||
|
@@ -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")
|
||||
|
Reference in New Issue
Block a user