Добавить в корзинуПозвонить
Найти в Дзене
Записки сисадмина

Python. MAX бот. Синхронизируем каналы с телеграмм

Дорогой дневник, мне не подобрать слов, чтобы описать ту боль и унижения… Короче, столкнулся я тут с вопросом: можно ли клонировать канал из телеграмма в MAX? Сразу скажу - функционалом ботов нельзя. Боты не видят историю сообщений, поэтому при необходимости нужно использовать user-agent библиотеки типа telethon. Я таким заниматься желанием не горю, да и вопрос сегодня про кросс-постинг. Если вкратце: есть канал в телеграмм, есть канал в MAX. В каналы отправляются посты с картинкой (может и не одной), либо видео и текстом. Предположим, стандартные новостные посты. Нужно сделать так, чтобы при добавлении поста в телеграмм, он автоматически добавлялся в канал MAX. Также, неплохо бы добавить и обратную схему на случай блокировок (отправлять из MAX в телеграмм). В этой статье мы не будем писать код, он уже написан и выложен мной на github. Я буду объяснять структуру проекта, и как функционал работает. Также напишу, как правильно поднять все окружение и настроить каналы. Для запуска проекта
Оглавление

Дорогой дневник, мне не подобрать слов, чтобы описать ту боль и унижения…

Короче, столкнулся я тут с вопросом: можно ли клонировать канал из телеграмма в MAX? Сразу скажу - функционалом ботов нельзя. Боты не видят историю сообщений, поэтому при необходимости нужно использовать user-agent библиотеки типа telethon. Я таким заниматься желанием не горю, да и вопрос сегодня про кросс-постинг.

Если вкратце: есть канал в телеграмм, есть канал в MAX. В каналы отправляются посты с картинкой (может и не одной), либо видео и текстом. Предположим, стандартные новостные посты.

Нужно сделать так, чтобы при добавлении поста в телеграмм, он автоматически добавлялся в канал MAX. Также, неплохо бы добавить и обратную схему на случай блокировок (отправлять из MAX в телеграмм).

Немного вводных:

В этой статье мы не будем писать код, он уже написан и выложен мной на github.

Я буду объяснять структуру проекта, и как функционал работает. Также напишу, как правильно поднять все окружение и настроить каналы.

Для запуска проекта нужно:

  1. Бот в телеграмме с его токеном.
  2. Канал в телеграмме, в который наш бот добавлен администратором.
  3. Бот в MAX с полученным токеном.
  4. Канал в MAX, в который бот добавлен администратором.

Настройка

  • Мы создаем бота в телеграмм и добавляем его администратором в наш канал.
  • После добавления бота, нам необходимо узнать chat_id нашего канала (всегда будет отрицательным).
  • Создаем бота в MAX и получаем его токен.
  • Аналогично телеграмму, создаем канал в MAX, добавляем туда бота и делаем его администратором.
  • В файле bots_config.py добавляем строки с токенами ботов и ID групп.

Отправка сообщений

В файле message_sender.py хранится две функции: для отправки сообщения в MAX и в телеграмм.

Отправлять сообщения в MAX будет тг бот, и наоборот соответственно.

  • Отправка в MAX

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

В функцию будет приходить текст, список вложений и ID группы в MAX.

-2

Благодаря структуре сообщений в MAX, все просто и лаконично.

  • Отправка в телеграмм

С телеграммом немного сложнее: текст сообщения (caption) должен прикрепляться именно к первой картинке, и только к ней. Поэтому нам необходимо отлавливать этот момент.

Также, если мы потом захотим дополнительно обрабатывать и видео, нужно будет дописать отдельное условие на него, т.к. вместо InputMediaPhoto придется использовать InputMediaVideo.

-3

В остальном, логика та же: мы принимаем текст, список вложений и ID группы.

Бот MAX

Бот состоит всего из одной функции:

-4

Давайте разбираться, как это работает.

  • @dp.message_created(F.chat.chat_id == max_group_id) - декоратор, который обрабатывает сообщения только из указанной группы.
  • event.message.body.attachments - список вложений в полученном сообщении. Если у сообщения не будет вложений - вернет пустой список.
  • match attach.type - проверка вложений по типу файла (если необходимо скачивать и видео - достаточно добавить:
case 'video':
file_name = f'{attach.payload.token[0:15]}.mp4'
-5
  • send_tg_message() - вызывает написанную нами функцию отправки сообщения в телеграмм.

Бот в телеграмм

А теперь немного личной боли.

Уже не в первый раз я сталкиваюсь с обработкой сообщений с фото, видео и т.д. А в частности - с обработкой медиа групп (когда в сообщении приходит сразу несколько файлов). Проблема заключается в том, что медиа группа приходит не одним сообщением, а каждый файл прилетает отдельно. Как правильно это обрабатывать, я так и не придумал, да и смысла уже не особо много, поэтому использую решение с таймаутами.

Для работы с файлами нам понадобятся функции:

  • Скачивание ботом файла через API телеграмм
-6
  • Сохранение картинок и видео
-7
  • Получение списка файлов медиа группы
-8
  • Функция, обрабатывающая сообщения (расскажу на примере фото, видео идентично):
-9

@bot.message_handler(content_types=['photo', 'video']) - обработка сообщений, в которых прикреплено фото, либо видео.

if message.chat.id == tg_group_id - обработка сообщений только из нашего канала.

if message.media_group_id is not None - если мы видим, что у полученного сообщения есть тег медиа группы.

save_image(f"{fileid}_{message.media_group_id}", downloaded_file) - сохраняем картинку с тегом медиа группы в названии.

if message.caption is not None - и если у сообщения есть подпись (первое сообщение из медиа группы)

text = message.caption - запоминаем текст сообщения и ждем 10 секунд (надеемся, что за это время дойдут и остальные сообщения, в случае больших задержек - увеличьте таймаут до 20-30 сек.)

list_of_files = get_list_of_files(message.media_group_id) - ищем все файлы в папке с тегом медиа группы в названии и формируем из них список.

asyncio.run(send_max_message(chat_id=max_group_id, message=text, attach=list_of_files)) - Отправляем сообщение в MAX.

-10

Если же нам пришло сообщение без тега медиа группы, сразу обрабатываем его и передаем дальше на отправку в MAX.

Весь проект выложен здесь. Можете свободно использовать его для своих нужд. При необходимости - доработайте под себя, а все вопросы задавайте в комментариях, по возможности с радостью отвечу.