🤖
Хостинг

Telegram-бот: webhook или polling — что выбрать

08.11.2026
← Все статьи

Каждый, кто пишет Telegram-бота, рано или поздно сталкивается с вопросом: как бот должен получать сообщения пользователей? Telegram Bot API предлагает два пути. Первый — polling, когда бот сам постоянно спрашивает сервер Telegram, нет ли новых сообщений. Второй — webhook, когда Telegram сам отправляет каждое новое обновление на адрес вашего сервера. Оба способа надёжны, но предъявляют разные требования к серверу, сети и архитектуре приложения.

Как работает polling

При polling бот регулярно вызывает метод getUpdates. На практике почти все библиотеки используют long polling: запрос отправляется с параметром timeout, и Telegram удерживает ответ, пока не придёт новое сообщение или не истечёт время. Благодаря этому бот не шлёт сотни пустых запросов в секунду, а сообщения доходят почти мгновенно. После каждого ответа бот увеличивает offset, чтобы одно и то же обновление не обрабатывалось дважды.

curl "https://api.telegram.org/bot<TOKEN>/getUpdates?timeout=30&offset=0"

Главное достоинство polling — простота. Боту не нужны публичный IP, домен или SSL-сертификат, он работает даже на офисном компьютере или сервере за NAT. Поэтому на этапе разработки и для небольших ботов polling — самый удобный вариант. Недостаток в том, что процесс бота должен работать постоянно: если он остановится, сообщения накопятся в очереди на стороне Telegram и будут обработаны только после перезапуска.

Как работает webhook

При webhook вы регистрируете в Telegram один HTTPS-адрес, например https://bot.example.uz/tg/webhook. После этого каждое обновление приходит на него POST-запросом в формате JSON. Бот не опрашивает сервер постоянно, а, как обычное веб-приложение, отвечает только на входящие запросы. Это экономит ресурсы в ботах с большим числом пользователей и позволяет запускать несколько экземпляров за балансировщиком нагрузки.

У webhook есть свои требования. Адрес обязан быть HTTPS, и согласно официальной документации Telegram поддерживаются только порты 443, 80, 88 и 8443. Сертификат должен быть выдан доверенным центром — сертификат Let's Encrypt полностью подходит. Можно использовать и самоподписанный сертификат, но тогда его нужно отдельно загрузить при вызове setWebhook.

curl -F "url=https://bot.example.uz/tg/webhook" \
     -F "secret_token=dlinnaya-sluchaynaya-stroka" \
     -F "drop_pending_updates=true" \
     "https://api.telegram.org/bot<TOKEN>/setWebhook"

curl "https://api.telegram.org/bot<TOKEN>/getWebhookInfo"

Безопасность: secret_token и секретный путь

Адрес webhook открыт в интернет, и любой может отправить на него поддельный запрос. Чтобы защититься, передайте в setWebhook параметр secret_token. Тогда Telegram будет добавлять к каждому запросу заголовок X-Telegram-Bot-Api-Secret-Token, а бот должен принимать только запросы с правильным значением. Дополнительно полезно выбрать путь, который невозможно угадать.

Никогда не публикуйте токен бота в открытом репозитории, клиентском JavaScript или на скриншотах. Если токен случайно утёк, сразу перевыпустите его через BotFather: старый токен станет недействительным, и посторонний человек больше не сможет управлять ботом.

Реальный пример: бот записи для учебного центра

Допустим, учебный центр в Ташкенте хочет запустить бота для записи на курсы. Сначала бот тестируется на ноутбуке разработчика через polling — на этом этапе нет смысла возиться с доменом и сертификатом. Когда бот заработал, центр хочет связать его с формой заявки на сайте, и бот переносится на поддомен bot.example.uz. Здесь удобнее webhook: Nginx принимает запросы на порту 443 и передаёт их процессу бота на внутреннем порту.

location /tg/webhook {
    proxy_pass http://127.0.0.1:8081;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Если бот живёт на одном сервере с сайтом, который уже работает по HTTPS, отдельный сертификат для webhook не нужен. На хостинге sayt.uz бесплатный сертификат Let's Encrypt автоматически продлевается и для поддоменов, поэтому риск, что webhook внезапно перестанет работать из-за истёкшего сертификата, заметно ниже.

Частые ошибки

Самая распространённая проблема — смешение двух способов. Если установлен webhook, вызов getUpdates вернёт ошибку 409 Conflict. Чтобы вернуться к polling, сначала вызовите deleteWebhook. Точно так же два polling-процесса с одним токеном будут мешать друг другу, поэтому убедитесь, что старый процесс полностью остановлен.

Что выбрать

Если бот небольшой, работает на простом VPS или домашнем сервере и у вас нет публичного HTTPS-адреса, начните с polling. Если бот обслуживает много пользователей, встроен в существующее веб-приложение или должен работать в нескольких экземплярах, правильный путь — webhook. Учтите и то, что на обычном PHP-хостинге держать постоянный процесс, как правило, нельзя, а вот обрабатывать webhook-запросы обычным PHP-скриптом — вполне. Многие команды используют polling в разработке и webhook в production, а современные библиотеки переключаются между режимами несколькими строками кода.

Похожие статьи

💽 Диск заполнен: ошибка 500, повреждённый .htaccess и восстановление базы 🍃 MongoDB: облачный Atlas или собственный сервер — что выбрать 🗄️ Кеширование статики в Nginx: Cache-Control, expires и версионирование 🐘 PostgreSQL на хостинге: создание базы и подключение к сайту
🌐 Язык
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский ✓ 🇬🇧 English