Разработка бота для Telegram с помощью PHP: лучшие подходы

Раздел: Разработка на PHP -> Telegram API

Создание 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"}

Telegram бот на PHP - comments

En
Tg php (php)