Как стать автором
Обновить

Комментарии 30

Вебхуки - штука хорошая, но, как справедливо заметили, требует домена с сертификатом. Не знаю, работает ли оно с самоподписанными сертификатами, но и для них нужен внешний IP. А если вы в домашней сетке через роутер пилите свой первый телегобот, то у вас вообще никаких вариантов кроме пулинга нет.

Вариант - у вас есть сервер, на нем принимаются запросы, и проксируются через тоннель к вам, на рабочую машину

Есть несколько вариантов (для дебага бота):

  • Использовать ZeroTier/TailScale для пробития NAT

  • Временно создать туннель с помощью Ngrok или похожего софта

Для продакшена же согласен, нужно будет брать белый IP

Если у вас совсем-совсем своего IP нет - то да, остаётся только long polling.

Но если есть хотя бы динамический IP - вы уже можете получить доменное имя через dynamic dns и получить на него сертификат от Let's Encrypt

Я локально, когда делал бота на webhook использовал ngrok. Сейчас же в vs code во вкладке Ports можно сделать себе url, который не будет меняться в проекте. По поводу сервера - cloudflare покатит, мне кажется, чтобы не мучиться с сертификатами

В vs code можно арендовать сервер чтоли?

Сервер нельзя (наверное), но порт, как оказалось - можно.

Можно прокинуть порт. Бесплатная альтернатива ngrok

Можно поднять локальный сервер бота, который будет работать напрямую с телеграмом и дергать хуки на локальном сервере.

Если провайдер выдает IPv6, то его должно быть достаточно. SSL Let's Encrypt по IPv6 работает отлично.

если вы в домашней сетке через роутер пилите свой первый телегобот

то вас вообще скорее всего не интересует, что такое webhook и вы еще не скоро об этом узнаете

Зачем отправлять запросы при Polling методе каждые 2 секунды, если сам по себе Polling метод подразумевает, что сервер как бы ждет некоторое время и держит соединение не отдавая его содержимое, пока данные не появятся?

Это тогда не Polling получается а какой Getting.

Когда делал своего бота (не на пайтоне), как раз использовал этот подход. Делаю запрос на сервер телеграмм с ожиданием в 30 секунд, если ответа не последовало, сбрасываю соединение и снова делаю новый запрос. Получается один запрос в 30 секунд что не так часто.

При увеличении нагрузки Polling может стать бутылочным горлышком. Такую проблемку можно решить увеличением интервала между запросами в моменты низкой активности и его уменьшение в пиковые часы.

Э... А что, long poll ещё не изобрели?

Тут и малограмотным должно быть понятно. Если у меня 1000 ботов на сервере - для лонгов нужно 1000 демонов поднимать и заставлять их жить. При хуках пофиг один бот или 1000.

А у моего бота такая схема: каждые 10 минут java приложение, которое запущено как сервис на моем сервере, сохраняет новости в БД на том же сервере. А пользователи через бота получают эти новости селектами к таблицам БД. В такой схеме есть смысл применять вебхук?

Как бот узнал о ваших пользователях? Они что-то ему отправили, верно? И отписаться могут, отправив команду? То есть канал связи двусторонний.

Вот, если тут скорость реакции важна, а накладные расходы на частый поллинг велики, то можно использовать вебхук. И наоборот, если при вызове хука нужна длительная операция (ну не знаю, запросить баланс пользователя у третьей стороны, например), то лучше использовать поллинг, иначе при увеличении бутылочным горлышком станут хуки.

Не совсем понимаю как хуки могут что то замедлить.

Пример:

Прилетел апдейт \wallet от пользователя. Бот лезет в базу, стучится по апишке на биржу за курсом, в общем проводит время с кайфом) и через час ответит пользователю. В этот самый момент падает хуком от другого пользователя апдейт с другим запросом. Сервер порождает ещё один процесс и бот отвечает незамедлительно.

Может я Вас неправильно понял?

Одинокий хук, конечно, ничего не замедлит. Предположим раньше бот быстро отвечал пользователям. Но вот в новостях сказали что этот бот развод и все ломанулись проверять баланс вводя /wallet. Вот пользователь ввёл /wallet, ничего не произошло. Он ещё раз ввёл, ещё, чертыхнулся и пошёл жаловаться другим пользователям. Они тоже пошли вводить /wallet. Проходит пять минут, пользователь думает что может починили и снова пишет /wallet. И снова нет. В итоге сервер засыпан запросами. Сколько процессов сможет выдержать ваш сервер? А если и сможет выдержать всё, то у биржи может быть ограничение на число одновременных запросов.

Разумно, логично. Спасибо.

Жаль не всегда можно реализовать без хуков. У меня например сейчас 2400 штук ботов, 7 разных типов (конструктор ботов через который пользователи создают сови боты). Как это сделать без хуков - даже предположить не могу.

Да без проблем, 2400 ботов - это всего лишь 2400 HTTP соединений с long polling. Держать столько соединений вообще не проблема пока памяти достаточно.

Да. Не забывайте о возможности слать всякие sendMessage не после приёма хука, а в ответ на хук. То есть пришёл апдейт хуком и ты не отвечаешь кодом 200 и после шлёшь ответ, а прям вместе с кодом 200 отвечаешь на хук. Одно но. Один хук = один ответ (1 сообщение или правка 1 сообщения или 1 answerCallbackCuery,....).

Сначала подумал, что автор статьи под polling имеет ввиду long polling, но нет, в статье описывается именно обычный polling и его недостатки, тогда как телеграм использует именно long polling.
Отсюда делаю вывод, что автор не вникал в предмет статьи и/или вовсе написал статью используя нейросеть

Согласен с мнением предыдущего оратора.
Увы, автор статьи не счёл нужным вникать в суть вопроса до того как рассказывать аудитории про "бутылочные горлышки" и т.п.

Коротко по сути вопроса:
в Телеграмме long polling (не просто polling!) сделан грамотно, удобен в использовании, надежен и бутылочным горлышком не является до тех по пока ваш инстанс обслужвает одного бота.
Webhook предпочтительнее когда:
- вебсервер уже есть для чего-то другого, а бот работает периодически на не частые запросы (в виде лямбды, например)
- один инстанс приложения обслуживает много разных ботов.

Одна из неочевидных для новичков проблем вебхуков это то, что если Телега по какой-то причине не смогла успешно достучаться до хоста (протух серт, заблочили подсеть, упал хостинг, ...), она ставит общение на паузу и этот момент надо отдельно как-то отслеживать.

Что это за ересь? Зачем динамически менять интервал? Ради чего? Зачем его ставить всего 2 секунды? Кто так делает вообще? Вебхуки это плохо переносимая технология и она требует внешнего адреса и настройки вебсервера в режиме проксирования или выделенно прослушивающего https порт инстанса бота. Вообще в лонгполе (да и везде) всё решается асинхронным подходом. aiohttp берешь и прикручиваешь, перебирая полученные события где то там в фоне, в ожидании новых ответов. Не успеваешь обрабатывать - делай очереди. У меня десяток ботов на самописном движке, дергающим getupdates и переезд на новый хостинг у меня занял пол часа от силы на добавление темплейта сисд юнита и распихивания папок с данными, создание венва с requirements.txt и включения этих юнитов..

На лонгполл в один ответ влезает 100 событий при условии что их накопилось, а телеговские серваки просто моментально отгружают их. я как то во время разработки не уследил за счетчиком и от ошибки сети бот зациклился на получении одного и того же списка апдейтов и телега несколько минут в режиме нон-стоп нагенерила мне несколько гигов логов со строками апдейтов. И при условии моментального повтора запроса так же моментально отдают принятое сейчас сообщение. если юзать http библиотеку с сессиями и поддержкой соединения, то это работает просто моментально. И пропустить апдейты при условии сохранения предыдущего id ну просто невозможно. Ты в запросе последний id в телегу передаешь.

по-моему автор выдумал проблему где ее нет. Впрочем это не самостоятельный автор, а реклама курсов питона

А как вебхуки будут обрабатываться, когда сервер с ботами отключается на обновления или вообще попросту упал? Или лег промежуточный сервер, который вам вебхуки пересылал?

Я выбрал polling из-за того что webhook слал сообщения с большим опозданием

Сложилось впечатление, что автор недостаточно погружен в тему освещаемого вопроса. Само сравнение polling и webhook относительно Telegram Bot API бесполезно, потому что у Telegram нет polling'а! (зато есть long polling, который работает отлично от того, что вы описали). Приведу ваш блок кода:

def main():
    while True:
        updates = get_updates()
        if updates["result"]:
            # Обработка каждого нового сообщения
            for item in updates["result"]:
                print(f"Сообщение от пользователя: {item['message']['text']}")
        time.sleep(2)  # Задержка в 2 секунды между запросами

Нет, задержка между запросами не 2 секунды. Long polling подразумевает, что сервер не разрывает запрос в течение длительного времени (обычно это минута или 30 секунд), если нет новых событий для вас, но вернет их моментально, как только они появятся. Таким образом, вы выполняете очень мало запросов (речь точно не идет о запросе каждые 2 секунды) и получаете запросы моментально. Long polling, в отличие от webhook, не может быть бутылочным горлышком для вашего бота, потому что вы сами отправляете запрос на обновления к Telegram, когда готовы их обработать, и работает это максимально эффективно. В случае с webhook Telegram сам шлет вам запросы, что на пике может положить ваш сервер или заставить его обрабатывать запросы значительно медленнее, потому что у веб-серверов есть ограничения на максимальное количество открытых запросов одновременно.

Более того, в случае с webhook 1 обновление = 1 запрос, то есть запросов будет гораздо больше, чем при использовании long polling, и на больших ботах это будет вызывать проблемы с производительностью.

Если к этому добавить то, что для работы webhook нужно возиться с сертификатами и получить белый IP, я считаю использование long polling выигрышным в 100% случаев.

Друзья, кроме такого вида транспорта как веб-хуки и лонгпулинг, в бот-апи телеграма давно уже доступны вебсокеты, более 5 лет назад уже их можно было использовать.

Не видел их ни в документации, ни в клиентских библиотеках.

Вот что пишут в документации:

There are two mutually exclusive ways of receiving updates for your bot - the getUpdates method on one hand and webhooks on the other. Incoming updates are stored on the server until the bot receives them either way, but they will not be kept longer than 24 hours

Зарегистрируйтесь на Хабре, чтобы оставить комментарий