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/guzzleuse 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/corerequire '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 секунду, что позволяет избежать блокировки.