Виконання запитів sendMessage у Telegram на Raw PHP: таймаути, JSON-парсинг та санація HTML

Для виконання стандартних HTTP-запитів до API Telegram Bot з використанням непобутаного PHP потрібно більше, ніж просто file_get_contents() виклик. Виробнича середовище потребує явних елементів управління таймаутом, перевірки мережових помилок, дозволеного синтаксичного аналізу JSON, обробки даних помилок на рівні API Telegram і суворого екранування виводу для форматованого тексту.

\n

У цьому посібнику ми створимо готовий PHP-функцію для виконання SendMessage запитів через cURL. Ми розглянемо сетові таймаути, перевірку HTTP-статусу, безпеку декодування JSON, обробку помилок на рівні Telegram і екранування динамічних рядків при наданні повідомлень у форматі HTML. Ми не будемо налаштовувати обробники веб-перехватчиків, обробляти входячі оновлення чи створювати фонові процеси очереди.

\n

Дезінфекція динамічних входних даних для Telegram HTML

\n

Іспольування parse_mode=HTML, Telegram підтримує підмножество HTML-тегів (<b>, <i>, <a>, <code>, <pre>). Якщо динамічні дані, вставлені в ваш шаблон, містять такі символи, як <, > або &, API Telegram не зможе проаналізувати дерево сущностей і повернути 400 Плохой запрошення помилку з описом Bad Request: не удається проаналізувати сущності.

\n

Іспольування htmlspecialchars де ENT_QUOTES | ENT_REPLACE для кодування непобутаних користувачських вхідних даних перед їх інтерполацією в форматовані рядки повідомлень:

\n
function sanitizeTelegramHtml(string $text): string
{
return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// Usage example:
$userInput = 'User <script>alert(1)</script> & "special"';
$safeUser = sanitizeTelegramHtml($userInput);

$formattedMessage = "New lead received:\n<b>Name:</b> {$safeUser}";
\n

Сборка мессенджера cURL

\n

Чтоб зробити надійні HTTP-запити POST, налаштуйте власний cURL з таймаутами зв'язку та загального часу виконання. Скрипт має явно перевіряти три рівні відмови:

\n

1. Транспортний рівень: помилки cURL (наприклад, збій розподілу DNS, перевищення часу очікування мережі). 2. HTTP-слой: HTTP-коди відповідей, що відрізняються від 200. 3. Прикладний рівень: стандартна структура JSON API Telegram, де OK є фальшивим.

\n

Ось повна реалізація:

\n
<?php

declare(strict_types=1);

/**
* Sends a message to a Telegram chat using cURL.
*
* @param int|string $chatId Unique identifier for the target chat or username
* @param string $text Text of the message to be sent
* @param string $parseMode Optional formatting (e.g., 'HTML')
* @return array<string, mixed>
* @throws RuntimeException On transport, HTTP, or Telegram API failures
*/
function sendTelegramMessage(int|string $chatId, string $text, string $parseMode = 'HTML'): array
{
$botToken = getenv('TELEGRAM_BOT_TOKEN');
if (!$botToken) {
throw new RuntimeException('TELEGRAM_BOT_TOKEN environment variable is missing.');
}

$url = sprintf('https://api.telegram.org/bot%s/sendMessage', $botToken);

$payload = [
'chat_id' => $chatId,
'text' => $text,
];

if ($parseMode !== '') {
$payload['parse_mode'] = $parseMode;
}

$ch = curl_init();

curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5, // Max time allowed to establish connection
CURLOPT_TIMEOUT => 10, // Max total time allowed for request execution
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
],
]);

$response = curl_exec($ch);
$curlErrno = curl_errno($ch);
$curlError = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// 1. Check cURL network transport errors
if ($curlErrno !== 0) {
throw new RuntimeException(sprintf('cURL error [%d]: %s', $curlErrno, $curlError));
}

if (!is_string($response) || $response === '') {
throw new RuntimeException('Received empty response from Telegram API server.');
}

// 2. Decode and validate JSON format
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException(sprintf(
'Failed to parse Telegram JSON response. Error: %s. Raw response: %s',
json_last_error_msg(),
$response
));
}

// 3. Check Telegram Application level status
if (!isset($data['ok']) || $data['ok'] !== true) {
$errorCode = $data['error_code'] ?? $httpCode;
$description = $data['description'] ?? 'Unknown API error occurred.';
throw new RuntimeException(sprintf(
'Telegram API Error [%d]: %s',
$errorCode,
$description
));
}

return $data;
}
\n

Исполнение Кодекса

\n

Ви можете запустити цю функцію в обробнику запитів або скрипті CLI, встановлюючи переменну середовища:

\n
export TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrsTUVwxyZ"
php send_message.php
\n
try {
$chatId = 123456789;
$rawMessage = "Order update: Status changed to <b>Processing</b>.";

$result = sendTelegramMessage($chatId, $rawMessage, 'HTML');
echo "Message sent successfully. Message ID: " . $result['result']['message_id'];
} catch (RuntimeException $e) {
error_log("Telegram delivery failed: " . $e->getMessage());
}
\n

V. Візуалізації, пов'язаних із підготовкою матеріалів

\n

- Обмеження швидкості (HTTP 429): Якщо Telegram відповідає HTTP-статусом 429 (Слишком багато запитів), перевірте parameters.retry_after поле корисної нагруди. Якщо це відбувається регулярно, делегуйте вихідні повідомлення базі даних або очереди Redis, а не виконуєте cURL всередині синхронних веб-HTTP-запитів. - Пользовательские блоки (HTTP 403): Якщо ваш бот був заблокований користувачем або чат видалений, Telegram повертає 403 Forbidden. Опис Запречено: бот був заблокований користувачем. Ловіть цю помилку спеціально, щоб позначити записів користувачів як неактивних у вашій базі даних. - Альтернатива корисної нагруди JSON: у наведеному вище прикладі використовується application/x-www-form-urlencoded. Якщо ваша полезная нагрузка включає складні вкладені масиви (наприклад, reply_markup inline keybaords), закодуйте всю корисну нагруду за допомогою json_encode() та відправьте її разом із Использувати Content-Type = application/json замість заголовка.

\n

Необхідно масштабирувати пользовательську автоматизацію, веб-перехватчики або бессерверну інфраструктуру для систем обміну повідомленнями? Зв'яжіться з BotCreator — студією, яка постачає Telegram-бот ов /-min-проєкти.

"}

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

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