mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-12 10:11:52 +00:00
Bot API 5.7 and some new features (#834)
* Update API, added some new features * Fixed unknown chat_action value * Separate events from dispatcher messages * Disabled cache for I18n LazyProxy * Rework events isolation * Added chat member status changed filter, update Bot API 5.7, other small changes * Improve exceptions in chat member status filter * Fixed tests, covered flags and events isolation modules * Try to fix flake8 unused type ignore * Fixed linter error * Cover chat member updated filter * Cover chat action sender * Added docs for chat action util * Try to fix tests for python <= 3.9 * Fixed headers * Added docs for flags functionality * Added docs for chat_member_updated filter * Added change notes * Update dependencies and fix mypy checks * Bump version
This commit is contained in:
parent
ac7f2dc408
commit
7776cf9cf6
77 changed files with 2485 additions and 502 deletions
103
docs/dispatcher/filters/chat_member_updated.rst
Normal file
103
docs/dispatcher/filters/chat_member_updated.rst
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
=================
|
||||
ChatMemberUpdated
|
||||
=================
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.filters.chat_member_updated.ChatMemberUpdatedFilter
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
|
||||
You can import from :code:`aiogram.dispatcher.filters` all available
|
||||
variants of `statuses`_, `status groups`_ or `transitions`_:
|
||||
|
||||
Statuses
|
||||
========
|
||||
|
||||
+-------------------------+--------------------------------------+
|
||||
| name | Description |
|
||||
+=========================+======================================+
|
||||
| :code:`CREATOR` | Chat owner |
|
||||
+-------------------------+--------------------------------------+
|
||||
| :code:`ADMINISTRATOR` | Chat administrator |
|
||||
+-------------------------+--------------------------------------+
|
||||
| :code:`MEMBER` | Member of the chat |
|
||||
+-------------------------+--------------------------------------+
|
||||
| :code:`RESTRICTED` | Restricted user (can be not member) |
|
||||
+-------------------------+--------------------------------------+
|
||||
| :code:`LEFT` | Isn't member of the chat |
|
||||
+-------------------------+--------------------------------------+
|
||||
| :code:`KICKED` | Kicked member by administrators |
|
||||
+-------------------------+--------------------------------------+
|
||||
|
||||
Statuses can be extended with `is_member` flag by prefixing with
|
||||
:code:`+` (for :code:`is_member == True)` or :code:`-` (for :code:`is_member == False`) symbol,
|
||||
like :code:`+RESTRICTED` or :code:`-RESTRICTED`
|
||||
|
||||
Status groups
|
||||
=============
|
||||
|
||||
The particular statuses can be combined via bitwise :code:`or` operator, like :code:`CREATOR | ADMINISTRATOR`
|
||||
|
||||
+-------------------------+-----------------------------------------------------------------------------------+
|
||||
| name | Description |
|
||||
+=========================+===================================================================================+
|
||||
| :code:`IS_MEMBER` | Combination of :code:`(CREATOR | ADMINISTRATOR | MEMBER | +RESTRICTED)` statuses. |
|
||||
+-------------------------+-----------------------------------------------------------------------------------+
|
||||
| :code:`IS_ADMIN` | Combination of :code:`(CREATOR | ADMINISTRATOR)` statuses. |
|
||||
+-------------------------+-----------------------------------------------------------------------------------+
|
||||
| :code:`IS_NOT_MEMBER` | Combination of :code:`(LEFT | KICKED | -RESTRICTED)` statuses. |
|
||||
+-------------------------+-----------------------------------------------------------------------------------+
|
||||
|
||||
Transitions
|
||||
===========
|
||||
|
||||
Transitions can be defined via bitwise shift operators :code:`>>` and :code:`<<`.
|
||||
Old chat member status should be defined in the left side for :code:`>>` operator (right side for :code:`<<`)
|
||||
and new status should be specified on the right side for :code:`>>` operator (left side for :code:`<<`)
|
||||
|
||||
The direction of transition can be changed via bitwise inversion operator: :code:`~JOIN_TRANSITION`
|
||||
will produce swap of old and new statuses.
|
||||
|
||||
+-----------------------------+-----------------------------------------------------------------------+
|
||||
| name | Description |
|
||||
+=============================+=======================================================================+
|
||||
| :code:`JOIN_TRANSITION` | Means status changed from :code:`IS_NOT_MEMBER` to :code:`IS_MEMBER` |
|
||||
| | (:code:`IS_NOT_MEMBER >> IS_MEMBER`) |
|
||||
+-----------------------------+-----------------------------------------------------------------------+
|
||||
| :code:`LEAVE_TRANSITION` | Means status changed from :code:`IS_MEMBER` to :code:`IS_NOT_MEMBER` |
|
||||
| | (:code:`~JOIN_TRANSITION`) |
|
||||
+-----------------------------+-----------------------------------------------------------------------+
|
||||
| :code:`PROMOTED_TRANSITION` | Means status changed from |
|
||||
| | :code:`(MEMBER | RESTRICTED | LEFT | KICKED) >> ADMINISTRATOR` |
|
||||
| | (:code:`(MEMBER | RESTRICTED | LEFT | KICKED) >> ADMINISTRATOR`) |
|
||||
+-----------------------------+-----------------------------------------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Note that if you define the status unions (via :code:`|`) you will need to add brackets for the statement
|
||||
before use shift operator in due to operator priorities.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Handle user leave or join events
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram.dispatcher.filters import IS_MEMBER, IS_NOT_MEMBER
|
||||
|
||||
@router.chat_member(chat_member_updated=IS_MEMBER >> IS_NOT_MEMBER)
|
||||
async def on_user_leave(event: ChatMemberUpdated): ...
|
||||
|
||||
@router.chat_member(chat_member_updated=IS_NOT_MEMBER >> IS_MEMBER)
|
||||
async def on_user_join(event: ChatMemberUpdated): ...
|
||||
|
||||
Or construct your own terms via using pre-defined set of statuses and transitions.
|
||||
|
||||
Allowed handlers
|
||||
================
|
||||
|
||||
Allowed update types for this filter:
|
||||
|
||||
- `my_chat_member`
|
||||
- `chat_member`
|
||||
|
|
@ -18,6 +18,7 @@ Here is list of builtin filters:
|
|||
command
|
||||
content_types
|
||||
text
|
||||
chat_member_updated
|
||||
exception
|
||||
magic_filters
|
||||
magic_data
|
||||
|
|
@ -83,7 +84,7 @@ Bound Filters with only default arguments will be automatically applied with def
|
|||
to each handler in the router and nested routers to which this filter is bound.
|
||||
|
||||
For example, although we do not specify :code:`chat_type` in the handler filters,
|
||||
but since the filter has a default value, the filter will be applied to the handler
|
||||
but since the filter has a default value, the filter will be applied to the handler
|
||||
with a default value :code:`private`:
|
||||
|
||||
.. code-block:: python
|
||||
|
|
|
|||
89
docs/dispatcher/flags.rst
Normal file
89
docs/dispatcher/flags.rst
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
=====
|
||||
Flags
|
||||
=====
|
||||
|
||||
Flags is a markers for handlers that can be used in `middlewares <#use-in-middlewares>`_
|
||||
or special `utilities <#use-in-utilities>`_ to make classification of the handlers.
|
||||
|
||||
Flags can be added to the handler via `decorators <#via-decorators>`_,
|
||||
`handlers registration <#via-handler-registration-method>`_ or
|
||||
`filters <via-filters>`_.
|
||||
|
||||
Via decorators
|
||||
==============
|
||||
|
||||
For example mark handler with `chat_action` flag
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram import flags
|
||||
|
||||
@flags.chat_action
|
||||
async def my_handler(message: Message)
|
||||
|
||||
Or just for rate-limit or something else
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram import flags
|
||||
|
||||
@flags.rate_limit(rate=2, key="something")
|
||||
async def my_handler(message: Message)
|
||||
|
||||
Via handler registration method
|
||||
===============================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.message(..., flags={'chat_action': 'typing', 'rate_limit': {'rate': 5}})
|
||||
|
||||
Via filters
|
||||
===========
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class Command(BaseFilter):
|
||||
...
|
||||
|
||||
def update_handler_flags(self, flags: Dict[str, Any]) -> None:
|
||||
commands = flags.setdefault("commands", [])
|
||||
commands.append(self)
|
||||
|
||||
|
||||
|
||||
Use in middlewares
|
||||
==================
|
||||
|
||||
.. automodule:: aiogram.dispatcher.flags.getter
|
||||
:members:
|
||||
|
||||
Example in middlewares
|
||||
----------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def my_middleware(handler, event, data):
|
||||
typing = get_flag(data, "typing") # Check that handler marked with `typing` flag
|
||||
if not typing:
|
||||
return await handler(event, data)
|
||||
|
||||
async with ChatActionSender.typing(chat_id=event.chat.id):
|
||||
return await handler(event, data)
|
||||
|
||||
Use in utilities
|
||||
================
|
||||
|
||||
For example you can collect all registered commands with handler description and then it can be used for generating commands help
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def collect_commands(router: Router) -> Generator[Tuple[Command, str], None, None]:
|
||||
for handler in router.message.handlers:
|
||||
if "commands" not in handler.flags: # ignore all handler without commands
|
||||
continue
|
||||
# the Command filter adds the flag with list of commands attached to the handler
|
||||
for command in handler.flags["commands"]:
|
||||
yield command, handler.callback.__doc__ or ""
|
||||
# Recursively extract commands from nested routers
|
||||
for sub_router in router.sub_routers:
|
||||
yield from collect_commands(sub_router)
|
||||
|
|
@ -24,3 +24,4 @@ Dispatcher is subclass of router and should be always is root router.
|
|||
filters/index
|
||||
middlewares
|
||||
finite_state_machine/index
|
||||
flags
|
||||
|
|
|
|||
56
docs/utils/chat_action.rst
Normal file
56
docs/utils/chat_action.rst
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
==================
|
||||
Chat action sender
|
||||
==================
|
||||
|
||||
Sender
|
||||
======
|
||||
|
||||
.. autoclass:: aiogram.utils.chat_action.ChatActionSender
|
||||
:members: __init__,running,typing,upload_photo,record_video,upload_video,record_voice,upload_voice,upload_document,choose_sticker,find_location,record_video_note,upload_video_note
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async with ChatActionSender.typing(bot=bot, chat_id=message.chat.id):
|
||||
# Do something...
|
||||
# Perform some long calculations
|
||||
await message.answer(result)
|
||||
|
||||
|
||||
Middleware
|
||||
==========
|
||||
|
||||
.. autoclass:: aiogram.utils.chat_action.ChatActionMiddleware
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Before usa should be registered for the `message` event
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
<router or dispatcher>.message.middleware(ChatActionMiddleware())
|
||||
|
||||
After this action all handlers which works longer than `initial_sleep` will produce the '`typing`' chat action.
|
||||
|
||||
Also sender can be customized via flags feature for particular handler.
|
||||
|
||||
Change only action type:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.message(...)
|
||||
@flags.chat_action("sticker")
|
||||
async def my_handler(message: Message): ...
|
||||
|
||||
|
||||
Change sender configuration:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.message(...)
|
||||
@flags.chat_action(initial_sleep=2, action="upload_document", interval=3)
|
||||
async def my_handler(message: Message): ...
|
||||
|
|
@ -6,3 +6,4 @@ Utils
|
|||
|
||||
i18n
|
||||
keyboard
|
||||
chat_action
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue