Telegram бот PHP: от основ до продвинутых сценариев

Раздел: API и боты -> Создание ботов

Основные подходы к созданию Telegram бота на PHP

Разработка ботов для Telegram на PHP может быть реализована несколькими способами. Выбор зависит от окружения, навыков и требований к проекту. Рассмотрим различные варианты, их достоинства и ограничения, а также типичные сложности.

Как создать эффективного бота с помощью Guzzle?

Библиотека GuzzleHttp предоставляет удобный интерфейс для HTTP запросов и является рекомендованным инструментом при наличии Composer. Установка:

composer require guzzlehttp/guzzle

Пример класса для работы с API:


<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

class TelegramBot {
    private $token;
    private $client;

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

    public function getUpdates() {
        $response = $this->client->get('getUpdates');
        return json_decode($response->getBody(), true);
    }

    public function sendMessage($chatId, $text) {
        $response = $this->client->post('sendMessage', [
            'form_params' => [
                'chat_id' => $chatId,
                'text' => $text
            ]
        ]);
        return json_decode($response->getBody(), true);
    }
}

Применение: создайте объект с токеном, получите обновления и отправьте ответ.

Типичные проблемы:

  • Необходимость установки Composer и зависимостей на сервере.
  • Таймауты при длительном polling (настройка timeout у Client).
  • Ошибки соединения - проверьте доступность api.telegram.org.

Как реализовать бота без внешних библиотек (чистый PHP)?

Если Composer недоступен, можно использовать встроенные функции cURL. Пример отправки текстового сообщения:


$token = '123456:ABC-DEF1234';
$chatId = 123456789;
$text = 'Привет!';
$url = "https://api.telegram.org/bot{$token}/sendMessage?chat_id={$chatId}&text=" . urlencode($text);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_error($ch)) {
    echo 'Ошибка cURL: ' . curl_error($ch);
}
curl_close($ch);

Этот вариант проще в развертывании, но менее удобен для сложных запросов (например, с клавиатурой).

Проблемы:

  • Обработка ошибок cURL вручную.
  • Трудности с передачей JSON в POST запросах (нужно указывать заголовок Content-Type).
  • Отсутствие автоматической десериализации ответа.

Как использовать готовые фреймворки для Telegram ботов?

Специализированные библиотеки, такие как irazasyed/telegram-bot-sdk или Longman/TelegramBot, упрощают разработку. Установка:

composer require irazasyed/telegram-bot-sdk ^2.0

Пример использования SDK:


use Telegram\Bot\Api;

$telegram = new Api('YOUR_BOT_TOKEN');
$response = $telegram->sendMessage([
    'chat_id' => $chatId,
    'text' => 'Hello'
]);

Библиотеки предоставляют готовые методы для команд, клавиатур и work-событий, что ускоряет разработку. Однако возможны проблемы с версиями зависимостей.

Проблемы:

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

Как настроить Webhook вместо Polling?

Webhook - более производительный метод получения обновлений. Telegram отправляет POST запрос на ваш сервер при каждом новом событии. Установка Webhook осуществляется через API:


$url = "https://yoursite.com/bot.php";
$response = file_get_contents("https://api.telegram.org/bot{$token}/setWebhook?url=$url");

Файл bot.php обрабатывает входящие данные:


$update = json_decode(file_get_contents('php://input'), true);
$chatId = $update['message']['chat']['id'] ?? null;
if ($chatId) {
    // обработка
}

Webhook требует HTTPS и часто статический IP. Ошибки - неверный SSL сертификат или блокировка порта 443.

Проблемы:

  • Сервер должен быть доступен из интернета с HTTPS.
  • Таймауты ответа - Telegram ждет ответ не более 10 секунд.
  • Сложность отладки - локально не протестировать.

Как обрабатывать команды /start и другие?

Распознавание команд - ключевая задача. Пример на чистом PHP:


$text = $update['message']['text'] ?? '';
if ($text === '/start') {
    sendMessage($chatId, 'Добро пожаловать!');
} elseif (str_starts_with($text, '/echo ')) {
    $msg = substr($text, 6);
    sendMessage($chatId, $msg);
}

Ошибка: не учитывать регистр команды. Рекомендуется сравнивать с помощью strtolower.

Проблемы: большие боты со множеством команд - клоноводство кода. Решение - использовать шаблон Command Handler.

Итоговый выбор: Для большинства проектов оптимально использовать Guzzle (или чистый cURL при ограничениях) с Webhook. Готовые SDK хороши для крупных проектов, но требуют изучения.

Расширенные примеры программного кода

Данный раздел содержит подробные примеры для типичных сценариев Telegram бота на PHP. Каждый пример сопровождается пояснением и результатом выполнения.

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

Inline-клавиатура позволяет пользователю нажимать кнопки внутри сообщения. Код с использованием Guzzle:

Пример

$chatId = 123456789;
$text = 'Выберите действие:';
$keyboard = [
    'inline_keyboard' => [
        [
            ['text' => 'Кнопка 1', 'callback_data' => 'btn1'],
            ['text' => 'Кнопка 2', 'callback_data' => 'btn2']
        ],
        [
            ['text' => 'Ссылка', 'url' => 'https://example.com']
        ]
    ]
];
$response = $client->post('sendMessage', [
    'form_params' => [
        'chat_id' => $chatId,
        'text' => $text,
        'reply_markup' => json_encode($keyboard)
    ]
]);
$result = json_decode($response->getBody(), true);
if ($result['ok']) {
    echo 'Сообщение отправлено с клавиатурой';
}
// Результат: в чат отправлено сообщение с двумя inline-кнопками и одной ссылкой.
// Пользователь может нажать кнопку, и Telegram пришлет callback_query с соответствующими данными.

Пример 2: Обработка Callback Query

Когда пользователь нажимает inline-кнопку, Telegram отправляет callback_query. Обработка:

Пример

$update = json_decode(file_get_contents('php://input'), true);
$callbackQuery = $update['callback_query'] ?? null;
if ($callbackQuery) {
    $callbackId = $callbackQuery['id'];
    $data = $callbackQuery['data'];
    $chatId = $callbackQuery['message']['chat']['id'];
    // Ответ на callback
    $client->post('answerCallbackQuery', [
        'form_params' => [
            'callback_query_id' => $callbackId,
            'text' => "Вы нажали: $data"
        ]
    ]);
    // Можно также изменить сообщение
}
// Пользователь увидит всплывающее уведомление с текстом "Вы нажали: btn1".

Пример 3: Отправка фотографии

Для отправки изображения используется метод sendPhoto. Файл может быть загружен из URL или локально.

Пример

$chatId = 123456789;
$photoUrl = 'https://picsum.photos/400/300';
$response = $client->post('sendPhoto', [
    'form_params' => [
        'chat_id' => $chatId,
        'photo' => $photoUrl,
        'caption' => 'Случайное изображение'
    ]
]);
// В чат отправлена фотография с подписью.

Пример 4: Загрузка файла с сервера (multipart)

Если изображение лежит на вашем сервере, используйте multipart/form-data:

Пример

$response = $client->post('sendPhoto', [
    'multipart' => [
        [
            'name' => 'chat_id',
            'contents' => $chatId
        ],
        [
            'name' => 'photo',
            'contents' => fopen('/path/to/image.jpg', 'r'),
            'filename' => 'image.jpg'
        ]
    ]
]);
// Отправленный файл появится в чате.

Пример 5: Работа с ParseMode (Markdown / HTML)

Telegram поддерживает форматирование текста. Пример с HTML:

Пример

$text = '<b>Жирный текст</b> и <i>курсив</i>';
$response = $client->post('sendMessage', [
    'form_params' => [
        'chat_id' => $chatId,
        'text' => $text,
        'parse_mode' => 'HTML'
    ]
]);
// В чате отобразится: Жирный текст и курсив.

Пример 6: Отправка документа (PDF, ZIP)

Пример

$response = $client->post('sendDocument', [
    'multipart' => [
        ['name' => 'chat_id', 'contents' => $chatId],
        ['name' => 'document', 'contents' => fopen('/path/to/file.pdf', 'r'), 'filename' => 'file.pdf']
    ]
]);
// Пользователь получает файл с именем file.pdf.

Пример 7: Получение информации о боте

Пример

$response = $client->get('getMe');
$result = json_decode($response->getBody(), true);
echo $result['result']['username']; // выведет username бота
// Пример вывода: MyTestBot

Пример 8: Удаление вебхука

Пример

$client->post('deleteWebhook');
// или с параметрами
$client->post('deleteWebhook', ['form_params' => ['drop_pending_updates' => true]]);
// После удаления можно переключиться на getUpdates.

Пример 9: Использование getUpdates с offset для пропуска обработанных обновлений

Пример

$offset = 0; // хранить в БД или файле
$response = $client->get('getUpdates', ['query' => ['offset' => $offset, 'timeout' => 30]]);
$updates = json_decode($response->getBody(), true)['result'];
if (!empty($updates)) {
    $lastId = end($updates)['update_id'];
    $offset = $lastId + 1;
    // сохранить offset
    foreach ($updates as $update) {
        // обработка
    }
}
// Каждый следующий вызов получит только новые сообщения.

Пример 10: Отправка сообщения с Reply-клавиатурой (обычной)

Пример

$keyboard = [
    'keyboard' => [
        ['Кнопка 1', 'Кнопка 2'],
        ['Кнопка 3']
    ],
    'resize_keyboard' => true,
    'one_time_keyboard' => false
];
$response = $client->post('sendMessage', [
    'form_params' => [
        'chat_id' => $chatId,
        'text' => 'Выберите кнопку:',
        'reply_markup' => json_encode($keyboard)
    ]
]);
// Внизу экрана появится клавиатура с тремя кнопками.
- Telegram bot php (telegram бот на php)

Telegram бот на PHP - comments

En
Telegram bot php (php)