Files
crm.clientright.ru/telegram_ai_qa.php
Fedor 119a74b0e8 Добавлена система уведомлений для Telegram AI бота
- Реализована функция createTelegramAINotification() в telegram_ai_qa.php
- Автоматическое создание уведомлений при общении клиента с AI ботом
- Уведомления отправляются ответственному по проекту
- Умная дедупликация - обновление существующих непрочитанных уведомлений
- Краткий заголовок с именем клиента и началом вопроса (до 80 символов)
- Ссылка ведет на проект с комментариями диалога
- Добавлена документация TELEGRAM_AI_NOTIFICATIONS.md
- Протестировано и работает корректно
2025-10-16 16:20:54 +03:00

247 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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();
// Функция для создания уведомления о диалоге с AI ботом
function createTelegramAINotification($projectId, $contactId, $contactName, $questionPreview) {
global $adb;
$logstring = date('Y-m-d H:i:s').' Создаем уведомление для проекта '.$projectId.' о диалоге с AI ботом'.PHP_EOL;
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
// Получаем ответственного по проекту
$query = 'SELECT e.smownerid FROM vtiger_crmentity e WHERE e.crmid = ? AND e.deleted = 0';
$result = $adb->pquery($query, array($projectId));
if ($adb->num_rows($result) === 0) {
$logstring = date('Y-m-d H:i:s').' WARNING: Проект '.$projectId.' не найден или удален'.PHP_EOL;
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
return false;
}
$userId = $adb->query_result($result, 0, 'smownerid');
$logstring = date('Y-m-d H:i:s').' Ответственный по проекту: пользователь '.$userId.PHP_EOL;
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
// Формируем текст уведомления
// Обрезаем вопрос до 80 символов для краткости
$shortQuestion = mb_strlen($questionPreview) > 80 ? mb_substr($questionPreview, 0, 80) . '...' : $questionPreview;
$notificationTitle = "Telegram AI: " . $contactName . " - " . $shortQuestion;
// Формируем ссылку на проект (VDNotifierPro убирает index.php? из ссылки)
$projectLink = "module=Project&view=Detail&record=" . $projectId;
// Проверяем, нет ли уже непрочитанного уведомления для этого проекта от AI бота
// Используем modulename='Project' и проверяем title на начало с "Telegram AI:"
$checkQuery = "SELECT id FROM vtiger_vdnotifierpro WHERE userid = ? AND crmid = ? AND modulename = 'Project' AND title LIKE 'Telegram AI:%' AND status = 5 ORDER BY modifiedtime DESC LIMIT 1";
$checkResult = $adb->pquery($checkQuery, array($userId, $projectId));
if ($adb->num_rows($checkResult) > 0) {
// Обновляем существующее уведомление - обновляем заголовок и время
$existingId = $adb->query_result($checkResult, 0, 'id');
$updateQuery = "UPDATE vtiger_vdnotifierpro SET title = ?, modifiedtime = NOW() WHERE id = ?";
$adb->pquery($updateQuery, array($notificationTitle, $existingId));
$logstring = date('Y-m-d H:i:s').' Обновлено существующее уведомление ID: '.$existingId.PHP_EOL;
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
return $existingId;
} else {
// Создаем новое уведомление
$insertQuery = "INSERT INTO vtiger_vdnotifierpro (userid, modulename, crmid, modiuserid, link, title, action, modifiedtime, status) VALUES (?, 'Project', ?, 0, ?, ?, '', NOW(), 5)";
$adb->pquery($insertQuery, array($userId, $projectId, $projectLink, $notificationTitle));
$notificationId = $adb->getLastInsertID();
$logstring = date('Y-m-d H:i:s').' ✅ Создано новое уведомление ID: '.$notificationId.' для пользователя '.$userId.PHP_EOL;
file_put_contents('logs/tg_ai_qa.log', $logstring, FILE_APPEND);
return $notificationId;
}
}
// 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. Создаем уведомление для ответственного по проекту
$contactName = $firstname . ' ' . $lastname;
$notificationId = createTelegramAINotification($projectid, $contactid, $contactName, $question);
// 7. Возвращаем успех
$response = array(
'status' => 'success',
'contact_id' => $contactid,
'project_id' => $projectid,
'question_comment_id' => $question_commentid,
'answer_comment_id' => $answer_commentid,
'notification_id' => $notificationId,
'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);
?>