net4me.net

Linux технологии, сети и электроника

Telegram, боты и PHP

Пишем простых ботов на php и разбираемся как это работает.
Просто, доступно, на конкретных примерах.

Telegram bot code

Telegram боты на php своими руками. Простые примеры.

Сюда буду сваливать примеры с комментариями.
Расписывать что да как - времени нет, извините.
Итак, этот раздел посвящен телеграм ботам.
И, как можно понять из названия, боты будут написаны именно РНР.
Постараюсь максимально упростить и писать без использования библиотек, модулей и т.п. Максимально просто и понятно.

Предполагается, что читатель уже знаком с телеграмом, зарегистрировал бота у @BotFather, разобрался с хостингом с SSL сертификатом, разобрался с telegram bot api, установкой, удалением Webhook на url скрипта (типа https://my.site.ru/bot/mytupobot.php лично мне в этом очень помог curl из консоли):
curl https://api.telegram.org/botXXXX:XXXXXXXXXXXXX/deleteWebhook
curl -d "url=https://my.site.ru/bot/mytupobot.php" https://api.telegram.org/botXXXX:XXXXXXXXXXX/setWebhook
curl https://api.telegram.org/botXXXX:XXXXXXXXXXXXX/getWebhookInfo
и готов написать своего первого бота прям срочно, чтобы хоть какой-то результат получить от этого. =)

Тупо-бот, самый простой телеграм бот на php, который почти ничего не делает болванка для проектов:

<?php
/**
 * Telegram Bot тупо бот access token и URL.
 */
$access_token = 'XXXXX:XXXXXXXXXXXXXXXXXXXXXXX';
$api = 'https://api.telegram.org/bot' . $access_token;
/**
 * Задаём основные переменные.
 */
$output = json_decode(file_get_contents('php://input'), TRUE);
@$chat_id = $output['message']['chat']['id'];
@$message = $output['message']['text'];
// команды тупо-бота
switch($message) {
    case '/start':
    sendMessage($chat_id, "\xF0\x9F\x93\xA1 тупобот на связи!");
    break;
}

function sendMessage($chat_id, $message) {
  file_get_contents($GLOBALS['api'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($message) . '&parse_mode=html');
}
Итак, этот тупо-бот всё же чего-то делает.
Например, бот умеет слушать сообщения чата в котором сидит и на команду /start выдавать тупо сообщение, смайлик и говорить что он на связи.
А для бота это самое главное - уметь слушать и уметь отправлять сообщение.
Постарался в примере показать некоторые детали. Такие как вставка смайлов в сообщения бота, парс-мод в html сообщения, выгребания из сообщений команд. Вроде самое необходимое есть и наглядно.

UPD: Исходники этих и других примеров php ботов расположены на гитЛабе https://gitlab.com/net4me/telegram-php и код лучше брать оттуда.
Тут код неудобно мне обновлять, но я стараюсь это делать по возможности.

Пример "welcome message".

Задача: При подключении юзера к каналу - выдать приветственное сообщение.
При покидании юзером канала - вывести прощальное сообщение.
<?php
/**
 * Telegram Bot встречальщик access token и URL.
 */
$access_token = 'XXXXX:XXXXXXXXXXXXXXXXXXXXXXX';
$api = 'https://api.telegram.org/bot' . $access_token;
/**
 * Задаём основные переменные.
 */
$output = json_decode(file_get_contents('php://input'), TRUE);
@$chat_id = $output['message']['chat']['id'];
@$message = $output['message']['text'];
// приветствие нового члена чата:
if ($output['message']['new_chat_member']){
	$obj = $output['message']['new_chat_member'];
	$newCM ="Привет 
	". $obj['first_name'] .", известный как @".$obj['username'] . "!
	Добро пожаловать!"; 
	sendMessage( $chat_id, $newCM );
}
// прощание
if ($output['message']['left_chat_member']){
	$leftCM = "Упс... @". $output['message']['left_chat_member']['username'] . " покинул нас.";
	sendMessage($chat_id, $leftCM);
}
// команды бота встречальщика
switch($message) {
    case '/start':
    sendMessage($chat_id, "\xF0\x9F\x93\xA1 бот встречальщик на связи!");
    break;
}

function sendMessage($chat_id, $message) {
  file_get_contents($GLOBALS['api'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($message) . '&parse_mode=html');
}
Пример простой. Но заставляет задуматься, а что же там в этом контенте такого, что оттуда можно достать всё что угодно? Делаем самого неправильного бота дебагера.

Бот дебагер отладчик. Постит json объекты как есть

Само-собой разумеется, что запускать такого бота-отладчика в паблик чаты глупо, вредно и очень по лоховски.
Предполагается, что у нас есть приватный чат, куда приглашен наш бот, которому мы сейчас сделаем отладочную начинку.
<?php
/**
 * Telegram Bot Debugger access token и URL.
 */
$access_token = 'XXXXX:XXXXXXXXXXXXXXXXXXXXXXX';
$api = 'https://api.telegram.org/bot' . $access_token;
/**
 * Задаём основные переменные.
 */
$output = json_decode(file_get_contents('php://input'), TRUE);
@$chat_id = $output['message']['chat']['id'];
@$message = $output['message']['text'];

switch($message) {
    case '/start':
    sendMessage($chat_id, "\xF0\x9F\x93\xA1 бот debugger на связи!");
    break;
    default:
    $myDebug = "<pre>". json_encode($output) ."</pre>"; sendMessage($chat_id, $myDebug);
    break;
}

function sendMessage($chat_id, $message) {
  file_get_contents($GLOBALS['api'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($message) . '&parse_mode=html');
}
Что мы сделали? Правильно. Все сообщения (кроме команды /start , на которую мы реагируем ) выдаём в сыром виде. Как есть.
Должен заметить, что PHP далеко не самый заточенный под ботов язык программирования. Но в качестве начала изучения telegram bot api вполне подходит и php.

Эти и другие примеры простых телеграм ботов, работающих через webHook вы найдете на github https://github.com/BenJanet4me/telegram-php
И конечно, до новых встреч на портале net4me!

Дополнение: Использование inline keyboard в сообщениях.

Спасибо 4eburashk.  
<?php
/**
 * Telegram Bot Debuger access token и URL.
 */
$access_token = 'XXXXX:XXXXXXXXXXXXXXXXXXXXXXX';
$api = 'https://api.telegram.org/bot' . $access_token;
/**
 * Задаём основные переменные.
 */
$output = json_decode(file_get_contents('php://input'), TRUE);
@$chat_id = $output['message']['chat']['id'];
@$message = $output['message']['text'];
@$callback_query = $output['callback_query'];
@$data = $callback_query['data'];
@$chat_id_in = $callback_query['message']['chat']['id'];
@$message_id = $callback_query['message']['message_id'];

// inline keyboard set:
$inline_button3 = array("inline_message_id"=>"3","text"=>"show all","callback_data"=>'/1');
$inline_button4 = array("inline_message_id"=>"4","text"=>"show callback","callback_data"=>'/2');
$inline_keyboard1 = [[$inline_button3,$inline_button4]];
$keyboard1=array("inline_keyboard"=>$inline_keyboard1);

// do markup with inline keyboard:
$replyMarkup1 = json_encode($keyboard1);
switch($message) {
    case '/start':
    	sendMessage($chat_id, "\xF0\x9F\x93\xA1 бот debugger на связи!");
    break;
    default:
		$myDebug = "<pre>". json_encode($output) ."</pre>";
		sendKeyboard($chat_id, $myDebug, $replyMarkup1); //send message with inline keyboard
    break;
}
// callback data
switch($data){
	case '/1':
		// чтоб не крутились часы, посылаем пустой ответ при нажатии на кнопку.
		// for delete "clock" on keyboard button - send null callback query answer:
		send_answerCallbackQuery($callback_query['id'], null, false);
		$myDebug = "<pre>". json_encode($output) ."</pre>";
		sendKeyboard($chat_id_in, $myDebug);
	break;
	case '/2':
		send_answerCallbackQuery($callback_query['id'],'callback id: ' . $callback_query['id'],true);
		$myDebug = "<pre>". json_encode($output) ."</pre>";
		sendKeyboard($chat_id_in, $myDebug);
	break;
}

// Вместо универсальной функции, для наглядности используем различные функции отправки сообщений.

// Посылаем сообщение (send only message)
function sendMessage($chat_id, $message) {
  file_get_contents($GLOBALS['api'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($message) . '&parse_mode=html');
}

// Посылаем сообщение с клавиатурой (send message with inline keyboard in reply markup)
function sendKeyboard($chat_id, $message, $replyMarkup) {
  file_get_contents($GLOBALS['api'] . '/sendMessage?chat_id=' . $chat_id . '&text=' . urlencode($message) . '&parse_mode=html&reply_markup=' . $replyMarkup);
}

// Посылае ответ на нажатие кнопок (send callback query answer):
function send_answerCallbackQuery($callback_query_id, $text, $show_alert){
  file_get_contents($GLOBALS['api'] . '/answerCallbackQuery?callback_query_id=' . $callback_query_id . '&text=' . $text . '&show_alert=' . $show_alert );
}

// END
Свежие версии этих php ботов вы найдёте в нашем репозитории на gitLab: https://gitlab.com/net4me/telegram-php
Дополнение: У данной статьи появилось продолжение про использование curl и post для отправки в telegram фото, файлов, координат, аудио и т.д.
Добро пожаловать во вторую часть статьи!