Appearance
Aiogram 3: командный фильтр
https://habr.com/ru/articles/821085/
Фильтры в aiogram
нужны для того, чтобы бот понимал, как реагировать на то или иное событие (действие, сообщение или тип сообщения). Приведу несколько примеров.
Фильтры по типу сообщения
На более высоком уровне мы указываем фильтры в декораторе перед функцией после роутера или диспетчера. Из наиболее часто используемых:
.message
Срабатывает на сообщения в личном чате с ботом или в группах (в каналах работать не будет). Здесь обрабатываются текстовые, фото, видео сообщения и сообщения с документами..callback_query
Срабатывает на сообщения, содержащиеcallback
дату..channel_post
Срабатывает на сообщения в канале, который администрирует бот.
Продолжим изучение фильтров и их применения, чтобы ваши боты стали еще более функциональными и гибкими в работе.
Встроенные командные фильтры.
Существует два встроенных командных фильтра: CommandStart
и Command
.
python
from aiogram.filters import CommandStart, Command
CommandStart
реагирует на команду/start
и записывается таким образом:python@start_router.message(CommandStart())
Как вы видите, здесь не указывается явно команда
/start
, но бот все равно будет реагировать на эту команду.Command
реагирует на команду, которую вы в него передали. Запись имеет такой вид:python@start_router.message(Command('test'))
Это указывает боту, что данный хендлер должен реагировать на команду
/test
.Кроме одиночного аргумента, данный фильтр может принимать список команд, на которые должен реагировать бот. Это полезная функция в связке с
CommandObject
.Запись в таком случае будет выглядеть так:
python@start_router.message(Command(commands=["settings", "config"]))
Давайте ещё немного освежим свои знания и напишем хендлер, который будет реагировать на метку в команде. Для этого нам нужно будет использовать CommandObject.
Импорт будет выглядеть так:
python
from aiogram.filters import CommandStart, Command, CommandObject
Пишем хендлер, который будет реагировать на команды /settings
и /about
:
python
@start_router.message(Command(commands=["settings", "about"]))
async def univers_cmd_handler(message: Message, command: CommandObject):
command_args: str = command.args
command_name = 'settings' if 'settings' in message.text else 'about'
response = f'Была вызвана команда /{command_name}'
if command_args:
response += f' с меткой <b>{command_args}</b>'
else:
response += ' без метки'
await message.answer(response)
Вот так можно обработать сразу несколько команд. Такое бывает полезно в админ панели. Например, если нужно быстро забанить пользователя /ban user_id
или выполнить другую команду без прописывания большого сценария через FSM или без создания кнопок.
Давайте разберем код.
python
@start_router.message(Command(commands=["settings", "about"]))
Здесь мы прописали хендлер для сообщений, который использует фильтр Command
. В него мы передали аргумент commands
со списком команд, на которые должен реагировать хендлер.
Далее мы настроили нашу функцию, указав, что она должна обрабатывать сообщение и что там будут аргументы (как минимум она будет их пытаться получить, а иначе присвоит значение None
).
command_args: str = command.args
Этой строкой мы достаем аргументы из команды, а затем прописываем простое условие, на основании которого генерируем ответное сообщение:
python
command_name = 'settings' if 'settings' in message.text else 'about'
response = f'Была вызвана команда /{command_name}'
if command_args:
response += f' с меткой <b>{command_args}</b>'
else:
response += ' без метки'
Сообщение мы форматируем простым образом (делаем тег метки жирным, если она есть) и отправляем пользователю.
Возможно, это выглядит не особо красиво, но реализация достаточно функциональная и иногда бывает очень удобно использовать именно такой подход. Конечно, заказчику лучше отрисовывать клавиатуры, но мы, как опытные разработчики, понимаем, что главное — это простота вызова команды, правда?