Telegram bot polling это

Чуть меньше года назад я обещал написать, как сделать на php телеграм-бота, работающего через longpolling. И вот, наконец-то, у меня дошли руки, чтобы выполнить это обещание.

В чём идея этого метода и чем он принципиально отличается от вебхуков, я уже описывал в первой части этой статьи. Главный смысл тут в том, что данные не присылают по заранее указанному адресу, а мы должны сами посылать на сервера телеграм запросы на их получение. На самом деле я бы назвал этот способ просто polling, поскольку запросы могут быть как «долгими» (или «длинными», — longpolling), так и обычными (или «короткими», — shortpolling).

Разница между «длинными» и обычными опросами состоит в том, что в случае с «длинными» опросами клиент может ждать ответ на отправленный запрос в течении довольно длительного, заранее указанного времени (всё это время соединение не будет разрываться), а в случае с обычными запросами ответ должен поступить сразу, иначе клиент просто будет считать, что сервер не отвечает. В случае с telegram это означает следующее: для «длинных» опросов при отсутствии новых апдейтов сервер telegram сначала подождёт указанное время и если за это время апдейты не появились, то пришлёт ответ с пустым массивом, а для обычных опросов при отсутствии новых апдейтов сервер telegram сразу пришлёт ответ с пустым массивом.

Пишем TELEGRAM бота на Python #1 Простой Бот на Long-Polling

Учтите, что оба способа одновременно (вебхуки и поллинги) использоваться не могут, — если установлен вебхук, то отвечать на запросы серверы телеграм не будут (как снять установленный ранее вебхук читайте в статье про работу с telegram через вебхуки).

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

На этом закончим с введением и перейдём к более конкретным вещам, — разберём API телеграмма для работы через поллинги.

Итак, для получения массива апдейтов нужно воспользоваться методом getUpdates и отправить на сервера телеграм запрос следующего вида: https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates[?options], где YOUR_BOT_TOKEN — токен вашего бота, options — список дополнительных опций.

Опции могут быть следующими:

  • offset — идентификатор первого запрашиваемого апдейта. С этой опцией будут получены все апдейты, начиная с апдейта с указанным в поле offset идентификатором. То есть, для того, чтобы получать все апдейты — мы должны каждый раз в запросе указывать идентификатор на единицу больше, чем идентификатор (update_id) последнего полученного апдейта. Все апдейты с идентификаторами меньше присланного значения offset «забываются»;
  • limit — максимальное количество апдейтов, которое будет прислано за один раз. Может принимать значения от 1 до 100 (по умолчанию 100).
  • timeout — время ожидания для «длинного» запроса. По умолчанию = 0 (то есть по умолчанию используется обычный опрос);
  • allowed_updates — тип сообщений, которые мы хотели бы получать (например можно получать только сообщения типа message). Эта опция добавлена недавно и на момент написания этой статьи мне не удалось добиться её заявленной работы (выбранные типы сообщений приходят не от всех пользователей).
Еще по теме:  Открыть Телеграмм канал на телефоне

Вот и весь API, можно переходить к переделыванию нашего бота, описанного в четвёртой части.

Webhook и Long Polling! Чем отличаются? Что лучше использовать?

Сначала давайте разберёмся, что именно мы будем переделывать. Как я уже говорил, в ответ на запрос мы получим оформленный в json массив апдейтов, исходя из этого (и всего остального, что я написал выше) переделывание будет заключаться в следующем:

  • Нужно написать код, формирующий и отправляющий запрос на сервера телеграм. Здесь следует учесть, что функция file_get_content не умеет работать через https (или я не смог разобраться как это сделать). К счастью, у нас есть curl, который умеет всё, что нам нужно.
  • Полученный ответ нужно будет разобрать на отдельные апдейты. Здесь нам поможет уже известная нам функция json_decode.
  • Далее нужно будет перебрать все апдейты (их количество можно подсчитать функцией count) и обработать их аналогично тому, как это было в случае с вебхуками.
  • Для каждого апдейта нужно извлекать update_id и сохранять в БД update_id последнего полученного апдейта. Это нужно для того, чтобы далее, при формировании запроса, мы могли извлечь из БД сохранённый там ранее update_id и прибавив к нему единицу сообщить в запросе, какие апдейты нам нужны (параметр offset).

Для сохранения в базе данных MySQL значения update_id заведём отдельную таблицу tlgrm_updates с полями update_id и number, типа integer. Нужное нам значение update_id будем хранить в ячейке update_id с индексом number=0.

Всё, теперь осталось только написать код.

Первое. Заменим file_get_content на curl. Для этого напишем новую функцию execRequest такого вида:

Код под катом

function execRequest($telegram_req_url){ $telegram_ch = curl_init(); curl_setopt($telegram_ch, CURLOPT_URL, $telegram_req_url); curl_setopt($telegram_ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($telegram_ch, CURLOPT_HTTPGET, true); // необязательно curl_setopt($telegram_ch, CURLOPT_SSL_VERIFYPEER, false); // отменяем проверку сертификатов curl_setopt($telegram_ch, CURLOPT_SSL_VERIFYHOST, false); // (это для тестов, ну а что делать) curl_setopt($telegram_ch, CURLOPT_MAXREDIRS, 10); // необязательно curl_setopt($telegram_ch, CURLOPT_CONNECTTIMEOUT, 5); // необязательно (таймаут попытки подключения) curl_setopt($telegram_ch, CURLOPT_TIMEOUT, 20); // необязательно (таймаут выполнения запроса) $telegram_ch_result = curl_exec($telegram_ch); return $telegram_ch_result; }

Еще по теме:  Как начать видеочат в Телеграмме с компьютера

Теперь во всех местах, где мы пользовались функцией file_get_content будем просто формировать нужный url, а сам запрос выполнять новой функцией execRequest, задавая для неё в качестве параметра нужный url.

Второе. Код обработки апдейта, который у нас ранее располагался в конструкции вот такого вида:

Код под катом

$input_array = json_decode(file_get_contents(‘php://input’),TRUE) if($input_array) < код обработки апдейта >else

теперь вместо этого заключим вот в такую конструкцию:

Код под катом

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

В дополнение ко всему изложенному хотелось бы добавить несколько замечаний:

  • Как известно, в нашей стране Telegram в настоящее время запрещён, его пытается лочить РКН. Однако, РКН не умеет лочить IPv6. То есть, если вы подключены к интернету по IPv4, то ваши запросы могут не доходить до серверов Telegram. Чтобы они до серверов Telegram доходили — придётся подключаться к интернету по IPv6 (если провайдер позволяет) или что-то колхозить с vpn и проксяшниками.
  • Вот здесь можно почитать про пример организации домашней сети таким образом, чтобы одновременно пользоваться плюшками и от IPv6, и от IPv4.
  • Если домашний роутер раздаёт IPv6, то можно поднять бота на отдельном, воткнутом в домашнюю сеть микрокомпьютере (например Omega2), который будет включен в режиме 24/7, и будет заниматься только этим ботом. К сожалению, родная прошивка микрокомпьютера Omega2 не поддерживает IPv6, однако его поддерживает моя самодельная прошивка, которую можно найти вот в этой статье. Другие альтернативные прошивки с поддержкой IPv6 можно скачать с нашего форума.
  • Для запуска на микрокомпьютере Omega2 описанного в этой статье Telegram-бота с использованием интерпретатора php7, на омеге должны быть установлены следующие модули:

Список под катом

  • php7
  • php7-cgi
  • php7-fastcgi
  • php7-mod-curl
  • php7-mod-hash
  • php7-mod-iconv
  • php7-mod-json
  • php7-mod-mysqli
  • php7-mod-mysqlnd
  • php7-mod-openssl
  • php7-mod-sockets
  • php7-mod-xml
  1. Часть 1. Что такое Telegram боты и как они работают
  2. Часть 2. Регистрация аккаунтов Telegram ботов в картинках
  3. Часть 3. Пишем простого чат-бота для Telegram на чистом php (webhook)
  4. Часть 4. Прикручиваем MySQL к чат-боту для Telegram на php (webhook)
  5. Часть 5. Пишем Telegram бота на php для работы через longpolling
  6. Часть 6. Делаем пользовательскую клавиатуру для бота
  7. Дополнение. Как отправлять правильные https-запросы через curl и при чём здесь SSL-cертификаты

Источник: radiohlam.ru

Polling и long polling

Чат-боты должны получать уведомления от соцсети моментально. Они не могут проверять обновления каждую секунду, это неэффективно. Большинство ответов от сервера будут неинформативны, вроде «У вас пока нет новых сообщений».

Такой подход, когда раз в n секунд опрашивается сторонний сервис, называется polling.

Еще по теме:  Как обойти цензуру в Телеграмме

Чтобы сэкономить на ресурсах, можно использовать long polling. Устроен он так же, как и polling, с одним отличием: сервер дольше отвечает. Вообще, при лонг-поллинге сервер отвечает в двух случаях: или потому, что пришло новое сообщение, или потому, что соединение пора разрывать.

У каждого запроса есть timeout — время, в течении которого нужно ответить. Если на запрос не ответили за это время, считается, что сервер не ответит вообще. Поэтому сервер смотрит на timeout и решает так:

  1. Если за это время у меня не появится обновлений для клиента, я отвечу ему, что их нет.
  2. Если появятся, я отправлю ему обновления сразу, не дожидаясь таймаута.

Чтобы реализовать long polling на стороне клиента, нужно выставить большой timeout: 30 или 60 секунд.

Вот так выглядит polling со стороны клиента на Python:

from time import sleep import requests while True: response = requests.get(«http://someurl.com») for message in response: bot.answer(message) sleep(1)

А вот так выглядит long polling:

import requests while True: response = requests.get(«http://someurl.com», timeout=60) for message in response: bot.answer(message)

Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

Источник: dvmn.org

В чем отличие bot.polling() от bot.polling(none_stop=True)?

Вот в принципе и вся проблема, всегда передавал polling(none_stop=True) , без этого бот будет выключаться?

Отслеживать
9,985 5 5 золотых знаков 22 22 серебряных знака 66 66 бронзовых знаков
задан 4 мая 2021 в 20:40
13 1 1 серебряный знак 5 5 бронзовых знаков
Если ответ является решением, пожалуйста, отметьте его таковым, это поможет другим участникам.
20 июн 2021 в 6:26

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

После вызова этой функции TeleBot начинает опрашивать серверы Telegram на предмет новых сообщений.

  • none_stop: True / False (по умолчанию False) — не прекращать опрос при получении ошибки от серверов Telegram
  • interval: True / False (по умолчанию False) — интервал между запросами на опрос. изменение этого параметра снижает время отклика бота.
  • таймаут: целое число (по умолчанию 20) — Тайм-аут в секундах для длительного опроса

Так же имеется bot.infinity_polling :

def infinity_polling(self, *args, **kwargs): while not self.__stop_polling.is_set(): try: self.polling(*args, **kwargs) except Exception as e: time.sleep(5) pass logger.info(«Break infinity polling»)

Метод infinity_polling нужен только для обхода падения бота путем перезапуска его. В обычной ситуации вызывался бы bot.polling , внутри которого также крутился цикл.

Т.к. этот код вызывает цикл, то все остальные действия ниже него не произойдут пока цикл не завершится.

Если нужно параллельно что-то выполнить, то нужно запускать что-то в отдельном потоке, например самого бота — через вызов infinity_polling .

Источник: ru.stackoverflow.com

Рейтинг
( Пока оценок нет )
Загрузка ...