Фильтры сообщений

· nikoontelegram's blog


Сегодня немного расширим бота разными способами обработки в зависимости от содержимого отправленного сообщения.

Код бота из последней заметки
 1import logging
 2
 3from aiogram import Bot, Dispatcher
 4from aiogram.filters import CommandStart
 5
 6TOKEN = "<TOKEN>"
 7
 8# включение логирования
 9logging.basicConfig(
10    level=logging.INFO,
11    format="%(asctime)s: "
12           "%(filename)s: "
13           "%(levelname)s: "
14           "%(funcName)s(): "
15           "%(lineno)d:\t"
16           "%(message)s",
17)
18
19
20dp = Dispatcher()
21bot = Bot(TOKEN)
22
23
24@dp.message(CommandStart())
25async def command_start_handler(message):
26    await message.answer(f"Hello, {message.from_user.full_name}!")
27
28
29@dp.message()
30async def echo_handler(message):
31    await message.answer(message.text)
32
33logging.info("Application started")
34dp.run_polling(bot)
35

Для начала исправим проблему, которая была в боте изначально. В функции echo_handler мы отправляем обратно текст, присланный пользователем. Однако не в каждом сообщении он есть. Сделаем так, чтобы эта функция обрабатывала только сообщения с текстом. Для этого нам нужно в начало файла добавить импорт

1from aiogram import F

И строку над функцией echo_handler заменить на

1@dp.message(F.text)

Она будет проверять, что у сообщения (которое олицетворяет F) присутствует поле text. Если вы попробуете отправить такому боту картинку, то в логе программы увидите, что событие о приходе картинке не было обработано, хоть бот его и получил. Это происходит потому, что у нас нет для него подходящего хендлера. Давайте это исправим:

1@dp.message(F.photo)
2async def photo_handler(message):
3    await message.answer(message.photo[0].file_id)

Здесь мы обращаемся к полю photo полученного сообщения по номеру 0, так как телеграм даёт возможность получить каждую картинку в нескольких размерах. По этой причине поле фото всегда будет представлять из себя массив. И далее, отправляем пользователю file_id - идентификатор файла внутри телеграма. Пока что он нам полезен только как доказательство того, что бот обработал получение фотографии. О том как использовать их с пользой я расскажу в следующей заметке.

Код бота целиком:

 1
 2import logging
 3
 4from aiogram import Bot, Dispatcher, F
 5from aiogram.filters import CommandStart
 6
 7TOKEN = "<TOKEN>"
 8
 9# включение логирования
10logging.basicConfig(
11    level=logging.INFO,
12    format="%(asctime)s: "
13           "%(filename)s: "
14           "%(levelname)s: "
15           "%(funcName)s(): "
16           "%(lineno)d:\t"
17           "%(message)s",
18)
19
20dp = Dispatcher()
21bot = Bot(TOKEN)
22
23
24@dp.message(CommandStart())
25async def command_start_handler(message):
26    await message.answer(f"Hello, {message.from_user.full_name}!")
27
28
29@dp.message(F.text)
30async def echo_handler(message):
31    await message.answer(message.text)
32
33
34@dp.message(F.photo)
35async def photo_handler(message):
36    await message.answer(message.photo[0].file_id)
37
38
39logging.info("Application started")
40dp.run_polling(bot)

Мой канал про разработку под телеграм: @NikoOnTelegram