Кто виноват: чат или аккаунт

Рассылка встала, в отчёте — сотни «забаненных чатов». Кажется, что площадки закрылись и надо искать новые. На деле чаще происходит обратное: с чатами всё в порядке, а список целей вы только что вычеркнули из-за нескольких больных аккаунтов. Разбираем, почему эту ошибку так легко сделать и как её ловить.

У любой рассылки по чатам есть один вопрос, от ответа на который зависит всё остальное: кто виноват в том, что сообщение не ушло — чат или аккаунт?

  • Приняли больной аккаунт за плохие чаты — вычеркнули из работы десятки и сотни живых площадок, в которые остальные ваши аккаунты пишут совершенно спокойно. Настоящая причина при этом осталась нетронутой: тот же аккаунт пойдёт дальше и «забанится» в каждом следующем чате по списку.
  • Приняли плохой чат за проблему аккаунта — сняли с работы здоровый аккаунт и полезли чинить то, что не сломано, пока чат продолжает молча отбивать отправки.

Первая ошибка дороже. Она умеет за один проход парализовать всю кампанию.

Почему это трудно: ошибка приходит не о том, о чём кажется

Ловушка первая: название ошибки прямо провоцирует ошибку

Существует ошибка Telegram, которая называется USER_BANNED_IN_CHANNEL. Прочтите название ещё раз: «пользователь забанен в канале». Любой разработчик, увидев её в ответ на отправку в чат, запишет чат в проблемные — название не оставляет вариантов.

А означает она другое. Дословный текст Telegram: «You're limited from sending messages in supergroups/channels» — то есть аккаунт ограничен в супергруппах вообще. Ни один конкретный чат в этом не виноват.

Дальше происходит цепная реакция. Ограниченный аккаунт идёт по списку и получает эту ошибку в каждом чате подряд. Если считать её свойством чата, то за один круг вы своими руками закроете весь список целей — и чем больше у аккаунта чатов, тем масштабнее разрушение.

Ловушка вторая: две разные беды начинаются одинаковыми словами

Есть медленный режим чата — «в этом чате можно писать раз в N секунд». И есть ограничение темпа для аккаунта — «ты слишком частишь, подожди». Первое про чат, второе про аккаунт, реакции на них должны быть противоположными.

Их текстовые сообщения начинаются буквально одними и теми же словами: «A wait of N seconds is required…». Различает их только код ошибки. Отсюда правило, которое стоило нам отдельного разбора: ошибки опознаются по идентификатору, а не по тексту. Разбор по словам однажды записал медленный режим чата во флуд аккаунта — и это ровно та же подмена, только в другую сторону.

Ловушка третья: число в тексте — не всегда секунды

В ответе Telegram встречается конструкция вида [420 FLOOD_WAIT_X]. Здесь 420 — код ошибки, а не время ожидания. Соблазн выдернуть из текста первое попавшееся число велик, и он приводит либо к абсурдной паузе, либо к «аккаунт ограничен до 1970 года».

У нас поэтому голое число не берётся вовсе: время достаётся только из осмысленных конструкций («120 seconds», «FloodWait: 120 сек», «Повтор через 120 секунд»), а если ничего не нашлось — честный ноль, и вызывающий берёт своё умолчание. Выдуманная пауза хуже честного нуля.

Решение: один разборщик и жёсткий порядок вопросов

Раньше каждый модуль решал сам, что значит ошибка, и решал по-своему. Сетевой таймаут записывался как «сессия умерла», ограничение аккаунта — как сотня плохих чатов. Сейчас разбор один на всех, и его вывод состоит из двух частей: к чему относится ошибка (аккаунт · сессия · чат · связь · таймер · наше внутреннее · неизвестное) и что именно случилось.

Порядок проверок не косметический — он и есть защита от подмены:

  1. Наши собственные служебные сообщения — «аккаунт занят другой задачей» ошибкой Telegram не является вовсе.
  2. Заморозка аккаунта — терминальное состояние, дальше можно не смотреть.
  3. Аккаунт удалён или забанен — тоже терминально.
  4. Сессия недействительна — лечится только повторным входом.
  5. Ограничение аккаунта — включая ту самую ошибку с обманчивым названием.
  6. Таймеры — медленный режим чата и просьба подождать.
  7. И только теперь — свойства чата: запрет записи, только для админов, не участник, чат стал приватным, платные сообщения.
  8. Связь — проверяется последней намеренно: слово «connect» попадается и в текстах телеграмных ошибок, а те к этому моменту уже разобраны.

Читать этот список надо так: прежде чем обвинить чат, исключи всё, что может быть про аккаунт. Именно поэтому свойства чата стоят почти в самом низу.

Что из этого следует для карантина

Карантин — это механизм «сюда пока не ходим». Возвращаться в чат, который отбивает отправки, на каждом круге — то есть при каждом новом проходе аккаунта по своему списку чатов — бессмысленно и заметно.

Первое, что стоит понять про него: откладывается пара «этот аккаунт → этот чат», а не чат целиком. Если чат закрылся для одного аккаунта, остальные продолжают туда писать как писали. Чат не «вычёркивается из списка» — он остаётся доступен всем, кому в нём рады.

Второе: список причин, по которым карантин вообще ставится, короткий и белый — то есть перечислено то, что можно, а не то, что нельзя.

ПричинаНа сколько откладывается пара
Чат включил платные сообщениянасовсем — само это не пройдёт, пока владелец не снимет карантин руками
В чат нельзя писать: запрет записи, только админам, не участник, чат стал приватным7 суток — лечится вступлением заново или снятием запрета
Медленный режимровно столько, сколько назвал Telegram

Всё остальное проходит мимо карантина: ограничение аккаунта, мёртвая сессия, обрыв связи, пауза по темпу. И отдельно — непонятное. Это намеренное решение: «не знаю, что случилось» — не повод закрыть чат на неделю.

Медленный режим в этом списке единственный таймер, и он тут по делу: ждать действительно придётся, но именно в этом чате — соседние работают как работали.

Пояс поверх подтяжек

Даже после того как разбор ошибок стал общим, в карантине оставлена отдельная проверка: если ошибка относится к аккаунту, сессии или связи — не откладывать, точка. Она дублирует логику, которая и так должна сработать выше.

Это не перестраховка ради красоты. Однажды перепутанные названия исходов уже стоили кампании; вторая проверка стоит одной строки и делает подмену невозможной, даже если кто-то ошибётся в первой.

Где карантина нет вообще — и это тоже решение

  • Там, где пишут людям, а не в чаты (личные сообщения, работа с пойманными лидами): отказ там про человека, и у этих модулей свои счётчики попыток.
  • В прогреве: он работает в ваших собственных чатах, откладывать нечего.
  • Там, где только читают — поиск каналов, слушатели чатов.
  • В копировании каналов: там один приёмник на всю задачу, и его отказ означает, что встала вся задача. Отложить пару здесь значило бы спрятать поломку от владельца вместо того, чтобы сказать о ней.

Три признака здоровья вместо одной паузы

Обратная сторона того же принципа. Если ошибка всё-таки про аккаунт, что с ним делать?

Раньше ответ был простой: поставить на паузу. Аккаунт замолкал — иногда до конца суток, иногда бессрочно, — а владелец видел молчание без объяснения. Сейчас машина не ставит пауз — она пишет три независимых признака: состояние сессии, наличие ограничения и состояние связи. Как они считаются и что показывают, описано на странице модуля «Живучесть». Каждый ставится своим источником и снимается своим.

Правило, которое из этого выросло: пауза — решение человека, машина пишет диагноз, а не приговор. И второе, не менее важное: что поставлено автоматически, то автоматически и снимается. Единственное исключение — заморозка: она терминальна, восстановления в продукте нет, и делать вид, что оно есть, мы не будем.

Отдельная мелочь того же ряда: если проверить карантин почему-то не удалось, ответ — «не мешаем работать». Молчаливый запрет хуже лишней попытки: человек не поймёт, почему аккаунт простаивает, и будет искать поломку не там.

Честные границы

  • Сроки карантина заданы причиной, а не настройкой. Никакой «умной эскалации» вида «первый раз на час, второй на сутки» в продукте нет.
  • У рассылки исторически свои правила. Она пользовалась карантином раньше, чем он стал общим, и до сих пор кладёт пару на пять суток даже по неопознанной ошибке — то есть ведёт себя строже общей двери, которая неизвестное намеренно пропускает.
  • Срок, названный Telegram, хранится во внешнем хранилище и при его недоступности не переживает перезапуск контейнера.
  • У перехватов карантина нет — ни у перехвата вступивших, ни у перехвата по словам. Есть автопауза источника, и она по умолчанию выключена.
  • Заморозка терминальна. Мы не обещаем восстановление замороженных аккаунтов, потому что его нет.

Читайте дальше

практика

Заморозка, ограничение и «притормози»

разбор

Тысяча отправок за круг

Откуда факты. Порядок разбора ошибок, состав белого списка причин карантина, сроки (7 суток на запрет записи, срок Telegram на медленный режим, бессрочно на платные сообщения), отдельная проверка «ошибка про аккаунт — карантин не ставим» и три независимых признака здоровья — всё это работающий код, а не план. Конкретные числа прошлых разборов (сколько чатов уехало в карантин и по вине скольких аккаунтов) в тексте намеренно не приводятся: публиковать их мы будем только с разрешения владельца продукта.

Разделение вины — не функция, а фундамент

Один разбор ошибок на все модули: чат отвечает за своё, аккаунт за своё, связь за своё.