PHP Bot API: эффективные способы интеграции с мессенджерами

Раздел: Программирование -> Разработка ботов

Основы работы с Bot API на PHP

Для создания ботов на PHP используется Bot API (чаще всего Telegram Bot API). Взаимодействие происходит через HTTP-запросы к серверу Telegram. Существует несколько подходов: от прямых вызовов cURL до использования готовых библиотек.

Какое решение обеспечивает быструю разработку с минимумом кода?

Наиболее эффективным способом является использование специализированной библиотеки, например Nutgram. Она предоставляет удобный интерфейс, автоматическую обработку вебхуков и long polling, а также поддержку всех методов Bot API.

composer require nutgram/nutgram

Пример простейшего бота:

require 'vendor/autoload.php';

use Nutgram\Nutgram;

$bot = new Nutgram('YOUR_BOT_TOKEN');

$bot->onCommand('start', function (Nutgram $bot) {
    $bot->sendMessage('Привет! Я бот на PHP.');
});

$bot->run();

Пояснение: создается объект Nutgram с токеном, регистрируется обработчик команды /start, запускается цикл ожидания сообщений. Библиотека сама обрабатывает входящие обновления.

Типичная ошибка:

Неправильный токен или отсутствие прав на отправку сообщений. Проверьте, что токен скопирован без лишних пробелов.

Как выполнить запрос к Bot API без библиотек?

Использование чистого cURL позволяет полностью контролировать процесс, но требует больше кода.

$token = 'YOUR_BOT_TOKEN';
$url = "https://api.telegram.org/bot{$token}/sendMessage";
$data = [
    'chat_id' => 123456789,
    'text' => 'Привет через cURL!'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);

echo $response;

Проблемы: сложность обработки ошибок, необходимость вручную парсить JSON, нет автоматического распознавания типов ошибок.

Ошибка:

cURL может вернуть false при проблемах с сетью. Всегда проверяйте результат curl_exec с помощью curl_error.

Как упростить HTTP-запросы с помощью Guzzle?

Guzzle - мощный PHP HTTP-клиент. Он обрабатывает JSON, поддерживает различные транспортные протоколы.

composer require guzzlehttp/guzzle
use GuzzleHttp\Client;

$token = 'YOUR_BOT_TOKEN';
$client = new Client(['base_uri' => "https://api.telegram.org/bot{$token}/"]);

$response = $client->post('sendMessage', [
    'json' => [
        'chat_id' => 123456789,
        'text' => 'Привет через Guzzle!'
    ]
]);

$result = json_decode($response->getBody(), true);
print_r($result);

Плюсы: автоматическая сериализация, управление исключениями. Минусы: все равно нужно реализовывать логику команд.

Ошибка:

Если токен неверен, Guzzle выбросит исключение GuzzleHttp\Exception\ClientException. Обрабатывайте его в try-catch.

Как создать свою обертку для Bot API?

Иногда требуется кастомная логика. Можно написать класс-обертку с методами под каждый эндпоинт.

class TelegramBot {
    private $token;
    private $apiUrl;

    public function __construct($token) {
        $this->token = $token;
        $this->apiUrl = "https://api.telegram.org/bot{$token}/";
    }

    public function sendMessage($chatId, $text) {
        $url = $this->apiUrl . 'sendMessage';
        $data = ['chat_id' => $chatId, 'text' => $text];
        // используем file_get_contents с контекстом
        $options = [
            'http' => [
                'method' => 'POST',
                'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                'content' => http_build_query($data)
            ]
        ];
        $context = stream_context_create($options);
        return file_get_contents($url, false, $context);
    }
}

$bot = new TelegramBot('YOUR_TOKEN');
echo $bot->sendMessage(123456789, 'Кастомная обертка');

Проблемы: отсутствие обработки ошибок, сложность расширения.

Какие возможности дает библиотека php-telegram-bot/core?

Это одна из популярных библиотек, предоставляющая готовые классы для работы с Bot API.

composer require php-telegram-bot/core
require 'vendor/autoload.php';

use Longman\TelegramBot\Telegram;
use Longman\TelegramBot\Request;

$telegram = new Telegram('YOUR_TOKEN', 'YOUR_BOT_USERNAME');

// Обработка вебхука или long polling
$telegram->handle();

// Отправка сообщения
Request::sendMessage([
    'chat_id' => 123456789,
    'text' => 'Привет от php-telegram-bot!'
]);

Библиотека поддерживает команды, клавиатуры, inline-режим. Требует больше настроек, чем Nutgram.

Расширенные примеры работы с Bot API на PHP

Ниже приведены подробные примеры с кодом и результатами для различных сценариев.

Пример 1: Отправка сообщения с клавиатурой (InlineKeyboard)

Пример
require 'vendor/autoload.php';

use Nutgram\Nutgram;
use Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;

$bot = new Nutgram('TOKEN');

$bot->onCommand('keyboard', function (Nutgram $bot) {
    $keyboard = InlineKeyboardMarkup::make()
        ->addRow(
            InlineKeyboardButton::make('Кнопка 1', callback_data: 'btn1'),
            InlineKeyboardButton::make('Кнопка 2', callback_data: 'btn2')
        );

    $bot->sendMessage('Выберите опцию:', reply_markup: $keyboard);
});

$bot->onCallbackQueryData('btn1', function (Nutgram $bot) {
    $bot->answerCallbackQuery(['text' => 'Нажата кнопка 1']);
    $bot->sendMessage('Вы выбрали кнопку 1');
});

$bot->run();
Результат: бот отправляет сообщение с двумя inline-кнопками. При нажатии на кнопку 1 отправляется ответ 'Вы выбрали кнопку 1'.

Пример 2: Загрузка и отправка фото

Пример
$bot->onCommand('photo', function (Nutgram $bot) {
    // Отправка фото из файла на сервере
    $bot->sendPhoto([
        'chat_id' => $bot->chatId(),
        'photo' => fopen('/path/to/photo.jpg', 'r'),
        'caption' => 'Пример фото'
    ]);
});
Результат: бот отправляет фото с подписью. Используется поток для избежания больших загрузок в память.

Пример 3: Обработка вебхука (настройка через setWebhook)

Пример
use Nutgram\Nutgram;

$bot = new Nutgram('TOKEN');

// Установка вебхука (выполнить один раз)
$bot->setWebhook('https://yourdomain.com/webhook.php');

// Файл webhook.php
require 'vendor/autoload.php';
$bot = new Nutgram('TOKEN');
$bot->run();
Результат: после установки вебхука все обновления будут приходить на указанный URL. Бот обрабатывает их в реальном времени без long polling.

Пример 4: Long polling с кастомными параметрами

Пример
$bot = new Nutgram('TOKEN');

// Запуск с таймаутом 30 секунд и ограничением на 100 обновлений
$bot->run(timeout: 30, limit: 100);
Результат: бот опрашивает сервер каждые 30 секунд, получая до 100 обновлений за раз. Экономит ресурсы по сравнению с короткими таймаутами.

Пример 5: Отправка запроса с использованием cURL и расширенной обработкой ошибок

Пример
function sendTelegramRequest($method, $data) {
    $token = 'TOKEN';
    $url = "https://api.telegram.org/bot{$token}/{$method}";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        throw new Exception("cURL error: $error");
    }

    $json = json_decode($response, true);
    if (!$json['ok']) {
        throw new Exception("Telegram error: " . $json['description']);
    }

    return $json['result'];
}

// Использование
try {
    $result = sendTelegramRequest('sendMessage', [
        'chat_id' => 123456789,
        'text' => 'Тест с обработкой ошибок'
    ]);
    print_r($result);
} catch (Exception $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
Результат: функция возвращает результат запроса или выбрасывает исключение с понятным описанием. 

Пример 6: Рассылка сообщений по списку пользователей (с ограничением скорости)

Пример
$userIds = [123, 456, 789];
$bot = new Nutgram('TOKEN');

foreach ($userIds as $userId) {
    try {
        $bot->sendMessage('Рассылка: важное уведомление', ['chat_id' => $userId]);
        sleep(1); // Telegram ограничивает 30 сообщений в секунду
    } catch (Exception $e) {
        // Логируем ошибку
        error_log("Не удалось отправить пользователю $userId: " . $e->getMessage());
    }
}
Результат: сообщение отправляется каждому пользователю с задержкой в 1 секунду, что позволяет избежать блокировки.

API ботов на PHP - comments

En
Bot api php (php)