3namespace Bitrix\Im\V2\Chat;
5use Bitrix\Im\Model\ChatTable;
6use Bitrix\Im\V2\Analytics\ChatAnalytics;
8use Bitrix\Im\V2\Chat\Ai\AiAssistantChat;
9use Bitrix\Im\V2\Chat\Ai\AiAssistantEntityChat;
10use Bitrix\Im\V2\Chat\Ai\AiAssistantPrivateChat;
11use Bitrix\Im\V2\Common\ContextCustomer;
12use Bitrix\Im\V2\Integration\AiAssistant\AiAssistantService;
13use Bitrix\Im\V2\Result;
14use Bitrix\Main\Application;
15use Bitrix\Main\Data\Cache;
16use Bitrix\Main\DI\ServiceLocator;
23 private const LOCK_TIMEOUT = 3;
28 private function __construct()
30 $this->aiAssistantService = ServiceLocator::getInstance()->get(AiAssistantService::class);
39 if (isset(self::$instance))
41 return self::$instance;
44 self::$instance =
new static();
46 return self::$instance;
78 $findResult = $this->
findChat($params);
80 if ($findResult->hasResult())
82 $chatParams = $findResult->getResult();
88 $type === Chat::IM_TYPE_SYSTEM
89 ||
$type === Chat::IM_TYPE_PRIVATE
92 $addResult = $this->
addChat($params);
93 if ($addResult->hasResult())
95 $chat = $addResult->getResult()[
'CHAT'];
96 $chat->setContext($this->context);
112 $userId = $this->getContext()->getUserId();
116 'TYPE' => Chat::IM_TYPE_SYSTEM,
125 $chatId = $this->getEntityChatId($entityType,
$entityId);
151 'TYPE' => Chat::IM_TYPE_PRIVATE,
152 'FROM_USER_ID' => $fromUserId,
153 'TO_USER_ID' => $toUserId,
166 $userId = $this->getContext()->getUserId();
170 'TYPE' => Chat::IM_TYPE_PRIVATE,
190 $entityType =
$params[
'ENTITY_TYPE'];
194 $entityType === Chat::ENTITY_TYPE_FAVORITE || $entityType ===
'PERSONAL' =>
new FavoriteChat(
$params),
216 $chat->setContext($this->context);
223 $botId = $this->aiAssistantService->getBotId();
225 if (
$params[
'TYPE'] !== Chat::IM_TYPE_PRIVATE || !$botId)
230 $users = [(int)(
$params[
'FROM_USER_ID'] ?? 0), (int)(
$params[
'TO_USER_ID'] ?? 0)];
233 $params[
'ENTITY_TYPE'] === Chat::ENTITY_TYPE_PRIVATE_AI_ASSISTANT
234 || in_array($botId, $users,
true)
245 $params[
'TYPE'] = Chat::IM_TYPE_SYSTEM;
257 $params[
'ENTITY_TYPE'] = Chat::ENTITY_TYPE_FAVORITE;
269 $params[
'TYPE'] = Chat::IM_TYPE_PRIVATE;
281 $params[
'TYPE'] = Chat::IM_TYPE_OPEN;
293 $params[
'TYPE'] = Chat::IM_TYPE_OPEN_LINE;
307 public function getChatById(
int $chatId):
Chat
309 $findResult = $this->
findChat([
'CHAT_ID' => $chatId]);
310 if ($findResult->hasResult())
312 $chatParams = $findResult->getResult();
315 $chat = $this->
initChat($chatParams);
364 if (!isset(
$params[
'MESSAGE_TYPE']))
366 $params[
'MESSAGE_TYPE'] = Chat::IM_TYPE_CHAT;
372 $params[
'MESSAGE_TYPE'] = Chat::IM_TYPE_PRIVATE;
378 $chatId = (int)
$params[
'CHAT_ID'];
380 $cachedChat = $cache->getVars();
382 if ($cachedChat !==
false)
384 return $result->setResult($this->filterNonCachedFields($cachedChat));
387 $chat = $this->getRawById($chatId);
391 $cache->startDataCache();
392 $cache->endDataCache($chat);
399 return $result->setResult($chat);
402 switch (
$params[
'MESSAGE_TYPE'] ??
'')
404 case Chat::IM_TYPE_SYSTEM:
408 case Chat::IM_TYPE_PRIVATE:
422 case Chat::IM_TYPE_CHAT:
423 case Chat::IM_TYPE_OPEN:
426 &&
$params[
'ENTITY_TYPE'] == Chat::ENTITY_TYPE_GENERAL
432 case Chat::IM_TYPE_OPEN_LINE:
443 private function filterNonCachedFields(
array $chat):
array
445 foreach (self::NON_CACHED_FIELDS as
$key)
453 private function getRawById(
int $id): ?
array
455 $chat = ChatTable::query()
456 ->setSelect([
'*',
'_ALIAS' =>
'ALIAS.ALIAS'])
466 $chat[
'ALIAS'] = $chat[
'_ALIAS'];
471 private function getEntityChatId(
string $entityType,
string $entityId): ?int
473 $row = ChatTable::query()
475 ->where(
'ENTITY_TYPE', $entityType)
486 return (
int)$row[
'ID'];
500 $params[
'TYPE'] ??= Chat::IM_TYPE_CHAT;
503 if ((
$params[
'SEARCHABLE'] ??
'N') ===
'Y')
505 if (
$params[
'TYPE'] === Chat::IM_TYPE_CHAT)
507 $params[
'TYPE'] = Chat::IM_TYPE_OPEN;
511 $params[
'TYPE'] = Chat::IM_TYPE_OPEN_CHANNEL;
519 ChatAnalytics::blockSingleUserEvents();
522 'TYPE' =>
$params[
'TYPE'] ??
null,
523 'ENTITY_TYPE' =>
$params[
'ENTITY_TYPE'] ??
null,
524 'FROM_USER_ID' =>
$params[
'FROM_USER_ID'] ??
null,
525 'TO_USER_ID' =>
$params[
'TO_USER_ID'] ??
null,
527 $chat = $this->
initChat($initParams);
528 $addResult = $chat->add(
$params);
535 $resultChat = $addResult->getResult()[
'CHAT'] ??
null;
536 if ($resultChat instanceof
Chat)
554 if (!isset(
$params[
'ENTITY_TYPE']))
558 if (!isset(
$params[
'ENTITY_ID']))
563 $entityType = (string)
$params[
'ENTITY_TYPE'];
565 $lockName = self::getUniqueAdditionLockName($entityType,
$entityId);
568 $isLocked =
$connection->lock($lockName, self::LOCK_TIMEOUT);
576 $chatId = $this->getEntityChatId($entityType,
$entityId);
582 return $this->
addChat($params);
584 catch (\Throwable $exception)
596 private static function getUniqueAdditionLockName(
string $entityType,
string $entityId): string
598 return "add_unique_chat_{$entityType}_{$entityId}";
614 $cacheTTL = defined(
"BX_COMP_MANAGED_CACHE") ? 18144000 : 1800;
615 $cacheId =
"chat_data_{$id}";
616 $cacheDir = $this->getCacheDir($id);
618 $cache->initCache($cacheTTL, $cacheId, $cacheDir);
623 private function getCacheDir(
int $id): string
625 $cacheSubDir = $id % 100;
627 return "/bx/imc/chatdata/7/{$cacheSubDir}/{$id}";
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
const ENTITY_TYPE_LIVECHAT
const ENTITY_TYPE_VIDEOCONF
static getChatId($dialogId, $userId=null)
createOpenLineChat(?array $params=null)
createPrivateChat(?array $params=null)
addUniqueChat(array $params)
isPrivateAiAssistantChat(array $params)
getNotifyFeed($userId=null)
getPrivateChat($fromUserId, $toUserId)
AiAssistantService $aiAssistantService
initChat(?array $params=null)
getPersonalChat($userId=null)
getEntityChat(string $entityType, string $entityId)
createPersonalChat(?array $params=null)
createNotifyFeed(?array $params=null)
createOpenChat(?array $params=null)
static find(array $params=[], ?Context $context=null)
static find(array $params=[], ?Context $context=null)
static find(array $params=[], ?Context $context=null)
static find(array $params, ?Context $context=null)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
static find(array $filter, array $order, ?int $limit=null, ?Context $context=null)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']