Files
crm.clientright.ru/include/utils/WhatsApp.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

212 lines
9.8 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
/*********************************************************************************
* Набор методов для работы с 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;
}
?>