<?php
// Dieses Modul verwandelt den Artikel in einen JSON-API-Endpunkt für den Chat.
// Im Backend nur Hinweis zeigen:
if (rex::isBackend()) {
echo '<p>Frontend-API-Endpunkt für den Winzerhof-Chat. Bitte diesen Artikel online lassen.</p>';
return;
}
// CORS / Headers
header('Access-Control-Allow-Origin: ' . ($_SERVER['HTTP_ORIGIN'] ?? '*'));
header('Vary: Origin');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
rex_response::cleanOutputBuffers();
rex_response::sendContent('', 'text/plain', 'utf-8', 204);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
// Für GET o.ä.: kurze Info ausgeben, damit die Seite nicht im Layout erscheint
rex_response::cleanOutputBuffers();
rex_response::sendContent(json_encode(['ok' => true, 'endpoint' => 'Winzerhof Chat API']), 'application/json');
exit;
}
// Body lesen
$body = json_decode(file_get_contents('php://input'), true);
$userMessage = trim($body['message'] ?? '');
$history = $body['history'] ?? []; // [{role:'user'|'assistant', content:'...'}]
if ($userMessage === '') {
rex_response::cleanOutputBuffers();
rex_response::sendContent(json_encode(['error' => 'message is required']), 'application/json', 'utf-8', 400);
exit;
}
// Systemprompt – hier kannst du Tonalität/Regeln anpassen
$systemPrompt = <<<SYS
Du bist der digitale Assistent des Ringhotel Winzerhof in Rauenberg.
Antworte verbindlich, präzise und hilfsbereit.
Bei Privatgästen gerne locker, bei Firmen/Tagungen formell.
SYS;
$messages = [['role' => 'system', 'content' => $systemPrompt]];
foreach ($history as $m) {
$role = ($m['role'] === 'assistant') ? 'assistant' : 'user';
$messages[] = ['role' => $role, 'content' => (string)$m['content']];
}
$messages[] = ['role' => 'user', 'content' => $userMessage];
// API-Key/Modell aus Server-Umgebung lesen (empfohlen über .htaccess/Hosting-Panel gesetzt)
$apiKey = rex_getEnv('OPENAI_API_KEY') ?: getenv('OPENAI_API_KEY') ?: 'DEIN_OPENAI_API_KEY';
$model = rex_getEnv('OPENAI_MODEL') ?: getenv('OPENAI_MODEL') ?: 'gpt-4o-mini';
// Payload für Responses API
$payload = [
'model' => $model,
'input' => $messages,
'max_output_tokens' => 700,
];
$ch = curl_init('https://api.openai.com/v1/responses');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE)
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$err = curl_error($ch);
curl_close($ch);
if ($response === false) {
rex_response::cleanOutputBuffers();
rex_response::sendContent(json_encode(['error' => $err ?: 'unknown error']), 'application/json', 'utf-8', 500);
exit;
}
$data = json_decode($response, true);
$text = $data['output'][0]['content'][0]['text'] ?? $data['output_text'] ?? null;
rex_response::cleanOutputBuffers();
if (!$text) {
// Rohantwort durchreichen, falls Format anders ist
rex_response::sendContent($response, 'application/json', 'utf-8', ($code >= 200 && $code < 300) ? 500 : $code);
exit;
}
rex_response::sendContent(json_encode(['reply' => $text]), 'application/json');
exit;
