Фильтры⚓︎
Фильтры необходимы для маршрутизации обновлений к определённому обработчику. Поиск обработчика всегда останавливается при первом совпадении с набором фильтров. По умолчанию все обработчики имеют пустой набор фильтров, поэтому все обновления будут переданы первому обработчику с пустым набором фильтров.
Tip
Наши фильтры, также как и фильтры aiogram, построены на библиотеке magic-filter.
Объединение фильтров⚓︎
Если указать несколько фильтров подряд, они будут проверены с условием «и»:
Кроме того, если вы хотите использовать два альтернативных способа запуска одного и того же обработчика (условие «или»), вы можете зарегистрировать обработчик два или более раз по вашему усмотрению.
MagicFilter⚓︎
MagicFilter — это мощный и гибкий инструмент из пакета magic-filter, интегрированный в python-trueconf-bot. Он позволяет строить выразительные и цепочечные фильтры, упрощающие маршрутизацию сообщений в вашем боте. Вместо того чтобы вручную проверять поля апдейта внутри обработчика, условия можно задать прямо в декораторе.
Фильтр работает «лениво»: при объявлении обработчика сохраняется сама цепочка проверок, а не её результат. Проверка выполняется только в момент, когда приходит новое событие, поэтому фильтры легко комбинируются и остаются читаемыми. Такой подход делает код короче и понятнее: сразу видно, какие именно апдейты пройдут через конкретный обработчик.
Идея MagicFilter проста: вы описываете цепочку атрибутов и условие, а затем применяете её к объекту. Представьте, что у вас есть объект с вложенными полями. Вместо ручной проверки вида if obj.foo.bar.baz == "spam": ...
можно собрать фильтр декларативно:
Получившийся фильтр — это не мгновенная проверка, а объект, который «запоминает» условие. При обработке апдейта этот фильтр автоматически применяется к объекту (роутер сам выполняет проверку под капотом). Технически для этого используется метод .resolve(obj)
, но напрямую вызывать его в коде не требуется — достаточно описать условие в декораторе, и оно будет выполнено при маршрутизации.
Здесь фильтр F.text == "ping"
будет автоматически проверен для каждого входящего сообщения. Если условие совпадает, сработает обработчик.
Возможные действия⚓︎
Объект MagicFilter поддерживает базовые логические операции над атрибутами объектов.
Существование или not None⚓︎
Действие по умолчанию:
Равенство⚓︎
F.text == "hello" # message.text == "hello"
F.from_user.id == 42 # message.from_user.id == 42
F.text != "spam" # message.text != "spam"
Принадлежность множеству⚓︎
# query.from_user.id in {42, 1000, 123123}
F.from_user.id.in_({42, 1000, 123123})
# query.data in {"foo", "bar", "baz"}
F.data.in_({"foo", "bar", "baz"})
Содержит⚓︎
Начинается/заканчивается строкой⚓︎
F.text.startswith("foo") # message.text.startswith("foo")
F.text.endswith("bar") # message.text.endswith("bar")
Регулярные выражения⚓︎
Пользовательская функция⚓︎
Инверсия результата⚓︎
Комбинирование условий⚓︎
(F.from_user.id == 42) & (F.text == "admin")
F.text.startswith("a") | F.text.endswith("b")
(F.from_user.id.in_({42, 777, 911})) & (F.text.startswith("!") | F.text.startswith("/")) & F.text.contains("ban")