Сегодня мы разберём, как создать бота который может реагировать на сообщения из групп.
С чего начать #
Есть два важных предварительных условия:
- Бот должен быть членом группы, иначе обновления о новых сообщениях он получать не будет.
- У бота должен быть выключен privacy mod.
Поговорим подробнее про второй пункт. Главное что нужно знать - это настройка, которая не даёт ботам получать оповещения о сообщениях в группах. Отключить её можно у @BotFather. Для этого выберите бота, откройте bot settings, и там выберите group privacy -> turn off. Детальнее о том, что это такое можно прочитать здесь.
Пишем бота #
После того как privacy mod отключен нам достаточно создать обычного бота. Для примера можем взять код бота из заметки про фильтры. Продублирую здесь его код:
1import logging
2
3from aiogram import Bot, Dispatcher, F
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
19dp = Dispatcher()
20bot = Bot(TOKEN)
21
22
23@dp.message(CommandStart())
24async def command_start_handler(message):
25 await message.answer(f"Hello, {message.from_user.full_name}!")
26
27
28@dp.message(F.text)
29async def echo_handler(message):
30 await message.answer(message.text)
31
32
33@dp.message(F.photo)
34async def photo_handler(message):
35 await message.answer(message.photo[0].file_id)
36
37
38logging.info("Application started")
39dp.run_polling(bot)
Добавив такого бота в группу, мы получим такое же поведение, как до этого в личных сообщениях: каждое текстовое сообщение бот будет дублировать от своего имени, а в ответ на картинки будет присылать их file_id.
Фильтруем сообщения по типу #
Так же полезной может быть возможность реагировать по-разному на личные сообщения и сообщения из групп. Для этого можно воспользоваться фильтром на тип чата. Изменим photo_handler
следующим образом:
1@dp.message(F.photo and F.chat.type == ChatType.PRIVATE)
2async def photo_handler(message):
3 await message.answer(message.photo[0].file_id)
Теперь в него будут попадать только сообщения отправленные боту в личку, а на текстовые бот будет реагировать как раньше.
Этой возможностью можно воспользоваться, например, для создания в личке панели администратора, позволяющей настраивать поведение бота в группе.
P.S. Правда, для создания админ-панели полезно будет ещё фильтровать сообщения по id отправителя, чтобы не каждый пришедший в личку к боту получал все права администратора - но об этом мы поговорим в одной из следующих заметок.
Итого #
Мы научились получать в боте сообщения из групп и разобрали новый вид фильтров, позволяющий отделять их от сообщений, полученных в личку. В остальном они друг от друга почти ничем не отличаются и вы можете обрабатывать их абсолютно одинаково.
Stay tuned!