- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
185 lines
8.3 KiB
PHP
185 lines
8.3 KiB
PHP
<?php
|
||
/*********************************************************************************
|
||
* Endpoint для сохранения AI-диалогов из Telegram в проекты CRM
|
||
* Сохраняет пары вопрос-ответ как два отдельных комментария
|
||
* All Rights Reserved.
|
||
********************************************************************************/
|
||
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', '1');
|
||
include_once 'modules/Users/Users.php';
|
||
include_once 'include/utils/CommonUtils.php';
|
||
include_once 'include/utils/utils.php';
|
||
require_once('include/Webservices/Utils.php');
|
||
require_once 'include/Webservices/Create.php';
|
||
require_once 'includes/Loader.php';
|
||
|
||
vimport ('includes.runtime.Globals');
|
||
vimport ('includes.runtime.BaseModel');
|
||
vimport ('includes.runtime.LanguageHandler');
|
||
|
||
// Получаем входные данные
|
||
$str = file_get_contents('php://input');
|
||
$logstring = date('Y-m-d H:i:s').' Получен запрос: '.$str.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
|
||
$data = json_decode($str, true);
|
||
|
||
// Проверяем обязательные поля
|
||
if (!isset($data['tgid']) || !isset($data['question']) || !isset($data['answer'])) {
|
||
$error = array('status' => 'error', 'message' => 'Не переданы обязательные поля: tgid, question, answer');
|
||
$logstring = date('Y-m-d H:i:s').' ОШИБКА: '.json_encode($error).PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
echo json_encode($error);
|
||
exit;
|
||
}
|
||
|
||
$tgid = $data['tgid'];
|
||
$question = $data['question'];
|
||
$answer = $data['answer'];
|
||
$projectid = isset($data['projectid']) ? $data['projectid'] : null;
|
||
$botname = isset($data['botname']) ? $data['botname'] : 'AI Bot';
|
||
|
||
$user = Users::getActiveAdminUser();
|
||
|
||
// 1. Находим контакт по tgid
|
||
$query = 'select c.contactid, c.firstname, c.lastname, e.smownerid as userid
|
||
from vtiger_contactdetails c
|
||
left join vtiger_crmentity e on e.crmid = c.contactid
|
||
where e.deleted = 0 and c.phone = ?';
|
||
$result = $adb->pquery($query, array($tgid));
|
||
|
||
if ($adb->num_rows($result) == 0) {
|
||
$error = array('status' => 'error', 'message' => 'Контакт с tgid='.$tgid.' не найден');
|
||
$logstring = date('Y-m-d H:i:s').' ОШИБКА: '.json_encode($error).PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
echo json_encode($error);
|
||
exit;
|
||
}
|
||
|
||
$contactid = $adb->query_result($result, 0, 'contactid');
|
||
$userid = $adb->query_result($result, 0, 'userid');
|
||
$firstname = $adb->query_result($result, 0, 'firstname');
|
||
$lastname = $adb->query_result($result, 0, 'lastname');
|
||
|
||
$logstring = date('Y-m-d H:i:s').' Найден контакт: '.$firstname.' '.$lastname.' (ID: '.$contactid.')'.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
|
||
// 2. Если projectid не передан - ищем активный проект
|
||
if (empty($projectid)) {
|
||
$query = 'select p.projectid
|
||
from vtiger_project p
|
||
left join vtiger_crmentity e on e.crmid = p.projectid
|
||
where e.deleted = 0 and p.linktoaccountscontacts = ? and p.projectstatus <> "completed"
|
||
order by e.modifiedtime desc
|
||
limit 1';
|
||
$result = $adb->pquery($query, array($contactid));
|
||
|
||
if ($adb->num_rows($result) == 0) {
|
||
$error = array('status' => 'error', 'message' => 'Не найден активный проект для контакта ID='.$contactid);
|
||
$logstring = date('Y-m-d H:i:s').' ОШИБКА: '.json_encode($error).PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
echo json_encode($error);
|
||
exit;
|
||
}
|
||
|
||
$projectid = $adb->query_result($result, 0, 'projectid');
|
||
$logstring = date('Y-m-d H:i:s').' Найден активный проект: '.$projectid.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
} else {
|
||
// 3. Если projectid передан - проверяем что он существует и связан с контактом
|
||
$query = 'select p.projectid
|
||
from vtiger_project p
|
||
left join vtiger_crmentity e on e.crmid = p.projectid
|
||
where e.deleted = 0 and p.projectid = ? and p.linktoaccountscontacts = ?';
|
||
$result = $adb->pquery($query, array($projectid, $contactid));
|
||
|
||
if ($adb->num_rows($result) == 0) {
|
||
$error = array('status' => 'error', 'message' => 'Проект ID='.$projectid.' не найден или не связан с контактом');
|
||
$logstring = date('Y-m-d H:i:s').' ОШИБКА: '.json_encode($error).PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
echo json_encode($error);
|
||
exit;
|
||
}
|
||
|
||
$logstring = date('Y-m-d H:i:s').' Проверен проект: '.$projectid.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
}
|
||
|
||
// Получаем ответственного за проект
|
||
$query = 'select smownerid from vtiger_crmentity where crmid = ?';
|
||
$result = $adb->pquery($query, array($projectid));
|
||
$ownerid = $adb->query_result($result, 0, 'smownerid');
|
||
|
||
// ID пользователя AI Bot
|
||
$ai_bot_userid = 23;
|
||
|
||
// Используем просто ID проекта (как в обычных комментариях)
|
||
|
||
$date_var = date('Y-m-d H:i:s');
|
||
|
||
// 4. Создаём комментарий с ВОПРОСОМ (напрямую через SQL)
|
||
$question_commentid = $adb->getUniqueID("vtiger_crmentity");
|
||
|
||
// Вставляем в crmentity
|
||
$sql = "insert into vtiger_crmentity (crmid, smcreatorid, smownerid, setype, description, createdtime, modifiedtime, presence, deleted)
|
||
values(?, ?, ?, 'ModComments', '', ?, ?, 1, 0)";
|
||
$params = array($question_commentid, $ownerid, $ownerid, $adb->formatDate($date_var, true), $adb->formatDate($date_var, true));
|
||
$adb->pquery($sql, $params);
|
||
|
||
// Вставляем в modcomments
|
||
$sql = "insert into vtiger_modcomments (modcommentsid, commentcontent, related_to, customer, userid, reasontoedit, channel, parent_comments)
|
||
values(?, ?, ?, ?, 0, '', 'Telegram AI', 0)";
|
||
$params = array($question_commentid, $question, $projectid, $contactid);
|
||
$adb->pquery($sql, $params);
|
||
|
||
// Вставляем в modcommentsrel
|
||
// $sql = "insert into vtiger_modcommentsrel (modcommentsid, related_to) values(?, ?)";
|
||
// $adb->pquery($sql, array($question_commentid, $projectid));
|
||
|
||
$logstring = date('Y-m-d H:i:s').' ✅ Создан комментарий с ВОПРОСОМ: '.$question_commentid.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
|
||
// Задержка 1 секунда, чтобы ответ был позже вопроса
|
||
sleep(1);
|
||
$date_var_answer = date('Y-m-d H:i:s');
|
||
|
||
// 5. Создаём комментарий с ОТВЕТОМ (напрямую через SQL)
|
||
$answer_commentid = $adb->getUniqueID("vtiger_crmentity");
|
||
|
||
// Вставляем в crmentity (от AI Bot пользователя)
|
||
$sql = "insert into vtiger_crmentity (crmid, smcreatorid, smownerid, setype, description, createdtime, modifiedtime, presence, deleted)
|
||
values(?, ?, ?, 'ModComments', '', ?, ?, 1, 0)";
|
||
$params = array($answer_commentid, $ai_bot_userid, $ai_bot_userid, $adb->formatDate($date_var_answer, true), $adb->formatDate($date_var_answer, true));
|
||
$adb->pquery($sql, $params);
|
||
|
||
// Вставляем в modcomments (от AI Bot, поэтому customer = 0, userid = AI Bot)
|
||
$sql = "insert into vtiger_modcomments (modcommentsid, commentcontent, related_to, customer, userid, reasontoedit, channel, parent_comments)
|
||
values(?, ?, ?, 0, ?, '', 'Telegram AI Bot', 0)";
|
||
$params = array($answer_commentid, $answer, $projectid, $ai_bot_userid);
|
||
$adb->pquery($sql, $params);
|
||
|
||
// Вставляем в modcommentsrel
|
||
// $sql = "insert into vtiger_modcommentsrel (modcommentsid, related_to) values(?, ?)";
|
||
// $adb->pquery($sql, array($answer_commentid, $projectid));
|
||
|
||
$logstring = date('Y-m-d H:i:s').' ✅ Создан комментарий с ОТВЕТОМ: '.$answer_commentid.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
|
||
// 6. Возвращаем успех
|
||
$response = array(
|
||
'status' => 'success',
|
||
'contact_id' => $contactid,
|
||
'project_id' => $projectid,
|
||
'question_comment_id' => $question_commentid,
|
||
'answer_comment_id' => $answer_commentid,
|
||
'botname' => $botname
|
||
);
|
||
|
||
$logstring = date('Y-m-d H:i:s').' ✅ SUCCESS: '.json_encode($response).PHP_EOL.PHP_EOL;
|
||
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
|
||
|
||
echo json_encode($response);
|
||
?>
|
||
|