Фильтры
Чтобы не городить сотни if'ов в одном хэндлере, были придуманы фильтры (правила).
Фильтры необходимы для маршрутизации событий конкретным хэндлерам.
Поиск обработчика всегда останавливается при прохождении первого соответствующего набора фильтров.
По умолчанию все хэндлеры не имеют фильтров, поэтому все события будут передаваться первому обработчику без фильтров.
Основной и самый удобный фильтр - магический F-фильтр.
Пользоваться им крайне легко - просто представьте, что вместо него стоит обрабатываемое событие, и обращайтесь к его атрибутам.
Кастомный фильтр
Если мы хотим реализовать какую-то сложную проверку (например, с запросом в бд или к какому-то апи), то надо создать свой фильтр.
Фильтры могут быть:
- Асинхронными функциями (
async def my_filter(*args, **kwargs): pass) - Синхронными функциями (
def my_filter(*args, **kwargs): pass) - Анонимными функциями (
lambda event: True) - Любым awaitable объектом
- Подклассом
aliceio.filters.base.Filter - Экземпляром
Магического фильтра
И они должны возвращать bool или dict.
Если возвращается словарь, полученные данные будут переданы следующим фильтрам и обработчику в качестве ключевых аргументов.
Сделаем простой class-based фильтр:
Теперь напишем хэндлеры, которые ловят согласие и отказ - слова "да", "нет" и похожие:
Магический фильтр
Для начала этот фильтр нужно импортировать из aliceio.
Если импортировать его из magic-filter, то метод .as_() не будет доступен
(о нём в главе про DI и про магический фильтр).
К уже написанным обработчикам создадим ещё два, которые будут реагировать на нажатия кнопок с payload'ом:
И чтобы эти кнопки появились, добавим хэндлер без фильтров, который будет срабатывать всегда, когда событие дойдёт до него:
Допишем обычную точку входа и вуаля, вы прекрасны!
Комбинация фильтров
Есть два основных способа комбинации фильтров: "и" и "или". Все фильтры можно комбинировать друг с другом и создавать любые конфигурации под любую задачу.
Логическое "и"
Предпочтительный:
Дополнительный (с помощью and_f() фильтра):
Логическое "или"
Предпочтительный:
Дополнительный (с помощью or_f() фильтра):
Логическое "не" (инверсия)
Предпочтительный:
Дополнительный (с помощью invert_f() фильтра):