- 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.
212 lines
9.8 KiB
PHP
212 lines
9.8 KiB
PHP
<?php
|
||
/*********************************************************************************
|
||
* Набор методов для работы с WhatsApp через сервис wappi.ru
|
||
* All Rights Reserved.
|
||
* Contributor(s): Илья Руденко itsaturn@yandex.ru
|
||
********************************************************************************/
|
||
require_once 'include/utils/utils.php';
|
||
|
||
function WhatsAppSendComment($commentid, $message){
|
||
// Вызывается из /modules/ModComments/actions/SaveAjax.php
|
||
global $adb;
|
||
|
||
$query = 'SELECT e.setype, c.related_to, c.userid, c.filename
|
||
FROM vtiger_modcomments c
|
||
LEFT JOIN vtiger_crmentity e on e.crmid = c.related_to
|
||
where c.modcommentsid = '.$commentid;
|
||
$result = $adb->pquery($query);
|
||
|
||
$output = 'YES';
|
||
|
||
if ($adb->num_rows($result) == 0) {
|
||
$output = 'Комментарий не найден';
|
||
} else {
|
||
// Проверяем наличие файлов через vtiger_seattachmentsrel
|
||
$attachQuery = 'SELECT COUNT(*) as cnt FROM vtiger_seattachmentsrel WHERE crmid = '.$commentid;
|
||
$attachResult = $adb->pquery($attachQuery);
|
||
$isAttach = ($adb->query_result($attachResult, 0, "cnt") > 0);
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' Проверка файлов для комментария '.$commentid.': найдено '.$adb->query_result($attachResult, 0, "cnt").' файлов, isAttach='.$isAttach.PHP_EOL, FILE_APPEND);
|
||
$setype = $adb->query_result($result, 0, "setype");
|
||
$related_to = $adb->query_result($result, 0, "related_to");
|
||
|
||
if ($setype == 'Leads') {
|
||
// Если коммент отправляется из Обращения
|
||
$query = 'select mobile from vtiger_leadaddress where mobile > 0 and leadaddressid = '.$related_to;
|
||
$result = $adb->pquery($query);
|
||
if ($adb->num_rows($result) == 0) {
|
||
$output = 'У Лида отсутствует телефон';
|
||
} else {
|
||
$mobile = $adb->query_result($result, 0, "mobile");
|
||
}
|
||
} else {
|
||
if ($setype == 'Contacts') {
|
||
// Если коммент отправляется из Контакта
|
||
$query = 'select mobile from vtiger_contactdetails where mobile > 0 and contactid = '.$related_to;
|
||
$result = $adb->pquery($query);
|
||
if ($adb->num_rows($result) == 0) {
|
||
$output = 'У Контакта отсутствует телефон';
|
||
} else {
|
||
$mobile = $adb->query_result($result, 0, "mobile");
|
||
}
|
||
} else {
|
||
if ($setype == 'Project') {
|
||
// Если коммент отправляется из Проекта
|
||
$query = 'select cf_1544 from vtiger_projectcf where cf_1544 <> "" and projectid = '.$related_to;
|
||
$result = $adb->pquery($query);
|
||
if ($adb->num_rows($result) == 0) {
|
||
$output = 'У Проекта отсутствует телефон';
|
||
} else {
|
||
$mobile = $adb->query_result($result, 0, "cf_1544");
|
||
}
|
||
} else {
|
||
$output = 'Комментарий к неизвестной сущности';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ($output <> 'YES') {
|
||
$logstring = date('Y-m-d H:i:s').' Отправка комментария ID: '.$commentid.' не удалать по причине: '.$output.PHP_EOL;
|
||
file_put_contents('wa_outbound.log', $logstring, FILE_APPEND);
|
||
} else {
|
||
if ($setype == 'Contacts') {
|
||
$query = 'select cf_1740 from vtiger_contactscf where contactid = '.$related_to;
|
||
} else
|
||
if ($setype == 'Project') {
|
||
$query = 'select cf.cf_1740
|
||
from vtiger_project p
|
||
left join vtiger_contactscf cf on cf.contactid = p.linktoaccountscontacts
|
||
where p.projectid = '.$related_to;
|
||
}
|
||
file_put_contents('wa_outbound.log', $query.PHP_EOL, FILE_APPEND);
|
||
//echo $query.'<br>';
|
||
|
||
$result = $adb->pquery($query);
|
||
|
||
$insurance = $adb->query_result($result, 0, "cf_1740");
|
||
if (empty($insurance)) {
|
||
//echo 'Нет<br>';
|
||
$from = '76847f65-fe9d';
|
||
} else {
|
||
//echo 'Есть<br>';
|
||
$from = '4f2d8b57-3889';
|
||
}
|
||
|
||
$logstring = date('Y-m-d H:i:s').' Отправка от '.$from.' на номер '.$mobile.PHP_EOL.'Текст: '.$message.PHP_EOL;
|
||
file_put_contents('wa_outbound.log', $logstring, FILE_APPEND);
|
||
$output = 'YES';
|
||
|
||
$mobile = preg_replace('/[^0-9]/', '', $mobile); // Удаляем всё, что не цифры
|
||
if (strlen($mobile) == 11) { //Если длина номера 11 цифр
|
||
$mobile = '7'.substr($mobile, 1); // Меняем первую на 7
|
||
} else {
|
||
if (strlen($mobile) == 10) {// А если 10 цифр
|
||
$mobile = '7'.$mobile; // То лепип 7 впереди
|
||
} else { //В третьем варианте - неверный номер телефона
|
||
$output = 'Неверный номер телефона: '.$mobile;
|
||
}
|
||
}
|
||
//$mobile = '79298407770';
|
||
|
||
if ($output == 'YES') {
|
||
|
||
// Заменяем одинарные и двойные кавычки в тексте на апострофы
|
||
$message = str_replace('"', '`', $message);
|
||
$message = str_replace("'", "`", $message);
|
||
// Меняем переносы строк на \n
|
||
$message = preg_replace('/\R/u', '\n', $message);
|
||
|
||
$ch = curl_init();
|
||
curl_setopt($ch, CURLOPT_URL, 'https://wappi.pro/api/sync/message/send?profile_id='.$from);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
curl_setopt($ch, CURLOPT_POST, 1);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"recipient": "'.$mobile.'", "body": "'.$message.'"}');
|
||
|
||
$headers = array();
|
||
$headers[] = 'Accept: application/json';
|
||
$headers[] = 'Authorization: 45971e2d99071461360515ced697ef08d270363d';
|
||
$headers[] = 'Content-Type: text/plain';
|
||
|
||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||
|
||
$output = curl_exec($ch);
|
||
if (curl_errno($ch)) {
|
||
$output = curl_error($ch);
|
||
}
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' Ответ от API-сервера: '.$output.PHP_EOL, FILE_APPEND);
|
||
|
||
if ($isAttach) {
|
||
// Получаем файлы, связанные с комментарием (обновленный запрос для S3)
|
||
// Используем запрос БЕЗ vtiger_notes, так как для файлов комментариев там нет записей
|
||
$query = 'SELECT a.attachmentsid, a.name, a.type, a.path, a.storedname
|
||
FROM vtiger_seattachmentsrel ar
|
||
LEFT JOIN vtiger_attachments a ON a.attachmentsid = ar.attachmentsid
|
||
LEFT JOIN vtiger_crmentity ce ON ce.crmid = ar.attachmentsid
|
||
WHERE ar.crmid = '.$commentid.' AND ce.setype LIKE "Documents%"';
|
||
|
||
$result = $adb->pquery($query);
|
||
$fileCount = $adb->num_rows($result);
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' Найдено файлов для отправки: '.$fileCount.PHP_EOL, FILE_APPEND);
|
||
|
||
curl_setopt($ch, CURLOPT_URL, 'https://wappi.pro/api/sync/message/document/send?profile_id='.$from);
|
||
|
||
if ($fileCount > 0) {
|
||
for ($i = 0; $i < $fileCount; $i++) {
|
||
$attachmentsid = $adb->query_result($result, $i, 'attachmentsid');
|
||
$origname = $adb->query_result($result, $i, 'name');
|
||
$mimetype = $adb->query_result($result, $i, 'type');
|
||
$path = $adb->query_result($result, $i, 'path');
|
||
$storedname = $adb->query_result($result, $i, 'storedname');
|
||
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' DEBUG: Файл '.$i.': attachmentId='.$attachmentsid.', name='.$origname.', path='.$path.', storedname='.$storedname.PHP_EOL, FILE_APPEND);
|
||
|
||
// Определяем URL файла - строим S3 URL из path и storedname
|
||
$fileUrl = '';
|
||
$fileContent = '';
|
||
if (!empty($path) && !empty($storedname)) {
|
||
if (strpos($path, 's3://') === 0) {
|
||
// Новый формат: s3://bucket/path
|
||
$bucket = str_replace('s3://', '', $path);
|
||
$fileUrl = 'https://s3.twcstorage.ru/' . $bucket . '/' . $storedname;
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' DEBUG: Строим S3 URL из path+storedname (s3://): '.$fileUrl.PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
// Старый формат: обычный path
|
||
$fileUrl = 'https://s3.twcstorage.ru/f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c/' . $path . '/' . $storedname;
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' DEBUG: Строим S3 URL из path+storedname (обычный): '.$fileUrl.PHP_EOL, FILE_APPEND);
|
||
}
|
||
|
||
// Скачиваем содержимое файла
|
||
$fileContent = file_get_contents($fileUrl);
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' DEBUG: Скачан файл, размер: '.strlen($fileContent).' байт'.PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' ERROR: Не удалось определить URL файла для attachmentId='.$attachmentsid.', path='.$path.', storedname='.$storedname.PHP_EOL, FILE_APPEND);
|
||
continue;
|
||
}
|
||
|
||
if (!empty($fileContent)) {
|
||
$params = '{"recipient": "'.$mobile.'", "caption": "'.$origname.'", "file_name": "'.$origname.'", "b64_file": "'.base64_encode($fileContent).'"}';
|
||
file_put_contents('wa_outbound.log', date('Y-m-d H:i:s').' Отправка файла: '.$origname.PHP_EOL, FILE_APPEND);
|
||
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
||
$output = curl_exec($ch);
|
||
|
||
if (curl_errno($ch)) {
|
||
$output = date('Y-m-d H:i:s').' Что-то пошло не так при отправке файла '.$origname.' : '.curl_error($ch);
|
||
} else {
|
||
$output = date('Y-m-d H:i:s').' Ответ от WhatsApp на отправку файла: '.$output;
|
||
}
|
||
file_put_contents('logs/wa_outbound.log', $output.PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
file_put_contents('logs/wa_outbound.log', date('Y-m-d H:i:s').' Не удалось получить содержимое файла: '.$origname.PHP_EOL, FILE_APPEND);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
curl_close($ch);
|
||
}
|
||
}
|
||
|
||
return $output;
|
||
}
|
||
?>
|