Skip to content

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 += ' без метки'

Сообщение мы форматируем простым образом (делаем тег метки жирным, если она есть) и отправляем пользователю.

img.png

Возможно, это выглядит не особо красиво, но реализация достаточно функциональная и иногда бывает очень удобно использовать именно такой подход. Конечно, заказчику лучше отрисовывать клавиатуры, но мы, как опытные разработчики, понимаем, что главное — это простота вызова команды, правда?