Есть два способа, которые позволяют вашему боту получать обновления от серверов Telegram, long polling и вебхуки. Давайте разберемся, что это такое и какие есть плюсы и минусы у этих подходов.
По сути, разница между long polling и вебхуками заключается только в том, как телеграм доставляет события вашему приложению.
Когда мы используем long polling, бот сам регулярно запрашивает обновления у сервера телеграма, тогда как при использовании вебхуков, телеграм отправляет события на указанный вами URL.
Из‑за этого процесс развертывания и настройки окружения происходит по разному, long polling можно запускать где угодно, даже локально, а вебхуки требуют публичного адреа и HTTPS.
Как работает Long Polling?
Представьте, что вы приходите в кафе и спрашиваете свой любимый десерт. Сотрудник проверяет и говорит, что сейчас его нет в наличии. На следующий день вы возвращаетесь, спрашиваете снова и в этот раз вам везет, он оказывается в наличии. То есть вы приходите и узнаете, появилось ли что‑то новое.
Long Polling работает по той же логике.
Ваше приложение может само раз в какой‑то период отправлять запрос с целью узнать, есть ли новые обновления. Тогда сервер будет возвращать пустой ответ, если обновлений нет, а если сообщения есть, то возвращать их массивом (до 100 штук за один ответ).
После получения ответа, бот будет отправлять новый запрос и схема взаимодействия будет выглядеть примерно таким образом:
______________ _____________
| | | |
| | <--- Есть новые сообщения? ---| |
| | --- нет. --->| |
| | | |
| | <--- Есть новые сообщения? ---| |
| Telegram | --- нет. --->| Бот |
| | | |
| | <--- Есть новые сообщения? ---| |
| | --- да, держи! --->| |
| | | |
|______________| |_____________|
Очевидно, что у такого подхода есть минусы. Бот будет получать новые сообщения только в момент запроса, то есть раз в несколько секунд. Чтобы получать их быстрее, мы могли бы отправлять запросы чаще, например раз в миллисекунду (хе‑хе, звучит устрашающе, да?), но это будет создавать ненужную нагрузку и превратится в бессмысленный трафик.
Это называется обычный поллинг (короткий), без приставки «long». Вместо того чтобы долбиться в API, мы можем использовать другой способ реализации.
Заранее отправить запрос на сервер и ждать. Если новых обновлений нет, телеграм не будет закрывать соединение, а будет удерживать запрос открытым, пока не появятся обновления. Когда они приходят, сервер будет сразу отправлять их в ответе.
Примерно так:
______________ _____________
| | | |
| | <--- Есть новые сообщения? ---| |
| | . | |
| | . | |
| | . *оба ждут* | |
| Telegram | . | Бот |
| | . | |
| | . | |
| | --- да, держи! --->| |
| | | |
|______________| |_____________|
Примечание: по умолчанию timeout в Telegram API = 0, то есть если не задать таймаут явно положительным числом, то будет реализован короткий поллинг без ожидания и сервер не будет удерживать соединение открытым.
Учтите, в реальности соединение не будет висеть открытым часами, у таких запросов есть таймаут (обычно это около 30 секунд). Если за это время ни одного обновления не пришло, запрос завершится и бот отправит его заново.
Как работают вебхуки?
После этого ужасающего опыта (целый день без любимого десерта), вы думаете о том, как было бы круто, если бы он сам мог прийти к вам без необходимости ходить в кафе и опрашивать сотрудников.
Вебхуки работают следующим образом. Вы даете телеграму URL, доступный из интернета и к��гда вашему боту приходит новое сообщение, он сам отправляет HTTP‑запрос с данными обновления на ваш сервис. В данном случае инициатором коммуникации уже является сервер Telegram.
______________ _____________
| | | |
| | | |
| | | |
| | *оба ждут* | |
| | | |
| Telegram | | Бот |
| | | |
| | | |
| | --- Привет, новое сообщение --->| |
| | <--- Спасибо! ---| |
|______________| |_____________|
Преимущества обоих подходов
Главное преимущество лонг поллинга — простота. Вам не нужен домен, публичный URL, возня с SSL‑сертификатами (если бот на VPS). Что касается нагрузки, опять же, вы сами контролируете сколько сообщений и как быстро вы будете обрабатывать.
Особенно хорошо он подходит для локальной разработки и в общем‑то большинства серверов.
Что касается вебхуков, их главное преимущество заключается в том, что они дешевле. Вы экономите тонну лишних запросов, не держите соединение постоянно открытым, можете использовать инструменты, которые автоматически усыпляют сервис при простое и эта идея прекрасно подходит для серверов с SSL сертификатами, облачных решений и серверов, которые автоматически масштабируются при росте нагрузки.
Все еще не решили что использовать?
Если у вас нет веской причины использовать вебхуки, выбирайте long polling. У этого подхода нет действительно серьезных минусов и обычно с ним меньше всего головной боли. С вебхуками иногда могут возникать сюрпризы.
Например, связанные со своевременным завершением запросов
Если ваша обработка событий укладывается в пару секунд, вы можете пропустить этот раздел. Он важен в ситуациях, когда бот, например, загружает или отправляет файлы, делает тяжелые запросы к API и тому подобное.
Когда телеграм отправляет вашему боту вебхук, он ждет пока вы ответите на HTTP‑запрос, прежде чем прислать следующее обновление из того же чата. То есть обновления одного чата приходят по очереди.
Телеграм стремится гарантировать доставку обновлений, поэтому если обработка одного обновления зависла или упала, все последующие обновления будут поставлены в очередь и не будут доставлены, пока первое не обработается корректно. Так что завершайте обработку запросов вовремя.
У каждого вебхук‑запроса есть таймаут. Если бот отвечает недостаточно быстро, то телеграм решает, что обновление не доставлено и отправляет его повторно. Как только Telegram отправит обновление вашему боту во второй раз, маловероятно, что ваша обработка будет быстрее, чем в первый раз. В результате, скорее всего, снова будет тайм‑аут, и Telegram снова отправит обновление и пользователь получит дублирование в ответах. Так что тяжелую логику лучше вынести в фон (очереди, worker«ы, async‑таски и так далее).»
Почему преждевременное завершение запросов также опасно
Вместо того, чтобы кидать ошибку после истечения таймаута, можно сконфигурироваться так, чтобы при получении вебхука сразу отправлялся ответ и запрос немедленно завершался, даже если middleware все еще работает. Есть некоторые валидные сценарии для такого подхода, но чаще это создаст проблемы.
Почему? Потому что как только вы ответили на запрос, телеграм считает обработку завершенной и может прислать следующее обновление из того же чата, хотя предыдущее обновление все еще выполняется в фоне. В итоге два обновления, которые должны обрабатываться строго по порядку, начинают выполняться параллельно. Это приводит к рассинхрону и гонкам данных (race conditions).
На самом деле на вопрос как это решать можно дать только один ответ. Он звучит достаточно просто, но гораздо сложнее реализуется. Ваш middleware должен отрабатывать достаточно быстро и не должен иметь долго выполняющихся операций.
Да, понятно, что иногда есть тяжелые таски, но не нужно выполнять их прямо в обработке вебхука. Вместо этого используйте систему очередей, которых сейчас существует огромное количество, как простых, так и очень сложных.
Идея такая:
Запишите таску в очередь.
Дайте ответ на полученный вебхук как можно быстрее.
Отдельным воркером или фоновой задачей заберите таску из очереди и выполните ее.
Когда таска будет выполнена, отправьте сообщение пользователю из воркера или фоновой задачи.
На самом деле race conditions очень трудно воспроизвести, они могут возникать крайне редко, но лучше потрать��е время на реализацию этого сценария и ваше будущее «я», а также пользователи поблагодарят вас.
Использованы материалы: grammY
Разобрались с polling и вебхуками — пора к практике. На курсе «Диалоговые боты и голосовые помощники» вы на Python соберете Telegram/VK-ботов и голосового ассистента, подключите ИИ-сервисы и внешние API. FSM, middlewares, Django-админка, логирование и деплой в Docker/Postgres — всё по продакшен-правилам.
Для знакомства с форматом обучения и экспертами приходите на бесплатные демо-уроки:
12 ноября: «Создание Telegram-бота на Python». Записаться
19 ноября: «Деплой Telegram-бота и работа с API». Записаться
