Autosave: 20260213-104737

This commit is contained in:
Flatlogic Bot 2026-02-13 10:47:37 +00:00
parent 89bba1a66a
commit 7406216157
3 changed files with 194 additions and 19 deletions

View File

@ -16,12 +16,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt = db()->prepare("DELETE FROM faqs WHERE id = ?");
$stmt->execute([$id]);
}
} elseif (isset($_POST['action']) && $_POST['action'] === 'update_settings') {
$token = $_POST['telegram_token'] ?? '';
$stmt = db()->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('telegram_token', ?) ON DUPLICATE KEY UPDATE setting_value = ?");
$stmt->execute([$token, $token]);
}
header("Location: admin.php");
exit;
}
$faqs = db()->query("SELECT * FROM faqs ORDER BY created_at DESC")->fetchAll();
$messages = db()->query("SELECT * FROM messages ORDER BY created_at DESC LIMIT 50")->fetchAll();
$telegramToken = '';
$stmt = db()->query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_token'");
$row = $stmt->fetch();
if ($row) {
$telegramToken = $row['setting_value'];
}
?>
<!doctype html>
<html lang="en">
@ -64,6 +76,21 @@ $faqs = db()->query("SELECT * FROM faqs ORDER BY created_at DESC")->fetchAll();
<a href="index.php" class="admin-link">Back to Chat</a>
</div>
<div class="admin-card" style="background: rgba(255, 255, 255, 0.6); padding: 2rem; border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.5); margin-bottom: 2.5rem; box-shadow: 0 10px 30px rgba(0,0,0,0.05);">
<h3 style="margin-top: 0; margin-bottom: 1.5rem; font-weight: 700;">Telegram Bot Settings</h3>
<form method="POST">
<input type="hidden" name="action" value="update_settings">
<div class="form-group">
<label for="telegram_token">Telegram Bot Token</label>
<input type="text" name="telegram_token" id="telegram_token" class="form-control" placeholder="Paste your bot token from @BotFather" value="<?= htmlspecialchars($telegramToken) ?>">
</div>
<p style="font-size: 0.85em; color: #555; margin-top: 0.5rem;">
Webhook URL: <code>https://<?= $_SERVER['HTTP_HOST'] ?>/api/telegram_webhook.php</code>
</p>
<button type="submit" class="btn-add" style="background: #0088cc; color: white; border: none; padding: 0.8rem 1.5rem; border-radius: 12px; cursor: pointer; font-weight: 600; width: 100%; transition: all 0.3s ease;">Save Token</button>
</form>
</div>
<div class="admin-card" style="background: rgba(255, 255, 255, 0.6); padding: 2rem; border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.5); margin-bottom: 2.5rem; box-shadow: 0 10px 30px rgba(0,0,0,0.05);">
<h3 style="margin-top: 0; margin-bottom: 1.5rem; font-weight: 700;">Add New FAQ</h3>
<form method="POST">
@ -105,6 +132,34 @@ $faqs = db()->query("SELECT * FROM faqs ORDER BY created_at DESC")->fetchAll();
<?php endforeach; ?>
</tbody>
</table>
<h3 style="margin-top: 3rem; margin-bottom: 1rem;">Recent Chat History (Last 50)</h3>
<div style="overflow-x: auto; background: rgba(255, 255, 255, 0.4); padding: 1rem; border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.3);">
<table class="table" style="width: 100%;">
<thead>
<tr>
<th style="width: 15%;">Time</th>
<th style="width: 35%;">User Message</th>
<th style="width: 50%;">AI Response</th>
</tr>
</thead>
<tbody>
<?php if (empty($messages)): ?>
<tr>
<td colspan="3" style="text-align: center; color: #777;">No messages yet.</td>
</tr>
<?php else: ?>
<?php foreach ($messages as $msg): ?>
<tr>
<td style="white-space: nowrap; font-size: 0.85em; color: #555;"><?= htmlspecialchars($msg['created_at']) ?></td>
<td style="background: rgba(255, 255, 255, 0.3); border-radius: 8px; padding: 8px;"><?= htmlspecialchars($msg['user_message']) ?></td>
<td style="background: rgba(255, 255, 255, 0.5); border-radius: 8px; padding: 8px;"><?= htmlspecialchars($msg['ai_response']) ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</body>

View File

@ -1,6 +1,7 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../ai/LocalAIApi.php';
$input = json_decode(file_get_contents('php://input'), true);
$message = $input['message'] ?? '';
@ -10,26 +11,54 @@ if (empty($message)) {
exit;
}
$faqs = db()->query("SELECT keywords, answer FROM faqs")->fetchAll();
try {
// 1. Fetch Knowledge Base (FAQs)
$stmt = db()->query("SELECT keywords, answer FROM faqs");
$faqs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$bestMatch = null;
$maxOverlap = 0;
$userWords = preg_split('/\W+/', strtolower($message), -1, PREG_SPLIT_NO_EMPTY);
foreach ($faqs as $faq) {
$keywords = preg_split('/[\s,]+/', strtolower($faq['keywords']), -1, PREG_SPLIT_NO_EMPTY);
$overlap = count(array_intersect($userWords, $keywords));
if ($overlap > $maxOverlap) {
$maxOverlap = $overlap;
$bestMatch = $faq['answer'];
$knowledgeBase = "Here is the knowledge base for this website:\n\n";
foreach ($faqs as $faq) {
$knowledgeBase .= "Q: " . $faq['keywords'] . "\nA: " . $faq['answer'] . "\n---\n";
}
}
if ($bestMatch) {
echo json_encode(['reply' => $bestMatch]);
} else {
// Default fallback
echo json_encode(['reply' => "I'm sorry, I don't have an answer for that yet. You can try asking about 'pricing' or 'support'."]);
// 2. Construct Prompt for AI
$systemPrompt = "You are a helpful, friendly AI assistant for this website. " .
"Use the provided Knowledge Base to answer user questions accurately. " .
"If the answer is found in the Knowledge Base, rephrase it naturally. " .
"If the answer is NOT in the Knowledge Base, use your general knowledge to help, " .
"but politely mention that you don't have specific information about that if it seems like a site-specific question. " .
"Keep answers concise and professional.\n\n" .
$knowledgeBase;
// 3. Call AI API
$response = LocalAIApi::createResponse([
'model' => 'gpt-4o-mini',
'input' => [
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $message],
]
]);
if (!empty($response['success'])) {
$aiReply = LocalAIApi::extractText($response);
// 4. Save to Database
try {
$stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)");
$stmt->execute([$message, $aiReply]);
} catch (Exception $e) {
error_log("DB Save Error: " . $e->getMessage());
// Continue even if save fails, so the user still gets a reply
}
echo json_encode(['reply' => $aiReply]);
} else {
// Fallback if AI fails
error_log("AI Error: " . ($response['error'] ?? 'Unknown'));
echo json_encode(['reply' => "I'm having trouble connecting to my brain right now. Please try again later."]);
}
} catch (Exception $e) {
error_log("Chat Error: " . $e->getMessage());
echo json_encode(['reply' => "An internal error occurred."]);
}

91
api/telegram_webhook.php Normal file
View File

@ -0,0 +1,91 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../ai/LocalAIApi.php';
// Get Telegram Update
$content = file_get_contents("php://input");
$update = json_decode($content, true);
if (!$update || !isset($update['message'])) {
exit;
}
$message = $update['message'];
$chatId = $message['chat']['id'];
$text = $message['text'] ?? '';
if (empty($text)) {
exit;
}
// Get Telegram Token from DB
$stmt = db()->query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_token'");
$token = $stmt->fetchColumn();
if (!$token) {
error_log("Telegram Error: No bot token found in settings.");
exit;
}
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\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];
$context = stream_context_create($options);
return file_get_contents($url, false, $context);
}
// Process with AI (Similar logic to api/chat.php)
try {
// 1. Fetch Knowledge Base
$stmt = db()->query("SELECT keywords, answer FROM faqs");
$faqs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$knowledgeBase = "Here is the knowledge base for this website:\n\n";
foreach ($faqs as $faq) {
$knowledgeBase .= "Q: " . $faq['keywords'] . "\nA: " . $faq['answer'] . "\n---\n";
}
$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.\n\n" .
$knowledgeBase;
// 2. Call AI
$response = LocalAIApi::createResponse([
'model' => 'gpt-4o-mini',
'input' => [
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $text],
]
]);
if (!empty($response['success'])) {
$aiReply = LocalAIApi::extractText($response);
// 3. Save History
try {
$stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)");
$stmt->execute(["[Telegram] " . $text, $aiReply]);
} catch (Exception $e) {}
// 4. Send back to Telegram
sendTelegramMessage($chatId, $aiReply, $token);
} else {
sendTelegramMessage($chatId, "I'm sorry, I encountered an error processing your request.", $token);
}
} catch (Exception $e) {
error_log("Telegram Webhook Error: " . $e->getMessage());
}