Перенос сообщений между чатами: опыт автоматизации в меcсенджере МАКС
Перенос постов между чатами через Bot API: как это работает
Практический разбор автоматизации: от подготовки бота до боевого переноса сотен сообщений с медиафайлами, а также обзор других полезных возможностей ботов мессенджера.
Задача
В мессенджере существует групповой чат, в котором за долгое время накопилось несколько сотен сообщений: текстовые заметки, фотографии, видео, аудио, пересланные публикации. Появилась необходимость перенести эти сообщения в отдельный канал — чтобы контент был собран в ленту новостей, удобную для подписчиков. Переносить вручную невозможно: сообщений много, часть содержит тяжёлые медиафайлы. Решение — написать программу-переносчик на базе официального Bot API мессенджера.
Что понадобилось для старта
- Бот с доступом к платформе. Чат-боты создаются через платформу для партнёров и работают от имени юридического лица или ИП. После создания и модерации выдаётся токен — ключ, который используется для всех запросов к API.
- Права администратора в обоих чатах. Чтобы читать историю сообщений и публиковать в канал, бот должен быть администратором группы-источника и канала-цели.
- Секретные данные строго изолированы. Токен хранится в отдельном конфигурационном файле, который не попадает в репозиторий и не выводится в логи.
Архитектура запросов к API
Все операции выполняются через HTTP-запросы к единому адресу платформы. Авторизация — заголовок:
Authorization: <токен бота>
Основные методы, задействованные в переносе:
| Метод | Назначение |
|---|---|
GET /chats | Получить список доступных боту чатов (групп, каналов) с их идентификаторами. |
GET /chats/{id} | Узнать права бота в конкретном чате, количество участников. |
GET /messages | Прочитать историю сообщений с пагинацией и фильтрами по времени. |
POST /uploads | Загрузить медиафайл и получить токен для его повторного использования. |
POST /messages | Опубликовать текстовое сообщение или сообщение с вложениями. |
DELETE /messages | Удалить сообщение по его идентификатору. |
Структура сообщения
Каждое сообщение в истории содержит время публикации, отправителя и тело. Тело — это объект с текстом и списком вложений. У вложений есть тип (изображение, видео, аудио, файл, стикер, пересланная ссылка) и «токен» — идентификатор уже загруженного медиа.
{
"timestamp": 1760000000000,
"sender": { "user_id": "...", "name": "..." },
"body": {
"text": "Текст сообщения",
"attachments": [
{ "type": "image", "payload": { "token": "...", "url": "..." } }
]
}
}
Подготовка бота и проверка прав
Перед запуском было реализовано несколько проверок, которые позволяют не тратить время впустую и сразу видеть готовность окружения:
- Проверка аутентификации токена.
- Проверка чтения из группы-источника: бот должен быть администратором, иначе история недоступна.
- Проверка чтения из канала-цели.
- Проверка наличия бота в списке администраторов канала.
- Тестовая публикация: единственная ошибка, которая на этом этапе допустима, — отсутствие права записи в канале.
--check, чтобы окружение можно было проверять быстро и часто, не перечитывая весь код.
Чтение истории: пагинация и сортировка
API отдаёт историю порциями — по 100 сообщений за запрос. Новые сообщения возвращаются первыми, поэтому для обхода всей истории используется курсор: после каждой порции фиксируется время самого старого сообщения, и следующая порция запрашивается «до этого времени». Цикл продолжается, пока порция не окажется пустой.
while True:
page = get_messages(chat, count=100, before=course)
if not page: break
all_messages.extend(page)
course = min(ts for m in page) - 1
Для переноса важно сохранить хронологический порядок: сообщения должны встать в канале так же, как стояли в исходном чате. Для этого все сообщения собираются в память, сортируются по возрастанию времени и только затем публикуются. Без этой сортировки лента получилась бы «перевёрнутой» — первыми ушли бы самые свежие посты.
Извлечение контента: где лежит текст и вложения
Есть два типа сообщений, и их устройство различается:
- Обычное сообщение — текст и вложения лежат в поле
body. - Пересланное сообщение — в теле может быть только заглушка, а сам контент (текст и медиа) лежит во вложенном объекте
link.message. Иногда цепочка пересылок вложена несколько уровней, и требуется рекурсивный поиск контента с ограничением глубины.
Именно второй случай — классическая ловушка для переносчика: если искать контент только в body, пересланные посты будут молча пропущены, а в логе появится расхождение между количеством сообщений в исходном чате и количеством опубликованных. По итогам отладки данные расхождения были обнаружены, логика извлечения исправлена, и пропущенные пересланные посты были доставлены отдельным повторным запуском.
Перенос медиафайлов
Вложения — самая требовательная часть. Механика выглядит так:
- У вложения берётся ссылка на файл или его существующий токен.
- Файл скачивается, затем перезагружается через
POST /uploadsпод ботом. - На ответе приходит свежий токен, который используется при публикации поста.
Оптимизация: если у вложения уже есть токен, повторная выгрузка не выполняется — токен переиспользуется. Это в разы ускоряет перенос серии постов с одинаковыми вложениями.
Ограничения платформы, которые учтены в коде:
- не более 12 вложений на одно сообщение;
- текст не длиннее нескольких тысяч символов;
- примерно 2 сообщения в секунду на чат — между публикациями вставлена задержка;
- стикеры репостятся как изображения (скачивание и перезагрузка в тип «картинка»);
- пересланные ссылки (превью сайтов) не переносятся как отдельные вложения — их текст сохраняется, превью отбрасывается.
Алгоритм одного поста
def build_post(message):
text, atts = resolve_content(message)
attachments = [make_attachment(a) for a in atts]
# разбивка на несколько постов, если attachment > 12
return chunk(attachments)
def publish(post):
if reuse_tokens: post.attachments = reuse_existing_tokens(post)
else: post.attachments = [upload_media(a) for a in post]
r = POST /messages { chat_id, text, attachments }
time.sleep(0.6) # лимит ~2 сообщения/сек
Устойчивость и защита от дублей
Перенос выполняется не «одним махом», а с сохранением прогресса:
- После каждого сообщения его идентификатор записывается в файл состояния.
- При следующем запуске те сообщения, что уже в состоянии, пропускаются — продолжение идёт с места остановки.
- Если что-то прервалось (сбой сети, лимиты, ошибка загрузки медиа), повторный запуск не создаст дубликатов.
- Предусмотрен режим просмотра (сухой прогон): программа полностью «проигрывает» перенос, ничего не публикуя, и показывает, сколько постов будет создано и какие пропущены. Это позволяет до боевого запуска убедиться в корректности фильтров и порядка.
Фильтрация по отправителю
Возможность, оказавшаяся ключевой для практического использования. В конфигурации задаётся список идентификаторов авторов, и бот переносит только их сообщения:
- сообщения сторонних участников пропускаются и помечаются в состоянии как обработанные — чтобы при повторных запусках к ним не возвращаться;
- фильтр работает по внешнему отправителю: если участник переслал чужой пост, считается тот, кто переслал;
- это позволило отобрать, например, только сообщения владельца группы — около двух третей всего объёма контента.
Боевой запуск и проверка результата
После успешного сухого прогона состояние сбрасывается и выполняется боевой перенос:
- Все посты выбранного автора публикуются в канал в хронологическом порядке.
- По завершении запускается контролёр: читается вся история канала, подсчитывается количество сообщений и проверяется, что нет дубликатов.
- Дополнительно проверяется монотонность времени публикаций — лента должна быть упорядочена от старого к новому.
В рассматриваемом сценарии было перенесено около 540 постов с медиафайлами без единого дубля и без потери порядка. Отдельно подтверждена одна из «фирменных» особенностей задачи: команда полной очистки канала через DELETE /messages позволила безопасно перезапустить перенос с нуля, когда изменились требования к отбору контента.
Что ещё умеют такие боты
Перенос постов — лишь малая часть того, на что способен бот в этом мессенджере. На той же базе (токен, API, право публикации) реализуются и более широкие сценарии.
Публикация и управление контентом
- Регулярные рассылки и посты по расписанию: новости, анонсы, подборки — бот публикует в канал по таймеру совсем без участия человека.
- Репосты и архивирование: перенос контента между группами и каналами, сбор «лучшего» из нескольких источников в одну ленту, бэкап истории.
- Редактирование и удаление своих сообщений — исправление опечаток, замена медиа, снятие устаревших анонсов.
Взаимодействие с участниками
- Приветствие и онбординг: автоматическое сообщение новому участнику группы с правилами и полезными ссылками.
- Автоответы на ключевые слова: бот отвечает на типовые вопросы (цены, адреса, часы работы), снимая нагрузку с администраторов.
- Кнопки и меню: интерактивные клавиатуры — меню с разделами, кнопки «записаться», «подписаться», «проголосовать».
- Опросы и голосования при наличии соответствующего метода API.
- Приём от участников: бот анализирует входящие сообщения, принимает заявки, собирает заказы, контактные данные и обратную связь.
Управление каналом и группой
- Модерация: отслеживание новых сообщений, удаление нежелательных, ограничение спама.
- Структура доступа: чтение состава участников, проверка прав администраторов у бота, управление подписками (с оговоркой об ограничениях API для некоторых типов чатов).
Бизнес и интеграции
- Синхронизация с внешними системами: CRM, базы клиентов, рассылки из маркетинговых платформ — токен бота используется как «мост» для доставки уведомлений в мессенджер.
- Онлайн-заказы и услуги: мини-приложения, подключаемые к боту, позволяют принимать заказы, оплату и брони без ухода из диалога.
- Уведомления о событиях: статусы заказов, напоминания о записи, триггеры из внешних сервисов.
- Рассылки подтверждённым контактам — доставка сообщений в личные диалоги подписчиков по заранее собранной базе (в рамках правил платформы).
- Цифровой ID: для организаций доступна проверка возраста и льготных статусов — идентификация подписчиков прямо внутри сценариев бота.
Инженерные возможности
- Устойчивость: повторные попытки при таймаутах, задержки по лимитам, логирование и контрольный аудит результатов.
- Режимы безопасного запуска: «сухой прогон», тестирование на копии канала, проверка прав перед боевой операцией.
- Масштабирование: тот же принцип переноса легко расширить на произвольное число источников и каналов — достаточно параметризовать конфигурацию.
Выводы
Перенос постов между чатами мессенджера на Bot API — задача, которая на первый взгляд кажется простой, но на практике требует внимания к деталям: разной структуре обычных и пересланных сообщений, лимитам на вложения и частоту запросов, сохранению хронологии и защите от дублей. Главные уроки проекта:
- проверяйте права бота до начала боевых операций;
- считайте ожидаемый результат и сверяйте его с фактическим после каждого запуска;
- всегда отвечайте на вопрос «сколько должно было получиться и почему другой результат» — так были найдены скрытые пропуски пересланных постов;
- сухой прогон и файл состояния — дешёвый способ избежать дорогих ошибок.
А дальше всё зависит от бизнес-задачи: тот же бот превращается из «переносчика» в полноценный инструмент коммуникации — от рассылок и автоответов до онбординга и интеграций с внешними системами.
Материал основан на практическом опыте автоматизации переноса контента в мессенджере: названия чатов, личные данные и идентификаторы участников намеренно не упоминаются.