38471-vm/api/telegram_webhook.php
2026-05-02 17:17:21 +00:00

174 lines
5.0 KiB
PHP

<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../ai/LocalAIApi.php';
function telegramTableExists(string $table): bool
{
static $cache = [];
$table = strtolower($table);
if (array_key_exists($table, $cache)) {
return $cache[$table];
}
try {
$stmt = db()->prepare("SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1");
$stmt->execute([$table]);
$cache[$table] = (bool)$stmt->fetchColumn();
} catch (Throwable $e) {
$cache[$table] = false;
}
return $cache[$table];
}
function telegramColumnExists(string $table, string $column): bool
{
static $cache = [];
$cacheKey = strtolower($table . '.' . $column);
if (array_key_exists($cacheKey, $cache)) {
return $cache[$cacheKey];
}
try {
$stmt = db()->prepare("SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1");
$stmt->execute([$table, $column]);
$cache[$cacheKey] = (bool)$stmt->fetchColumn();
} catch (Throwable $e) {
$cache[$cacheKey] = false;
}
return $cache[$cacheKey];
}
function telegramSettingValue(string $key): ?string
{
try {
if (telegramColumnExists('settings', 'key') && telegramColumnExists('settings', 'value')) {
$stmt = db()->prepare("SELECT `value` FROM settings WHERE `key` = ? LIMIT 1");
$stmt->execute([$key]);
$value = $stmt->fetchColumn();
return $value === false ? null : (string)$value;
}
if (telegramColumnExists('settings', 'setting_key') && telegramColumnExists('settings', 'setting_value')) {
$stmt = db()->prepare("SELECT setting_value FROM settings WHERE setting_key = ? LIMIT 1");
$stmt->execute([$key]);
$value = $stmt->fetchColumn();
return $value === false ? null : (string)$value;
}
} catch (Throwable $e) {
error_log('Telegram settings error: ' . $e->getMessage());
}
return null;
}
function telegramFetchFaqs(): array
{
if (!telegramTableExists('faqs') || !telegramColumnExists('faqs', 'keywords') || !telegramColumnExists('faqs', 'answer')) {
return [];
}
$stmt = db()->query("SELECT keywords, answer FROM faqs");
return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
}
function telegramStoreMessage(string $userMessage, string $aiResponse): void
{
if (!telegramTableExists('messages') || !telegramColumnExists('messages', 'user_message') || !telegramColumnExists('messages', 'ai_response')) {
return;
}
try {
$stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)");
$stmt->execute([$userMessage, $aiResponse]);
} catch (Throwable $e) {
error_log('Telegram DB Save Error: ' . $e->getMessage());
}
}
function sendTelegramMessage($chatId, $text, $token)
{
$url = "https://api.telegram.org/bot$token/sendMessage";
$data = [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'Markdown',
];
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded
",
'method' => 'POST',
'content' => http_build_query($data),
],
];
$context = stream_context_create($options);
return file_get_contents($url, false, $context);
}
$content = file_get_contents('php://input');
$update = json_decode($content, true);
if (!$update || !isset($update['message'])) {
exit;
}
$message = $update['message'];
$chatId = $message['chat']['id'] ?? null;
$text = $message['text'] ?? '';
if ($chatId === null || $text === '') {
exit;
}
$token = telegramSettingValue('telegram_token');
if (!$token) {
error_log('Telegram Error: No bot token found in settings.');
exit;
}
try {
$faqs = telegramFetchFaqs();
$knowledgeBase = '';
if ($faqs !== []) {
$knowledgeBase = "Here is the knowledge base for this website:
";
foreach ($faqs as $faq) {
$knowledgeBase .= "Q: " . ($faq['keywords'] ?? '') . "
A: " . ($faq['answer'] ?? '') . "
---
";
}
}
$systemPrompt = "You are a helpful AI assistant integrated with Telegram. " .
"Use the provided Knowledge Base to answer user questions. " .
"Keep answers concise for mobile reading. Use Markdown for formatting.
" .
$knowledgeBase;
$response = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $text],
],
]);
if (!empty($response['success'])) {
$aiReply = LocalAIApi::extractText($response);
telegramStoreMessage('[Telegram] ' . $text, $aiReply);
sendTelegramMessage($chatId, $aiReply, $token);
} else {
sendTelegramMessage($chatId, "I'm sorry, I encountered an error processing your request.", $token);
}
} catch (Throwable $e) {
error_log('Telegram Webhook Error: ' . $e->getMessage());
}