Разработка бота для Telegram с помощью PHP: лучшие подходы
Создание Telegram бота на PHP - одна из популярных задач веб-разработки. В этой статье рассматриваются различные подходы: от прямых запросов к API до использования готовых библиотек, с разбором типичных ошибок и примеров кода.
Основные варианты реализации бота
Наиболее эффективный способ: использование библиотеки irazasyed/telegram-bot-sdk
Данный пакет предоставляет удобный объектно-ориентированный интерфейс для работы с Telegram Bot API. Он поддерживает все методы, обработку команд, клавиатуры и вебхуки. Установка через Composer:
composer require irazasyed/telegram-bot-sdk ^3.0
Пример отправки простого текстового сообщения:
require __DIR__ . '/vendor/autoload.php';
use Telegram\Bot\Api;
$telegram = new Api('YOUR_BOT_TOKEN');
$response = $telegram->sendMessage([
'chat_id' => 'CHAT_ID',
'text' => 'Привет, мир!'
]);
Результат - объект Message, содержащий информацию об отправленном сообщении (id, дата, чат и т.д.).
Возможные проблемы:
- Неверный токен - возвращается ошибка 404. Проверьте токен, полученный от BotFather.
- Пользователь не начал диалог с ботом - бот не может отправить сообщение первым, если пользователь не активировал бота.
- Превышение лимитов (20 сообщений в секунду для групп) - добавьте паузу между отправками с помощью sleep().
Другие варианты реализации
Как отправить сообщение без использования сторонних библиотек?
Чистый PHP с cURL или file_get_contents. Токен и параметры передаются в URL GET-запроса.
$token = 'YOUR_BOT_TOKEN';
$chat_id = 'CHAT_ID';
$text = 'Текст сообщения';
$url = "https://api.telegram.org/bot$token/sendMessage?chat_id=$chat_id&text=" . urlencode($text);
$response = file_get_contents($url);
$data = json_decode($response, true);
Ответ JSON содержит поле ok: true при успехе.
Типичные ошибки:
- Отсутствует urlencode() - неверно передаётся текст с пробелами или спецсимволами.
- SSL ошибки при использовании file_get_contents - включите CURLOPT_SSL_VERIFYPEER в пользовательском контексте.
Как реализовать полноценного бота с поддержкой команд через Longman\TelegramBot?
Эта библиотека предоставляет готовую архитектуру для команд, командных классов и обработчиков. Установка: composer require longman/telegram-bot.
require __DIR__ . '/vendor/autoload.php';
use Longman\TelegramBot\Telegram;
use Longman\TelegramBot\Request;
$telegram = new Telegram('BOT_TOKEN', 'BOT_USERNAME');
$telegram->addCommandClass(MyCommand::class);
$telegram->handle();
Класс MyCommand может быть определён как:
use Longman\TelegramBot\Commands\UserCommands\Command;
class MyCommand extends Command
{
protected $name = 'mycommand';
public function execute()
{
$message = $this->getMessage();
$chat_id = $message->getChat()->getId();
$data = ['chat_id' => $chat_id, 'text' => 'Команда выполнена'];
return Request::sendMessage($data);
}
}
Как организовать обработку команд с параметрами без использования сложных библиотек?
При получении обновления из вебхука или long polling, текст сообщения парсится регулярными выражениями.
$update = json_decode(file_get_contents('php://input'), true);
if (isset($update['message']['text'])) {
$text = $update['message']['text'];
if (preg_match('/^\/start (.+)$/', $text, $matches)) {
$param = $matches[1];
// обработка параметра (например, save to DB)
}
}
Подходит для простых ботов с несколькими командами.
Как настроить вебхук для получения обновлений в реальном времени?
Вебхук отправляет обновления на ваш HTTPS-сервер. Установка вебхука выполняется один раз через GET-запрос.
$url = "https://api.telegram.org/botTOKEN/setWebhook?url=https://yourdomain.com/hook.php";
file_get_contents($url);
Файл hook.php читает входящий JSON из php://input и обрабатывает его.
$content = file_get_contents('php://input');
$update = json_decode($content, true);
// обработка обновления
Проблемы с вебхуком:
- Требуется действующий SSL-сертификат (HTTPS). Для тестирования можно использовать self-signed сертификат с указанием публичного ключа.
- Сервер должен отвечать в течение 2 секунд, иначе Telegram повторяет запрос.
- Нельзя одновременно использовать getUpdates и вебхук - предварительно удалите вебхук через deleteWebhook.
Расширенные примеры кода
Пример 1: Отправка изображения с подписью через библиотеку
require __DIR__ . '/vendor/autoload.php';
use Telegram\Bot\Api;
$telegram = new Api('YOUR_BOT_TOKEN');
$response = $telegram->sendPhoto([
'chat_id' => 'CHAT_ID',
'photo' => 'https://example.com/image.jpg',
'caption' => 'Описание изображения'
]);
Результат - объект Message с информацией о фото и подписи.
{
"ok": true,
"result": {
"message_id": 123,
"from": {...},
"chat": {...},
"date": 1700000000,
"photo": [{"file_id": "...", "width": 320, "height": 240, "file_size": 12345}],
"caption": "Описание изображения"
}
}
Пример 2: Отправка инлайн-клавиатуры с callback-обработкой
use Telegram\Bot\Keyboard\Keyboard;
$inlineKeyboard = Keyboard::make()
->inline()
->row([
Keyboard::inlineButton(['text' => 'Кнопка 1', 'callback_data' => 'btn1']),
Keyboard::inlineButton(['text' => 'Кнопка 2', 'callback_data' => 'btn2'])
]);
$telegram->sendMessage([
'chat_id' => 'CHAT_ID',
'text' => 'Выберите опцию:',
'reply_markup' => $inlineKeyboard
]);
Обработка callback_query:
$update = json_decode(file_get_contents('php://input'), true);
if (isset($update['callback_query'])) {
$callback_data = $update['callback_query']['data'];
// ответ на callback
$telegram->answerCallbackQuery([
'callback_query_id' => $update['callback_query']['id'],
'text' => 'Вы нажали: ' . $callback_data
]);
}
Пример 3: Получение обновлений через getUpdates с offset и лимитами
$url = "https://api.telegram.org/botTOKEN/getUpdates?offset=12345&limit=10&timeout=30";
$response = file_get_contents($url);
$data = json_decode($response, true);
foreach ($data['result'] as $update) {
// обработка каждого обновления
$update_id = $update['update_id'];
// после обработки сохраняем update_id+1 как offset для следующего запроса
}
Результат - массив обновлений:
{
"ok": true,
"result": [
{
"update_id": 12345,
"message": {"message_id":1, "chat":{"id":123}, "text":"Hello"}
}
]
}
Пример 4: Обработка команды /start с аргументом (deep linking)
$update = json_decode(file_get_contents('php://input'), true);
$text = $update['message']['text'] ?? '';
if (preg_match('/^\/start (\w+)$/', $text, $matches)) {
$param = $matches[1];
$telegram->sendMessage([
'chat_id' => $update['message']['chat']['id'],
'text' => "Получен параметр: $param"
]);
}
Пример 5: Настройка вебхука с self-signed сертификатом
$cert_path = '/path/to/cert.pem';
$url = "https://yourdomain.com/hook.php";
$post_fields = [
'url' => $url,
'certificate' => new CURLFile($cert_path)
];
$ch = curl_init("https://api.telegram.org/botTOKEN/setWebhook");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Результат:
{"ok":true,"result":true,"description":"Webhook was set"}