У любой рассылки по чатам есть один вопрос, от ответа на который зависит всё остальное: кто виноват в том, что сообщение не ушло — чат или аккаунт?
- Приняли больной аккаунт за плохие чаты — вычеркнули из работы десятки и сотни живых площадок, в которые остальные ваши аккаунты пишут совершенно спокойно. Настоящая причина при этом осталась нетронутой: тот же аккаунт пойдёт дальше и «забанится» в каждом следующем чате по списку.
- Приняли плохой чат за проблему аккаунта — сняли с работы здоровый аккаунт и полезли чинить то, что не сломано, пока чат продолжает молча отбивать отправки.
Первая ошибка дороже. Она умеет за один проход парализовать всю кампанию.
Почему это трудно: ошибка приходит не о том, о чём кажется
Ловушка первая: название ошибки прямо провоцирует ошибку
Существует ошибка 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 секунд»), а если ничего не нашлось — честный ноль, и вызывающий берёт своё умолчание. Выдуманная пауза хуже честного нуля.
Решение: один разборщик и жёсткий порядок вопросов
Раньше каждый модуль решал сам, что значит ошибка, и решал по-своему. Сетевой таймаут записывался как «сессия умерла», ограничение аккаунта — как сотня плохих чатов. Сейчас разбор один на всех, и его вывод состоит из двух частей: к чему относится ошибка (аккаунт · сессия · чат · связь · таймер · наше внутреннее · неизвестное) и что именно случилось.
Порядок проверок не косметический — он и есть защита от подмены:
- Наши собственные служебные сообщения — «аккаунт занят другой задачей» ошибкой Telegram не является вовсе.
- Заморозка аккаунта — терминальное состояние, дальше можно не смотреть.
- Аккаунт удалён или забанен — тоже терминально.
- Сессия недействительна — лечится только повторным входом.
- Ограничение аккаунта — включая ту самую ошибку с обманчивым названием.
- Таймеры — медленный режим чата и просьба подождать.
- И только теперь — свойства чата: запрет записи, только для админов, не участник, чат стал приватным, платные сообщения.
- Связь — проверяется последней намеренно: слово «connect» попадается и в текстах телеграмных ошибок, а те к этому моменту уже разобраны.
Читать этот список надо так: прежде чем обвинить чат, исключи всё, что может быть про аккаунт. Именно поэтому свойства чата стоят почти в самом низу.
Что из этого следует для карантина
Карантин — это механизм «сюда пока не ходим». Возвращаться в чат, который отбивает отправки, на каждом круге — то есть при каждом новом проходе аккаунта по своему списку чатов — бессмысленно и заметно.
Первое, что стоит понять про него: откладывается пара «этот аккаунт → этот чат», а не чат целиком. Если чат закрылся для одного аккаунта, остальные продолжают туда писать как писали. Чат не «вычёркивается из списка» — он остаётся доступен всем, кому в нём рады.
Второе: список причин, по которым карантин вообще ставится, короткий и белый — то есть перечислено то, что можно, а не то, что нельзя.
| Причина | На сколько откладывается пара |
|---|---|
| Чат включил платные сообщения | насовсем — само это не пройдёт, пока владелец не снимет карантин руками |
| В чат нельзя писать: запрет записи, только админам, не участник, чат стал приватным | 7 суток — лечится вступлением заново или снятием запрета |
| Медленный режим | ровно столько, сколько назвал Telegram |
Всё остальное проходит мимо карантина: ограничение аккаунта, мёртвая сессия, обрыв связи, пауза по темпу. И отдельно — непонятное. Это намеренное решение: «не знаю, что случилось» — не повод закрыть чат на неделю.
Медленный режим в этом списке единственный таймер, и он тут по делу: ждать действительно придётся, но именно в этом чате — соседние работают как работали.
Пояс поверх подтяжек
Даже после того как разбор ошибок стал общим, в карантине оставлена отдельная проверка: если ошибка относится к аккаунту, сессии или связи — не откладывать, точка. Она дублирует логику, которая и так должна сработать выше.
Это не перестраховка ради красоты. Однажды перепутанные названия исходов уже стоили кампании; вторая проверка стоит одной строки и делает подмену невозможной, даже если кто-то ошибётся в первой.
Где карантина нет вообще — и это тоже решение
- Там, где пишут людям, а не в чаты (личные сообщения, работа с пойманными лидами): отказ там про человека, и у этих модулей свои счётчики попыток.
- В прогреве: он работает в ваших собственных чатах, откладывать нечего.
- Там, где только читают — поиск каналов, слушатели чатов.
- В копировании каналов: там один приёмник на всю задачу, и его отказ означает, что встала вся задача. Отложить пару здесь значило бы спрятать поломку от владельца вместо того, чтобы сказать о ней.
Три признака здоровья вместо одной паузы
Обратная сторона того же принципа. Если ошибка всё-таки про аккаунт, что с ним делать?
Раньше ответ был простой: поставить на паузу. Аккаунт замолкал — иногда до конца суток, иногда бессрочно, — а владелец видел молчание без объяснения. Сейчас машина не ставит пауз — она пишет три независимых признака: состояние сессии, наличие ограничения и состояние связи. Как они считаются и что показывают, описано на странице модуля «Живучесть». Каждый ставится своим источником и снимается своим.
Правило, которое из этого выросло: пауза — решение человека, машина пишет диагноз, а не приговор. И второе, не менее важное: что поставлено автоматически, то автоматически и снимается. Единственное исключение — заморозка: она терминальна, восстановления в продукте нет, и делать вид, что оно есть, мы не будем.
Отдельная мелочь того же ряда: если проверить карантин почему-то не удалось, ответ — «не мешаем работать». Молчаливый запрет хуже лишней попытки: человек не поймёт, почему аккаунт простаивает, и будет искать поломку не там.
Честные границы
- Сроки карантина заданы причиной, а не настройкой. Никакой «умной эскалации» вида «первый раз на час, второй на сутки» в продукте нет.
- У рассылки исторически свои правила. Она пользовалась карантином раньше, чем он стал общим, и до сих пор кладёт пару на пять суток даже по неопознанной ошибке — то есть ведёт себя строже общей двери, которая неизвестное намеренно пропускает.
- Срок, названный Telegram, хранится во внешнем хранилище и при его недоступности не переживает перезапуск контейнера.
- У перехватов карантина нет — ни у перехвата вступивших, ни у перехвата по словам. Есть автопауза источника, и она по умолчанию выключена.
- Заморозка терминальна. Мы не обещаем восстановление замороженных аккаунтов, потому что его нет.