Кальтер / Блог

Webhook или long polling для Telegram-бота: как выбрать

Сравнение webhook и long polling для Telegram-бота: инфраструктура, получение updates, подтверждение и проверка запросов.

Материал подготовлен с помощью ИИ; источники и расчёты проверены редакцией ZASLON.

При webhook Telegram отправляет событие на сервер, при long polling сервер бота запрашивает обновления у Telegram.
Редакционная схема ZASLON. Условная иллюстрация процесса, не скриншот сервиса.

Для Telegram-бота выбирай long polling, если бот сам запрашивает updates; выбирай webhook, если Telegram отправляет события на настроенный URL. На hosted Bot API эти режимы взаимоисключающие: активный webhook мешает getUpdates. При любом транспорте проектируй дедупликацию отдельно, потому что повторная доставка возможна.

Официальные требования сверяй по Bot API и Bot FAQ: список допустимых портов и параметры могут меняться. По текущей документации hosted API хранит updates не дольше 24 часов, поэтому долговременное хранение и очередь должны быть частью твоего бота.

Сравнение hosted Bot API

Long polling Webhook
Кто открывает соединение Процесс бота делает getUpdates Telegram отправляет POST на endpoint
Входящий публичный адрес Не нужен; достаточно исходящего соединения Нужен доступный HTTPS URL
Где обычно работает Постоянный процесс на сервере или VM Serverless-функция или web service
Подтверждение Следующий offset выше последнего обработанного update_id Endpoint подтверждает принятый update успешным HTTP-ответом
Частая причина молчания Неверный offset или второй poller TLS, неправильный URL, редирект или ошибка endpoint

Сначала сохрани update, потом делай действие

update_id помогает распознать повтор, но сам по себе не гарантирует exactly-once для внешнего эффекта. Для polling не двигай offset вперёд до надёжного сохранения update: при раннем подтверждении сбой может потерять событие; при позднем оно может прийти повторно.

Рабочая схема: транзакционно записать update_id с уникальным ограничением и положить задачу в durable queue. Если такой ID уже есть, не создавай вторую задачу. Worker выполняет внешнее действие с его собственным idempotency key, если поставщик его поддерживает, и отмечает событие обработанным. Если внешний сервис не поддерживает идемпотентность, возможна неопределённость после сбоя между действием и сохранением статуса; предусмотрите проверку состояния или ручную сверку.

Webhook Telegram может быть повторён после неуспешного ответа. Для hosted API настрой secret_token и проверяй заголовок X-Telegram-Bot-Api-Secret-Token до передачи payload обработчику. Не клади секрет в URL и не пиши его в лог. Очередь должна надёжно принять update до успешного ответа endpoint, иначе процесс может потерять его уже после подтверждения.

Как выбрать и диагностировать

  • Если у тебя уже есть постоянно работающий сервер, polling часто проще для первого запуска.
  • Если есть HTTPS endpoint и событийная платформа, webhook может быть естественнее.
  • Для локальной разработки без публичного URL используй polling к hosted API.
  • Для высокой нагрузки сначала спроектируй durable queue, идемпотентность и мониторинг: смена транспорта не решит эти задачи.

Если бот молчит, проверь:

  1. Токен нужного бота, не выводя его в лог.
  2. getWebhookInfo: URL, pending count и последнюю ошибку, если включён webhook.
  3. Не конфликтуют ли webhook и getUpdates; запущен ли один poller.
  4. Корректен ли offset и есть ли у бота доступ к конкретному типу события/чату.
  5. Проходит ли одно безопасное тестовое событие от входа до записи в БД.

Bot API не даёт боту произвольно выгрузить всю историю канала: updates — отдельная модель доставки событий, а не архив прошлых сообщений.

Переключение транспорта

Перед сменой режима сохрани результат getWebhookInfo и оцени очередь. setWebhook принимает drop_pending_updates; этот параметр намеренно удаляет ожидающие события, поэтому не включай его как способ «починить очередь». Для возврата к polling сначала вызови deleteWebhook, затем проверь, что getUpdates получает ожидающие updates.

Явно задавай allowed_updates, если набор типов важен. Если параметр не передать, Telegram может сохранить предыдущую настройку; её изменение также не отменяет уже созданные события. Переключайся в окно, когда можешь проверить тестовое событие и ошибки доставки.

Когда нужен свой Bot API server

Стандартный hosted API находится на api.telegram.org; для webhook ему нужен HTTPS endpoint без редиректов. Отдельный self-hosted Local Bot API Server нужен лишь при конкретной потребности. Его документация допускает для webhook HTTP URL, local IP и произвольный порт; это свойства собственного сервера Bot API, а не стандартного hosted API. В этом режиме ты также отвечаешь за обновления, сетевую доступность и сопровождение отдельного runtime.

Не путай «локальный процесс бота», который ходит в hosted API через polling, со своим Bot API server. Для обработки недоверенного текста через ИИ смотри материал о prompt injection; разработка ботов и интеграций — в MK Ultra.