botToken = $this->repo->getConfig('telegram_bot_token'); $this->chatId = $this->repo->getConfig('telegram_chat_id'); error_log(sprintf("Telegram: bot_token=%s, chat_id=%s", $this->botToken ? substr($this->botToken, 0, 8) . '...' : 'EMPTY', $this->chatId ?? 'EMPTY')); } public function isConfigured(): bool { return !empty($this->botToken) && !empty($this->chatId); } public function send(Alert $alert): bool { if (!$this->isConfigured()) { error_log("Telegram: not configured, skipping alert #{$alert->id}"); return false; } error_log("Telegram: sending alert #{$alert->id} [{$alert->severity->value}]..."); $emoji = match ($alert->severity->value) { 'emergency', 'critical_high', 'critical' => "\xF0\x9F\x94\xA5", 'critical_low', 'error' => "\xE2\x9D\x8C", 'warning_high', 'warning' => "\xE2\x9A\xA0\xEF\xB8\x8F", 'warning_low' => "\xF0\x9F\x93\xA2", default => "\xE2\x84\xB9\xEF\xB8\x8F", }; $text = sprintf( "%s *ALERT #%d* [%s]\n", $emoji, $alert->id, strtoupper($alert->severity->value) ); $text .= sprintf("*Rule:* %s\n", $alert->ruleName); $text .= sprintf("*Source:* %s\n", $alert->sourceName ?? '—'); $text .= sprintf("*Message:* ```\n%s\n```", mb_substr($alert->message, 0, 1000)); $url = 'https://api.telegram.org/bot' . $this->botToken . '/sendMessage'; error_log("Telegram: POST " . preg_replace('/bot.*\//', 'botTOKEN/', $url)); $postData = http_build_query([ 'chat_id' => $this->chatId, 'text' => $text, 'parse_mode' => 'Markdown', 'disable_web_page_preview' => true, ]); error_log("Telegram: post data length=" . strlen($postData) . ", text length=" . strlen($text)); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 15); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); error_log("Telegram: HTTP $httpCode, curl_error=$curlError, response=" . substr($response, 0, 500)); if ($httpCode !== 200) { error_log("Telegram send failed (HTTP $httpCode): $response"); return false; } error_log("Telegram: sent successfully"); return true; } }