Пример простого бота для телеграм.
Он умеет получать сообщения пользователя и отвечать на них.
Данный способ работы основан на вебхуках, поэтому стоит учесть, что для его работы потребуется домен с SSL (HTTPS).
Файл "точка входа", его нужно выполнить в консоли сервера для установки веб хука.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
use Oddler\Telegram\CurrentTelegramBot as CTBot;
require_once (__DIR__.'/protected/config.php');
require_once (__DIR__.'/protected/CurrentTelegramBot.php');
/**
*
* Документация: https://core.telegram.org/api
*
* Запускать нужно через консоль:
*
* php main.php - установка хука
* php main.php unset - удаление хука
*/
// Переменная существует только при вызове из консоли
$argv = isset($argv)?$argv:[];
$oTelegramBot = new CTBot();
$oTelegramBot->dispath($argv);
Класс для работы с API телеграмма.
TelegramApi.php (Download)
<?php
/**
* Created by PhpStorm.
* User: Oddler
* Date: 17.11.2018
* Time: 13:03
*/
namespace Oddler\Telegram;
class TelegramApi
{
protected function _error_log ($sMessage){
//$sFile = __DIR__.'/bot.log';
//file_put_contents($sFile, date("m.d.Y H:i:s").': '.$sMessage."\n".file_get_contents($sFile));
error_log($sMessage);
}
/**
* Делает запрос к серверу
*
* @param resource $handle
*
* @return boolean
*/
protected function _exec_curl_request($handle)
{
$response = curl_exec($handle);
if ($response === false) {
$errno = curl_errno($handle);
$error = curl_error($handle);
$this->_error_log("Curl returned error $errno: $error");
curl_close($handle);
return false;
}
$http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
curl_close($handle);
if ($http_code >= 500) {
// do not wat to DDOS server if something goes wrong
sleep(10);
return false;
}
else if ($http_code != 200) {
$response = json_decode($response, true);
if ($http_code == 401) {
$this->_error_log("Invalid access token provided: {$response['error_code']}: {$response['description']}");
}
else {
$this->_error_log("Request has failed with error {$response['error_code']}: {$response['description']}");
}
return false;
}
else
{
$response = json_decode($response, true);
if (isset($response['description'])) {
$this->_error_log("Request was successfull: {$response['description']}");
}
$response = $response['result'];
}
return $response;
}
/**
* Подготовка запроса
*
* @param string $method
* @param array $parameters
*
* @return boolean
*/
// public function apiCall2($method, $parameters)
// {
// if (!is_string($method)) {
// $this->_error_log("Method name must be a string");
// return false;
// }
//
// if (!$parameters) {
// $parameters = array();
// }
// else if (!is_array($parameters)) {
// $this->_error_log("Parameters must be an array");
// return false;
// }
//
// foreach($parameters as $key => & $val) {
// // encoding to JSON array parameters, for example reply_markup
// if (!is_numeric($val) && !is_string($val)) {
// $val = json_encode($val);
// }
// }
//
// $url = API_URL . $method . '?' . http_build_query($parameters);
// $handle = curl_init($url);
// curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
// curl_setopt($handle, CURLOPT_TIMEOUT, 60);
// return $this->_exec_curl_request($handle);
// }
/**
* Подготовка Json запроса
*
* @param string $method
* @param array $parameters
*
* @return boolean
*/
public function apiCall($method, $parameters)
{
if (!is_string($method))
{
$this->_error_log("Method name must be a string");
return false;
}
if (!$parameters)
{
$parameters = array();
}
else if (!is_array($parameters))
{
$this->_error_log("Parameters must be an array");
return false;
}
$parameters["method"] = $method;
$handle = curl_init(API_URL);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 60);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($handle, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json"
));
return $this->_exec_curl_request($handle);
}
}
Класс с основными методами бота.
TelegramBot.php (Download)
<?php
/**
* Created by PhpStorm.
* User: Oddler
* Date: 17.11.2018
* Time: 13:13
*/
namespace Oddler\Telegram;
require_once (__DIR__.'/TelegramApi.php');
abstract class TelegramBot
{
/*
* @var object api
*/
protected $_oApi = null;
/**
* TelegramBot constructor.
*/
public function __construct() {
$this->_oApi = new TelegramApi();
}
/**
* Подготовка запроса (обертка для метода объекта TelegramApi)
*
* @param string $method
* @param array $parameters
*
* @return boolean
*/
protected function _apiCall($method, $parameters){
return $this->_oApi->apiCall($method, $parameters);
}
/**
* Обработка полученных сообщений
*
* @param array $message
*
* @return void
*/
protected abstract function _processMessage($message);
/**
* Устанавливаем web Hook
*
* @param array $argv Массив переданных скрипту аргументов
*
* @return void
*/
protected function _setHook($argv)
{
// if run from console, set or delete webhook
$this->_apiCall('setWebhook', array(
'url' => isset($argv[1]) && $argv[1] == 'unset' ? '' : WEBHOOK_URL
));
exit;
}
/**
* Обработка запроса
*
* @return void
*/
protected function _processRequest()
{
$content = file_get_contents("php://input");
$update = json_decode($content, true);
if (!$update) {
// receive wrong update, must not happen
exit;
}
if (isset($update["message"])) {
$this->_processMessage($update["message"]);
}
}
/**
* Обработка запроса
* @param array $argv Массив переданных скрипту аргументов
*/
public function dispath($argv){
try {
// Если вызавн из консоли
if (php_sapi_name() == 'cli'){
$this->_setHook($argv);
} else { // Если вызавн по https
$this->_processRequest();
}
} catch (\Exception $e) {
echo 'Выброшено исключение: ', $e->getMessage(), "\n";
}
}
}
Класс с методами конкретного бота. Можно сделать несколько таких классов и вызывать их при рамных условиях.
CurrentTelegramBot.php (Download)
<?php
/**
* Created by PhpStorm.
* User: Oddler
* Date: 17.11.2018
* Time: 16:07
*/
namespace Oddler\Telegram;
require_once (__DIR__.'/TelegramBot.php');
class CurrentTelegramBot extends TelegramBot
{
protected function _processPhoto($message){
//$sText = '852456';
// Получаем фото максимального размера
$aPhoto = $message['photo'][count($message['photo'])-1];
$id_file = $aPhoto['file_id'];
$aRet = $this->_apiCall("getFile", array(
'file_id' => $id_file
));
//$sText = print_r($aRet, TRUE);
$sFileName = basename($aRet['file_path']);
// Скачиваем во временную папку
copy('https://api.telegram.org/file/bot'.TOKEN.'/'.$aRet['file_path'],
__DIR__.'/../TMP/'.$sFileName
);
// Возвращает в чат, реплаем ссылку
$this->_apiCall("sendMessage", array(
'chat_id' => $message['chat']['id'],
'parse_mode' => 'html',
"reply_to_message_id" => $message['message_id'],
"text" => '<a href="'.SITE_URL.'/images/'.$sFileName.'">'.$sFileName.'</a>'
));
}
/**
* Обработка полученных сообщений
*
* @param array $message
*
* @return void
*/
protected function _processMessage($message)
{
// process incoming message
$id_message = $message['message_id'];
$id_chat = $message['chat']['id'];
if (isset($message['text']))
{
// incoming text message
$text = $message['text'];
if (strpos($text, "/start") === 0)
{
$this->_apiCall("sendMessage", array(
'chat_id' => $id_chat,
"text" => 'Hello',
'reply_markup' => array(
'keyboard' => array(
array(
'Hello',
'Hi'
)
) ,
'one_time_keyboard' => true,
'resize_keyboard' => true
)
));
}
else if ($text === "Hello" || $text === "Hi")
{
$this->_apiCall("sendMessage", array(
'chat_id' => $id_chat,
"text" => 'Nice to meet you'
));
}
else if ($text === "123")
{
$this->_apiCall("sendMessage", array(
'chat_id' => $id_chat,
"text" => print_r($message, TRUE)
));
}
else
{
$this->_apiCall("sendMessage", array(
'chat_id' => $id_chat,
"reply_to_message_id" => $id_message,
"text" => 'Cool'
));
}
}
else if (isset($message['photo']))
{
$this->_processPhoto($message);
}
else
{
$this->_apiCall("sendMessage", array(
'chat_id' => $id_chat,
"text" => print_r($message, TRUE)
));
}
}
}
Скачать паком