Підключення Telegram Webhook на чистому PHP

Підключення Telegram webhook на чистому PHP вимагає правильного налаштування endpoint'а, валідації request'а та ідемпотентності обробки. Нижче наведено minimal working example, який можна використовувати як стартову точку.

Встановлення webhook та POST запит setWebhook

// Отправка setWebhook запроса
$url = 'https://api.telegram.org/bot/YOUR_BOT_TOKEN/setWebhook';
$headers = [
'Content-Type' => 'application/json',
'Secret-Token' => 'YOUR_SECRET_TOKEN'
];
$payload = json_encode(['mode' => 'private']);
$ch = curl_init($url);
curl_setopt($ch, 'POST', $payload);
curl_setopt($ch, 'HTTP/1.1', '200 OK');
curl_setopt($ch, 'Connection', 'close');
curl_exec($ch);
curl_close($ch);
// Убедитесь, что получите ответ 200 и валидите secret_token из заголовка.

Валідація callback_data та ідемпотентність через update_id

// Получение обновления из API
$url = 'https://api.telegram.org/bot/YOUR_BOT_TOKEN/getUpdates';
$ch = curl_init();
$ch->post($url, json_encode(['offset' => 0, 'timeout' => 30]), $headers);
$body = json_decode((string) $(get_webhook_params()), true);
$lastUpdateId = $body['result'][0]['update_id'] ?? null;

// Проверка idempotency — если update_id уже обработан, пропускаем
if (in_array($lastUpdateId, $processedUpdates)) {
http_response_code(200);
die('Already processed');
}

// Извлечение initData для валидации
$callback = $body['result'][0]['data'];
if (!$is_valid_initiate_data($callback)) {
http_response_code(400);
exit;
}

// Дальше обрабатываем бизнес-логику
if ($callback['type'] === 'message') {
// обработка сообщения пользователя
}

Перевірка secret_token та ініціалізація сховища

Для безпеки використовуйте secret_token у заголовку GET request'а webhook. Перевірка виконується через HMAC-SHA256: порівняйте hash_equals(output_hash, input_hash, secret_token). Також зберігайте processed_updates у БД для ідемпотентності — уникайте повторної обробки одного й того самого update_id. Якщо DB порожня, створіть таблицю з колонками update_id та processed_at.

Приклад перевірки: if (hash_equals(hash_hmac('sha256', $request['secret'], $secret_token), $request['data']['secret'])) { ... }

Приклад повного циклу — cURL + обробка та валідація

// Полный пример: получить last update и обработать
$token = getenv('TELEGRAM_SECRET_TOKEN');
$ch = curl_init();
$ch->post('https://api.telegram.org/bot/' . $botToken . '/getUpdates',
[], ['header' => ['Host' => 'api.telegram.org']]);
$res = json_decode((string)$ch->get_response(), true);
if (empty($res['result'])) return;
$update = $res['result'][0];
$lastId = $update['update_id'];

// Идемпотентность
$db = new PDO('mysql:host=localhost;dbname=telemetr', $user, $pass);
$stmt = $db->prepare(

Нові статті — у Telegram

Розбираємо, що автоматизувати в бізнесі та як це працює на практиці. Без спаму.