Делаем это в группе

· nikoontelegram's blog


Сегодня мы разберём, как создать бота который может реагировать на сообщения из групп.

С чего начать #

Есть два важных предварительных условия:

  1. Бот должен быть членом группы, иначе обновления о новых сообщениях он получать не будет.
  2. У бота должен быть выключен 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!


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