PHP

Бот Телеграм на PHP

Примеры как зарегистрировать бота в Telegram, описание и взаимодействие с основными методами API. Документация на core.telegram.org и tlgrm.ru (неофициальный, на русском).

Ограничения:

  • Все запросы к API должны осуществляться по HTTPS, подойдет бесплатный сертификат «Let’s Encrypt».
  • В связи с блокировкой Telegram в РФ, возможно придется использовать прокси (в зависимости от нахождения серверов хостинга).
1

Регистрация бота

Для регистрации нового бота нужно написать «папе ботов» @BotFather команду /newbot

Регистрация бота в Telegram

Следующим сообщением отправляем название для бота, обязательно на конце имени должно быть слово «bot» или «_bot». Ответным сообщением получим токен:

Получение токена к bot API Telegram

Тут же можно настроить описание и аватарку:

/setname имя
/setdescription краткое описание
/setabouttext описание бота
/setuserpic юзерпик

Далее нужно поставить «Webhook» чтобы все сообщения из Telegram приходили на PHP скрипт. Для этого нужно пройти по ссылке в которой подставлены полученный токен и адрес скрипта.

https://api.telegram.org/bot<token>/setWebhook?url=https://snipp.ru/bot.php

В ответе будет:

{"ok":true,"result":true,"description":"Webhook was set"}

При смене токена, установку вебхука нужно повторить.

2

Входящие сообщения

Сообщения приходят POST-запросом, с типом application/json. Получить его в PHP можно следующим образом:

$data = file_get_contents('php://input');
$data = json_decode($data, true);

Чтобы посмотреть входящие данные, их придется дампить в файл:

ob_start();
print_r($data);
$out = ob_get_clean(); 
file_put_contents(__DIR__ . '/message.txt', $out);

Текстовое сообщение

Запрос от Телеграм:

Array (
    [update_id] => 17584194
    [message] => Array (
        [message_id] => 26
        [from] => Array (
            [id] => 123456789
                [is_bot] => 
                [first_name] => UserName
                [language_code] => ru-US
            )
        [chat] => Array (
            [id] => 123456789
            [first_name] => UserName
            [type] => private
        )
        [date] => 1541888068
        [text] => Привет бот!
    )
)

Получим текст сообщения:

if (!empty($data['message']['text'])) {
    $text = $data['message']['text'];
    echo $text;
}

Фотографии

При отправки фото боту, на скрипт приходит массив превьюшек, последним элементом будет оригинальное фото. Максимальный размер файла 20МБ.

Запрос от Телеграм:

Array (
    [update_id] => 17584194
    [message] => Array (
        [message_id] => 38
        [from] => Array (
            [id] => 123456789
            [is_bot] => 
            [first_name] => UserName
            [language_code] => ru-US
        )
        [chat] => Array (
            [id] => 123456789
            [first_name] => UserName
            [type] => private
        )
        [date] => 1541924962
        [photo] => Array (
            [0] => Array (
                [file_id] => AgADAgADUqexG7u8OEudBvlhgMzKC1agOQ8ABC6Bx26USA7Mw3gAAgI
                [file_size] => 1196
                [width] => 51
                [height] => 90
            )
            [1] => Array (
                [file_id] => AgttAgADUqoxG7u8OEudBvlhgMzKC1agOQ8ABKwp_3jDPrIlxHgAAgI
                [file_size] => 21146
                [width] => 180
                [height] => 320
            )
            [2] => Array (
                [file_id] => AgADAgADUqyxG7u8OEudBvlhgMzKC1agOQ8ABAN8gJWpUT1MxXgAAgI
                [file_size] => 90940
                [width] => 449
                [height] => 800
            )
            [3] => Array (
                [file_id] => AgADAgADUqouu7u8OEudBvlhgMzKC1agOQ8ABIqVC1nEpbLDwngAAgI
                [file_size] => 114363
                [width] => 719
                [height] => 1280
            )
        )
    )
)

Чтобы скачать файл нужно отправить POST или GET запрос на получение c параметром file_id изображения по URL:

https://api.telegram.org/bot<token>/getFile

В ответ придет информация о файле:

Array (
    [ok] => 1
    [result] => Array (
        [file_id] => AgADAgADUqoxG5u88E0dBvlhgMzKC1agOQ8ABIqVC1nEpbLDwngAAgI
        [file_size] => 114363
        [file_path] => photos/file_1.jpg
    )
)

Далее его можно скачать по ссылке:

https://api.telegram.org/file/bot<token>/<file_path>

В PHP сохранение файла на сервер можно реализовать следующим образом:

$token = '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11';

if (!empty($data['message']['photo'])) {
    $photo = array_pop($data['message']['photo']);
    
    $ch = curl_init('https://api.telegram.org/bot' . $token . '/getFile');  
    curl_setopt($ch, CURLOPT_POST, 1);  
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('file_id' => $photo['file_id']));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    $res = curl_exec($ch);
    curl_close($ch);
    
    $res = json_decode($res, true);
    if ($res['ok']) {
        $src  = 'https://api.telegram.org/file/bot' . $token . '/' . $res['result']['file_path'];
        $dest = __DIR__ . '/' . time() . '-' . basename($src);
        copy($src, $dest);
    }
}

Документ

Запрос от Телеграм:

Array (
    [update_id] => 17474201
    [message] => Array (
        [message_id] => 44
        [from] => Array (
            [id] => 123456789
            [is_bot] => 
            [first_name] => UserName
            [language_code] => ru-US
        )
        [chat] => Array (
            [id] => 123456789
            [first_name] => UserName
            [type] => private
        )
        [date] => 1541925844
        [document] => Array (
            [file_name] => IMG_7947.JPG
            [mime_type] => image/jpeg
            [thumb] => Array (
                    [file_id] => AAQCABMNv_QOAATwQugveIZBldZ3AAIC
                    [file_size] => 2644
                    [width] => 67
                    [height] => 90
                )
            [file_id] => BQADAgADtQEAAqu9OEhzn2cEz8LpkgI
            [file_size] => 1976218
        )
    )
)

Скачивание файлов происходит по такой же схеме как у фотографий.

if (!empty($data['message']['document'])) {
    $file_id = $data['message']['document']['file_id'];
    
    $ch = curl_init('https://api.telegram.org/bot' . $token . '/getFile');  
    curl_setopt($ch, CURLOPT_POST, 1);  
    curl_setopt($ch, CURLOPT_POSTFIELDS, array('file_id' => $file_id));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    $res = curl_exec($ch);
    curl_close($ch);
    
    $res = json_decode($res, true);
    if ($res['ok']) {
        $src  = 'https://api.telegram.org/file/bot' . $token . '/' . $res['result']['file_path'];
        $dest = __DIR__ . '/' . time() . '-' . basename($src);
        copy($src, $dest);
    }
}
3

Ответы бота

Отправка текста

$response = array(
    'chat_id' => $data['message']['chat']['id'],
    'text' => 'Хай!'
);    
        
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendMessage');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);

Отправка картинки

$response = array(
    'chat_id' => $data['message']['chat']['id'],
    'photo' => curl_file_create(__DIR__ . '/image.png')
);    
        
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendPhoto');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);

Отправка файла

$response = array(
    'chat_id' => $data['message']['chat']['id'],
    'document' => curl_file_create(__DIR__ . '/file.xls')
);    
        
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendDocument');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
4

Пример скрипта

Скрипт простейшего бота @SnippRu. Он отвечает на вопросы и сохраняет файлы и изображение на сервере.

<?php

$data = file_get_contents('php://input');
$data = json_decode($data, true);

if (empty($data['message']['chat']['id'])) {
    exit();
}

define('TOKEN', '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11');

// Функция вызова методов API.
function sendTelegram($method, $response)
{
    $ch = curl_init('https://api.telegram.org/bot' . TOKEN . '/' . $method);  
    curl_setopt($ch, CURLOPT_POST, 1);  
    curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    $res = curl_exec($ch);
    curl_close($ch);

    return $res;
}

// Прислали фото.
if (!empty($data['message']['photo'])) {
    $photo = array_pop($data['message']['photo']);
    $res = sendTelegram(
        'getFile', 
        array(
            'file_id' => $photo['file_id']
        )
    );
    
    $res = json_decode($res, true);
    if ($res['ok']) {
        $src = 'https://api.telegram.org/file/bot' . TOKEN . '/' . $res['result']['file_path'];
        $dest = __DIR__ . '/' . time() . '-' . basename($src);

        if (copy($src, $dest)) {
            sendTelegram(
                'sendMessage', 
                array(
                    'chat_id' => $data['message']['chat']['id'],
                    'text' => 'Фото сохранено'
                )
            );
            
        }
    }
    
    exit();    
}

// Прислали файл.
if (!empty($data['message']['document'])) {
    $res = sendTelegram(
        'getFile', 
        array(
            'file_id' => $data['message']['document']['file_id']
        )
    );
    
    $res = json_decode($res, true);
    if ($res['ok']) {
        $src = 'https://api.telegram.org/file/bot' . TOKEN . '/' . $res['result']['file_path'];
        $dest = __DIR__ . '/' . time() . '-' . $data['message']['document']['file_name'];

        if (copy($src, $dest)) {
            sendTelegram(
                'sendMessage', 
                array(
                    'chat_id' => $data['message']['chat']['id'],
                    'text' => 'Файл сохранён'
                )
            );    
        }
    }
    
    exit();    
}

// Ответ на текстовые сообщения.
if (!empty($data['message']['text'])) {
    $text = $data['message']['text'];

    if (mb_stripos($text, 'привет') !== false) {
        sendTelegram(
            'sendMessage', 
            array(
                'chat_id' => $data['message']['chat']['id'],
                'text' => 'Хай!'
            )
        );

        exit();    
    } 

    // Отправка фото.
    if (mb_stripos($text, 'фото') !== false) {
        sendTelegram(
            'sendPhoto', 
            array(
                'chat_id' => $data['message']['chat']['id'],
                'photo' => curl_file_create(__DIR__ . '/torin.jpg')
            )
        );
        
        exit();    
    }

    // Отправка файла.
    if (mb_stripos($text, 'файл') !== false) {
        sendTelegram(
            'sendDocument', 
            array(
                'chat_id' => $data['message']['chat']['id'],
                'document' => curl_file_create(__DIR__ . '/example.xls')
            )
        );

        exit();    
    }
}

      

17 ноября 2018
В последнее время письма отправляемые с хостингов через функции mail() и mb_send_mail() часто попадают или совсем не...
В статье приведены основные примеры работы с расширением PHP PDO. Такие как подключение к БД, получение, изменение и...
Библиотека GD дает возможность работать с изображениями в PHP. Далее представлены примеры как изменить размер, вырезать...
В продолжении темы работы с массивами поговорим о типичной задаче – их сортировке. Для ее выполнения в PHP существует...