131 if ($v2SendEnabled ===
'Y' &&
$arFields[
'MESSAGE_TYPE'] !==
'S')
133 $messageObject = self::getMessageObject(
$arFields);
137 $chat = $messageObject->getChat()->withContextUser($messageObject->getContext()->getUserId());
141 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
147 !$messageObject->isSystem()
150 && $messageObject->getAuthorId()
154 if (
$arFields[
'MESSAGE_TYPE'] === Chat::IM_TYPE_PRIVATE)
156 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CANCELED"),
"ERROR_NO_ACCESS");
160 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
170 self::throwLegacyExceptionFromErrors(
$result->getErrors());
175 if ((
$arFields[
'WAIT_FULL_EXECUTION'] ??
'Y') ===
'Y')
177 $result->getPromise()?->wait();
180 return $result->getMessageId() ??
false;
192 $uuidAddResult = $messageUuid->add();
196 $messageIdByUuid = $messageUuid->getMessageId();
198 if (!is_null($messageIdByUuid))
200 return $messageIdByUuid;
205 if (!$messageUuid->updateIfExpired())
240 $arFields[
'MESSAGE'] = trim(str_replace(Array(
'[BR]',
'[br]',
'#BR#'),
"\n",
$arFields[
'MESSAGE']));
241 if (mb_strlen(
$arFields[
'MESSAGE']) > self::MESSAGE_LIMIT + 6)
243 $arFields[
'MESSAGE'] = mb_substr(
$arFields[
'MESSAGE'], 0, self::MESSAGE_LIMIT).
' (...)';
252 $isImportant = isset(
$arFields[
'IS_IMPORTANT']) &&
$arFields[
'IS_IMPORTANT'] ===
'Y' ?
'Y' :
'N';
258 $arFields[
'SKIP_COUNTER_INCREMENTS'] ??=
'N';
273 $incrementCounter =
true;
302 if (is_object($attach))
304 $arFields[
'PARAMS'][
'ATTACH'] = Array($attach);
306 else if (is_array($attach))
323 $arFields[
'PARAMS'][
'FILE_ID'] = Array();
329 if (is_object($keyboard))
331 $arFields[
'PARAMS'][
'KEYBOARD'] = $keyboard;
335 $arFields[
'PARAMS'][
'KEYBOARD'] = Array();
341 if (is_object($menu))
361 if (
$arFields[
'SILENT_CONNECTOR'] ==
'Y')
363 $arFields[
'PARAMS'][
'CLASS'] =
"bx-messenger-content-item-system";
366 $arFields[
'PARAMS'][
'COMPONENT_ID'] =
'HiddenMessage';
374 && class_exists(
'\Bitrix\ImOpenLines\Relation')
377 $fakeRelation = (new \Bitrix\ImOpenLines\Relation((
int)
$arFields[
'TO_CHAT_ID']))->getRelationUserIds();
380 if (is_int($fakeRelation) && $fakeRelation > 0)
382 $fakeRelation = [$fakeRelation];
390 else if (!isset(
$arFields[
'NOTIFY_TYPE']))
409 else if (
$arFields[
'URL_PREVIEW'] ==
'Y')
413 $urlPrepare = $link->prepareInsert(
$message);
414 if ($urlPrepare[
'RESULT'])
420 $arFields[
'MESSAGE'] = $urlPrepare[
'MESSAGE'];
422 if (isset(
$arFields[
'PARAMS'][
'URL_ID']))
424 $arFields[
'PARAMS'][
'URL_ID'] = array_merge(
$arFields[
'PARAMS'][
'URL_ID'], $urlPrepare[
'URL_ID']);
428 $arFields[
'PARAMS'][
'URL_ID'] = $urlPrepare[
'URL_ID'];
430 $arFields[
'URL_ATTACH'] = $urlPrepare[
'ATTACH'];
432 if ($urlPrepare[
'MESSAGE_IS_LINK'])
438 else if (isset(
$arFields[
'PARAMS'][
'URL_ID']) && is_array(
$arFields[
'PARAMS'][
'URL_ID']))
440 $urlId = (int)(array_values(
$arFields[
'PARAMS'][
'URL_ID'])[0] ?? 0);
459 foreach(
GetModuleEvents(
"im",
"OnBeforeMessageNotifyAdd",
true) as $arEvent)
464 $reason = self::GetReasonForMessageSendError(
$arFields[
'MESSAGE_TYPE'],
$result[
'reason']);
465 $GLOBALS[
"APPLICATION"]->ThrowException($reason,
"ERROR_FROM_OTHER_MODULE");
508 $relations = CIMChat::GetRelationById($chatId,
false,
true,
false);
511 foreach ($relations as $rel)
515 && $rel[
'USER_ID'] ==
$arFields[
'FROM_USER_ID']
521 $arFields[
'TO_USER_ID'] = $rel[
'USER_ID'];
542 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CANCELED"),
"ERROR_NO_ACCESS");
554 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CANCELED"),
"TEXT_FIELD_DISABLED");
558 $chatData = \Bitrix\Im\Model\ChatTable::getById($chatId)->fetch();
559 $prevMessageId = intval($chatData[
'PREV_MESSAGE_ID']);
565 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_LINES_SHARE_FILE"),
"LINES_SHARE");
586 if (isset(
$arFields[
'PARAMS'][
'FILE_ID']))
588 foreach (
$arFields[
'PARAMS'][
'FILE_ID'] as $fileId)
595 $messageFiles = self::GetFormatFilesMessageOut(
$arFields[
'FILES']);
596 if ($messageFiles <>
'')
603 $messageID = intval(
$result->getId());
607 if (isset($messageUuid))
609 $messageUuid->updateMessageId($messageID);
612 \Bitrix\Im\Model\ChatTable::update($chatId, Array(
615 'LAST_MESSAGE_ID' => $messageID,
619 if ($chatData[
'PARENT_MID'])
621 CIMMessageParam::set($chatData[
'PARENT_MID'], Array(
622 'CHAT_MESSAGE' => $chatData[
'MESSAGE_COUNT']+1,
625 CIMMessageParam::SendPull($chatData[
'PARENT_MID'], Array(
'CHAT_MESSAGE',
'CHAT_LAST_DATE'));
630 CIMMessageParam::Set($messageID,
$arFields[
'PARAMS']);
635 if (isset(
$arFields[
'PARAMS'][
'ATTACH']))
645 $relations = CIMChat::GetRelationById($chatId,
false,
true,
false);
649 foreach ($relations as $relation)
660 if (isset(
$arFields[
'RECENT_SKIP_AUTHOR']) && $relation[
'USER_ID'] ==
$arParams[
'AUTHOR_ID'])
666 if ($incrementCounter !==
true && !in_array($relation[
'USER_ID'], $incrementCounter))
668 $addToRecent = \CIMContactList::InRecent($relation[
'USER_ID'],
$arFields[
'MESSAGE_TYPE'], $relation[
'CHAT_ID']);
672 CIMContactList::SetRecent(Array(
674 'MESSAGE_ID' => $messageID,
676 'CHAT_ID' => $relation[
'CHAT_ID'],
677 'RELATION_ID' => $relation[
'ID'],
678 'USER_ID' => $relation[
'USER_ID']
685 $pullIncluded = CModule::IncludeModule(
"pull");
686 $pullServerActive = $pullIncluded && CPullOptions::GetNginxStatus();
689 'WITHOUT_COUNTERS' =>
'Y',
693 foreach ($relations as $id => $relation)
699 else if ($relation[
'USER_DATA'][
'ACTIVE'] ==
'N')
705 'USER_ID' => (
int)$relation[
'USER_ID'],
706 'CHAT_ID' => $relation[
'CHAT_ID'],
707 'MESSAGE_TYPE' => $relation[
'MESSAGE_TYPE'],
708 'NOTIFY_BLOCK' => $relation[
'NOTIFY_BLOCK'] ===
'Y',
710 $relationObject->setId((
int)$relation[
'ID']);
711 $relationCollection->add($relationObject);
712 if ($isSelfChat || $relation[
"USER_ID"] ==
$arFields[
"FROM_USER_ID"])
714 $relations[$id][
'COUNTER'] = 0;
715 $relationUpdate =
array(
720 "LAST_ID" => $messageID,
721 "LAST_SEND_MESSAGE_ID" => $messageID,
729 if ($pullServerActive)
731 \Bitrix\Im\Model\RelationTable::update($relation[
"ID"], $relationUpdate);
757 ->onAfterMessageSend(
$message, $relationCollection,
$arFields[
'SKIP_COUNTER_INCREMENTS'] ===
'Y')
758 ->getResult()[
'COUNTERS']
761 $importantFor = self::getMentionUsers(
$arParams[
'MESSAGE'] ??
'');
765 $relationCollection->getUserIds()
769 $relationCollection->getUserIds()
772 if (CModule::IncludeModule(
"pull") && (
$arFields[
'SKIP_PULL'] ??
'N') !==
'Y')
777 $pullMessage = Array(
779 'command' =>
'message',
782 'TEMPLATE_ID' =>
$arFields[
'TEMPLATE_ID'] ??
null,
783 'FILE_TEMPLATE_ID' =>
$arFields[
'FILE_TEMPLATE_ID'] ??
null,
784 'PREV_ID' => self::getRealPrevId($messageID, $chatId),
785 'CHAT_ID' => $chatId,
787 'FROM_USER_ID' =>
$arParams[
'FROM_USER_ID'],
790 'DATE_CREATE' => time(),
791 'PARAMS' => self::PrepareParamsForPull(
$arFields[
'PARAMS']),
793 'NOTIFY' => $incrementCounter,
794 'IMPORTANT_FOR' => $importantFor,
795 'IS_IMPORTANT' => $isImportant,
800 $pullMessageTo = $pullMessage;
801 $pullMessageTo[
'params'][
'dialogId'] =
$arParams[
'FROM_USER_ID'];
803 $pullMessageFrom = $pullMessage;
804 $pullMessageFrom[
'params'][
'dialogId'] =
$arParams[
'TO_USER_ID'];
806 $pullMessageFrom[
'params'][
'counter'] =
$counters[(int)
$arParams[
'FROM_USER_ID']] ?? 0;
814 $pullMessageTo = self::PreparePushForPrivate($pullMessageTo);
815 $pullMessageFrom = self::PreparePushForPrivate($pullMessageFrom);
824 $pullMessageTo[
'push'][
'message'] =
$arFields[
'MESSAGE_PUSH'];
825 $pullMessageTo[
'push'][
'advanced_params'][
'senderMessage'] =
$arFields[
'MESSAGE_PUSH'];
826 $pullMessageFrom[
'push'][
'message'] =
$arFields[
'MESSAGE_PUSH'];
827 $pullMessageFrom[
'push'][
'advanced_params'][
'senderMessage'] =
$arFields[
'MESSAGE_PUSH'];
830 $pullMessageTo[
'push'][
'advanced_params'][
'counter'] =
$counters[
$arParams[
'TO_USER_ID']] ?? 0;
831 \Bitrix\Pull\Push::add(
$arParams[
'TO_USER_ID'], $pullMessageTo);
833 $pullMessageFrom[
'push'][
'advanced_params'][
'counter'] =
$counters[
$arParams[
'FROM_USER_ID']] ?? 0;
834 \Bitrix\Pull\Push::add(
$arParams[
'FROM_USER_ID'], array_merge_recursive($pullMessageFrom, [
'push' => [
835 'skip_users' => [
$arParams[
'FROM_USER_ID']],
836 'advanced_params' => [
837 "notificationsToCancel" => [
'IM_MESS'],
839 'send_immediately' =>
'Y',
848 $arFields[
'COMMAND_CONTEXT'] =
'TEXTAREA';
852 \Bitrix\Im\Bot::onMessageAdd(intval($messageID),
$arFields);
857 (new \Bitrix\Im\V2\Link\Url\UrlService())->saveUrlsFromMessage(
$message);
860 $allFiles = self::getFilesFromMessage(
866 (new \Bitrix\Im\V2\Link\File\FileService())->saveFilesFromMessage($allFiles,
$message);
876 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
880 else if (in_array(
$arFields[
'MESSAGE_TYPE'], CIMChat::getGroupTypesExtra()))
885 $systemMessage =
false;
891 C.PARENT_ID CHAT_PARENT_ID,
892 C.PARENT_MID CHAT_PARENT_MID,
894 C.AUTHOR_ID CHAT_AUTHOR_ID,
896 C.AVATAR CHAT_AVATAR,
898 C.ENTITY_TYPE CHAT_ENTITY_TYPE,
899 C.ENTITY_ID CHAT_ENTITY_ID,
900 C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
901 C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
902 C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
903 C.EXTRANET CHAT_EXTRANET,
904 C.PREV_MESSAGE_ID CHAT_PREV_MESSAGE_ID,
905 C.CAN_POST CHAT_CAN_POST,
910 WHERE C.ID = ".intval(
$arFields[
'TO_CHAT_ID']).
"
912 $systemMessage =
true;
919 C.PARENT_ID as CHAT_PARENT_ID,
920 C.PARENT_MID as CHAT_PARENT_MID,
921 C.TITLE as CHAT_TITLE,
922 C.AUTHOR_ID as CHAT_AUTHOR_ID,
924 C.AVATAR as CHAT_AVATAR,
925 C.COLOR as CHAT_COLOR,
926 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
927 C.ENTITY_ID as CHAT_ENTITY_ID,
928 C.ENTITY_DATA_1 as CHAT_ENTITY_DATA_1,
929 C.ENTITY_DATA_2 as CHAT_ENTITY_DATA_2,
930 C.ENTITY_DATA_3 as CHAT_ENTITY_DATA_3,
931 C.EXTRANET as CHAT_EXTRANET,
932 C.PREV_MESSAGE_ID as CHAT_PREV_MESSAGE_ID,
933 C.CAN_POST as CHAT_CAN_POST,
935 R.MANAGER as IS_MANAGER,
938 LEFT JOIN b_im_relation R ON R.CHAT_ID = C.ID AND R.USER_ID = ".$arFields[
'FROM_USER_ID'].
"
939 WHERE C.ID = ".intval(
$arFields[
'TO_CHAT_ID']).
"
946 $chatId = intval(
$arRes[
'CHAT_ID']);
948 $chatAuthorId = intval(
$arRes[
'CHAT_AUTHOR_ID']);
949 $chatParentId = intval(
$arRes[
'CHAT_PARENT_ID']);
950 $chatParentMid = intval(
$arRes[
'CHAT_PARENT_MID']);
951 $chatExtranet =
$arRes[
'CHAT_EXTRANET'] ==
'Y';
954 $prevMessageId = intval(
$arRes[
'CHAT_PREV_MESSAGE_ID']);
955 $importantPush =
$arRes[
'CHAT_ENTITY_TYPE'] ==
'ANNOUNCEMENT';
959 $isSystem = (
$arFields[
'SYSTEM'] ??
'N') ===
'Y';
960 if ((
int)
$arFields[
'FROM_USER_ID'] !== 0 && !$isSystem)
962 $userRole = Chat::ROLE_MEMBER;
963 if (
$arRes[
'IS_MANAGER'] ===
'Y')
965 $userRole = Chat::ROLE_MANAGER;
969 $userRole = Bitrix\Im\V2\Chat::ROLE_OWNER;
971 if (!\
Bitrix\
Im\
V2\Permission::compareRole($userRole,
$arRes[
'CHAT_CAN_POST'] ??
''))
973 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
978 if (
$arRes[
'CHAT_ENTITY_TYPE'] ==
'ANNOUNCEMENT' &&
$arRes[
'IS_MANAGER'] !==
'Y')
980 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
988 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
991 else if (intval(
$arRes[
'RID']) <= 0)
995 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
1001 $chat->AddUser($chatId,
$arFields[
'FROM_USER_ID']);
1005 else if (intval(
$arRes[
'RID']) <= 0)
1007 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
1014 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"CANCELED");
1020 foreach(
GetModuleEvents(
"im",
"OnBeforeChatMessageAdd",
true) as $arEvent)
1025 $reason = self::GetReasonForMessageSendError(
$arFields[
'MESSAGE_TYPE'],
$result[
'reason']);
1026 $GLOBALS[
"APPLICATION"]->ThrowException($reason,
"ERROR_FROM_OTHER_MODULE");
1041 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_GROUP_CANCELED"),
"TEXT_FIELD_DISABLED");
1047 $chatId = intval(
$arRes[
'CHAT_ID']);
1067 if (isset(
$arFields[
'PARAMS'][
'FILE_ID']))
1069 foreach (
$arFields[
'PARAMS'][
'FILE_ID'] as $fileId)
1075 $messageFiles = self::GetFormatFilesMessageOut(
$arFields[
'FILES']);
1076 if ($messageFiles <>
'')
1083 $messageID = intval(
$result->getId());
1084 if ($messageID <= 0)
1087 if (isset($messageUuid))
1089 $messageUuid->updateMessageId($messageID);
1094 CIMMessageParam::Set($messageID,
$arFields[
'PARAMS']);
1099 if (isset(
$arFields[
'PARAMS'][
'ATTACH']))
1111 \Bitrix\Im\Model\ChatTable::update($chatId, Array(
1114 'LAST_MESSAGE_ID' => $messageID,
1118 $realPrevId = self::getRealPrevId($messageID, $chatId);
1119 $importantFor = self::getMentionUsers(
$arParams[
'MESSAGE'] ??
'');
1120 if (
$arFields[
'MESSAGE_TYPE'] === Chat::IM_TYPE_COMMENT)
1123 $userToSubscribe = $importantFor;
1126 $chat->subscribe(
true, (
int)
$arFields[
'FROM_USER_ID']);
1127 $chat->subscribeUsers(
true, $userToSubscribe, $realPrevId);
1133 $chatData = \Bitrix\Im\Model\ChatTable::getById($chatId)->fetch();
1134 CIMMessageParam::set($chatParentMid, Array(
1135 'CHAT_MESSAGE' => $chatData[
'MESSAGE_COUNT'],
1138 CIMMessageParam::SendPull($chatParentMid, Array(
'CHAT_MESSAGE',
'CHAT_LAST_DATE'));
1144 $arBotInChat = Array();
1145 $parentRelations =
null;
1148 $allBots = \Bitrix\Im\Bot::getListCache();
1150 foreach ($fakeRelation as $fakeId)
1152 $relations[$fakeId] = [
1154 'USER_ID' => $fakeId,
1156 'MESSAGE_TYPE' =>
'S',
1157 'NOTIFY_BLOCK' =>
'N',
1158 'FROM_USER_ID' =>
$arFields[
'FROM_USER_ID'],
1162 'EXTERNAL_AUTH_ID' => isset($allBots[$fakeId]) ?
'bot' :
'default',
1169 $filter =
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT ? [
'NOTIFY_BLOCK' =>
'N'] : [];
1172 'WITHOUT_COUNTERS' =>
'Y',
1174 'SKIP_CONNECTOR' =>
$arRes[
'CHAT_ENTITY_TYPE'] ==
'LINES'?
'Y':
'N',
1177 if (
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT)
1179 [$relations, $parentRelations] = self::filterRelationsByParentRelations($relations, $chatParentId);
1185 $shouldAddToRecent = !empty($recentSections);
1186 $isCounterIncrementAllowed = $shouldAddToRecent ||
$arFields[
'MESSAGE_TYPE'] === Chat::IM_TYPE_COMMENT;
1188 $pullIncluded = CModule::IncludeModule(
"pull");
1189 $pullServerActive = $pullIncluded && CPullOptions::GetNginxStatus();
1192 $skippedRelations = [];
1198 foreach ($relations as $id => $relation)
1202 $skippedRelations[$id] =
true;
1205 if ($relation[
'USER_DATA'][
"EXTERNAL_AUTH_ID"] == \
Bitrix\
Im\Bot::EXTERNAL_AUTH_ID)
1207 $arBotInChat[$relation[
"USER_ID"]] = $relation[
"USER_ID"];
1209 else if ($relation[
'USER_DATA'][
'ACTIVE'] ==
'N')
1211 $skippedRelations[$id] =
true;
1216 if (
$arRes[
'CHAT_ENTITY_TYPE'] ==
"LINES")
1218 if ($relation[
'USER_DATA'][
"EXTERNAL_AUTH_ID"] ==
'imconnector')
1220 $skippedRelations[$id] =
true;
1223 if (
$arRes[
'CHAT_ENTITY_DATA_1'])
1225 $fieldData = explode(
"|",
$arRes[
'CHAT_ENTITY_DATA_1']);
1226 $sessionId = intval($fieldData[5]);
1230 $addToRecent =
true;
1231 if ($incrementCounter !==
true && !in_array($relation[
'USER_ID'], $incrementCounter))
1233 $addToRecent = \CIMContactList::InRecent($relation[
'USER_ID'],
$arFields[
'MESSAGE_TYPE'], $relation[
'CHAT_ID']);
1236 if ($addToRecent && !$fakeRelation && $shouldAddToRecent)
1238 CIMContactList::SetRecent([
1239 'ENTITY_ID' => $chatId,
1240 'MESSAGE_ID' => $messageID,
1241 'CHAT_TYPE' =>
$arFields[
'MESSAGE_TYPE'],
1242 'USER_ID' => $relation[
'USER_ID'],
1243 'CHAT_ID' => $relation[
'CHAT_ID'],
1244 'RELATION_ID' => $relation[
'ID'],
1245 'SESSION_ID' => $sessionId,
1252 'USER_ID' => (
int)$relation[
'USER_ID'],
1253 'CHAT_ID' => $relation[
'CHAT_ID'],
1254 'MESSAGE_TYPE' => $relation[
'MESSAGE_TYPE'],
1255 'NOTIFY_BLOCK' => $relation[
'NOTIFY_BLOCK'] ===
'Y',
1257 $relationObject->setId((
int)$relation[
'ID']);
1258 $relationCollection->add($relationObject);
1261 if ($relation[
"USER_ID"] ==
$arFields[
"FROM_USER_ID"])
1263 $relations[$id][
'COUNTER'] = $relation[
'COUNTER'] = 0;
1265 $relationUpdate =
array(
1270 "LAST_ID" => $messageID,
1271 "LAST_SEND_MESSAGE_ID" => $messageID,
1279 if ($pullServerActive)
1281 \Bitrix\Im\Model\RelationTable::update($relation[
"ID"], $relationUpdate);
1311 if ($relation[
'USER_ID'] ==
$arParams[
'FROM_USER_ID'])
1313 CPushManager::DeleteFromQueueBySubTag(
$arParams[
'FROM_USER_ID'],
'IM_MESS');
1316 else if ($relation[
'NOTIFY_BLOCK'] ==
'Y' && !$importantPush)
1318 $pushUserSkip[] = $relation[
'USER_ID'];
1319 $pushUserSend[] = $relation[
'USER_ID'];
1327 $pushUserSend[] = $relation[
'USER_ID'];
1332 $arFields[
'MESSAGE_TYPE'] === Chat::IM_TYPE_COMMENT
1333 && $parentRelations !==
null
1334 &&
$arFields[
'SKIP_COUNTER_INCREMENTS'] !==
'Y'
1337 $lastActivity = new \Bitrix\Main\Type\DateTime();
1339 static function () use (
$arRes, $parentRelations, $lastActivity) {
1341 $chat->setRelations($parentRelations);
1349 $message->setMessageId($messageID);
1350 if ($shouldAddToRecent)
1354 $relationCollection->getUserIds(),
1359 $relationCollection->getUserIds(),
1363 $notify = $incrementCounter;
1365 if (
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT)
1369 if (!$shouldAddToRecent)
1375 'module_id' =>
'im',
1376 'command' =>
'messageChat',
1379 'TEMPLATE_ID' =>
$arFields[
'TEMPLATE_ID'] ??
null,
1380 'FILE_TEMPLATE_ID' =>
$arFields[
'FILE_TEMPLATE_ID'] ??
null,
1381 'PREV_ID' => $realPrevId,
1382 'CHAT_ID' => $chatId,
1383 'TO_CHAT_ID' =>
$arParams[
'TO_CHAT_ID'],
1384 'FROM_USER_ID' =>
$arParams[
'FROM_USER_ID'],
1386 'SYSTEM' => (
$arFields[
'SYSTEM'] ??
null) ===
'Y' ?
'Y' :
'N',
1387 'DATE_CREATE' => time(),
1388 'PARAMS' => self::PrepareParamsForPull(
$arFields[
'PARAMS']),
1390 'EXTRA_PARAMS' =>
$arFields[
'EXTRA_PARAMS'],
1392 'NOTIFY' => $notify,
1393 'IMPORTANT_FOR' => $importantFor,
1394 'IS_IMPORTANT' => $isImportant,
1401 $withoutCounters =
$arFields[
'SKIP_COUNTER_INCREMENTS'] ===
'Y' || !$isCounterIncrementAllowed;
1403 ->onAfterMessageSend(
$message, $relationCollection, $withoutCounters)
1404 ->getResult()[
'COUNTERS']
1409 foreach ($fakeRelation as $fakeId)
1413 isset($pullMessage[
'params'][
'userInChat'][
$arParams[
'TO_CHAT_ID']])
1414 && !in_array($fakeId, $pullMessage[
'params'][
'userInChat'][
$arParams[
'TO_CHAT_ID']]))
1416 $pullMessage[
'params'][
'userInChat'][
$arParams[
'TO_CHAT_ID']][] = $fakeId;
1421 foreach ($relations as $id => $relation)
1423 $skippedRelation = $skippedRelations[$id] ??
null;
1424 if ($skippedRelation)
1428 $events[$relation[
'USER_ID']] = $pullMessage;
1429 $events[$relation[
'USER_ID']][
'params'][
'counter'] =
$counters[$relation[
'USER_ID']] ?? 0;
1431 $events[$relation[
'USER_ID']][
'groupId'] =
'im_chat_'.$chatId.
'_'.$messageID.
'_'.$events[$relation[
'USER_ID']][
'params'][
'counter'];
1434 if ((
$arFields[
'SYSTEM'] ??
null) !==
'Y')
1437 'CHAT_ID' => $chatId,
1438 'CHAT_TITLE' => $chatTitle,
1439 'CHAT_RELATION' => $relations,
1440 'CHAT_TYPE' =>
$arFields[
'MESSAGE_TYPE'],
1441 'CHAT_ENTITY_TYPE' =>
$arRes[
'CHAT_ENTITY_TYPE'],
1442 'CHAT_COLOR' =>
$arRes[
'CHAT_COLOR'],
1445 'FROM_USER_ID' =>
$arParams[
'FROM_USER_ID'],
1446 'MENTION_USERS' => $importantFor,
1447 'MESSAGE_OBJECT' => $messageObject,
1448 'MESSAGE_ID' => $messageID,
1452 if ($pullIncluded && (
$arFields[
'SKIP_PULL'] ??
'N') !==
'Y')
1454 $watchPullMessage = $pullMessage;
1455 $watchPullMessage[
'params'][
'message'][
'params'][
'NOTIFY'] =
'N';
1456 $watchPullMessage[
'extra'][
'is_shared_event'] =
true;
1457 $watchPullMessage[
'params'][
'recentConfig'][
'sections'] = $chatObject->getRecentSectionsForGuest();
1458 if (self::needToSendPublicPull(
$arRes[
'CHAT_TYPE']))
1460 CPullWatch::AddToStack(
'IM_PUBLIC_' . $chatId, $watchPullMessage);
1462 if (
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT)
1464 CPullWatch::AddToStack(
'IM_PUBLIC_COMMENT_' . $chatParentId, $watchPullMessage);
1466 if (
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_OPEN_CHANNEL)
1471 $groups = self::GetEventByCounterGroup($events);
1476 $userList = array_intersect($pushUserSend, $group[
'users']);
1480 $pushParams = $group[
'event'];
1482 $pushParams = self::PreparePushForChat($pushParams);
1486 $pushParams[
'push'][
'important'] =
'Y';
1489 $pushParams[
'skip_users'] = $pushUserSkip;
1493 $pushParams[
'push'][
'message'] =
$arFields[
'MESSAGE_PUSH'];
1494 $pushParams[
'push'][
'advanced_params'][
'senderMessage'] =
$arFields[
'MESSAGE_PUSH'];
1496 $pushParams[
'push'][
'advanced_params'][
'counter'] = $group[
'event'][
'params'][
'counter'];
1498 \Bitrix\Pull\Push::add(
$userList, $pushParams);
1503 $arFields[
'CHAT_AUTHOR_ID'] = $chatAuthorId;
1509 $arFields[
'BOT_IN_CHAT'] = $arBotInChat;
1511 foreach (
GetModuleEvents(
"im",
"OnAfterMessagesAdd",
true) as $arEvent)
1514 if (
$arRes[
'CHAT_ENTITY_TYPE'] &&
$arRes[
'CHAT_TYPE'] === Chat::IM_TYPE_CHAT)
1516 $converter =
new Converter(Converter::TO_CAMEL | Converter::UC_FIRST);
1517 $eventName =
'OnAfterMessagesAdd' . $converter->process(
$arRes[
'CHAT_ENTITY_TYPE']);
1518 $eventAfterMessageAddEntityChat = new \Bitrix\Main\Event(
'im', $eventName,
$arFields);
1519 $eventAfterMessageAddEntityChat->send();
1522 $arFields[
'COMMAND_CONTEXT'] =
'TEXTAREA';
1526 \Bitrix\Im\Bot::onMessageAdd(intval($messageID),
$arFields);
1529 if (
$arFields[
'SKIP_URL_INDEX'] !==
'Y')
1531 (new \Bitrix\Im\V2\Link\Url\UrlService())->saveUrlsFromMessage(
$message);
1534 $allFiles = self::getFilesFromMessage(
1540 (new \Bitrix\Im\V2\Link\File\FileService())->saveFilesFromMessage($allFiles,
$message);
1550 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
1561 ->setSelect([
'EXTERNAL_AUTH_ID'])
1563 ->where(
'ACTIVE',
'Y')
1569 || in_array($userData[
'EXTERNAL_AUTH_ID'], $blockedExternalAuthId,
true)
1572 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"TO_USER_ID");
1577 SELECT ID as CHAT_ID
1579 WHERE AUTHOR_ID = ".$arFields[
'TO_USER_ID'].
" AND TYPE = '".
IM_MESSAGE_SYSTEM.
"'
1585 $chatId = intval(
$arRes[
'CHAT_ID']);
1595 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
1599 $chatId =
$result->getResult()[
'CHAT_ID'];
1603 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
1620 $arFields[
'PUSH_MESSAGE'] = $html = str_replace(
' ',
' ',
$arFields[
'PUSH_MESSAGE']);;
1641 $skipFlash = $skipAdd;
1644 if (!$skipAdd && (
$arFields[
'NOTIFY_ONLY_FLASH'] ??
null) ===
'Y')
1678 if (is_array($arButtons))
1680 if (isset($arButtons[
'TITLE']) && $arButtons[
'TITLE'] <>
''
1681 && isset($arButtons[
'VALUE']) && $arButtons[
'VALUE'] <>
''
1682 && isset($arButtons[
'TYPE']) && $arButtons[
'TYPE'] <>
'')
1698 $acceptTitleCallback = fn (?
string $languageId =
null) => Loc::getMessage(
"IM_ERROR_BUTTON_ACCEPT",
null, $languageId);
1699 $cancelTitleCallback = fn (?
string $languageId =
null) => Loc::getMessage(
"IM_ERROR_BUTTON_CANCEL",
null, $languageId);
1703 'TITLE' => CIMNotify::getTextMessageByLang(
$arFields[
'TO_USER_ID'], $acceptTitleCallback),
1708 'TITLE' => CIMNotify::getTextMessageByLang(
$arFields[
'TO_USER_ID'], $cancelTitleCallback),
1719 $messageID = time();
1725 'USER_ID' => (
int)
$arFields[
'TO_USER_ID'],
1726 'CHAT_ID' => $chatId,
1728 'NOTIFY_BLOCK' =>
false,
1730 $relation->setId(1);
1742 $messageID =
$message->getMessageId();
1743 if ($messageID ===
null)
1766 \Bitrix\Im\Model\ChatTable::update($chatId, Array(
1769 'LAST_MESSAGE_ID' => $messageID,
1779 if (CModule::IncludeModule(
'pull'))
1781 $pullNotificationParams = CIMNotify::GetFormatNotify(
1784 'DATE_CREATE' => time(),
1785 'FROM_USER_ID' => (
int)
$arFields[
'FROM_USER_ID'],
1787 'PARAMS' => self::PrepareParamsForPull(
$arFields[
'PARAMS']),
1788 'NOTIFY_ONLY_FLASH' => $skipAdd,
1789 'NOTIFY_LINK' =>
$arFields[
'NOTIFY_LINK'] ??
null,
1790 'NOTIFY_MODULE' =>
$arParams[
'NOTIFY_MODULE'],
1791 'NOTIFY_EVENT' =>
$arParams[
'NOTIFY_EVENT'],
1792 'NOTIFY_TAG' =>
$arParams[
'NOTIFY_TAG'],
1793 'NOTIFY_TYPE' =>
$arParams[
'NOTIFY_TYPE'],
1794 'NOTIFY_BUTTONS' =>
$arParams[
'NOTIFY_BUTTONS'] ?? serialize([]),
1795 'NOTIFY_TITLE' =>
$arParams[
'NOTIFY_TITLE'] ??
'',
1812 if (isset(
$arFields[
'PUSH_PARAMS'][
'ADVANCED_PARAMS']))
1814 $advancedParams =
$arFields[
'PUSH_PARAMS'][
'ADVANCED_PARAMS'];
1815 unset(
$arFields[
'PUSH_PARAMS'][
'ADVANCED_PARAMS']);
1819 $advancedParams = self::prepareAdvancedParamsForNotificationPush(
1820 $pullNotificationParams,
1825 \Bitrix\Pull\Push::add(
1828 'module_id' =>
$arParams[
'NOTIFY_MODULE'],
1831 'message' =>
$arFields[
'PUSH_MESSAGE'] ??
null,
1832 'params' =>
$arFields[
'PUSH_PARAMS'] ?? [
'TAG' =>
'IM_NOTIFY'],
1833 'advanced_params' => $advancedParams,
1834 'important' => isset(
$arFields[
'PUSH_IMPORTANT']) &&
$arFields[
'PUSH_IMPORTANT'] ===
'Y' ?
'Y':
'N',
1836 'sub_tag' =>
$arParams[
'NOTIFY_SUB_TAG'],
1837 'app_id' =>
$arParams[
'PUSH_APP_ID'] ??
'',
1848 'module_id' =>
'im',
1849 'command' =>
'notifyAdd',
1850 'params' => $pullNotificationParams,
1866 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_CREATE"),
"CHAT_ID");
1872 $GLOBALS[
"APPLICATION"]->ThrowException(
GetMessage(
"IM_ERROR_MESSAGE_TYPE"),
"MESSAGE_TYPE");
3593 $ppStatus =
'false';
3594 $ppServerStatus =
'false';
3595 $updateStateInterval =
'auto';
3596 if (CModule::IncludeModule(
"pull"))
3598 $ppStatus = CPullOptions::ModuleEnable()?
'true':
'false';
3599 $ppServerStatus = CPullOptions::GetNginxStatus()?
'true':
'false';
3601 $updateStateInterval = CPullOptions::GetNginxStatus()? self::GetSessionLifeTime(): 80;
3602 if ($updateStateInterval > 100)
3604 if ($updateStateInterval > 3600)
3605 $updateStateInterval = 3600;
3607 if (in_array(
$arTemplate[
"CONTEXT"], Array(
"POPUP-FULLSCREEN",
"MESSENGER")))
3608 $updateStateInterval = $updateStateInterval-60;
3610 $updateStateInterval = intval($updateStateInterval/2)-10;
3617 $phoneCanPerformCalls =
false;
3618 $phoneDeviceActive =
false;
3619 $phoneCanCallUserNumber =
false;
3620 $phoneEnabled =
false;
3621 $chatExtendShowHistory = \COption::GetOptionInt(
'im',
'chat_extend_show_history');
3622 $contactListLoad = \COption::GetOptionInt(
'im',
'contact_list_load');
3623 $contactListBirthday = \COption::GetOptionString(
'im',
'contact_list_birthday');
3624 $isFullTextEnabled = \Bitrix\Im\Model\MessageIndexTable::getEntity()->fullTextIndexEnabled(
"SEARCH_CONTENT");
3626 $phoneCanInterceptCall = self::CanInterceptCall();
3630 $phoneEnabled = self::CheckPhoneStatus();
3631 if ($phoneEnabled && CModule::IncludeModule(
'voximplant'))
3633 $phoneCanPerformCalls = self::CanUserPerformCalls();
3634 $phoneDeviceActive = CVoxImplantUser::GetPhoneActive(
$USER->GetId());
3635 $phoneCanCallUserNumber = self::CanUserCallUserNumber();
3643 $olConfig = Array();
3644 $businessUsers =
false;
3656 $olConfig[
'canDeleteMessage'] = str_replace(
'.',
'_', \
Bitrix\
Imopenlines\Connector::getListCanDeleteMessage());
3657 $olConfig[
'canDeleteOwnMessage'] = str_replace(
'.',
'_', \
Bitrix\
Imopenlines\Connector::getListCanDeleteOwnMessage());
3658 $olConfig[
'canUpdateOwnMessage'] = str_replace(
'.',
'_', \
Bitrix\
Imopenlines\Connector::getListCanUpdateOwnMessage());
3660 $olConfig[
'queue'] = Array();
3663 $olConfig[
'queue'][] = array_change_key_case(
$config, CASE_LOWER);
3666 foreach (\
Bitrix\ImOpenLines\Config::getAllLinesSettings([
'CONFIRM_CLOSE']) as
$config)
3669 $olConfig[
'settings'][$lineId] = array_change_key_case(
$config, CASE_LOWER);
3671 $connectorStatus = \Bitrix\ImConnector\Status::getInstance(\
Bitrix\ImOpenLines\Connector::TYPE_NETWORK, $lineId);
3672 if ($connectorStatus->isStatus())
3674 $connectorData = $connectorStatus->getData();
3675 if (isset($connectorData[
'MULTIDIALOG']) && $connectorData[
'MULTIDIALOG'] ===
'Y')
3677 $olConfig[
'settings'][$lineId][
'multidialog'] =
'Y';
3681 $olConfig[
'settings'][$lineId][
'multidialog'] =
'N';
3691 $bitrix24blocked =
false;
3692 $bitrix24Enabled =
false;
3696 $bitrix24Enabled =
true;
3697 $bitrixPaid = CBitrix24::IsLicensePaid() || CBitrix24::IsNfrLicense();
3700 $bitrix24blocked = \Bitrix\Bitrix24\Limits\User::getUserRestrictedHelperCode();
3710 $pathToDisk = Array(
3714 $recentLastUpdate = (new \Bitrix\Main\Type\DateTime())->format(\DateTimeInterface::RFC3339);
3716 'SKIP_NOTIFICATION' =>
'Y',
3717 'SKIP_OPENLINES' =>
'Y',
3719 'GET_ORIGINAL_TEXT' =>
'Y',
3723 $iframeRequest =
$_REQUEST[
'IFRAME'] ??
null;
3724 $iframeTypeRequest =
$_REQUEST[
'IFRAME_TYPE'] ??
null;
3725 $imMenuRequest =
$_REQUEST[
'IM_MENU'] ??
null;
3726 $imSearchRequest =
$_REQUEST[
'IM_SEARCH'] ??
null;
3727 $imStatusRequest =
$_REQUEST[
'IM_STATUS'] ??
null;
3728 $imRecentRequest =
$_REQUEST[
'IM_RECENT'] ??
null;
3729 $imLinesRequest =
$_REQUEST[
'IM_LINES'] ??
null;
3730 $imV2LayoutRequest =
$_REQUEST[
'IM_V2_LAYOUT'] ??
null;
3733 $imBackgroundRequest =
'auto';
3737 $imBackgroundRequest =
$_REQUEST[
'IM_BACKGROUND'] ===
'dark'?
'dark':
'light';
3746 BX.ready(function() {
3747 BXIM = new BX.IM(BX('bx-notifier-panel'), {
3748 'init': ".($arTemplate[
'INIT'] ==
'Y'?
'true':
'false').
",
3755 'ppStatus': ".$ppStatus.
",
3756 'ppServerStatus': ".$ppServerStatus.
",
3757 'updateStateInterval': '".$updateStateInterval.
"',
3760 'isAdmin': ".(self::IsAdmin()?
'true':
'false').
",
3762 'isLinesOperator': 'true',
3765 'bitrix24': ".($bitrix24Enabled?
'true':
'false').
",
3766 'bitrix24blocked': ".($bitrix24blocked? $bitrix24blocked:
'false').
",
3768 'bitrixPaid': ".($bitrixPaid?
'true':
'false').
",
3774 'desktop': ".(
$arTemplate[
"DESKTOP"] ??
'false').
",
3777 'desktopLinkOpen': ".(
$arTemplate[
"DESKTOP_LINK_OPEN"] ??
'false').
",
3778 'language': '".LANGUAGE_ID.
"',
3794 'recentLastUpdate': '".$recentLastUpdate.
"',
3800 'openNotify' : ".(isset($_GET[
'IM_NOTIFY']) && $_GET[
'IM_NOTIFY'] ==
'Y'?
'true':
'false').
",
3801 'openSettings' : ".(isset($_GET[
'IM_SETTINGS'])? $_GET[
'IM_SETTINGS'] ==
'Y'?
"'true'":
"'".CUtil::JSEscape(
htmlspecialcharsbx($_GET[
'IM_SETTINGS'])).
"'":
'false').
",
3802 'externalRecentList' : '".(isset(
$arTemplate[
'EXTERNAL_RECENT_LIST'])?
$arTemplate[
'EXTERNAL_RECENT_LIST']:
'').
"',
3804 'generalChatId': ".CIMChat::GetGeneralChatId().
",
3805 'canSendMessageGeneralChat': ".(CIMChat::CanSendMessageToGeneralChat(
$USER->GetID())?
'true':
'false').
",
3806 'debug': ".(defined(
'IM_DEBUG')?
'true':
'false').
",
3807 'next': ".(defined(
'IM_NEXT')?
'true':
'false').
",
3808 'userId': ".
$USER->GetID().
",
3809 'userEmail': '".CUtil::JSEscape(
$USER->GetEmail()).
"',
3816 'turnServer' : '".CUtil::JSEscape(
$arTemplate[
'TURN_SERVER']).
"',
3817 'turnServerFirefox' : '".CUtil::JSEscape(
$arTemplate[
'TURN_SERVER_FIREFOX']).
"',
3818 'turnServerLogin' : '".CUtil::JSEscape(
$arTemplate[
'TURN_SERVER_LOGIN']).
"',
3819 'turnServerPassword' : '".CUtil::JSEscape(
$arTemplate[
'TURN_SERVER_PASSWORD']).
"',
3821 'mobileSupport': false,
3822 'phoneEnabled': ".($phoneEnabled?
'true':
'false').
",
3823 'phoneDeviceActive': '".($phoneDeviceActive?
'Y':
'N').
"',
3824 'phoneCanPerformCalls': '".($phoneCanPerformCalls?
'Y':
'N').
"',
3825 'phoneCanCallUserNumber': '".($phoneCanCallUserNumber?
'Y':
'N').
"',
3826 'phoneCanInterceptCall': ".($phoneCanInterceptCall?
'true':
'false').
",
3828 'phoneDefaultLineId': '".self::GetDefaultTelephonyLine().
"',
3830 'formatRecordDate': '".\Bitrix\Main\Context::getCurrent()->getCulture()->getShortDateFormat().
"'
3833 'options': {'contactListLoad' : ".($contactListLoad?
'true':
'false').
", 'contactListBirthday' : '".$contactListBirthday.
"', 'chatExtendShowHistory' : ".($chatExtendShowHistory?
'true':
'false').
", 'frameMode': ".($iframeRequest ===
'Y'?
'true':
'false').
", 'frameType': '".($iframeTypeRequest ===
'SIDE_SLIDER'?
'SIDE_SLIDER':
'NONE').
"', 'showRecent': ".($imRecentRequest ===
'N'?
'false':
'true').
", 'showMenu': ".($imMenuRequest ===
'N'?
'false':
'true').
", 'showSearch': ".($imSearchRequest ===
'N'?
'false':
'true').
", 'showStatus': ".($imStatusRequest ===
'N'?
'false':
'true').
", 'openLinesRecent': ".($imLinesRequest ===
'Y'?
'true':
'false').
", 'v2layout': ".($imV2LayoutRequest ===
'Y'?
'true':
'false').
", 'background': '".$imBackgroundRequest.
"'},
3834 'disk': {'enable' : ".($diskStatus?
'true':
'false').
", 'external' : ".($diskExternalLinkStatus?
'true':
'false').
"},
3836 'path' : {'lf' : '".CUtil::JSEscape($pathToLf).
"', 'profile' : '".CUtil::JSEscape(
$arTemplate[
'PATH_TO_USER_PROFILE']).
"', 'profileTemplate' : '".CUtil::JSEscape(
$arTemplate[
'PATH_TO_USER_PROFILE_TEMPLATE']).
"', 'mail' : '".CUtil::JSEscape(
$arTemplate[
'PATH_TO_USER_MAIL']).
"', 'im': '".CUtil::JSEscape($pathToIm).
"', 'call': '".CUtil::JSEscape($pathToCall).
"', 'file': '".CUtil::JSEscape($pathToFile).
"', 'crm' : ".
\Bitrix\Im\Common::objectEncode($crmPath).
", 'disk' : ".
\Bitrix\Im\Common::objectEncode($pathToDisk).
"}