Автоматизация каналов с авторизацией, альбомами и rate-limits

После того как модуль публикаций в соцсети доказал свою состоятельность, клиент захотел такую же связку для своих каналов в мессенджере. Паттерн похожий — десятки каналов, регулярное расписание, контент из публичных лент, — но платформа под капотом устроена принципиально иначе. Там, где у соцсети простой API с app-level токенами, мессенджер требует полноценной авторизации пользовательского аккаунта. Это меняет всё: ты постишь не как приложение, а как человек, а значит приходится иметь дело с подтверждением по номеру телефона, кодами двухфакторки, управлением сессиями и всеми ограничениями, которые сопутствуют попыткам выдать бота за человека.

Стек

  • Next.js 14
  • Telegram
  • PostgreSQL
  • Node.js

процесс авторизации

Авторизация — многошаговый визард в админ-панели платформы. Оператор добавляет аккаунт, вводя номер телефона; система инициирует вход по протоколу MTProto и ждёт код подтверждения. Оператор вводит код (и пароль 2FA, если он включён), и система сохраняет авторизованную сессию. Сессии переживают рестарты сервера, но истекают непредсказуемо — иногда через недели, иногда через дни, если платформа замечает необычную активность. Сделали автоматические проверки здоровья сессий: тестируют способность каждого аккаунта прочитать собственный профиль. Если сессия умирает, аккаунт помечается, оператор получает оповещение пройти авторизацию заново, а планировщик тем временем тихо перераспределяет каналы этого аккаунта на другие.

альбомы и медиагруппы

Парсинг контента стал вторым крупным вызовом. Каналы репостят медиа-тяжёлый контент — фотоальбомы, видео с подписями, смешанные медиагруппы. API мессенджера трактует медиагруппу (альбом) как набор отдельно отправленных сообщений с общим group ID, и отправлять их надо вместе, одним API-вызовом и в определённом порядке. Если отправить их по одному, они появятся как отдельные посты, а не как аккуратный альбом. Наш парсер находит медиагруппы в исходном контенте, сохраняет их структуру и порядок, а движок публикации отправляет их атомарными пачками. Чтобы это заработало корректно, понадобилось несколько итераций: краевые случаи вроде альбомов со смешанными фото и видео или альбомов, где у одного элемента есть подпись, а у других нет, потребовали отдельной обработки.

адаптивный троттлинг

Лимиты на этой платформе строгие и непрозрачные. Никакого опубликованного rate-limit-заголовка — ты просто начинаешь получать flood-wait-ошибки с указанием подождать N секунд. Время ожидания эскалируется: сначала 15 секунд, потом минута, потом 10 минут, и в итоге аккаунт получает временное ограничение. Адаптивный троттлинг отслеживает flood-wait-ответы по каждому аккаунту, динамически подстраивает интервалы публикаций и распределяет нагрузку между аккаунтами, чтобы держаться сильно ниже порога. Система целится примерно в 70% от расчётно безопасной скорости, оставляя запас на пики.

планировщик и bin packing

Планировщик использует ту же календарную модель, что и модуль соцсети, — слоты на каждый канал, автоматическое распределение контента, возможность ручной правки, — но с более жёсткими ограничениями. Каждый аккаунт может вести только ограниченное число каналов, прежде чем частота публикаций упрётся в ограничения, поэтому системе нужно решать задачу bin packing: распределить каналы по аккаунтам так, чтобы ни один не превышал свою безопасную скорость публикаций. При добавлении или удалении аккаунтов распределение автоматически пересчитывается.

результаты

Система ведёт 25+ каналов с ежедневной автоматической публикацией, а повторная авторизация случается примерно один-два раза в неделю на все аккаунты — неприятно, но с оповещениями вполне переносимо. Каждое взаимодействие с платформой спроектировано как восстановимая операция: упало — залогируй причину, отступи и попробуй ещё раз с другим аккаунтом.