Передо мной появилась задача сделать телеграм бота на PHP. Я нашел два варианта решения этой задачи. Первый вариант, используя библиотеку telegram api, второй вариант без использования каких-либо библиотек. Сначала я будут инструкции, которые применимы к этим двум вариантам, а после рассмотрим каждый вариант более подробно
Обратите внимание, что действия указанные в этой статье, я делал на реальном сервере и домене у которого есть сертификат безопасности ssl, т.е. домен доступен по https. Телеграм требует этот сертификат.
Итак для начала нам необходимо создать нашего телеграм бота, для этого в телеграме необходимо найти телеграм бота @BotFather, в диалоге с этим ботом введите команду /newbot, после чего задайте имя и никнейм вашего бота. Вам будет предоставлен уникальный токен, сохраните его куда-нибудь, он вам еще пригодится.
Если вы хотите использовать вашего бота в чатах, то необходимо изменить его приватность. Для этого в диалоге с @BotFather введите команду /setprivacy, вам надо установить значение приватности в Disable.
Теперь перейдем к вариантам создания телеграм бота.
Для работы с телеграм ботом, вам надо выбрать папку на вашем сервере, в которой вы будете с ним работать, у меня это будет - mysite.ru/botinfo.
Установим библиотеку telegram api, которая упростит нам взаимодействие с ботом. Откройте консоль, перейдите в папку, которую вы выбрали и выполните следующие команды:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php composer-setup.php php -r "unlink('composer-setup.php');"
Этими командами вы установите composer, при помощи которого мы и скачаем библиотеку для работы с телеграмом. Выполните команду:
php composer.phar require telegram-bot/api
Этой командой вы установили библиотеку.
Теперь в папке, в моем случае это папка botinfo, создадим файл index.php в этом файле будем писать код для работы с нашим ботом.
Пример моего php кода в файле index.php
header('Content-Type: text/html; charset=utf-8'); // подключим API require_once("vendor/autoload.php"); $token = "token"; //Ваш токен, который вы получили при создании бота $bot = new \TelegramBot\Api\Client($token); if(!file_exists("registered.trigger")){ // URl текущей страницы $page_url = "https://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; $result = $bot->setWebhook($page_url); if($result){ file_put_contents("registered.trigger",time()); // создаем файл дабы прекратить повторные регистрации } } $bot->command('start', function ($message) use ($bot) { $answer = 'Привет!'; $bot->sendMessage($message->getChat()->getId(), $answer); }); $bot->on(function($Update) use ($bot){ $message = $Update->getMessage(); $mtext = $message->getText(); $cid = $message->getChat()->getId(); if($mtext == "+"){ $bot->sendMessage($message->getChat()->getId(), "-"); } }, function($message) use ($name){ return true; }); $bot->run();
В моем примере бот, на команду /start будет отвечать "Привет!", а на сообщение +, будет отвечать "-".
Условие if(!file_exists("registered.trigger")) нужно для того, чтобы телеграм бот понимал куда ему обращаться на вашем сайте, вам надо будет запустить этот файл из браузера, один раз, чтобы появился файл registered.trigger
Вы можете полазить по папкам библиотеки, которую вы скачали и посмотреть какую информацию может получить ваш бот. Ниже я приведу пару примеров таких функций и расскажу, что ими можно делать. Все эти функции я буду использовать в блоке $bot->on
$message->getFrom()->getId() - Уникальный идентификатор пользователя;
$message->getFrom()->getFirstName() - Имя пользователя;
$message->getFrom()->getLastName() - Фамилия пользователя;
$message->getFrom()->getUsername() - Никнейм пользователя;
$message->getChat()->getTitle() - Название чата;
$message->getChat()->getId() - Уникальный идентификатор чата;
$message->getDate() - Дата сообщения, в формате unix;
Пример получения координат, которые пользователь передал, отправив геолокацию в телеграме:
if($message->getLocation()){ $coord1 = $message->getLocation()->getLatitude(); $coord2 = $message->getLocation()->getLongitude(); }
Пример получения фото, которое отправил в телеграм пользователь:
$photoInfo = $message->getPhoto(); if($photoInfo){ $photoId = $photoInfo[0]->getFileId(); $file = $bot->getFile($photoId); $furl = $bot->getFileUrl().'/'.$file->getFilePath(); file_put_contents(basename($furl), file_get_contents( $furl ) ); } file_put_contents("/",$text);
Данный код, сохранит отправленную пользователем в телеграме картинку, к вам на сервер. Если вас не устраивает размер картинки, то можете поэксперементировать и заменить $photoInfo[0] на $photoInfo[1]. Как я понял в этом массиве содержатся разные размеры изображения.
Пример кода, для отправки фото
$pic = "https://mysite.ru/img/myphoto.jpg; $bot->sendPhoto($message->getChat()->getId(), $pic);
Этот код отправит фото, в тот чат, откуда был задан вопрос - $message->getChat()->getId(). В переменной $pic содержится ссылка на фото, которое вы хотите отправить.
Прежде всего рекомендую вам ознакомиться с документацией, которую дает телеграм - https://core.telegram.org/api
Для начала я приведу вам пример кода двух файлов, после чего разберу и поясню, что написано в каждом из этих файлов.
Файл telegrambot.php:
$body = file_get_contents('php://input'); $arr = json_decode($body, true); include_once ('telegramgclass.php'); $tg = new tg('токен который вы получили'); $chat_id = $arr['message']['chat']['id']; $userTgId = $arr['message']['from']['id']; $text = $arr['message']['text']; $coord1 = $arr['message']['location']['latitude']; $coord2 = $arr['message']['location']['longitude']; $tg->send($chat_id, "Нас не догонят!");
Файл telegramgclass.php:
class TG { public $token = ''; public function __construct($token) { $this->token = $token; } public function send($id, $message,$keyboard) { //Удаление клавы if($keyboard == "DEL"){ $keyboard = array( 'remove_keyboard' => true ); } if($keyboard){ //Отправка клавиатуры $encodedMarkup = json_encode($keyboard); $data = array( 'chat_id' => $id, 'text' => $message, 'reply_markup' => $encodedMarkup ); }else{ //Отправка сообщения $data = array( 'chat_id' => $id, 'text' => $message ); } $out = $this->request('sendMessage', $data); return $out; } public function getPhoto($data){ $out = $this->request('getFile', $data); return $out; } public function savePhoto($url,$puth){ $ch = curl_init('https://api.telegram.org/file/bot' . $this->token . '/' . $url); $fp = fopen($puth, 'wb'); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); } public function request($method, $data = array()) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'https://api.telegram.org/bot' . $this->token . '/' . $method); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); $out = json_decode(curl_exec($curl), true); curl_close($curl); return $out; } }
После того как создадите эти файлы, дайте знать телеграму куда ему слать информацию, это делается ссылкой: https://api.telegram.org/botВАШТОКЕН/setWebhook?url=ССЫЛКА_НА_telegrambot.php
Используя эти два файла, ваш телеграм бот на любое сообщение будет отвечать "Нас не догонят!" Разберемся, что у нас написано в файле telegrambot.php.
Переменная $body содержит информацию в json формате, которая приходит от телеграм. Как вы наверное уже догадались в переменной $chat_id у нас находится id чата, в переменной $userTgId - id пользователя, который послал сообщение, в $text - текст сообщения, которое послал пользователь, в переменных $coord1 и $coord2 будет информация о координатах, в случае если пользователь отправил геолокацию.
Если вам интересны все данные, которые приходят от телеграм, то советую эти данные записать в какой-нибудь файл, к примеру:
$fp = fopen("test.txt", "w+"); fwrite($fp, $body);
После чего можете отослать сообщение своему боту, затем открыть файл test.txt и посмотреть информацию в json формате, которая пришла когда вы отправили своему боту сообщение.
Пример такой информации:
{ "update_id":5489999, "message":{ "message_id":199, "from":{ "id":246667777, "is_bot":false, "first_name":"Stanislav", "last_name":"Korobkin", "username":"Korobkin_tg", "language_code":"ru" }, "chat":{ "id":246667777, "first_name":"Stanislav", "last_name":"Korobkin", "username":"Korobkin_tg", "type":"private" }, "date":1564644489, "photo":[ { "file_id":"AgADAgADdawxG_xHEErcM5mS2f7jD8ABuA8ABAEAgwIlA2jAA7-_AQABFgQ", "file_size":13083, "width":320,"height":227 }, { "file_id":"AgADAgADXawxG_xHEErcM5mS2v7jD8ABuA8ABAEAAwhUT3gAA8C_AQABFgQ", "file_size":36568, "width":639,"height":453 } ] } }
Как вы могли заметить, в этом примере, есть "photo", что говорит нам о том, что боту послали фото. Для того, чтобы сохранить фото, которое послали вашему боту, необходимо в файле telegrambot.php использовать следующий код:
$ardata = array('file_id' => $arr['message']['photo'][0]['file_id']); $zz = $tg->getPhoto($ardata); $filename = "/myimages/tg".strtotime(date("y-m-d H:i:s")).".jpg"; //Путь и название картинки, которую вы сохраняете $tg->savePhoto($zz["result"]["file_path"],$filename);
Кстати, если мы говорим о фото, которые вы посылаете телеграму, то имейте ввиду, что он их сжимает. Если вам надо получить информацию о фото, например какие-нибудь exif данные, то советую отправлять фото, как файл.
У вас также есть возможность отправить клавиатуру или кнопки в чат. Пример отправки кнопок в чат:
$arInfo["inline_keyboard"][0][0]["callback_data"] = 1; $arInfo["inline_keyboard"][0][0]["text"] = "Кнопка 1"; $arInfo["inline_keyboard"][1][0]["callback_data"] = 2; $arInfo["inline_keyboard"][1][0]["text"] = "Кнопка 2"; $tg->send($chat_id, "Примеры кнопок",$arInfo);
Пример отправки клавиатуры в чат:
$arInfo["keyboard"][0][0]["text"] = "Кнопка"; $tg->send($chat_id, "Посмотрите у вас должна появиться клавиатура!",$arInfo);
Для удаления клавиатуры, напишите вот это:
$tg->send($chat_id, "Удалили кнопку", "DEL");
В заключение могу сказать, что мне оказался ближе второй вариант, потому что достаточно прочитать документацию https://core.telegram.org/api и при этом не надо доплонительно изучать как работает какая-то сторонняя библиотека. Если у вас есть вопросы, пишите их в комментарии, я постараюсь ответить.