$chatId, 'text' => $text, ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded ", 'method' => 'POST', 'content' => http_build_query($data), 'timeout' => 20, ], ]; $context = stream_context_create($options); $result = @file_get_contents($url, false, $context); return $result !== false; } function findFaqReply(array $faqs, string $message): string { $normalizedMessage = function_exists('mb_strtolower') ? mb_strtolower($message, 'UTF-8') : strtolower($message); foreach ($faqs as $faq) { $keywords = isset($faq['keywords']) && is_string($faq['keywords']) ? preg_split('/\s*,\s*/', $faq['keywords']) : []; foreach ($keywords as $keyword) { if (!is_string($keyword) || $keyword === '') { continue; } $needle = function_exists('mb_strtolower') ? mb_strtolower($keyword, 'UTF-8') : strtolower($keyword); $found = function_exists('mb_strpos') ? mb_strpos($normalizedMessage, $needle, 0, 'UTF-8') !== false : strpos($normalizedMessage, $needle) !== false; if ($needle !== '' && $found) { return (string) ($faq['answer'] ?? ''); } } } return ''; } $content = file_get_contents('php://input'); $update = json_decode($content ?: '', true); if (!is_array($update) || !isset($update['message']) || !is_array($update['message'])) { exit; } $message = $update['message']; $chatId = $message['chat']['id'] ?? null; $text = isset($message['text']) && is_string($message['text']) ? trim($message['text']) : ''; if ($chatId === null || $text === '') { exit; } try { ensureSupportSchema(); $stmt = db()->prepare('SELECT setting_value FROM settings WHERE setting_key = :setting_key LIMIT 1'); $stmt->bindValue(':setting_key', 'telegram_token'); $stmt->execute(); $token = (string) ($stmt->fetchColumn() ?: ''); if ($token === '') { error_log('Telegram Error: No bot token found in settings.'); exit; } $faqs = []; try { $stmt = db()->query('SELECT keywords, answer FROM faqs ORDER BY id ASC'); $faqs = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: []; } catch (Throwable $faqError) { error_log('Telegram FAQ Load Error: ' . $faqError->getMessage()); } $faqReply = findFaqReply($faqs, $text); if ($faqReply !== '') { try { $stmt = db()->prepare('INSERT INTO messages (user_message, ai_response) VALUES (:user_message, :ai_response)'); $stmt->bindValue(':user_message', '[Telegram] ' . $text); $stmt->bindValue(':ai_response', $faqReply); $stmt->execute(); } catch (Throwable $saveError) { error_log('Telegram Save Error: ' . $saveError->getMessage()); } sendTelegramMessage($chatId, $faqReply, $token); exit; } $knowledgeBase = "Berikut knowledge base website ini: "; if ($faqs === []) { $knowledgeBase .= "- Belum ada FAQ khusus yang dikonfigurasi. "; } else { foreach ($faqs as $faq) { $knowledgeBase .= 'Q: ' . ($faq['keywords'] ?? '') . " "; $knowledgeBase .= 'A: ' . ($faq['answer'] ?? '') . " --- "; } } $systemPrompt = "Anda adalah asisten AI Telegram untuk website ini. " . "Gunakan knowledge base bila relevan. " . "Jawab ringkas, jelas, dan profesional dalam Bahasa Indonesia. " . $knowledgeBase; $response = LocalAIApi::createResponse( [ 'input' => [ ['role' => 'system', 'content' => $systemPrompt], ['role' => 'user', 'content' => $text], ], ], [ 'poll_interval' => 2, 'poll_timeout' => 45, ] ); if (!empty($response['success'])) { $aiReply = LocalAIApi::extractText($response); if ($aiReply === '') { $decoded = LocalAIApi::decodeJsonFromResponse($response); if ($decoded) { $aiReply = json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } } if ($aiReply === '') { $aiReply = 'Pesan Anda sudah diterima, tetapi balasan otomatis belum tersedia saat ini.'; } try { $stmt = db()->prepare('INSERT INTO messages (user_message, ai_response) VALUES (:user_message, :ai_response)'); $stmt->bindValue(':user_message', '[Telegram] ' . $text); $stmt->bindValue(':ai_response', $aiReply); $stmt->execute(); } catch (Throwable $saveError) { error_log('Telegram Save Error: ' . $saveError->getMessage()); } sendTelegramMessage($chatId, $aiReply, $token); exit; } error_log('Telegram AI Error: ' . ($response['error'] ?? 'Unknown')); sendTelegramMessage($chatId, 'Maaf, saya belum bisa memproses permintaan Anda saat ini.', $token); } catch (Throwable $error) { error_log('Telegram Webhook Error: ' . $error->getMessage()); }