PHP и фреймворки
Yii2
Как интегрировать Telegram Bot API в Yii2: создание кастомного компонента, обработка Webhook в контроллере и отключение CSRF-валидации.
Интеграция Telegram Bot API в Yii2 строится на двух основных элементах: компоненте приложения (для отправки запросов к API) и контроллере (для приема входящих обновлений через Webhook).
Создание компонента Telegram
Чтобы не инициализировать клиент в каждом контроллере, вынесем логику взаимодействия с API в отдельный компонент Yii2. Это позволит вызывать методы бота из любой части приложения через Yii::$app->telegram. Архитектура аналогична той, что мы рассматривали на странице HTTP-клиент на PHP.
Создайте файл components/Telegram.php:
<?php
namespace app\components;
use yii\base\Component;
use yii\base\InvalidConfigException;
class Telegram extends Component
{
public $token;
public $timeout = 15;
public function init()
{
parent::init();
if (empty($this::token)) {
throw new InvalidConfigException("Токен Telegram не задан.");
}
}
public function sendMessage(array $params): array
{
return $this->call("sendMessage", $params);
}
public function call(string $method, array $params = []): array
{
$ch = curl_init("https://api.telegram.org/bot" . $this->token . "/" . $method);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode($params, JSON_UNESCAPED_UNICODE),
]);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return ["ok" => false, "description" => $error];
}
return json_decode($response, true) ?? ["ok" => false, "description" => "Invalid JSON"];
}
}
Настройка конфигурации
Добавьте созданный компонент в конфигурационный файл приложения (обычно config/web.php или common/config/main.php для advanced-шаблона):
'components' => [
// ...
'telegram' => [
'class' => 'app\components\Telegram',
'token' => '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
],
],
Прием обновлений через Webhook
Для обработки входящих сообщений от Telegram нужен контроллер. Главная особенность при работе с вебхуками в Yii2 — необходимость отключить валидацию CSRF-токена для экшена, так как Telegram отправляет POST-запросы без CSRF-токенов вашего приложения.
Создайте контроллер controllers/TelegramController.php:
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\web\Response;
class TelegramController extends Controller
{
// Отключаем CSRF для запросов от Telegram
public $enableCsrfValidation = false;
public function actionWebhook()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$rawBody = Yii::$app->request->getRawBody();
$update = json_decode($rawBody, true);
if (!$update) {
Yii::warning("Получены пустые или некорректные данные вебхука");
return ["status" => "error", "message" => "No data"];
}
if (isset($update["message"])) {
$chatId = $update["message"]["chat"]["id"];
$text = $update["message"]["text"] ?? "";
if ($text === "/start") {
Yii::$app->telegram->sendMessage([
'chat_id' => $chatId,
'text' => "Привет из Yii2!",
]);
}
}
return ["status" => "ok"];
}
}
Маршрутизация и безопасность
Для повышения безопасности рекомендуется скрыть URL вебхука, добавив в него секретный токен, как было описано в разделе Webhook. В Yii2 это легко настроить через urlManager в конфигурационном файле:
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'telegram-webhook-SECRET123' => 'telegram/webhook',
],
],
],
Теперь Telegram будет отправлять запросы на адрес https://yourdomain.com/telegram-webhook-SECRET123, а Yii2 прозрачно перенаправит их на telegram/webhook.
Использование компонентов и контроллеров в Yii2 позволяет легко масштабировать бота: вы можете подключить базу данных через ActiveRecord для хранения состояний или использовать очереди yii2-queue для отложенной отправки сообщений.
Дальше: Laravel