Files
crm.clientright.ru/telegram_old.php
Fedor ac7467f0b4 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.
2025-10-16 11:17:21 +03:00

340 lines
16 KiB
PHP
Raw Permalink 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 для вызова снаружи вебхуками входящих сообщений в Telegram
* All Rights Reserved.
* Contributor(s): Илья Руденко itsaturn@yandex.ru
********************************************************************************/
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 'include/Webservices/Revise.php';
require_once 'include/utils/WhatsApp.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_inbound.log', $logstring, FILE_APPEND);
$data = json_decode($str, true); // Формируем массив
$message = $data['message']; // Тело сообщения
$firstname = $data['firstname']; // Имя отправителя
$botname = $data['botname']; // Имя отправителя
if (isset($data['mobile'])) {
$lastname = $data['lastname']; // Фамилия отправителя
} else {
$lastname = '-';
}
if (!isset($botname) or empty($botname)) {
// Если ничего не передали, будем считать, что это первый бот
$botname = 'klientprav_bot';
} else {
if ($botname <> 'klientprav_bot' and $botname <> 'lexpriority_bot') {
// Если что-то передали, но это не первый и не второй бот, то будем считать, что это первый бот
$botname = 'klientprav_bot';
}
}
$tgid = $data['tgid']; // Telegram ID отправителя
$mime_type = $data['mime_type'];
$file_size = $data['file_size'];
$file_id = $data['file_id'];
$customer = 0;
// Сначала попробуем найти клиента по его tgid
if ($tgid <> 0) {
$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) {
$customer = $adb->query_result($result, 0, 'contactid');
$userid = $adb->query_result($result, 0, 'userid');
$crmid = '12x'.$adb->query_result($result, 0, 'contactid');
$setype = 'Contacts';
$firstname = $adb->query_result($result, 0, 'firstname');
$lastname = $adb->query_result($result, 0, 'lastname');
$logstring = date('Y-m-d H:i:s').' Найден клиент с ID: '.$customer.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
}
}
$user = Users::getActiveAdminUser(); // Получаем пользователя, под которым будем создавать записи
// А если и по телефону не нашлось - тогда будем создавать Контакта
if ($customer == 0) {
$logstring = date('Y-m-d H:i:s').' По телефону не нашли - будем создавать'.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
try {
$params = array (
'firstname' => $firstname,
'lastname' => $lastname,
'phone' => $tgid,
'assigned_user_id' => $user
);
if ($botname == 'lexpriority_bot') {
$params['cf_1740'] = '000';
}
//$logstring = date('Y-m-d H:i:s').' Массив: '.json_encode($params).PHP_EOL;
//file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
$contact = vtws_create('Contacts', $params, $user);
$output = 'ID : '.$contact['id'];
$customer = substr($contact['id'], 3);
$crmid = $contact['id'];
$setype = 'Contacts';
$userid = substr($user, 3);
} catch (WebServiceException $ex) {
$output = $ex->getMessage();
}
$logstring = date('Y-m-d H:i:s').' Создание Контакта : '.$output.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
}
// Ну и теперь наконец-то создадим коммент
if ($customer <> 0) {
$msg = '';
$allowed_types = array(
'text/plain',
'image',
'image/png',
'image/jpeg',
'image/jpg',
'application/pdf',
'application/msword',
'application/excel',
'application/vnd.ms-excel',
'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
); //Список разрешенных к сохранению типов файлов
$images = array('image', 'image/png', 'image/jpeg', 'image/jpg');
if (isset($file_id)) {
// Передан какой-то файл
$filename = $data['filename'];
if ($botname == 'klientprav_bot') {
$bot_token = '6118440594:AAGpqeudXF9wHSZ7vpAsXQ4Jp5XXlUoqB1A';
} else {
$bot_token = '6631721508:AAG0FIXhlprPGeeb_6zh5gjOpNdWzSWIRS8';
}
if ($file_size > 5242880) {
// Размером более 5мб
$msg = 'Передан файл более 5 мб - НЕ загружен!';
$logstring = date('Y-m-d H:i:s').' '.$msg.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
Reply($tgid, 'Файл '.$filename.' не доставлен!'.PHP_EOL.PHP_EOL.'Объем файла не должен превышать 5Мб', $bot_token);
} else {
if (!in_array($mime_type, $allowed_types)) {
// Недопустимого формата
$msg = 'Передан файл недопустимого формата (не Документ, не PDF и не картина) - НЕ загружен!';
$logstring = date('Y-m-d H:i:s').' '.$msg.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
Reply($tgid, 'Файл '.$filename.' не доставлен!'.PHP_EOL.PHP_EOL.'Принимаются только картинки, PDF и документы Word и Excel', $bot_token);
}
}
if (!isset($message) or empty($message)) {
// Если это просто файл, без текста
if ($msg <> '') {
// и при этом файл мы не будем грузить
$message = $msg;
} else {
$message = 'Файл во вложении';
}
} else {
// Если текст сообщения есть
if ($msg <> '') {
// И есть файл, который мы не будем грузить
$message .= PHP_EOL.'======='.PHP_EOL.$msg;
}
}
}
// Проверка на 0 на тот случай, если при создании Контакта был какой-то exception и мы не получили id нового клиента
try {
$params = array (
'commentcontent' => $message,
'related_to' => $crmid,
'channel' => 'Telegram',
'assigned_user_id' => $user
);
//$logstring = date('Y-m-d H:i:s').' Массив: '.json_encode($params).PHP_EOL;
//file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
$comment = vtws_create('ModComments', $params, $user);
$output = 'ID : '.$comment['id'];
// Почему-то при попытке сразу прописать customer при создании коммента, в половине случаев вылетает ошибка
// поэтому сначала просо создаем комментарий, а потом отдельным апдейтом корректируем, что это не просто коммент, а ответ от клиента
$commentid = substr($comment['id'], 3);
$query = 'update vtiger_modcomments set customer = ?, userid = 0 where modcommentsid = ?';
$adb->pquery($query, array($customer, $commentid));
} catch (WebServiceException $ex) {
$output = $ex->getMessage();
}
$logstring = date('Y-m-d H:i:s').' Создание коммента: '.$output.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
if (isset($file_id) and $msg == '') {
// Файл есть и он валидный - надо скачать и загрузить в коммент
//$url = 'https://api.telegram.org/bot'.$bot_token.'/getFile?file_id='.$file_id;
$url = 'https://api.telegram.org/bot'.$bot_token.'/getFile';
file_put_contents('logs/tg_inbound.log', date('Y-m-d H:i:s').' url для вызова файла '.$url.PHP_EOL, FILE_APPEND);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url); // адрес api телеграмм
curl_setopt($curl, CURLOPT_POST, true); // отправка данных методом POST
curl_setopt($curl, CURLOPT_TIMEOUT, 10); // максимальное время выполнения запроса
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, array('file_id' => $file_id));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($curl);
$output = json_decode($output, true);
//file_put_contents('logs/tg_inbound.log', date('Y-m-d H:i:s').' Ответ от телеги '.$output.PHP_EOL, FILE_APPEND);
if (curl_errno($curl)) {
$output = date('Y-m-d H:i:s').' Что-то пошло не так при получении данных файла: '.curl_error($curl);
} else {
if ($output['ok']) {
$file_path = $output['result']['file_path'];
$output = date('Y-m-d H:i:s').' Получен путь закачки файла: '.$file_path;
} else {
$output = date('Y-m-d H:i:s').' Ответ от Telegram при получении данных файла: '.$output['description'];
}
}
file_put_contents('logs/tg_inbound.log', $output.PHP_EOL, FILE_APPEND);
curl_close($curl);
if (isset($file_path)) {
// Получили путь закачки файла
$url = 'https://api.telegram.org/file/bot'.$bot_token.'/'.$file_path;
$current_id = $adb->getUniqueID("vtiger_crmentity");
$date_var = date('Y-m-d H:i:s');
$ownerid = getUserId($userid, $customer); // Если у клиента есть активный Проект - достанем оттуда ответственного
$upload_file_path = decideFilePath();
if ($filename == 'image') {
// Нам прислали скриншот без расширения - возьмем то имя, которое ему дала телега
$slash = strpos($file_path, '/');
$filename = substr($file_path, $slash+1);
}
file_put_contents($upload_file_path . $current_id . "_" . $filename, file_get_contents($url));
$logstring = date('Y-m-d H:i:s').' Файл '.$filename.' типа '.$mime_type.' сохранен в storage'.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
if (in_array($mime_type, $images)) {
// Если прислали картинку, то преобразуем ее в PDF
$PDFPath = jpg2pdf($upload_file_path . $current_id . "_" . $filename);
// Грохнем ненужную картинку
unlink($upload_file_path . $current_id . "_" . $filename);
// Из полного пути к PDF вытащим чисто имя файла
$file_parts = pathinfo($filename);
$base_name = $file_parts['filename'];
$filename = $base_name . '.pdf';
$mime_type= 'application/pdf';
}
$sql1 = "insert into vtiger_crmentity (crmid,smcreatorid,smownerid,setype,createdtime,modifiedtime) values(?,?,?,?,?,?)";
$params1 = array($current_id, $ownerid, $ownerid, 'ModComments Attachment', $adb->formatDate($date_var, true), $adb->formatDate($date_var, true));
$adb->pquery($sql1, $params1);
$logstring = date('Y-m-d H:i:s').' Добавили аттач в crmentity'.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
$sql2 = "insert into vtiger_attachments(attachmentsid, name, type, path, storedname) values(?,?,?,?,?)";
$params2 = array($current_id, $filename, $mime_type, $upload_file_path, $filename);
$adb->pquery($sql2, $params2);
$logstring = date('Y-m-d H:i:s').' Добавили аттач в attachments'.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
$sql3 = "insert into vtiger_seattachmentsrel(crmid, attachmentsid) values(?,?)";
$adb->pquery($sql3, array($commentid, $current_id));
$sql4 = 'update vtiger_modcomments set filename = ? where modcommentsid = ?';
$adb->pquery($sql4, array($current_id, $commentid));
$logstring = date('Y-m-d H:i:s').' связали аттач с комментом '.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
}
}
// А теперь покажем всплывашку пользователю
// Собираем ссылку на сущность, куда добавлен коммент
$link = 'module='.$setype.'&view=Detail&record='.$customer.'&app=MARKETING';
// Собираем текст уведомления с именем отправителя
$title = $firstname.' '.$lastname.' - новое сообщение'; // Итоговый текст уведомления
$userid = getUserId($userid, $customer); // Если у клиента есть активный Проект - достанем оттуда ответственного
// Ищем непрочтенную всплывашку с этим клиентом
$query = 'select id from vtiger_vdnotifierpro where userid = ? and crmid = ? and title = ? and status = 5';
$result = $adb->pquery($query, array($userid, $customer, $title));
if ($adb->num_rows($result) > 0) {
// Обновляем время в старой всплывашке, чтобы не плодить дубли
$id = $adb->query_result($result, 0, 'id');
$query = 'update vtiger_vdnotifierpro set modifiedtime = ? where id = ?';
$result = $adb->pquery($query, array(date('Y-m-d H:i:s'), $id));
//$logstring = date('Y-m-d H:i:s').' id записи '.$id.PHP_EOL;
//file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
} else {
// Добавляем новую всплывашку
$query = 'insert into vtiger_vdnotifierpro (userid, modulename, crmid, modiuserid, link, title, action, modifiedtime, status) values (?, ?, ?, 0, ?, ?, "", ?, 5)';
$result = $adb->pquery($query, array($userid, $setype, $customer, $link, $title, date('Y-m-d H:i:s')));
}
} else {
$logstring = date('Y-m-d H:i:s').' Почему-то мы не нашли и не создали Контакта'.PHP_EOL;
file_put_contents('logs/tg_inbound.log', $logstring, FILE_APPEND);
}
function getUserId($userid, $contactid) {
global $adb;
$query = 'select e.smownerid as userid
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"';
$result = $adb->pquery($query, array($contactid));
if ($adb->num_rows($result) == 1) {
// Единственный активный Проект - вытащим оттуда ответственного
$output = $adb->query_result($result, 0, 'userid');
} else {
// Активных Проектов нет, а может быть несколько - значит ответственным будет владелец Контакта
$output = $userid;
}
return $output;
}
function Reply($chat_id, $message, $bot_token) {
$params = array(
'chat_id' => $chat_id, // id получателя сообщения
'text' => $message, // текст сообщения
'parse_mode' => 'HTML', // режим отображения сообщения, не обязательный параметр
);
$curl = curl_init();
$url = 'https://api.telegram.org/bot'.$bot_token.'/sendMessage';
curl_setopt($curl, CURLOPT_URL, $url); // адрес api телеграмм
curl_setopt($curl, CURLOPT_POST, true); // отправка данных методом POST
curl_setopt($curl, CURLOPT_TIMEOUT, 10); // максимальное время выполнения запроса
curl_setopt($curl, CURLOPT_POSTFIELDS, $params); // параметры запроса
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // чтобы получить нормальный ответ
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
?>