Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system

- 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.
This commit is contained in:
Fedor
2025-10-16 11:17:21 +03:00
parent dabcd43a00
commit ac7467f0b4
26580 changed files with 50860 additions and 3261 deletions

184
telegram_ai_qa.php Normal file
View File

@@ -0,0 +1,184 @@
<?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);
?>