- Создан API create_document_with_text.php для создания DOCX/XLSX/PPTX с текстом от AI - Поддержка Markdown форматирования (заголовки, жирный, курсив, списки, код) - Установлен PHPWord для красивого форматирования документов - Исправлены пути сохранения (crm2/CRM_Active_Files/... без /crm/ в начале) - Замена пробелов на подчеркивания в именах папок - Создана документация для AI и разработчиков - Добавлены API для работы с шаблонами Nextcloud
131 lines
4.5 KiB
PHP
131 lines
4.5 KiB
PHP
<?php
|
||
// callback_ai_response.php
|
||
// Endpoint для приема ответов от n8n
|
||
|
||
header('Content-Type: application/json');
|
||
header('Access-Control-Allow-Origin: *');
|
||
header('Access-Control-Allow-Methods: POST, OPTIONS');
|
||
header('Access-Control-Allow-Headers: Content-Type');
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||
http_response_code(200);
|
||
exit();
|
||
}
|
||
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', 1);
|
||
|
||
try {
|
||
// Подключаемся к БД
|
||
include_once('config.inc.php');
|
||
|
||
$conn = new mysqli($dbconfig['db_server'], $dbconfig['db_username'], $dbconfig['db_password'], $dbconfig['db_name']);
|
||
|
||
if ($conn->connect_error) {
|
||
throw new Exception("DB connection failed: " . $conn->connect_error);
|
||
}
|
||
|
||
$conn->set_charset('utf8mb4');
|
||
|
||
// Получаем данные от n8n
|
||
$input = json_decode(file_get_contents('php://input'), true);
|
||
|
||
if (!$input) {
|
||
throw new Exception('Invalid JSON input');
|
||
}
|
||
|
||
$taskId = $input['taskId'] ?? null;
|
||
$response = $input['response'] ?? null;
|
||
$status = $input['status'] ?? 'completed';
|
||
$error = $input['error'] ?? null;
|
||
|
||
if (!$taskId) {
|
||
throw new Exception('Missing taskId');
|
||
}
|
||
|
||
error_log("Callback: Received response for task {$taskId}, status: {$status}");
|
||
|
||
// Обновляем запись в БД
|
||
if ($status === 'error') {
|
||
$stmt = $conn->prepare("UPDATE ai_responses SET status = 'error', error_message = ?, updated_at = NOW() WHERE task_id = ?");
|
||
$stmt->bind_param('ss', $error, $taskId);
|
||
} else {
|
||
$stmt = $conn->prepare("UPDATE ai_responses SET status = 'completed', response_data = ?, updated_at = NOW() WHERE task_id = ?");
|
||
$stmt->bind_param('ss', $response, $taskId);
|
||
}
|
||
|
||
if (!$stmt->execute()) {
|
||
throw new Exception("Failed to update task: " . $stmt->error);
|
||
}
|
||
|
||
$affected = $stmt->affected_rows;
|
||
$stmt->close();
|
||
$conn->close();
|
||
|
||
error_log("Callback: Updated task {$taskId}, affected rows: {$affected}");
|
||
|
||
// Публикуем событие в Redis для мгновенной доставки через SSE
|
||
try {
|
||
if (class_exists('Redis')) {
|
||
$redis = new Redis();
|
||
if ($redis->connect('crm.clientright.ru', 6379)) {
|
||
$redis->auth('CRM_Redis_Pass_2025_Secure!');
|
||
|
||
$channel = "ai:response:{$taskId}";
|
||
$event = json_encode([
|
||
'task_id' => $taskId,
|
||
'status' => $status,
|
||
'response' => $response,
|
||
'error' => $error,
|
||
'timestamp' => date('Y-m-d H:i:s')
|
||
], JSON_UNESCAPED_UNICODE);
|
||
|
||
$redis->publish($channel, $event);
|
||
error_log("Callback: Published to Redis channel {$channel}");
|
||
$redis->close();
|
||
}
|
||
} else {
|
||
// Используем Predis если расширение Redis недоступно
|
||
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
|
||
$redis = new Predis\Client([
|
||
'scheme' => 'tcp',
|
||
'host' => 'crm.clientright.ru',
|
||
'port' => 6379,
|
||
'password' => 'CRM_Redis_Pass_2025_Secure!',
|
||
]);
|
||
|
||
$channel = "ai:response:{$taskId}";
|
||
$event = json_encode([
|
||
'task_id' => $taskId,
|
||
'status' => $status,
|
||
'response' => $response,
|
||
'error' => $error,
|
||
'timestamp' => date('Y-m-d H:i:s')
|
||
], JSON_UNESCAPED_UNICODE);
|
||
|
||
$redis->publish($channel, $event);
|
||
error_log("Callback: Published to Redis channel {$channel} via Predis");
|
||
}
|
||
} catch (Exception $redisError) {
|
||
error_log("Callback: Redis publish error (non-critical): " . $redisError->getMessage());
|
||
// Не прерываем выполнение, если Redis недоступен - БД уже обновлена
|
||
}
|
||
|
||
echo json_encode([
|
||
'success' => true,
|
||
'message' => 'Response received',
|
||
'taskId' => $taskId,
|
||
'affected' => $affected
|
||
]);
|
||
|
||
} catch (Exception $e) {
|
||
error_log("Callback Error: " . $e->getMessage());
|
||
|
||
http_response_code(500);
|
||
echo json_encode([
|
||
'success' => false,
|
||
'error' => $e->getMessage()
|
||
]);
|
||
}
|
||
?>
|