Основная задача обработчиков (хэндлеров) — обрабатывать сообщения, в том числе и от пользователей. Разберёмся, как это делать. Для этого импортируем модуль MagicFilter с классом F и воспользуемся его методами:
Описание фильтров:
F.text == '123' - Ловит определённый текст
F.text.startswith('smth_') - Ловит определенный текст, который начинается с smth_
F.data == '123' - Ловит определенный Callback
F.data.startswith('smth_') - Ловит определенный Callback который начинается с smth_
F.photo - Ловит только фото (все)
F.document - Ловит только документы
F.from_user.id == 123 - Ловит только от определенного юзера по его ID
Пример использования:
@dp.message(F.photo)
async def get_photo(message: Message):
await message.answer(f'ID фотографии: {message.photo[-1].file_id}')
С помощью метода message.photo[-1].file_id можно получить ID фотографии. Этот идентификатор используется для хранения фото на сервере или отправки этого же изображения без повторной загрузки.
Фото хранится на сервере Telegram, и нам не нужно загружать его заново. Достаточно указать ID в аргументе photo метода message.answer_photo, и оно отправится. Однако это должно быть фото, которое хотя бы один раз было отправлено этому боту. Если бот о нём не знает, то он его не найдёт.
Индекс [-1] в этой конструкции означает, что мы получаем самое лучшее качество (последнее фото), так как Telegram сжимает картинки.
Сообщение было словлено этим методом и получено ID:
Command()
Класс Command() используется для обработки команд, которые начинаются со слэша (например, /help).
@dp.message(Command('help'))
async def cmd_help(message: Message):
await message.answer(f'{message.from_user.first_name}, вам нужна помощь?')
await message.answer(f'Ваш ID: {message.from_user.id}')
Из приведённого примера видно, что в класс Command была передана строка 'help', следовательно, мы можем использовать эту команду:
При отправке сообщений можно использовать методы message.from_user.first_name и message.from_user.id. Первый метод выводит имя пользователя, а второй — ID пользователя в Telegram.
CommandObject()
@dp.message(Command('get'))
async def cmd_get(message: Message, command: CommandObject):
await message.answer(f'Вы ввели команду get с аргументом {command.args}')
В некоторых случаях команда должна принимать аргументы, например /get 123. Для этого существует класс CommandObject. В данном примере был принят один аргумент:
Можно принимать и несколько аргументов. В таком случае их необходимо разделить между собой и перебрать:
@dp.message(Command('get'))
async def cmd_get(message: Message, command: CommandObject):
value1, value2 = command.args.split(' ', maxsplit=1)
await message.answer(f'Вы ввели команду get с аргументом {value1} {value2}')
В этой конструкции могут быть недоработки. Рассмотрим все возможные варианты ошибок:
@dp.message(Command('get'))
async def cmd_get(message: Message, command: CommandObject):
if not command.args:
await message.answer('Аргументы не переданы')
return
try:
value1, value2 = command.args.split(' ', maxsplit=1)
await message.answer(f'Вы ввели команду get с аргументом {value1} {value2}')
except:
await message.answer('Были введены неправильные аргументы')
CommandStart()
Мы уже познакомились с фильтром CommandStart(), который предназначен для обработки команды /start. Однако его возможности не ограничиваются только этим. С помощью него можно также обрабатывать дополнительные параметры и, например, реализовать реферальную систему: t.me/bot?start=123. В этом случае бот получит сообщение в формате /start 123. Это называется deep links (дип-линкс). Обратите внимание, что здесь может быть передан только один аргумент!
@dp.message(CommandStart(deep_link=True))
async def cmd_start(message: Message, command: CommandObject):
await message.answer(f'Привет! Ты пришел от {command.args}')
Команда принимает любые данные, переданные по ссылке. Давайте рассмотрим все возможные варианты и ограничим передачу данных только числами:
@dp.message(CommandStart(deep_link=True))
async def cmd_start(message: Message, command: CommandObject):
if command.args.isdigit():
await message.answer(f'Привет! Ты пришел от {command.args}')
else:
await message.answer('Ошибка')
Если вы не хотите, чтобы появлялось сообщение об ошибке, можно использовать аргумент magic:
@dp.message(CommandStart(deep_link=True, magic=F.args.isdigit()))
async def cmd_start(message: Message, command: CommandObject):
await message.answer(f'Привет! Ты пришел от {command.args}')
Здесь вы узнали основное о фильтрах. Если ваша цель — создать простого бота, то необязательно изучать всё. Возьмите для работы только то, что вам пригодится.
P.S. Даже если эта статья потеряет свою актуальность, она всё равно будет служить мне напоминанием о некоторых командах и избавит меня от необходимости искать их снова в интернете. Возможно, спустя пару лет я вернусь к этой статье и освежу свои знания. А тем, кто дочитал до конца, я желаю, чтобы ваши труды, проекты и творческие работы всегда оставались актуальными и востребованными! =)