feat(telegram-client): sendMessage wrapper classifying permanent/transient errors

This commit is contained in:
Vladimir Bryzgalov
2026-04-17 22:44:41 +05:00
parent 1f85d009c4
commit 786a306f29
+76
View File
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace Cf7stg;
final class TelegramClient
{
/**
* Send a message. Throws TelegramException on error.
*
* @param string|int $chat_id
* @param string $text Pre-escaped HTML
* @param array|null $reply_markup Optional inline_keyboard structure
*/
public static function send_message($chat_id, string $text, ?array $reply_markup = null): array
{
$token = Settings::get_bot_token();
if ($token === '' || $chat_id === '' || $chat_id === null) {
throw new TelegramException('Bot token or chat_id not configured', 0, true);
}
$body = [
'chat_id' => $chat_id,
'text' => $text,
'parse_mode' => 'HTML',
'disable_web_page_preview' => true,
];
if ($reply_markup !== null) {
$body['reply_markup'] = wp_json_encode($reply_markup);
}
$url = 'https://api.telegram.org/bot' . $token . '/sendMessage';
$response = wp_remote_post($url, [
'timeout' => 10,
'body' => $body,
]);
if (is_wp_error($response)) {
throw new TelegramException('Network: ' . $response->get_error_message(), 0, false);
}
$code = (int)wp_remote_retrieve_response_code($response);
$raw = (string)wp_remote_retrieve_body($response);
$data = json_decode($raw, true);
if ($code === 200 && is_array($data) && !empty($data['ok'])) {
return $data;
}
$desc = is_array($data) ? (string)($data['description'] ?? '') : '';
$retry_after = 0;
if (is_array($data) && isset($data['parameters']['retry_after'])) {
$retry_after = (int)$data['parameters']['retry_after'];
}
$permanent = self::is_permanent($code, $desc);
throw new TelegramException(
sprintf('HTTP %d %s', $code, $desc !== '' ? $desc : 'unknown error'),
$code,
$permanent,
$retry_after
);
}
private static function is_permanent(int $code, string $desc): bool
{
if ($code === 401 || $code === 403) return true;
if ($code === 400) {
$d = strtolower($desc);
if (strpos($d, 'chat not found') !== false) return true;
if (strpos($d, 'bot was blocked') !== false) return true;
if (strpos($d, 'user is deactivated') !== false) return true;
}
return false;
}
}