ai chat bot!
This commit is contained in:
parent
b86f18f85f
commit
0490892e31
1
.env
1
.env
@ -1 +1,2 @@
|
|||||||
OPENAI_API_KEY=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
|
OPENAI_API_KEY=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
|
||||||
|
OPENAI_MODEL=gpt-4o
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
OPENAI_API_KEY=
|
OPENAI_API_KEY=
|
||||||
|
OPENAI_MODEL=gpt-4o-mini
|
||||||
120
api/chat.php
120
api/chat.php
@ -1,58 +1,92 @@
|
|||||||
<?php
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$logFile = __DIR__ . '/error.log';
|
||||||
|
// Clear the log file for each request to ensure we're only seeing the latest error.
|
||||||
|
file_put_contents($logFile, "");
|
||||||
|
|
||||||
|
// This is the top-level error handler.
|
||||||
|
// It will catch any exception that isn't caught elsewhere.
|
||||||
|
set_exception_handler(function($exception) use ($logFile) {
|
||||||
|
http_response_code(500);
|
||||||
|
$error = [
|
||||||
|
'error' => 'An unexpected error occurred.',
|
||||||
|
'message' => $exception->getMessage(),
|
||||||
|
'file' => $exception->getFile(),
|
||||||
|
'line' => $exception->getLine(),
|
||||||
|
];
|
||||||
|
file_put_contents($logFile, json_encode($error, JSON_PRETTY_PRINT));
|
||||||
|
// We must output valid JSON, otherwise the frontend will get a syntax error.
|
||||||
|
echo json_encode($error);
|
||||||
|
});
|
||||||
|
|
||||||
require_once __DIR__ . '/../lib/config.php';
|
require_once __DIR__ . '/../lib/config.php';
|
||||||
require_once __DIR__ . '/../lib/OpenAIService.php';
|
require_once __DIR__ . '/../lib/OpenAIService.php';
|
||||||
require_once __DIR__ . '/../db/config.php';
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
// The main try-catch block for the application logic.
|
||||||
|
|
||||||
session_start();
|
|
||||||
if (empty($_SESSION['session_id'])) {
|
|
||||||
$_SESSION['session_id'] = bin2hex(random_bytes(16));
|
|
||||||
}
|
|
||||||
$session_id = $_SESSION['session_id'];
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
||||||
echo json_encode(['error' => 'Invalid request method.']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$input = json_decode(file_get_contents('php://input'), true);
|
|
||||||
|
|
||||||
if (!isset($input['message']) || trim($input['message']) === '') {
|
|
||||||
echo json_encode(['error' => 'Message is required.']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_message = trim($input['message']);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
|
||||||
|
|
||||||
// Save user message
|
// Check if it's a POST request
|
||||||
$stmt = $pdo->prepare("INSERT INTO chat_log (session_id, sender, message) VALUES (?, ?, ?)");
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
$stmt->execute([$session_id, 'user', $user_message]);
|
http_response_code(405); // Method Not Allowed
|
||||||
|
throw new Exception('Only POST requests are allowed.');
|
||||||
// Get AI response
|
|
||||||
$response = OpenAIService::getCompletion($user_message);
|
|
||||||
|
|
||||||
if (!empty($response['error'])) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode($response);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$ai_message = $response['reply'];
|
// Get the user's message from the request body
|
||||||
|
$json_data = file_get_contents('php://input');
|
||||||
|
$data = json_decode($json_data);
|
||||||
|
$user_message = $data->message ?? '';
|
||||||
|
|
||||||
// Save AI message
|
if (empty($user_message)) {
|
||||||
|
http_response_code(400); // Bad Request
|
||||||
|
throw new Exception('Message is required.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Database Interaction ---
|
||||||
|
$pdo = db();
|
||||||
|
if (empty($_SESSION['chat_session_id'])) {
|
||||||
|
$_SESSION['chat_session_id'] = bin2hex(random_bytes(16));
|
||||||
|
}
|
||||||
|
$chat_session_id = $_SESSION['chat_session_id'];
|
||||||
|
|
||||||
|
// Log the user's message
|
||||||
$stmt = $pdo->prepare("INSERT INTO chat_log (session_id, sender, message) VALUES (?, ?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO chat_log (session_id, sender, message) VALUES (?, ?, ?)");
|
||||||
$stmt->execute([$session_id, 'ai', $ai_message]);
|
$stmt->execute([$chat_session_id, 'user', $user_message]);
|
||||||
|
|
||||||
echo json_encode(['reply' => $ai_message]);
|
// --- OpenAI API Call ---
|
||||||
|
$bot_response_data = OpenAIService::getCompletion($user_message);
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
if (isset($bot_response_data['error'])) {
|
||||||
// Log error and return a generic error message
|
throw new Exception('OpenAI API Error: ' . $bot_response_data['error']);
|
||||||
error_log("Database error: " . $e->getMessage());
|
}
|
||||||
echo json_encode(['error' => 'An internal server error occurred.']);
|
$bot_response = $bot_response_data['reply'];
|
||||||
exit;
|
|
||||||
|
// Log the bot's response
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO chat_log (session_id, sender, message) VALUES (?, ?, ?)");
|
||||||
|
$stmt->execute([$chat_session_id, 'bot', $bot_response]);
|
||||||
|
|
||||||
|
// --- Send Response ---
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode(['reply' => $bot_response]);
|
||||||
|
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// This will catch both Exceptions and Errors
|
||||||
|
http_response_code(500);
|
||||||
|
$errorDetails = [
|
||||||
|
'error' => 'Caught in main try-catch',
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'trace' => $e->getTraceAsString()
|
||||||
|
];
|
||||||
|
file_put_contents($logFile, date('Y-m-d H:i:s') . " - " . json_encode($errorDetails, JSON_PRETTY_PRINT) . "
|
||||||
|
", FILE_APPEND);
|
||||||
|
// Ensure a JSON response is sent on error
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode($errorDetails);
|
||||||
}
|
}
|
||||||
7
api/error.log
Normal file
7
api/error.log
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
2025-09-11 22:08:09 - {
|
||||||
|
"error": "Caught in main try-catch",
|
||||||
|
"message": "Only POST requests are allowed.",
|
||||||
|
"file": "\/home\/ubuntu\/executor\/workspace\/api\/chat.php",
|
||||||
|
"line": 37,
|
||||||
|
"trace": "#0 {main}"
|
||||||
|
}
|
||||||
@ -42,7 +42,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if(data.error) {
|
if(data.error) {
|
||||||
appendMessage(data.error, 'ai');
|
appendMessage(data.error, 'ai');
|
||||||
} else {
|
} else {
|
||||||
appendMessage(data.message, 'ai'); // Bug fix: data.reply -> data.message
|
appendMessage(data.reply, 'ai');
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -29,10 +29,10 @@ function db() {
|
|||||||
// Now, connect to the newly created database
|
// Now, connect to the newly created database
|
||||||
$pdo = new PDO($dsn . ';dbname=' . DB_NAME, DB_USER, DB_PASS, $options);
|
$pdo = new PDO($dsn . ';dbname=' . DB_NAME, DB_USER, DB_PASS, $options);
|
||||||
} catch (PDOException $ce) {
|
} catch (PDOException $ce) {
|
||||||
die("Failed to create database and connect: " . $ce->getMessage());
|
throw new PDOException("Failed to create database and connect: " . $ce->getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
die("Database connection failed: " . $e->getMessage());
|
throw new PDOException("Database connection failed: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,12 @@
|
|||||||
class OpenAIService
|
class OpenAIService
|
||||||
{
|
{
|
||||||
private static $apiKey;
|
private static $apiKey;
|
||||||
|
private static $model;
|
||||||
|
|
||||||
public static function init()
|
public static function init()
|
||||||
{
|
{
|
||||||
self::$apiKey = getenv('OPENAI_API_KEY');
|
self::$apiKey = getenv('OPENAI_API_KEY');
|
||||||
|
self::$model = getenv('OPENAI_MODEL') ?: 'gpt-4o-mini';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getCompletion($message)
|
public static function getCompletion($message)
|
||||||
@ -18,7 +20,7 @@ class OpenAIService
|
|||||||
$url = 'https://api.openai.com/v1/chat/completions';
|
$url = 'https://api.openai.com/v1/chat/completions';
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'model' => 'gpt-3.5-turbo',
|
'model' => self::$model,
|
||||||
'messages' => [
|
'messages' => [
|
||||||
['role' => 'system', 'content' => 'You are a helpful assistant.'],
|
['role' => 'system', 'content' => 'You are a helpful assistant.'],
|
||||||
['role' => 'user', 'content' => $message]
|
['role' => 'user', 'content' => $message]
|
||||||
@ -31,19 +33,31 @@ class OpenAIService
|
|||||||
'Authorization: Bearer ' . self::$apiKey
|
'Authorization: Bearer ' . self::$apiKey
|
||||||
];
|
];
|
||||||
|
|
||||||
$ch = curl_init($url);
|
$options = [
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
'http' => [
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
'header' => implode("\r\n", $headers),
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
'method' => 'POST',
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
'content' => json_encode($data),
|
||||||
|
'ignore_errors' => true,
|
||||||
|
'timeout' => 30,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$context = stream_context_create($options);
|
||||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$response = @file_get_contents($url, false, $context);
|
||||||
$error = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
if ($error) {
|
// Get HTTP status code from the response headers
|
||||||
return ['error' => 'API call failed: ' . $error];
|
$httpcode = 0;
|
||||||
|
if (isset($http_response_header[0])) {
|
||||||
|
preg_match('{HTTP/1\.\d (\d{3})}', $http_response_header[0], $matches);
|
||||||
|
if (isset($matches[1])) {
|
||||||
|
$httpcode = (int)$matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response === false) {
|
||||||
|
$error = error_get_last();
|
||||||
|
return ['error' => 'API call failed: ' . ($error['message'] ?? 'Unknown error')];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($httpcode !== 200) {
|
if ($httpcode !== 200) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user