Как сделать бота в Telegram
Всем привет! Давно не писал, и чувствую, что это надо восполнить)
В общем недавно делал бота в телеграмме (@GraphCreator_bot или http://t.me/GraphCreator_bot), который из текстовых файлов делает графики. Не очень полезная штука, но это первый блин.
Создать бота
Итак, как создать бота в телеграмме.
В телеграмме перейдите к «Крёстному отцу» всех ботов — @BotFather. Выберите команду /newbot и дайте ему любое имя. После, введите username (уникальный и заканчивающийся на bot). Отнеситесь к уникальному имени серьёзно, ведь именно по нему будут искать вашего бота. Ваш бот готов! Отец всех ботов пришлёт вам токен вашего бота, который мы и будем использовать. Отца так же можно попросить добавить ботам описание и фото аватара.
На этом можно окончить возню с телеграммом (для отладки лучше скачать десктоп версию кстати!).
Настройка вебхука
Пожалуй наитруднейшая часть.
У вас должен быть SSL сеертификат, а по-обывательски: домен должен начинаться с https. Что бы его приобрести можно пойти двумя путями:
1) Изначально при покупке домена подключить SSL. У многих хостинг-провайдеров есть бесплатные сертификаты (к примеру у TimeWeb).
2) Можно самому на сервере поработать с командной строкой и сделать «самодельный сертификат». Однако боюсь, что для многих действий потребуется, права администратора, то есть сервер у вас должен быть либо выделенным, либо VDS. Подробнее тут.
Дальше нужно сказать серверу телеграмма, что по такому-то адресу он должен отправлять нам обновления (updates), то есть команды и сообщения, которые он отправляет нашему боту в чат.
Для этого нам нужно отправить запрос от нашего сервера к серверу телеграмма, поэтому напишем сразу команду, которой мы будем отправлять методы и параметры, а она будет выдавать результаты наших запросов.
[Сразу оговорюсь, что я использую фреймворк yii2, поэтому читайте дальше в конце дам совет, если вы не на фреймворке]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Tgram extends \yii\base\Model { protected $token = 'NUMBERS:RandoMStRing'; //ваш токен public function getReq($method,$params=[],$decoded=0){ //параметр 1 это метод, 2 - это массив параметров к методу, 3 - декодированный ли будет результат будет или нет. $url = "https://api.telegram.org/bot{$this->token}/$method"; //основная строка и метод if(count($params)){ $url=$url.'?'.http_build_query($params);//к нему мы прибавляем парметры, в виде GET-параметров } $curl = curl_init($url); //инициализируем curl по нашему урлу curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //здесь мы говорим, чтобы запром вернул нам ответ сервера телеграмма в виде строки, нежели напрямую. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //Не проверяем сертификат сервера телеграмма. $result = curl_exec($curl); // исполняем сессию curl curl_close($curl); // завершаем сессию if($decoded){ return json_decode($result);// если установили, значит декодируем полученную строку json формата в объект языка PHP } return $result; //Или просто возращаем ответ в виде строки } //..... } |
Теперь создадим экшн в контроллере, который отправит запрос серверам телеграмма с url нашей странички, которая будет принимать апдейты от сервера телеграмма, а именно от пользователей нашего бота.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php namespace app\modules\grapher\controllers; use yii\web\Controller; use app\modules\grapher\models\Tgram; /** * Default controller for the `grapher` module */ class DefaultController extends Controller { /** * Renders the index view for the module * @return string */ public function actionIndex() { $model = new Tgram(); //открываем наш класс с функцией послания запроса //отправляем метод setWebhook с параметром полного url нашей страницы, которая будет принимать все апдейты $resp = $model->getReq('setWebhook',[ 'url'=>'https://tonygram.ru/grapher/hook/index', ]); return $resp; } } |
После этого переходим по адресу этого php файла и отправляется запрос.
вебхук установлен! Поздравляю, если у вас всё получилось.
Тело бота
Итак, что мы сделали? Установив вебхук, бот работает в следующем режиме:
- Пользователь отправляет команду или текст
- Оно приходит на сервер телеграмма
- Телеграмм тут же «стучиться» в ваш вебхук
- Вебхук отправляет запрос телеграмму, а тот наконец пользователю.
Это pull запрос, то есть не мы вытягиваем апдейт с телеграмма, а он идёт к нам.
Как выглядит вебхук. вообще как-то так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php namespace app\modules\grapher\controllers; use Yii; use yii\web\Controller; use app\modules\grapher\models\Tgram; use yii\helpers\Url; /** * Default controller for the `grapher` module */ class HookController extends Controller { /** * Renders the index view for the module * @return string */ public function beforeAction($action) { $this->enableCsrfValidation = false;// эта строка для тех, кто пользуется Yii2 - означает, что мы отключаем проверку csrf, которая контролировала, что бы все запросы были от нашего сайта, а не с левых серваков return parent::beforeAction($action); } public function actionIndex() { $content = file_get_contents('php://input'); //интересная строка: означает, что мы поточно воспринимаем запрос, который к нам пришел. Подробнее после) $update = json_decode($content); //декодируем апдейт json, пришедший с телеграмма if($update){ echo $content; } $file = file_put_contents('income.txt', $content); // создаем текстовый файл для отладки(по желанию) } |
Итак что же такое file_get_contents(‘php://input’) ? php:// — это доступ к различным потокам ввода-вывода. php://input является потоком только для чтения, который позволяет вам читать необработанные данные из тела запроса (подробнее).
А дальше обрабатывайте апдейты как хотите!) Вот пример отправки сообщения с html маркировкой:
1 2 3 4 5 |
$model->getReq('sendMessage',[ 'chat_id'=>$update->message->chat->id, 'text'=>"Great! Now send me column number with <strong>X </strong>values", 'parse_mode'=>'HTML', ]); |
Выглядеть это будет так:
На этом можно закончить. Ссылка на методы Bot API https://core.telegram.org/bots/api .
Если вам необходимо выполнить какой-то проект в сфере Телеграмм ботов — обращайтесь: anton@abrekhov.ru !)
Тем, кто не на фреймворке
Итак, если вы скопируете всё, что внутри экшнов и классов и поместите всё в один php файл получится всё то же самое)
19 февраля, 2018 @ 08:03
Нет кода Экшена, вместо него в блоке вывода кода содержится «Произошла ошибка. Попробуйте ещё раз позднее.»
Поправьте пожалуйста.
20 июня, 2018 @ 07:43
Спасибо, что отписал! Исправил, теперь вроде отображается.