Фільтрування подій#
Filters is needed for routing updates to the specific handler. Searching of handler is always stops on first match set of filters are pass. By default, all handlers has empty set of filters, so all updates will be passed to first handler that has empty set of filters.
aiogram has some builtin useful filters or you can write own filters.
Вбудовані фільтри#
Ось список вбудованих фільтрів:
Написання власних фільтрів#
Фільтри бувають:
Асинхронною функцією (
async def my_filter(*args, **kwargs): pass
)Синхронною функцією (
def my_filter(*args, **kwargs): pass
)Анонімною функцією (
lambda event: True
)Будь-яким очікуваним об’єктом (awaitable object, об’єкт, який може бути використаний в
await
виразі)Підкласом
aiogram.filters.base.Filter
Екземпляром MagicFilter
і має повертати bool або dict. Якщо словник передається як результат фільтра, отримані дані будуть передані до наступних фільтрів і обробника як аргументи ключових слів.
Базовий клас для власних фільтрів#
- class aiogram.filters.base.Filter[source]#
Якщо Ви хочете зареєструвати власні фільтри, як вбудовані фільтри, Вам потрібно буде написати підклас цього класу з заміною методу
__call__
і додаванням атрибутів фільтра.
Приклад власного фільтра#
Наприклад, якщо Вам потрібно створити простий текстовий фільтр:
from aiogram import Router
from aiogram.filters import Filter
from aiogram.types import Message
router = Router()
class MyFilter(Filter):
def __init__(self, my_text: str) -> None:
self.my_text = my_text
async def __call__(self, message: Message) -> bool:
return message.text == self.my_text
@router.message(MyFilter("hello"))
async def my_handler(message: Message):
...
Комбінування фільтрів#
Взагалом, усі фільтри можна комбінувати двома способами
Рекомендований спосіб#
Якщо Ви вкажете кілька фільтрів поспіль, це буде перевірено умовою «and» :
@<router>.message(F.text.startswith("show"), F.text.endswith("example"))
Крім того, якщо ви хочете використовувати два альтернативні способи запуску одного обробника (умова «or»), ви можете зареєструвати обробник двічі або більше разів, як вам подобається
@<router>.message(F.text == "hi")
@<router>.message(CommandStart())
Також іноді Вам потрібно буде інвертувати результат фільтра, наприклад, у вас є фільтр IsAdmin і ви хочете перевірити, чи користувач не є адміністратором
@<router>.message(~IsAdmin())
Інший можливий спосіб#
Альтернативним способом є об’єднання за допомогою спеціальних функцій (and_f()
, or_f()
, invert_f()
з модуля aiogram.filters
):
and_f(F.text.startswith("show"), F.text.endswith("example"))
or_f(F.text(text="hi"), CommandStart())
invert_f(IsAdmin())
and_f(<A>, or_f(<B>, <C>))