225 lines
18 KiB
Markdown
225 lines
18 KiB
Markdown
|
[https://habr.com/ru/company/netologyru/blog/326174/](https://habr.com/ru/company/netologyru/blog/326174/)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Шукюров Заур, разработчик [@KinomanBot](http://t.me/kinomanbot) и [@GaidarForum_bot](http://t.me/gaidarforum_bot), написал руководство по созданию простого чат-бота на [PHP](http://netology.ru/programs/php-sql?utm_source=blog&utm_medium=747&utm_campaign=habr).
|
|||
|
|
|||
|
24 июня 2015 года разработчики Telegram [открыли](https://core.telegram.org/bots) платформу для создания ботов (программ, которые выполняют определенные действия по заданному алгоритму).
|
|||
|
|
|||
|
За полтора года работы платформы набралось много интересных чат-ботов, решающих множество проблем и позволяющих с пользой провести время в мессенджере.
|
|||
|
|
|||
|
![[1c54f0445bdf4c9e8b9152d44ba018ea.jpg]]
|
|||
|
|
|||
|
## Шаг 1: регистрация бота у _@BotFather_
|
|||
|
|
|||
|
Прежде чем начать писать код, нового бота нужно зарегистрировать у «папы всех ботов» — _@BotFather_, чтобы получить токен (ключ) для работы с Telegram API.
|
|||
|
|
|||
|
Регистрация проходит в 5 простых этапов:
|
|||
|
|
|||
|
1) Открываете чат с _@BotFather_;
|
|||
|
2) Вводите или выбираете из списка команду
|
|||
|
_/newbot_;
|
|||
|
3) Отправляете желаемое название для бота;
|
|||
|
|
|||
|
4) Пишете юзернейм бота, по которому его будут находить через поиск. Обязательно на конце вашего юзернейма должно быть слово «bot» или «_bot». Например,
|
|||
|
_NetologyRSSbot_;
|
|||
|
5) По желанию можно сразу настроить полное или краткое описание, список команд и аватарку.
|
|||
|
|
|||
|
![[5b740f4b03044274a3949b129d0b9635.png]]
|
|||
|
|
|||
|
По итогу регистрации получаем наш токен — _375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s_.
|
|||
|
Будьте осторожны: никогда и никому не показывайте токен, иначе ваш бот может быть скомпрометирован. Если по несчастливой случайности кто-то нехороший все-таки узнал ваш токен, то заменить его можно всё в том же
|
|||
|
_@BotFather_, нажав на кнопку «Revoke current token» в разделе «API Token».
|
|||
|
|
|||
|
## Шаг 2: выбираем способ обработки запросов
|
|||
|
|
|||
|
Исходя из официальной документации, Telegram API основан на простых HTTP-запросах. Существует всего два различных способа обрабатывать запросы, которые пользователи будут посылать боту:
|
|||
|
|
|||
|
1) проверять «вручную», используя «Long Polling»;
|
|||
|
2) доверить всё Telegram, поставив «Webhook». В этом случае любой запрос от пользователя Telegram сам будет посылать нам на сервер.
|
|||
|
|
|||
|
Мы остановимся на втором варианте, но у него есть ограничение: у вас на сайте обязательно должен быть установлен SSL-сертификат, чтобы все запросы проходили через безопасный протокол HTTPS. Самоподписанные и бесплатные сертификаты «Let’s Encrypt», которые поддерживает большинство хостингов, также подходят.
|
|||
|
|
|||
|
[Пример](https://core.telegram.org/bots/self-signed) настройки самоподписанного сертификата из официальной документации Telegram.
|
|||
|
|
|||
|
## Шаг 3: пишем код
|
|||
|
|
|||
|
Писать код бота будем на PHP, но чтобы не изобретать заново колесо, воспользуемся уже готовой и очень удобной [библиотекой](https://github.com/irazasyed/telegram-bot-sdk).
|
|||
|
|
|||
|
Перво-наперво привязываем через метод SetWebhook бота к нашему файлу-обработчику. Сделать это можно при помощи библиотеки, но есть вариант быстрее и проще – это построить вот такую ссылку:_https:// api. telegram. org/bot__**375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s**__/setWebhook?url=__**https:// yoursitehere .ru/directory/bot.php**_,
|
|||
|
где
|
|||
|
_375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s_ — это наш токен,_https:// yousitehere. ru/directory/bot.php_ — ссылка на файл-обработчик на нашем сайте.
|
|||
|
|
|||
|
Открыв в браузере эту ссылку, должен прийти JSON-ответ со значением _«Webhook was set»_, что будет означать, что вебхук установлен, и теперь все запросы от пользователей будут присылаться по адресу файла-обработчика.
|
|||
|
|
|||
|
Переходим к самому главному — обработке этих самых запросов и написанию функционала бота.
|
|||
|
|
|||
|
Ниже представлен полный листинг файла-обработчика:
|
|||
|
|
|||
|
```
|
|||
|
<?php
|
|||
|
include('vendor/autoload.php'); //Подключаем библиотеку
|
|||
|
use Telegram\Bot\Api;
|
|||
|
|
|||
|
$telegram = new Api('375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s'); //Устанавливаем токен, полученный у BotFather
|
|||
|
$result = $telegram -> getWebhookUpdates(); //Передаем в переменную $result полную информацию о сообщении пользователя
|
|||
|
|
|||
|
$text = $result["message"]["text"]; //Текст сообщения
|
|||
|
$chat_id = $result["message"]["chat"]["id"]; //Уникальный идентификатор пользователя
|
|||
|
$name = $result["message"]["from"]["username"]; //Юзернейм пользователя
|
|||
|
$keyboard = [["Последние статьи"],["Картинка"],["Гифка"]]; //Клавиатура
|
|||
|
|
|||
|
if($text){
|
|||
|
if ($text == "/start") {
|
|||
|
$reply = "Добро пожаловать в бота!";
|
|||
|
$reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);
|
|||
|
}elseif ($text == "/help") {
|
|||
|
$reply = "Информация с помощью.";
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply ]);
|
|||
|
}elseif ($text == "Картинка") {
|
|||
|
$url = "https://68.media.tumblr.com/6d830b4f2c455f9cb6cd4ebe5011d2b8/tumblr_oj49kevkUz1v4bb1no1_500.jpg";
|
|||
|
$telegram->sendPhoto([ 'chat_id' => $chat_id, 'photo' => $url, 'caption' => "Описание." ]);
|
|||
|
}elseif ($text == "Гифка") {
|
|||
|
$url = "https://68.media.tumblr.com/bd08f2aa85a6eb8b7a9f4b07c0807d71/tumblr_ofrc94sG1e1sjmm5ao1_400.gif";
|
|||
|
$telegram->sendDocument([ 'chat_id' => $chat_id, 'document' => $url, 'caption' => "Описание." ]);
|
|||
|
}elseif ($text == "Последние статьи") {
|
|||
|
$html=simplexml_load_file('http://netology.ru/blog/rss.xml');
|
|||
|
foreach ($html->channel->item as $item) {
|
|||
|
$reply .= "\xE2\x9E\xA1 ".$item->title." (<a href='".$item->link."'>читать</a>)\n";
|
|||
|
}
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, 'text' => $reply ]);
|
|||
|
}else{
|
|||
|
$reply = "По запросу \"<b>".$text."</b>\" ничего не найдено.";
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode'=> 'HTML', 'text' => $reply ]);
|
|||
|
}
|
|||
|
}else{
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => "Отправьте текстовое сообщение." ]);
|
|||
|
}
|
|||
|
?>
|
|||
|
```
|
|||
|
|
|||
|
Разберем всё по порядку.
|
|||
|
|
|||
|
**1.** Сначала мы подключаем скачанную библиотеку, указав путь (лучше полный) до файла автозагрузчика.
|
|||
|
|
|||
|
```
|
|||
|
include('vendor/autoload.php'); //Подключаем библиотеку
|
|||
|
use Telegram\Bot\Api;
|
|||
|
```
|
|||
|
|
|||
|
**2.** Создаем экземпляр класса в переменной _$telegram_ и передаем в него наш токен.
|
|||
|
|
|||
|
В переменной _$result_ получаем информацию о сообщении, которое пришлет нам Telegram.
|
|||
|
|
|||
|
```
|
|||
|
$telegram = new Api('375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s'); //Устанавливаем токен, полученный у BotFather
|
|||
|
$result = $telegram -> getWebhookUpdates(); //Передаем в переменную $result полную информацию о сообщении пользователя
|
|||
|
```
|
|||
|
|
|||
|
**3.** Затем определяем главные переменные: текстовое сообщение, уникальный идентификатор пользователя и его юзернейм. Если предстоит работа с БД, то не забывайте про фильтрацию (или лучше используйте PDO).
|
|||
|
|
|||
|
```
|
|||
|
$text = $result["message"]["text"]; //Текст сообщения
|
|||
|
$chat_id = $result["message"]["chat"]["id"]; //Уникальный идентификатор пользователя
|
|||
|
$name = $result["message"]["from"]["username"]; //Юзернейм пользователя
|
|||
|
```
|
|||
|
|
|||
|
**4.** Создаем нашу клавиатуру, состоящую из трех кнопок.
|
|||
|
|
|||
|
```
|
|||
|
$keyboard = [["Последние статьи"],["Картинка"],["Гифка"]]; //Клавиатура
|
|||
|
```
|
|||
|
|
|||
|
**5.** Теперь, когда мы обозначили все переменные, можно перейти к обработке полученного сообщения. Для этого можно использовать конструкцию _switch-case_ либо _if-else_. Так как принципиальной разницы между ними нет, остановимся на втором варианте, как наиболее привычном.
|
|||
|
|
|||
|
В самом начале проверяем, заполнена ли переменная _$text_ и является ли сообщение пользователя текстовым.
|
|||
|
|
|||
|
```
|
|||
|
if($text){
|
|||
|
…
|
|||
|
//код
|
|||
|
...
|
|||
|
}else{
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => "Отправьте текстовое сообщение." ]);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Если нет, то отправляем пользователю с помощью метода sendMessage сообщение с просьбой ввести текстовое сообщение.
|
|||
|
|
|||
|
**6.** Рассмотрим вариант, когда пользователь прислал сообщение с командами _/start_ или _/help_
|
|||
|
|
|||
|
```
|
|||
|
if ($text == "/start") {
|
|||
|
$reply = "Добро пожаловать в бота!";
|
|||
|
$reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);
|
|||
|
}elseif ($text == "/help") {
|
|||
|
$reply = "Информация с помощью.";
|
|||
|
$reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
В этом случае помимо текста из переменной _$reply_ будет подгружаться клавиатура, состоящая из трёх кнопок: «Последние статьи», «Картинка» и «Гифка».
|
|||
|
|
|||
|
Реализуется это с помощью метода _replyKeyboardMarkup_, параметрами которого являются:
|
|||
|
|
|||
|
- _'keyboard' => $keyboard_, передаем нашу клавиатуру
|
|||
|
- _'resize_keyboard' => true_, клавиатура будет сжата в размерах.
|
|||
|
- _'one_time_keyboard' => false_, клавиатура не исчезнет после нажатия на какую-то кнопку.
|
|||
|
|
|||
|
**7.** После появления клавиатуры пользователь явно захочет попробовать потыкать на расположенные на ней кнопки, и вот что у нас «под капотом» в этом случае:
|
|||
|
|
|||
|
```
|
|||
|
}elseif ($text == "Картинка") {
|
|||
|
$url = "https://68.media.tumblr.com/6d830b4f2c455f9cb6cd4ebe5011d2b8/tumblr_oj49kevkUz1v4bb1no1_500.jpg";
|
|||
|
$telegram->sendPhoto([ 'chat_id' => $chat_id, 'photo' => $url, 'caption' => "Описание." ]);
|
|||
|
}elseif ($text == "Гифка") {
|
|||
|
$url = "https://68.media.tumblr.com/bd08f2aa85a6eb8b7a9f4b07c0807d71/tumblr_ofrc94sG1e1sjmm5ao1_400.gif";
|
|||
|
$telegram->sendDocument([ 'chat_id' => $chat_id, 'document' => $url, 'caption' => "Описание." ]);
|
|||
|
}elseif ($text == "Последние статьи") {
|
|||
|
$html=simplexml_load_file('http://netology.ru/blog/rss.xml');
|
|||
|
foreach ($html->channel->item as $item) {
|
|||
|
$reply .= "\xE2\x9E\xA1 ".$item->title." (<a href='".$item->link."'>читать</a>)\n";
|
|||
|
}
|
|||
|
$telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, 'text' => $reply ]);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
**8.** Для отправки картинки используется метод _sendPhoto_, для отправки гифки – _sendDocument_. В обоих случаях Telegram позволяет передавать прямую ссылку на файл, что безусловно очень удобно, но не так быстро, как если бы мы передавали [_file_id_](https://core.telegram.org/bots/api#sending-files) уже отправленной на сервера Telegram картинки или гифки.
|
|||
|
|
|||
|
**9.** Для получения последних статей используется простой парсинг [RSS](http://netology.ru/blog/rss.xml) ленты Нетологии при помощи встроенной в PHP функции _simplexml_load_file_.
|
|||
|
|
|||
|
В параметрах метода _sendMessage_ можно заметить два новых значения:
|
|||
|
|
|||
|
1) `'parse_mode' => 'HTML'`, чтобы в сообщение можно было вставить HTML-теги
|
|||
|
|
|||
|
```
|
|||
|
<b>, <a>, <i>, <code>
|
|||
|
```
|
|||
|
|
|||
|
или
|
|||
|
|
|||
|
```
|
|||
|
<pre>
|
|||
|
```
|
|||
|
|
|||
|
2) чтобы к сообщению со ссылкой не подгружалось превью.
|
|||
|
|
|||
|
**10.** В качестве смайла (стрелка вправо) используются символы _\xE2\x9E\xA1_. Список всех смайлов в таком виде можно найти на специальном [сайте](http://apps.timwhitlock.info/emoji/tables/unicode).
|
|||
|
|
|||
|
![[1618e71f9c8d491f85910a33a2536659.jpg]]
|
|||
|
|
|||
|
**11.** После того, как вы протестируете бота и будете уверены в его работоспособности, можно отправлять его на всеобщее обозрение.
|
|||
|
|
|||
|
Благодаря удобному API, боты Telegram могут стать хорошей платформой для автоматизации рутинных действий, настройки уведомлений, удобному и быстрому получению информации и созданию игр.
|
|||
|
|
|||
|
Бесплатными площадками для продвижения могут послужить каталоги ботов [Telegram Bot Store](https://storebot.me/), [TeleChappy](http://telechappy.com/) или [50bots](http://50bots.com/).
|
|||
|
|
|||
|
А анализировать активность пользователей можно с помощью бесплатного инструмента для аналитики ботов от Яндекса — [Botan](http://botan.io/).
|
|||
|
|
|||
|
## От редакции
|
|||
|
|
|||
|
[PHP](http://netology.ru/programs/php-sql?utm_source=blog&utm_medium=747&utm_campaign=habr) — один из самых популярных языков программирования. Его легко изучать, с ним легко работать, у него мощное сообщество. 5 мая «Нетология» запускает курс [«PHP/SQL: back-end разработка и базы данных»](http://netology.ru/programs/php-sql?utm_source=blog&utm_medium=747&utm_campaign=habr), где ведущие программисты расскажут об управляющих конструкциях, циклах, функциях, о строках и массивах. Вы узнаете все про реляционные базы данных и язык запросов SQL, научитесь устанавливать и настраивать веб-сервер nginx и php, управлять базами данных различной сложности. Ждем вас!
|