mirror of
https://github.com/pyrogram/pyrogram
synced 2025-08-28 21:07:59 +00:00
parent
f440b1f969
commit
1960b00280
@ -84,6 +84,7 @@ To get started, press the Next button.
|
|||||||
|
|
||||||
resources/UpdateHandling
|
resources/UpdateHandling
|
||||||
resources/UsingFilters
|
resources/UsingFilters
|
||||||
|
resources/MoreOnUpdates
|
||||||
resources/SmartPlugins
|
resources/SmartPlugins
|
||||||
resources/AutoAuthorization
|
resources/AutoAuthorization
|
||||||
resources/CustomizeSessions
|
resources/CustomizeSessions
|
||||||
|
148
docs/source/resources/MoreOnUpdates.rst
Normal file
148
docs/source/resources/MoreOnUpdates.rst
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
More on Updates
|
||||||
|
===============
|
||||||
|
|
||||||
|
Here we'll show some advanced usages when working with updates.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This page makes use of Handlers and Filters to show you how to handle updates.
|
||||||
|
Learn more at `Update Handling <UpdateHandling.html>`_ and `Using Filters <UsingFilters.html>`_.
|
||||||
|
|
||||||
|
Handler Groups
|
||||||
|
--------------
|
||||||
|
|
||||||
|
If you register handlers with overlapping filters, only the first one is executed and any other handler will be ignored.
|
||||||
|
|
||||||
|
In order to process the same update more than once, you can register your handler in a different group.
|
||||||
|
Groups are identified by a number (number 0 being the default) and are sorted, that is, a lower group number has a
|
||||||
|
higher priority.
|
||||||
|
|
||||||
|
For example, in:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@app.on_message(Filters.text | Filters.sticker)
|
||||||
|
def text_or_sticker(client, message):
|
||||||
|
print("Text or Sticker")
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.text)
|
||||||
|
def just_text(client, message):
|
||||||
|
print("Just Text")
|
||||||
|
|
||||||
|
``just_text`` is never executed because ``text_or_sticker`` already handles texts. To enable it, simply register the
|
||||||
|
function using a different group:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@app.on_message(Filters.text, group=1)
|
||||||
|
def just_text(client, message):
|
||||||
|
print("Just Text")
|
||||||
|
|
||||||
|
Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@app.on_message(Filters.text, group=-1)
|
||||||
|
def just_text(client, message):
|
||||||
|
print("Just Text")
|
||||||
|
|
||||||
|
With :meth:`add_handler() <pyrogram.Client.add_handler>` (without decorators) the same can be achieved with:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
app.add_handler(MessageHandler(just_text, Filters.text), -1)
|
||||||
|
|
||||||
|
Update propagation
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Registering multiple handlers, each in a different group, becomes useful when you want to handle the same update more
|
||||||
|
than once. Any incoming update will be sequentially processed by all of your registered functions by respecting the
|
||||||
|
groups priority policy described above. Even in case any handler raises an unhandled exception, Pyrogram will still
|
||||||
|
continue to propagate the same update to the next groups until all the handlers are done. Example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@app.on_message(Filters.private)
|
||||||
|
def _(client, message):
|
||||||
|
print(0)
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=1)
|
||||||
|
def _(client, message):
|
||||||
|
print(1 / 0) # Unhandled exception: ZeroDivisionError
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=2)
|
||||||
|
def _(client, message):
|
||||||
|
print(2)
|
||||||
|
|
||||||
|
All these handlers will handle the same kind of messages, that are, messages sent or received in private chats.
|
||||||
|
The output for each incoming update will therefore be:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
0
|
||||||
|
ZeroDivisionError: division by zero
|
||||||
|
2
|
||||||
|
|
||||||
|
Stop Propagation
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
In order to prevent further propagation of an update in the dispatching phase, you can do *one* of the following:
|
||||||
|
|
||||||
|
- Call the update's bound-method ``.stop_propagation()`` (preferred way).
|
||||||
|
- Manually ``raise StopPropagation`` error (more suitable for raw updates only).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Note that ``.stop_propagation()`` is just an elegant and intuitive way to raise a ``StopPropagation`` error;
|
||||||
|
this means that any code coming *after* calling it won't be executed as your function just raised a custom exception
|
||||||
|
to signal the dispatcher not to propagate the update anymore.
|
||||||
|
|
||||||
|
Example with ``stop_propagation()``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@app.on_message(Filters.private)
|
||||||
|
def _(client, message):
|
||||||
|
print(0)
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=1)
|
||||||
|
def _(client, message):
|
||||||
|
print(1)
|
||||||
|
message.stop_propagation()
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=2)
|
||||||
|
def _(client, message):
|
||||||
|
print(2)
|
||||||
|
|
||||||
|
Example with ``raise StopPropagation``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from pyrogram import StopPropagation
|
||||||
|
|
||||||
|
@app.on_message(Filters.private)
|
||||||
|
def _(client, message):
|
||||||
|
print(0)
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=1)
|
||||||
|
def _(client, message):
|
||||||
|
print(1)
|
||||||
|
raise StopPropagation
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_message(Filters.private, group=2)
|
||||||
|
def _(client, message):
|
||||||
|
print(2)
|
||||||
|
|
||||||
|
The handler in group number 2 will never be executed because the propagation was stopped before. The output of both
|
||||||
|
examples will be:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
0
|
||||||
|
1
|
@ -5,7 +5,8 @@ For a finer grained control over what kind of messages will be allowed or not in
|
|||||||
:class:`Filters <pyrogram.Filters>`.
|
:class:`Filters <pyrogram.Filters>`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
This section makes use of Handlers to handle updates. Learn more at `Update Handling <UpdateHandling.html>`_.
|
This page makes use of Handlers to show you how to handle updates.
|
||||||
|
Learn more at `Update Handling <UpdateHandling.html>`_.
|
||||||
|
|
||||||
- This example will show you how to **only** handle messages containing an :obj:`Audio <pyrogram.Audio>` object and
|
- This example will show you how to **only** handle messages containing an :obj:`Audio <pyrogram.Audio>` object and
|
||||||
ignore any other message:
|
ignore any other message:
|
||||||
@ -99,45 +100,6 @@ More handlers using different filters can also live together.
|
|||||||
def from_pyrogramchat(client, message):
|
def from_pyrogramchat(client, message):
|
||||||
print("New message in @PyrogramChat")
|
print("New message in @PyrogramChat")
|
||||||
|
|
||||||
Handler Groups
|
|
||||||
--------------
|
|
||||||
|
|
||||||
If you register handlers with overlapping filters, only the first one is executed and any other handler will be ignored.
|
|
||||||
|
|
||||||
In order to process the same message more than once, you can register your handler in a different group.
|
|
||||||
Groups are identified by a number (number 0 being the default) and are sorted. This means that a lower group number has
|
|
||||||
a higher priority.
|
|
||||||
|
|
||||||
For example, in:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@app.on_message(Filters.text | Filters.sticker)
|
|
||||||
def text_or_sticker(client, message):
|
|
||||||
print("Text or Sticker")
|
|
||||||
|
|
||||||
|
|
||||||
@app.on_message(Filters.text)
|
|
||||||
def just_text(client, message):
|
|
||||||
print("Just Text")
|
|
||||||
|
|
||||||
``just_text`` is never executed because ``text_or_sticker`` already handles texts. To enable it, simply register the
|
|
||||||
function using a different group:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@app.on_message(Filters.text, group=1)
|
|
||||||
def just_text(client, message):
|
|
||||||
print("Just Text")
|
|
||||||
|
|
||||||
or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
@app.on_message(Filters.text, group=-1)
|
|
||||||
def just_text(client, message):
|
|
||||||
print("Just Text")
|
|
||||||
|
|
||||||
Custom Filters
|
Custom Filters
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ from .client.types import (
|
|||||||
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
|
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
|
||||||
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
||||||
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
|
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
|
||||||
Poll, PollOption, ChatPreview
|
Poll, PollOption, ChatPreview, StopPropagation
|
||||||
)
|
)
|
||||||
from .client import (
|
from .client import (
|
||||||
Client, ChatAction, ParseMode, Emoji,
|
Client, ChatAction, ParseMode, Emoji,
|
||||||
|
@ -134,24 +134,29 @@ class Dispatcher:
|
|||||||
parsed_update, handler_type = parser(update, users, chats)
|
parsed_update, handler_type = parser(update, users, chats)
|
||||||
|
|
||||||
for group in self.groups.values():
|
for group in self.groups.values():
|
||||||
for handler in group:
|
try:
|
||||||
args = None
|
for handler in group:
|
||||||
|
args = None
|
||||||
|
|
||||||
if isinstance(handler, RawUpdateHandler):
|
if isinstance(handler, RawUpdateHandler):
|
||||||
args = (update, users, chats)
|
args = (update, users, chats)
|
||||||
elif isinstance(handler, handler_type):
|
elif isinstance(handler, handler_type):
|
||||||
if handler.check(parsed_update):
|
if handler.check(parsed_update):
|
||||||
args = (parsed_update,)
|
args = (parsed_update,)
|
||||||
|
|
||||||
if args is None:
|
if args is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
handler.callback(self.client, *args)
|
||||||
|
except StopIteration:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e, exc_info=True)
|
||||||
|
|
||||||
try:
|
|
||||||
handler.callback(self.client, *args)
|
|
||||||
except Exception as e:
|
|
||||||
log.error(e, exc_info=True)
|
|
||||||
finally:
|
|
||||||
break
|
break
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(e, exc_info=True)
|
log.error(e, exc_info=True)
|
||||||
|
|
||||||
|
@ -37,3 +37,4 @@ from .user_and_chats import (
|
|||||||
Chat, ChatMember, ChatMembers, ChatPhoto,
|
Chat, ChatMember, ChatMembers, ChatPhoto,
|
||||||
Dialog, Dialogs, User, UserStatus, ChatPreview
|
Dialog, Dialogs, User, UserStatus, ChatPreview
|
||||||
)
|
)
|
||||||
|
from .update import StopPropagation
|
||||||
|
@ -22,10 +22,11 @@ from struct import pack
|
|||||||
import pyrogram
|
import pyrogram
|
||||||
from pyrogram.api import types
|
from pyrogram.api import types
|
||||||
from ..pyrogram_type import PyrogramType
|
from ..pyrogram_type import PyrogramType
|
||||||
|
from ..update import Update
|
||||||
from ..user_and_chats import User
|
from ..user_and_chats import User
|
||||||
|
|
||||||
|
|
||||||
class CallbackQuery(PyrogramType):
|
class CallbackQuery(PyrogramType, Update):
|
||||||
"""This object represents an incoming callback query from a callback button in an inline keyboard.
|
"""This object represents an incoming callback query from a callback button in an inline keyboard.
|
||||||
If the button that originated the query was attached to a message sent by the bot, the field message
|
If the button that originated the query was attached to a message sent by the bot, the field message
|
||||||
will be present. If the button was attached to a message sent via the bot (in inline mode),
|
will be present. If the button was attached to a message sent via the bot (in inline mode),
|
||||||
|
@ -26,11 +26,12 @@ from .location import Location
|
|||||||
from .message_entity import MessageEntity
|
from .message_entity import MessageEntity
|
||||||
from ..messages_and_media.photo import Photo
|
from ..messages_and_media.photo import Photo
|
||||||
from ..pyrogram_type import PyrogramType
|
from ..pyrogram_type import PyrogramType
|
||||||
|
from ..update import Update
|
||||||
from ..user_and_chats.chat import Chat
|
from ..user_and_chats.chat import Chat
|
||||||
from ..user_and_chats.user import User
|
from ..user_and_chats.user import User
|
||||||
|
|
||||||
|
|
||||||
class Message(PyrogramType):
|
class Message(PyrogramType, Update):
|
||||||
"""This object represents a message.
|
"""This object represents a message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -22,10 +22,11 @@ import pyrogram
|
|||||||
from pyrogram.api import types
|
from pyrogram.api import types
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from ..pyrogram_type import PyrogramType
|
from ..pyrogram_type import PyrogramType
|
||||||
|
from ..update import Update
|
||||||
from ..user_and_chats import Chat
|
from ..user_and_chats import Chat
|
||||||
|
|
||||||
|
|
||||||
class Messages(PyrogramType):
|
class Messages(PyrogramType, Update):
|
||||||
"""This object represents a chat's messages.
|
"""This object represents a chat's messages.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
26
pyrogram/client/types/update.py
Normal file
26
pyrogram/client/types/update.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||||
|
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||||
|
#
|
||||||
|
# This file is part of Pyrogram.
|
||||||
|
#
|
||||||
|
# Pyrogram is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Pyrogram is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
class StopPropagation(StopIteration):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Update:
|
||||||
|
def stop_propagation(self):
|
||||||
|
raise StopPropagation
|
@ -20,9 +20,10 @@ import pyrogram
|
|||||||
|
|
||||||
from pyrogram.api import types
|
from pyrogram.api import types
|
||||||
from ..pyrogram_type import PyrogramType
|
from ..pyrogram_type import PyrogramType
|
||||||
|
from ..update import Update
|
||||||
|
|
||||||
|
|
||||||
class UserStatus(PyrogramType):
|
class UserStatus(PyrogramType, Update):
|
||||||
"""This object represents a User status (Last Seen privacy).
|
"""This object represents a User status (Last Seen privacy).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
Loading…
x
Reference in New Issue
Block a user