Инструкция по созданию Telegram ботов. Часть 5. Пишем Telegram бота на php для работы через longpolling
Чуть меньше года назад я обещал написать, как сделать на php телеграм-бота, работающего через longpolling. И вот, наконец-то, у меня дошли руки, чтобы выполнить это обещание.
В чём идея этого метода и чем он принципиально отличается от вебхуков, я уже описывал в первой части этой статьи. Главный смысл тут в том, что данные не присылают по заранее указанному адресу, а мы должны сами посылать на сервера телеграм запросы на их получение. На самом деле я бы назвал этот способ просто polling, поскольку запросы могут быть как «долгими» (или «длинными», — longpolling), так и обычными (или «короткими», — shortpolling).
Разница между «длинными» и обычными опросами состоит в том, что в случае с «длинными» опросами клиент может ждать ответ на отправленный запрос в течении довольно длительного, заранее указанного времени (всё это время соединение не будет разрываться), а в случае с обычными запросами ответ должен поступить сразу, иначе клиент просто будет считать, что сервер не отвечает. В случае с telegram это означает следующее: для «длинных» опросов при отсутствии новых апдейтов сервер telegram сначала подождёт указанное время и если за это время апдейты не появились, то пришлёт ответ с пустым массивом, а для обычных опросов при отсутствии новых апдейтов сервер telegram сразу пришлёт ответ с пустым массивом.
Учтите, что оба способа одновременно (вебхуки и поллинги) использоваться не могут, — если установлен вебхук, то отвечать на запросы серверы телеграм не будут (как снять установленный ранее вебхук читайте в статье про работу с 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, можно переходить к переделыванию нашего бота, описанного в четвёртой части.
Сначала давайте разберёмся, что именно мы будем переделывать. Как я уже говорил, в ответ на запрос мы получим оформленный в 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 такого вида:
Telegram API. Как написать бота?
Сегодня мы побеседуем о том как делаются Telegram боты.
Кто ты по жизни?
Telegram боты бывают двух видов:
- Боты основанные на Webhoock
- Боты основанные на Long Polling
Первый вариант бота требует от вас поднять сервер и установить “вебхуки” для асинхронного оповещения вас о новых изменениях. На вашем сервере должен быть соответствующий роутинг.
Второй вариант бота — это имитация асинхронности. Ваш бот с определенным периодом будет запрашивать последние изменения с сервера телеграм на основании механизма long polling. Т.е. бот делает запрос и подвисает, а отвисает либо по таймауту, либо по получению новыйх обновлений. Об этом виде ботов сегодня и пойдет речь.
Long polling в разрезе работы с сетью
Когда вы работаете с Telegram Api вы нагружаете сервера Telegram. Все запросы вы отправляете по одному URL, но в один момент времени может работать только один обработчик для Telegram бота.
Интересно, что в API предусмотрена умная обработка ошибок, среди прочего, в ответе телеграм сервера, который вы за DDOS’или, может сообщить вам сколько нужно подождать, чтобы вы могли взаимодействовать с Telegram снова
Как сказано выше у вас фактически однопоточная обработка запросов к телеграм. По этому, кажется, здравым принять одну из следующих реализаций ботов:
- реализовать поток, который будет отправлять запросы и складировать ответы в общую очередь из которой потоки-обработчики будут их разбирать;
- поставить прокси-сервер, который будет затягивать последние изменения и шарить их между нодами (другими серверами) бота. В этом случае можно подменяя прокси-сервер менять реализации взаимодействия с telegram api не меняя реализацию для нод. Это решение мне нравится несколько больше, его масштабируемость зависит от потребностей в функциональности бота, т.к. если можно обрабатывать параллельно несколько чатов независимо друг от друга, то масштабируемость на пределе.
Оставим использование прокси-сервера для будущих статей, а пока давайте рассмотрим как вы можете реализовать своего бота.
Красная или синяя таблетка?
На сколько вы любите писать велосипеды? В зависимости от этого у вас есть 2 пути реализации Telegram бота:
- писать всё самому с нуля;
- воспользоваться существующей библиотекой.
Если вы используете динамически типизируемые языки, которые поддерживают нативную работу с JSON, то первый вариант, не так уж и плох, однако, уже существует большое количество библиотек для разработки ботов их публичный перечень вы можете увидеть здесь. Вы найдете много вариантов для PHP, Java, Python, Node.js и так далее. Я сейчас реализую собственную библиотеку на языке Kotlin — Clabo. Эта библиотека поможет вам на основании расширяемого DSL описать работу своего бота, например, всё что надо для запуска бота, который говорит “Привет!” по команде /start это небольшой кусочек кода по ссылке.
BotFather
В телеграме есть специальный бот, который позволяет создавать других ботов и настраивать их. Некоторые действия вы, как пользователь, не можете сделать из интерфейса, например, сменить имя бота или задать набор команд, для этого нужен BotFather.
Теперь у вас есть представление, как реализовать бота, но что с ним можно сделать? Об этом я расскажу ниже.
И зачем всё это?
Боты очень способные, они обладают следующими возможностями:
- Встраиваемый мод (Inline mode). Вы можете встроить бота прямо в строку с вводом, хорошие примеры таких ботов это GifBot и YouTubeBot. Вы вписываете имя бота, например, @youtube и он предлагает вам результаты поиска видео или вы можете авторизоваться и результаты будут специфичны для вас.
- Клавиатуры. Есть два вида клавиатур: “Клавиатура для быстрого ответа” и “Встроенная клавиатура”. Первый вариант позволяет пользователю не писать сообщение, а просто отправить его выбрав один из вариантов. Встроенная клавиатура размещается прямо под сообщением и ассоциирована именно с ним.
- Команды. Всё что вы пишете после “/” в телеграм называется командами, чтобы избежать коллизий, когда два бота в одном чате имеют одну и ту же команду используется следующий формат /command@BotName .
- Бот может отправлять отформатированные с помощью html или markdown сообщения.
- Бот может запросить местоположение или номер телефона.
- Ботов можно добавлять в группы и, например, администрировать их.
Что в итоге?
Мы обзорно рассмотрели основы того как можно сделать ботов, для чего это и что они могут делать. Применение ботов ограничивается только вашей фантазией. Вы создаете бота и запускаете сопровождающий код, который обрабатывает сообщения. Ничего сложного. Увидимся в следующих статьях!
Let’s make a Telegram Bot with PHP
I spend a few days creating a Telegram bot for my SaaS. It serves as a convenient way for my users to enter data. The bot isn’t smart at all, but at its core is a regex pattern matcher which allows entering various health-related data points.
While the Telegram docs try to give you an easy start, I found them lacking. With this article, I want to fill some gaps.
How does the Telegram Bot work?
Make sure to read the official Bot introduction for developers by Telegram. This explains how to register your bot with Telegram. Once you registered your bot, the bot won’t do anything, because a Telegram bot is basically only an account with a few extra settings, such as an URL for the Webhook callback.
For the rest of the article, I will call the thing you configure via BotFather your Bot Account.
Your bot lives on your server and processes all messages there. I will call the stuff that runs on your server the Telegram Bot.
The Telegram Bot could be tightly integrated with your web app or it could also be hosted on an extra server and talks to your web app via an API. This is up to you.
I drew an image to illustrate this:
How does the Bot API work?
This is where I found the docs quite confusing. Your bot needs three things:
- It must be able to receive messages.
- This behavior must be configured.
- The bot should be able to send messages to the Telegram user.
I. Receiving Messages
Currently, there are two options: Long polling and Webhooks. I decided to use Webhooks, since long polling is kind of outdated and Webhooks are the way to go.
Your webhook is actually quite simple and doesn’t require the Telegram Bot API:
See, that’s all there is to receive messages from Telegram.
II. Configuring the Webhook
The Telegram server needs to know where to send messages (called Updates).
The confusing part for me was the setWebhook part. You really need to call this only once to setup your Bot Account.
Telegram’s extremely simple (and confusing, and undocumented, and not-very-clean) HelloBot has this section:
Which means that you need to need to run this weird script from your command line once to configure the Webhook. There’s are two much better ways. One is to use existing Telegram API clients (I’ll get back to this in a minute). The second is using cURL from the command line:
This sends a JSON request to Telegram’s API and configures the Bot Account to use my-secret-webhook.php on your server.
Once your Webhook URL is set, you don’t have to touch it again and that’s it for the configuration part.
Wait, what about bot commands? All of them live in your actual Telegram Bot on your own server. There is no need to tell the Telegram service which commands your bot understands.
III. Sending Messages
This is where it gets interesting and a bit more complex. I recommend using an inofficial Telegram API client to make this work (because there is no official API client). I tried these four projects and the last one is the best:
kolar/telegram-poll-bot. Simple, but too intermingled with the Poll Bot functionality and kind of hard to separate. Also, it’s outdated and probably doesn’t support everything of the new Bot API 2.0.
TelegramBot/Api. I tried to use this project, but found it confusing and it lacks proper documentation. If I’d try again now with some experience, I might find it useful. At least, it is up to date.
akalongman/php-telegram-bot. This was the first project I got to work. It seems to be actively developed. However, I had the impression that this project is a bit too opinionated about a few things and comes with too much boilerplate. Check out the examples to get an idea of what this project can do.
irazasyed/telegram-bot-sdk. This project is what I finally settled on. It is well documented, comes with optional Laravel integration, but can also be used as a standalone project. I even threw out the entire Command stuff and wrote my own, i. e. you don’t have to use all features. Only downside: Has more Composer dependencies.
Sending messages to a Telegram user
Most of the time, you want to send a message as a reaction when Telegram notifies your bot about an Update (a message). The Update datastructure gives you access to the chat_id , which is another word for Telegram user id. The chat_id for one user is always the same, even if he deletes your bot, the entire chat history and then restarts the bot. It’s also the same accross different devices.
Sending a message to a Telegram user doesn’t have to be a reaction to an Update as long as you know the chat_id (and as long as the user didn’t block the bot). You could even use this to send Push notifications to your users with a cronjob.
The question now is: How do you associate your web app user accounts with the Telegram userids?
The official documentation has a good example for that under section Deep Linking.
I do it slightly different, because not every bot is added via a deep link. A user could simply search for the bot within Telegram:
- User adds the bot. Bot replies with the help text and suggest to use the command /connect
- User types /connect , Bot generates a random token and stores it along with chat_id and an expiration date in the database. It replies with a message: To connect your account, please visit https://example.com/connect/$RANDOM_TOKEN
- User clicks on the link and must log in to the web app (in the browser). Please keep the possibility of CSRF attacks in mind. If I have a connect link and give it to you and you confirm it, I can access your account via the bot, because your web app userid is now associated with my chat_id .
- Once the user is logged in, the web app retrieves the token, checks its expiration date and the associated chat_id and stores it in the user properties in another database table.
- Now, if we want to send a message to this user, we can look up his chat_id and send a message via the Telegram Bot API.
- Furthermore, if bot commands require to retrieve or change data of this user, the Bot needs to access the user data based on the chat_id .
And that’s it for now.
As a quick summary:
- setWebhook must be called only once
- retrieving updates is basically processing php://input
- sending messages via irazasyed/telegram-bot-sdk is easy
Chris on Code

Webdev blog about stuff I explore. Currently:
JavaScript, TypeScript, Ionic 2+
GitHub · Twitter
Пишем простого чат-бота для Telegram на PHP
Шукюров Заур, разработчик @KinomanBot и @GaidarForum_bot, написал руководство по созданию простого чат-бота на PHP.
24 июня 2015 года разработчики Telegram открыли платформу для создания ботов (программ, которые выполняют определенные действия по заданному алгоритму).
За полтора года работы платформы набралось много интересных чат-ботов, решающих множество проблем и позволяющих с пользой провести время в мессенджере.
Шаг 1: регистрация бота у @BotFather
Прежде чем начать писать код, нового бота нужно зарегистрировать у «папы всех ботов» — @BotFather, чтобы получить токен (ключ) для работы с Telegram API.
Регистрация проходит в 5 простых этапов:
1) Открываете чат с @BotFather;
2) Вводите или выбираете из списка команду /newbot;
3) Отправляете желаемое название для бота;
4) Пишете юзернейм бота, по которому его будут находить через поиск. Обязательно на конце вашего юзернейма должно быть слово «bot» или «_bot». Например, NetologyRSSbot;
5) По желанию можно сразу настроить полное или краткое описание, список команд и аватарку.

По итогу регистрации получаем наш токен — 375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s.
Будьте осторожны: никогда и никому не показывайте токен, иначе ваш бот может быть скомпрометирован. Если по несчастливой случайности кто-то нехороший все-таки узнал ваш токен, то заменить его можно всё в том же @BotFather, нажав на кнопку «Revoke current token» в разделе «API Token».
Шаг 2: выбираем способ обработки запросов
Исходя из официальной документации, Telegram API основан на простых HTTP-запросах. Существует всего два различных способа обрабатывать запросы, которые пользователи будут посылать боту:
1) проверять «вручную», используя «Long Polling»;
2) доверить всё Telegram, поставив «Webhook». В этом случае любой запрос от пользователя Telegram сам будет посылать нам на сервер.
Мы остановимся на втором варианте, но у него есть ограничение: у вас на сайте обязательно должен быть установлен SSL-сертификат, чтобы все запросы проходили через безопасный протокол HTTPS. Самоподписанные и бесплатные сертификаты «Let’s Encrypt», которые поддерживает большинство хостингов, также подходят.
Пример настройки самоподписанного сертификата из официальной документации Telegram.
Шаг 3: пишем код
Писать код бота будем на PHP, но чтобы не изобретать заново колесо, воспользуемся уже готовой и очень удобной библиотекой.
Перво-наперво привязываем через метод SetWebhook бота к нашему файлу-обработчику. Сделать это можно при помощи библиотеки, но есть вариант быстрее и проще – это построить вот такую ссылку:
https:// api. telegram. org/bot375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s/setWebhook?url=https:// yoursitehere .ru/directory/bot.php,
где
375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s — это наш токен,
https:// yousitehere. ru/directory/bot.php — ссылка на файл-обработчик на нашем сайте.
Открыв в браузере эту ссылку, должен прийти JSON-ответ со значением «Webhook was set», что будет означать, что вебхук установлен, и теперь все запросы от пользователей будут присылаться по адресу файла-обработчика.
Переходим к самому главному — обработке этих самых запросов и написанию функционала бота.
Ниже представлен полный листинг файла-обработчика:
Разберем всё по порядку.
1. Сначала мы подключаем скачанную библиотеку, указав путь (лучше полный) до файла автозагрузчика.
2. Создаем экземпляр класса в переменной $telegram и передаем в него наш токен.
В переменной $result получаем информацию о сообщении, которое пришлет нам Telegram.
3. Затем определяем главные переменные: текстовое сообщение, уникальный идентификатор пользователя и его юзернейм. Если предстоит работа с БД, то не забывайте про фильтрацию (или лучше используйте PDO).
4. Создаем нашу клавиатуру, состоящую из трех кнопок.
5. Теперь, когда мы обозначили все переменные, можно перейти к обработке полученного сообщения. Для этого можно использовать конструкцию switch-case либо if-else. Так как принципиальной разницы между ними нет, остановимся на втором варианте, как наиболее привычном.
В самом начале проверяем, заполнена ли переменная $text и является ли сообщение пользователя текстовым.
Если нет, то отправляем пользователю с помощью метода sendMessage сообщение с просьбой ввести текстовое сообщение.
6. Рассмотрим вариант, когда пользователь прислал сообщение с командами /start или /help
В этом случае помимо текста из переменной $reply будет подгружаться клавиатура, состоящая из трёх кнопок: «Последние статьи», «Картинка» и «Гифка».
Реализуется это с помощью метода replyKeyboardMarkup, параметрами которого являются:
- ‘keyboard’ => $keyboard, передаем нашу клавиатуру
- ‘resize_keyboard’ => true, клавиатура будет сжата в размерах.
- ‘one_time_keyboard’ => false, клавиатура не исчезнет после нажатия на какую-то кнопку.
8. Для отправки картинки используется метод sendPhoto, для отправки гифки – sendDocument. В обоих случаях Telegram позволяет передавать прямую ссылку на файл, что безусловно очень удобно, но не так быстро, как если бы мы передавали file_id уже отправленной на сервера Telegram картинки или гифки.
9. Для получения последних статей используется простой парсинг RSS ленты Нетологии при помощи встроенной в PHP функции simplexml_load_file.
В параметрах метода sendMessage можно заметить два новых значения:
1) ‘parse_mode’ => ‘HTML’ , чтобы в сообщение можно было вставить HTML-теги или
2) чтобы к сообщению со ссылкой не подгружалось превью.
10. В качестве смайла (стрелка вправо) используются символы \xE2\x9E\xA1. Список всех смайлов в таком виде можно найти на специальном сайте.

11. После того, как вы протестируете бота и будете уверены в его работоспособности, можно отправлять его на всеобщее обозрение.
Благодаря удобному API, боты Telegram могут стать хорошей платформой для автоматизации рутинных действий, настройки уведомлений, удобному и быстрому получению информации и созданию игр.
Бесплатными площадками для продвижения могут послужить каталоги ботов Telegram Bot Store, TeleChappy или 50bots.
А анализировать активность пользователей можно с помощью бесплатного инструмента для аналитики ботов от Яндекса — Botan.