1) Проверьте токен у BotFather и /setcommands, /setprivacy. 2) Оставьте один канал апдейтов: webhook или polling (409 = включены оба). 3) Снимите показания getWebhookInfo — last_error_message пуст, хук даёт 200 OK < 10 c, без 301/302. 4) Проверьте права в чате и форму вызова /cmd@YourBot в группе. 5) Включите логи update_id, chat_id, type, handler, duration_ms, reply_status и повторите тест в PM и в тестовой группе. 6) Если «тихо» — временно включите polling и ищите сеть/TLS/обработчик.
Когда все проверки пройдены и бот стабильно отвечает, прогоните воронку на реальных пользователях малыми волнами трафика. Накрутка подписчиков тг Украина поможет быстро дать первичный поток для замера p95 ответа, error rate, CTR команд и конверсии в целевое действие. Подавайте равномерно 30-60 минут, сравните метрики до и после и зафиксируйте безопасный темп.
Откройте BotFather и убедитесь, что токен актуален и вы не делали недавно /revoke (отзыв токена). Сверьте /setcommands и нужный scope (по умолчанию/для групп/для лички) с тем, что реально зашито в коде. Проверьте /setprivacy: Enabled, если бот работает только по командам, Disabled, если читает обычные сообщения. В моей практике «немоту» бота в 3 кейсах из 10 решал именно этот блок.
У бота должен быть один способ приёма событий: либо webhook (веб-хук), либо long polling (опрос). Одновременный запуск даёт 409 Conflict и дубли, поэтому снимите лишний канал перед тестом. Для polling сначала вызовите deleteWebhook?drop_pending_updates=true, для веб-хука остановите поллер. «Мой быстрый тест»: убрать один канал, проверить, исчезли ли дубли.
Выполните getWebhookInfo и проверьте url, last_error_message, ip_address. Ошибки TLS/timeout/wrong response лечатся на стороне сети/сертификата/обработчика; ответ сервера должен быть 200 OK быстро (лучше до 2 секунд, максимум 10). Без редиректов и HTML-страниц вместо JSON. Я всегда снимаю веб-хук с drop_pending_updates и ставлю заново после фикса.
Пример запроса и типичного ответа (last_error_message заполнен):
curl -s https://api.telegram.org/bot$TOKEN/getWebhookInfo | jq .{
"ok": true,
"result": {
"url": "https://your.domain/bot-hook",
"has_custom_certificate": false,
"ip_address": "149.154.xx.yy",
"pending_update_count": 12,
"last_error_date": 1731085200,
"last_error_message": "SSL routines: certificate verify failed",
"max_connections": 40
}
}Ожидание «после фикса»: last_error_message отсутствует/пуст, pending_update_count → 0, хук стабильно отвечает 200 OK < 2 c.
В личке пользователь должен начать диалог, иначе 403 Forbidden. В группе при включённом Privacy Mode команда вызывается как /cmd@YourBot, иначе бот её не увидит. Проверьте права «писать/медиа/закреплять/удалять» и роль админа там, где это нужно. Один чек прав часто экономит час дебага.
Отправьте /start в личку и ту же команду в чистую «песочницу» без ограничений. Включите расширенный лог: update_id, chat_id, type, handler, duration_ms, reply_status. Если апдейтов нет вовсе – ищите доставку (webhook/polling/TLS), если есть – смотрите логику/права. Этот «перекрёстный тест» стабильно показывает, где болит.
Пользователь не писал первым, бот заблокирован или 403 на sendMessage. Попросите пользователя нажать /start и обработайте 403 без ретраев (не спамьте повторно). Проверьте, нет ли лимита по частоте 429: включите бэкофф и очереди. В моих кейсах это закрывало 8 из 10 «тишин» в PM.
Включён Privacy Mode, и команда без упоминания не видна, либо у бота нет прав писать. В канале постить можно только с правами администратора, это правило платформы. Проверьте ограничения супергруппы: slow mode, антиспам, запреты на ссылки/медиа. Тест в песочнице сразу отделяет политику группы от проблем кода.
Проверьте, подписан ли хэндлер на callback_query и не превышена ли длина callback_data. Экранируйте Markdown/HTML в кнопках и убедитесь, что Content-Type корректный. Посмотрите логи: приходит ли update.callback_query и что с ответом на edit/answerCallbackQuery. Часто проблема не в «кнопках», а в валидации payload.
Смотрите на 429 Too Many Requests, очередь сообщений и количество параллельных воркеров. Дубли лечатся идемпотентностью (без повторной обработки) и хранением last_update_id. Задержки – это лимиты, длинные операции в хэндлере или медленный апстрим. Вынесите тяжёлое в фон и ограничьте параллелизм.
После /revoke старый ключ мёртв сразу – обновите секреты в env/CI/CD и перезапустите процессы. Сверьте, нет ли «застрявших» контейнеров со старым токеном. Проверьте, что вы используете верный токен в staging/prod (бывает путаница). В моей практике рассинхрон токенов ломал бота на часы без единой ошибки в логах.
Если нужно читать обычные сообщения в группе, отключите /setprivacy (Disabled) и добавьте фильтры по чатам/ролям. Иначе используйте только команды и инлайн, а в группе всегда вызывайте /cmd@YourBot. Это прозрачно для пользователей и предсказуемо для вас. Я всегда документирую форму вызова команды в README.
Поддерживайте команды раздельно для лички и групп через scope у BotFather. Следите за локалями описаний, иначе клиенты не подсказывают команды. Проверяйте, что названия совпадают с кодом и что у бота есть права для команд, которые предполагают постинг/удаление. Это мелочи, но они часто «роняют» функциональность.
Два канала одновременно приводят к 409 Conflict и дублям. Держите единственную точку приёма апдейтов и уберите гонки между инстансами. Зафиксируйте в .env переменную UPDATES_MODE=webhook|polling и валидируйте её при релизе. Это сбережёт время и нервы.
Регистрируйте веб-хук на публичном HTTPS-домене и проверяйте getWebhookInfo после включения. Поле last_error_message должно быть пустым; ответ сервера 200 OK без редиректов. При миграциях снимайте хвост drop_pending_updates=true, чтобы не получить лавину старых апдейтов. «Мой порядок»: health → setWebhook → контроль getWebhookInfo.
Для отладки снимите веб-хук и включите polling с timeout 25–30 секунд. Храните last_update_id и сдвигайте offset на +1, чтобы не ловить дубли. После фикса верните веб-хук и выключите поллер на всех инстансах. Это исключает конфликт и делает поток событий предсказуемым.
Сертификат должен быть от публичного CA, с полной цепочкой (intermediate), корректным SNI (имя сервера в TLS) и CN/SAN (имя домена в сертификате). Просроченный, самоподписанный или неполный cert «глушит» веб-хук без явных ошибок в боте. Быстрая проверка одной командой:
echo | openssl s_client -servername your.domain -connect your.domain:443 -showcerts 2>/dev/null | openssl x509 -noout -issuer -subject -datesСверьте issuer/subject/dates и совпадение CN/SAN с доменом.
Проверьте, что reverse-proxy не делает 301/302 и не переписывает Host/SNI. Установите разумные timeouts, client_max_body_size и прокиньте real IP хедеры. Возвращайте 200 OK быстро и не шлите HTML-страницы вместо «пустого» ответа. Логи на уровне прокси сильно ускоряют поиск причин.
Сделайте /bot-hook/health, который возвращает 200 OK, версию билда и uptime. Логируйте время ответа (duration) и метки корреляции, чтобы ловить шипы. Пишите входящее тело апдейта в debug-лог, чтобы воспроизводить редкие события. Это превращает «мистику» в управляемую диагностику.
proxy_read_timeout 10s; proxy_connect_timeout 3s; — держите ответ до 10 c, не больше.certificate verify failed.Host, добавьте X-Request-Id для трассировки.Сделайте /bot-hook/health, который возвращает 200 OK, версию билда и uptime. Логируйте время ответа (duration) и метки корреляции, чтобы ловить шипы. Пишите входящее тело апдейта в debug-лог, чтобы воспроизводить редкие события. Это превращает «мистику» в управляемую диагностику.
Задайте timeout=25–30 и храните last_update_id, двигая offset на +1. Следите за limit, чтобы не крутить пустые запросы и не упираться в лимиты. Такой режим устойчив и экономит трафик. На проде polling — временная мера, но для отладки он идеален.
Не допускайте двух поллеров на один токен — это дубли и гонки. Отмечайте обработанные update_id (таблица/Redis) и держите хэндлеры идемпотентными (повтор безопасен). Любые побочные эффекты (платёж, начисление) — только после отметки «обработано». Это контора, которая экономит вам деньги.
Проверяйте таймауты HTTP-клиента и прокси, включайте бэкофф и ретраи для временных сбоев. Разрешите исходящие к api.telegram.org:443 и проверьте MTU, если сеть «рвётся». Если провайдер режет трафик, переходите на веб-хук и мониторьте время ответа. Этот блок часто недооценивают, а зря.
Без прав «писать/медиа/закреплять» бот в группе будет «молчать», даже если код верный. Супергруппы добавляют slow mode и антиспам, которые визуально «глушат» активность. Дайте боту нужные права и протестируйте в песочнице. В моих проектах это была самая быстрая победа.
403 на sendMessage означает «заблокирован» или чат приватный. Не ретратьте в этот диалог — это тратит лимиты и раздражает. Сделайте FAQ «как написать боту в личку» и просите пользователя начать чат первым. Это снижает жалобы и повышает доверие.
В канал бот публикует только как админ — это не баг, а правило платформы. Включите обсуждения, если нужен диалог под постом, и убедитесь, что у бота есть право писать в связанную группу. Проверьте ограничения на ссылки/медиа, чтобы посты не отскакивали. Эти шаги часто упускают в ТЗ, а потом удивляются «тишине».
Telegram не публикует точные числа для всех методов. Ниже — практические границы и рекомендации; сверяйте с официальной документацией.
| Область | Ориентир | Рекомендация |
|---|---|---|
| На чат | ~1–2 сообщения/сек | Группируйте ответы, не спамьте подряд |
| На бота | ~20–30 сообщений/сек | Ограничьте параллелизм, распределяйте нагрузку |
answerCallbackQuery | краткие ответы, частые | Не отправляйте «пустые» ответы, следите за частотой |
sendMediaGroup | тяжёлые медиа | Проверяйте размеры/тип, дайте буфер по времени |
Бэкофф с джиттером: base 0.5–1.5 s, умножать ×2 до 30 s, добавлять случайный джиттер. На 429 снижайте частоту и ставьте очередь.
Проверяйте Content-Type: application/json, длины полей и экранирование Markdown/HTML. Валидируйте эмодзи, RTL-текст и длинные подписи. Тестируйте крайние кейсы заранее — «тихие» 400 не очевидны. Это экономит ночные часы поддержки.
401 — неверный/отозванный токен (получите новый и обновите env). 403 — нет прав/пользователь заблокировал (не ретратьте, попросите написать первым). Сопровождайте эти коды понятными ответами пользователю и логами для команды. Честная обработка ошибок повышает траст.
409 — одновременно включены polling и веб-хук (снимите один канал). 413 — файл слишком большой (сжимайте/режьте, отправляйте как документ). 429 — превышен лимит (очереди, бэкофф, снижение частоты и батчинг). 5xx — сбои апстрима (внешний шлюз/сервер), лечится ретраями и мониторингом времени ответа.
Добавьте глобальный перехват ошибок и перезапуск по watchdog. Фиксируйте падения и время обработки (duration_ms), чтобы видеть «узкие места». На внешних вызовах — таймауты и ретраи с джиттером; пользователь должен видеть дружелюбный ответ, а не молчание. Это базовая гигиена бота.
Сверьте список типов апдейтов: message/command, callback_query, inline_query, edited_message, channel_post. Добавьте заглушки и логи на неожиданные события — бот не должен «падать молча». По опыту, забытый callback_query — причина третьи кнопочных «поломок». Обновляйте схему по документации после релизов Telegram.
Не держите долгие операции в веб-хуке или поллере — выводите в очередь/воркеры. Ограничьте параллелизм и держите идемпотентность побочных действий (платёж/бонус). Измеряйте p95/p99 времени ответа и уводите тяжёлое «в фон». Так бот остаётся отзывчивым.
Сверьте валидность ключей, квоты и SLA партнёров. На 4xx/5xx применяйте «мягкую деградацию» и понятные тексты пользователю, а не молчание. Держите ссылки на статус-страницы провайдеров. Это экономит деньги и нервы.
Ставьте таймауты на HTTP-клиентах и ретраи по экспоненте с джиттером (base 0.5–1.5 s, умножать ×2 до 30 s). Включите circuit breaker (автовыключатель запросов) на нестабильных направлениях. Актуализируйте тексты при деградации, чтобы сохранить доверие. Я всегда держу этот middleware единым для всех внешних вызовов.
Валидируйте JSON/формы по схеме и экранируйте спецсимволы (sanitize/escape). Экранируйте Markdown/HTML и эмодзи в подписи/кнопках, проверяйте длины полей. Никогда не доверяйте «как в примере в интернете» — проверяйте. Это снимает «тихие» 400 и XSS-риски.
api.telegram.org:443 и статус‑страницам провайдеров.UPDATES_MODE=webhook|polling в .env, валидируйте на CI/CD, чтобы второй канал был выключен.Откройте исходящие к api.telegram.org:443 и входящие на порт веб-хука. Проверьте заголовки Host/SNI на прокси/Cloudflare и отсутствие редиректов. Белые списки IP Telegram иногда требуются у хостера — уточняйте. Трассировка и проверка MTU спасали мне недели поиска «призрачных» таймаутов.
Проверьте A/AAAA-записи и TTL, особенно после миграций. Несовместимость IPv6 вызывает таймауты у части клиентов — или включайте поддержку, или убирайте AAAA. Дождитесь распространения DNS перед включением веб-хука. Это простой шаг, который часто забывают.
Холодный старт функций убивает 200 OK — держите прогрев, повышайте memory/CPU и выносите тяжёлое в фон. Следите за глубиной очередей и временем обработки — это ранний индикатор проблемы. Задайте health и readiness-пробы, чтобы оркестратор не убивал здоровые воркеры. В проде это не роскошь, а необходимость.
| Симптом | Причина | Что проверить |
| Команда не срабатывает | Токен/команда/локаль | BotFather /token,/setcommands, scope |
| Нет апдейтов | Канал/веб-хук | getWebhookInfo, 200 OK, drop_pending_updates |
| Кнопка без ответа | callback не ловим | Подписка на callback, длина callback_data |
| Дубли событий | Два поллера/offset | Один поллер, last_update_id, идемпотентность |
| В группе «тихо» | Privacy/права | /setprivacy, права админа, форма /cmd@Bot |
| 409 Conflict | Два канала | Снять веб-хук или остановить polling |
| 429 задержки | Частота/лимит | Бэкофф, очереди, снижение частоты |
| 400/403 | JSON/права | Экранирование, длины полей, права в чате |
| Код/лимит | Описание | Действие | Раздел |
| 400 | Неверные параметры/Markdown | Валидация JSON/escape | Лимиты и форматы |
| 401 | Неверный/отозванный токен | Обновить токен/env | Токен и BotFather |
| 403 | Нет прав/PM запрещён | Права/попросить написать первым | Права и доступы |
| 409 | Конфликт каналов | Отключить один канал | Канал апдейтов |
| 413 | Большой файл | Сжимать/резать | Лимиты и форматы |
| 429 | Превышен rate limit | Очереди/бэкофф | Лимиты и форматы |
| 5xx | Сбои апстрима | Ретраи/мониторинг | Сеть и инфраструктура |
Типовые фиксы (коротко): TLS — выложить intermediate и проверить SNI/CN; 409 — снять один канал (deleteWebhook?drop_pending_updates=true) и оставить единственный приёмник; 429 — включить бэкофф+очереди и снизить частоту.
Сначала выясните, какой канал активен. Для веб-хука: getWebhookInfo → нет ли last_error_message, 200 OK без редиректов → проверка TLS/DNS. Для polling: один поллер, корректные offset/timeout → логи апдейтов. Если оба шага чистые — смотрим права и код.
Проверьте /setprivacy и форму вызова команды: /cmd@YourBot или reply. Убедитесь, что у бота есть права «писать/медиа/закреплять/удалять». Посмотрите политику супергруппы: slow mode/антиспам/запрет ботов. В песочнице проблема воспроизводится? Если нет — это настройки группы.
401 — перевыпустить токен и обновить env. 403 — права/блок в PM; отвечать дружелюбно и не ретратить. 429 — понизить частоту, включить очереди и экспоненциальный бэкофф с джиттером. 5xx — ретраи, мониторинг latencies, деградация функции без молчания.
Токен обновлён, /setcommands и /setprivacy соответствуют сценарию (личка/группа). Веб-хук даёт быстрый 200 OK, цепочка TLS полная, SNI/CN верные. Выбран один канал апдейтов и зафиксирован в .env/оркестраторе; второй выключен. Таймауты/лимиты/очереди/мониторинг включены.
Запишите активный режим (webhook или polling) и отключите второй. Включите расширенный лог апдейтов и ошибок, перезапустите воркеры/контейнер. Временно перейдите на polling, чтобы не терять события, и параллельно чините веб-хук/TLS/код. После фикса верните веб-хук и проверьте, что last_error_message пуст, p95 в норме.
Поставьте алерт на getWebhookInfo.last_error_message != "" (Slack/Email), отслеживайте p95 времени ответа и долю 5xx. Обновите README: матрица прав, порядок включения/переключения каналов, команды BotFather. Проведите ретро, зафиксируйте изменения в change log и проверьте чек-листы команды.
Скорее всего, в группе включён Privacy Mode или у бота нет прав писать/читать. Используйте форму /cmd@YourBot или отключите приватность, если нужен доступ к обычным сообщениям. Выдайте боту нужные права и повторите тест. Если в тестовой группе всё ок — причина в настройках целевой группы.
409 означает, что одновременно включены webhook и polling. Отключите один канал: deleteWebhook?drop_pending_updates=true или остановите поллер, оставив единственную точку приёма. Проверьте .env и процессы на инстансах, чтобы не было «забытых» поллеров. После фикса проверьте getWebhookInfo — ошибок быть не должно.
Проверьте подписку на callback_query, длину callback_data и экранирование Markdown/HTML. Логируйте входящие update.callback_query и ответ на answerCallbackQuery/editMessage. Если событие не приходит — проверяйте права, антиспам в группе и лимиты частоты. Это самые частые причины «молчания» кнопок.
Если last_error_message указывает на TLS/timeout/wrong response — лечите сеть/TLS/веб-сервер. Проверьте цепочку и SNI одной командой openssl s_client (пример выше), затем повторите getWebhookInfo. Если polling получает апдейты, а веб-хук — нет, код в большинстве случаев ни при чём. После фикса ошибка уходит за минуты.
Смотрите 429 и частоту вызовов методов — возможно, упёрлись в лимит. Проверьте глубину очередей и время обработки — это первые индикаторы узких мест. Включите бэкофф с джиттером (base 0.5–1.5 s, ×2 до 30 s) и ограничьте параллелизм. При необходимости масштабируйте воркеры и оптимизируйте блокирующие участки кода.