public function addMessage($params)
{
$result = false;
$finishSession = false;
$voteSession = false;
if (!empty($params))
{
if (
!in_array($params['connector']['connector_id'], self::$noVote)
&&
(
mb_strpos($params['message']['text'], '1') === 0
|| mb_strpos($params['message']['text'], '0') === 0
)
&&
(
mb_strlen(trim($params['message']['text'])) == 1
|| mb_substr($params['message']['text'], 1, 1) == " "
)
)
{
$voteSession = true;
}
$addMessage = [
"FROM_USER_ID" => $params['message']['user_id'],
"PARAMS" => $params['message']['params'] ?? []
//"SKIP_COMMAND" => "Y"
];
//if (is_object($params['message']['date']))
//{
// $addMessage["MESSAGE_DATE"] = $params['message']['date']->toString();
//}
if (!empty($params['message']['text']) || $params['message']['text'] === '0')
{
$addMessage["MESSAGE"] = $params['message']['text'];
}
if (!empty($params['message']['attach']))
{
if ($params['connector']['connector_id'] == self::TYPE_LIVECHAT)
{
$addMessage["ATTACH"] = $params['message']['attach'];
}
else
{
$addMessage["ATTACH"] = CIMMessageParamAttach::GetAttachByJson($params['message']['attach']);
}
}
if (!empty($params['message']['keyboard']))
{
if ($params['connector']['connector_id'] == self::TYPE_LIVECHAT)
{
$addMessage["KEYBOARD"] = $params['message']['keyboard'];
}
else
{
$keyboard = [];
if (!isset($params['message']['keyboard']['BUTTONS']))
{
$keyboard['BUTTONS'] = $params['message']['keyboard'];
}
else
{
$keyboard = $params['message']['keyboard'];
}
$addMessage["KEYBOARD"] = Keyboard::getKeyboardByJson($keyboard);
}
}
if (!empty($params['message']['fileLinks']))
{
if (!$addMessage["ATTACH"])
{
$addMessage["ATTACH"] = new CIMMessageParamAttach(null, CIMMessageParamAttach::CHAT);
}
foreach ($params['message']['fileLinks'] as $key => $value)
{
if ($value['type'] === 'image')
{
$addMessage["ATTACH"]->AddImages([[
"NAME" => $value['name'],
"LINK" => $value['link'],
"WIDTH" => (int)$value['width'],
"HEIGHT" => (int)$value['height'],
]]);
}
else
{
$addMessage["ATTACH"]->AddFiles([[
"NAME" => $value['name'],
"LINK" => $value['link'],
"SIZE" => $value['size'],
]]);
}
}
}
$userCode = self::getUserCode($params['connector']);
$keyLock = Chat::PREFIX_KEY_LOCK_NEW_SESSION . $userCode;
$iteration = 0;
$isAddMessage = false;
do
{
$iteration++;
if (
$iteration > self::LOCK_MAX_ITERATIONS
|| ToolsLock::getInstance()->set($keyLock)
)
{
if (
!empty($params['message']['files'])
|| !empty($addMessage['ATTACH'])
|| $addMessage['MESSAGE'] <> ''
)
{
$userViewChat = false;
$addVoteResult = false;
$session = new Session();
$resultLoadSession = $session->load([
'USER_CODE' => self::getUserCode($params['connector']),
'CRM_SKIP_PHONE_VALIDATE' => ($params['extra']['skip_phone_validate'] ?? ''),
//TODO: ??
'CONNECTOR' => $params,
'DEFERRED_JOIN' => 'Y',
'VOTE_SESSION' => $voteSession? 'Y': 'N'
]);
if (
$resultLoadSession ||
$session->isCloseVote()
)
{
$addMessage["TO_CHAT_ID"] = $session->getData('CHAT_ID');
if (!empty($params['message']['files']))
{
$params['message']['files'] = CIMDisk::UploadFileFromMain(
$session->getData('CHAT_ID'),
$params['message']['files']
);
if ($params['message']['files'])
{
$addMessage["PARAMS"]['FILE_ID'] = $params['message']['files'];
}
else if ($addMessage["MESSAGE"] == '' && empty($addMessage["ATTACH"]))
{
$addMessage["MESSAGE"] = '[FILE]';
}
}
}
if ($resultLoadSession)
{
if ($session->isNowCreated())
{
$customDataMessage = '';
$customDataAttach = null;
$customData = ImOpenLinesWidgetCache::get($params['connector']['user_id'], 'CUSTOM_DATA');
if ($customData)
{
$customDataAttach = CIMMessageParamAttach::GetAttachByJson($customData);
if ($customDataAttach && $customDataAttach->IsEmpty())
{
$customDataAttach = null;
}
else
{
$customDataMessage = '[B]'.Loc::getMessage('IMOL_CONNECTOR_RECEIVED_DATA').'[/B]';
}
}
else // TODO remove this after delete old livechat - see ImOpenLinesConnector::saveCustomData
{
if ($params['connector']['connector_id'] == self::TYPE_LIVECHAT)
{
$orm = ChatTable::getById($params['chat']['id']);
$guestChatData = $orm->fetch();
}
else
{
$guestChatData = $session->getChat()->getData();
}
if ($guestChatData && $guestChatData['DESCRIPTION'] <> '')
{
$customDataMessage = '[B]'.Loc::getMessage('IMOL_CONNECTOR_RECEIVED_DATA').'[/B][BR] '.$guestChatData['DESCRIPTION'];
}
}
if ($params['connector']['connector_id'] == self::TYPE_LIVECHAT)
{
$chat = new Chat($params['chat']['id']);
$chat->updateFieldData([Chat::FIELD_LIVECHAT => [
'SESSION_ID' => $session->getData('ID'),
'SHOW_FORM' => 'Y'
]]);
}
if ($customDataMessage)
{
Im::addMessage([
'TO_CHAT_ID' => $session->getData('CHAT_ID'),
'MESSAGE' => $customDataMessage,
'ATTACH' => $customDataAttach,
'SYSTEM' => 'Y',
'SKIP_COMMAND' => 'Y',
'PARAMS' => [
'CLASS' => 'bx-messenger-content-item-system'
],
]);
}
}
if (!empty($params['message']['description']))
{
Im::addMessage([
'TO_CHAT_ID' => $session->getData('CHAT_ID'),
'MESSAGE' => $params['message']['description'],
'SYSTEM' => 'Y',
'SKIP_COMMAND' => 'Y',
'URL_PREVIEW' => 'N',
'PARAMS' => [
'CLASS' => 'bx-messenger-content-item-system'
],
]);
unset($params['message']['description']);
}
$session->joinUser();
if ($session->getData('OPERATOR_ID') > 0)
{
$userViewChat = CIMContactList::InRecent($session->getData('OPERATOR_ID'), IM_MESSAGE_OPEN_LINE, $session->getData('CHAT_ID'));
}
else
{
$userViewChat = false;
}
if (
$voteSession &&
$session->getData('WAIT_VOTE') == 'Y'
)
{
$voteValue = 0;
if (mb_strlen($addMessage["MESSAGE"]) > 1)
{
$userViewChat = true;
}
if (mb_strpos($addMessage["MESSAGE"], '1') === 0)
{
$voteValue = 5;
$addMessage["MESSAGE"] = '[like]'.mb_substr($addMessage["MESSAGE"], 1);
$addVoteResult = $session->getConfig('VOTE_MESSAGE_2_LIKE');
}
else if (mb_strpos($addMessage["MESSAGE"], '0') === 0)
{
$voteValue = 1;
$addMessage["MESSAGE"] = '[dislike]'.mb_substr($addMessage["MESSAGE"], 1);
$addVoteResult = $session->getConfig('VOTE_MESSAGE_2_DISLIKE');
}
if ($addVoteResult)
{
$voteEventParams = [
'SESSION_DATA' => $session->getData(),
'VOTE' => $voteValue,
];
$event = new Event('imopenlines', 'OnSessionVote', $voteEventParams);
$event->send();
$addMessage['RECENT_ADD'] = $userViewChat? 'Y': 'N';
$session->update(['VOTE' => $voteValue, 'WAIT_VOTE' => 'N']);
if ($session->getConfig('VOTE_CLOSING_DELAY') == 'Y')
{
$finishSession = true;
}
Chat::sendRatingNotify(Chat::RATING_TYPE_CLIENT, $session->getData('ID'), $voteValue, $session->getData('OPERATOR_ID'), $session->getData('USER_ID'));
}
}
else
{
$voteSession = false;
}
}
if (
$resultLoadSession ||
$session->isCloseVote()
)
{
$event = new Event('imopenlines', self::EVENT_IMOPENLINE_MESSAGE_RECEIVE, $addMessage);
$event->send();
$eventMessageFields = $event->getParameters();
if (!empty($eventMessageFields['MESSAGE']))
{
$addMessage['MESSAGE'] = $eventMessageFields['MESSAGE'];
}
if (!empty($eventMessageFields['PARAMS']))
{
$addMessage['PARAMS'] = $eventMessageFields['PARAMS'];
}
$messageId = Im::addMessage($addMessage);
}
if (
$resultLoadSession &&
!empty($messageId)
)
{
$isGroupChatAllowed = BitrixImConnectorConnector::isChatGroup($params['connector']['connector_id']) != true;
if (
$addMessage["MESSAGE"]
&& (empty($params['extra']['disable_tracker']) || $params['extra']['disable_tracker'] !== 'Y')
&& $isGroupChatAllowed
)
{
$tracker = new ImOpenLinesTracker();
$tracker
->setSession($session)
->trackMessage([
'ID' => $messageId,
'TEXT' => $addMessage["MESSAGE"]
])
;
}
if ($params['message']['id'])
{
if ($params['connector']['connector_id'] == self::TYPE_LIVECHAT)
{
if ($session->isNowCreated())
{
$updateParams = [
'CONNECTOR_MID' => $messageId,
'IMOL_SID' => $session->getData('ID'),
'IMOL_FORM' => 'welcome',
'TYPE' => 'lines',
'COMPONENT_ID' => 'bx-imopenlines-message',
];
}
else
{
$updateParams = [
'CONNECTOR_MID' => $messageId,
];
}
CIMMessageParam::Set($params['message']['id'], $updateParams);
CIMMessageParam::SendPull($params['message']['id'], array_keys($updateParams));
ImOpenLinesMail::removeSessionFromMailQueue($session->getData('ID'), false);
Session::setLastSendMailId($session->getData(), $params['message']['id']);
}
CIMMessageParam::Set($messageId, ['CONNECTOR_MID' => $params['message']['id']]);
if (!in_array($params['connector']['connector_id'], [self::TYPE_LIVECHAT, self::TYPE_NETWORK]))
{
CIMMessageParam::SendPull($messageId, ['CONNECTOR_MID']);
}
}
if ($addVoteResult)
{
Im::addMessage([
"TO_CHAT_ID" => $session->getData('CHAT_ID'),
"MESSAGE" => $addVoteResult,
"SYSTEM" => 'Y',
"IMPORTANT_CONNECTOR" => 'Y',
'NO_SESSION_OL' => 'Y',
"PARAMS" => [
"CLASS" => "bx-messenger-content-item-ol-output"
],
"RECENT_ADD" => $userViewChat? 'Y': 'N'
]);
}
//Automatic messages
(new AutomaticAction($session))->automaticAddMessage($messageId, $finishSession, $voteSession);
$limit = ImConnectorConnector::getReplyLimit($params['connector']['connector_id']);
$chat = $session->getChat();
if (
!empty($limit['BLOCK_DATE']) &&
!empty($limit['BLOCK_REASON']) &&
$chat
)
{
$limit['BLOCK_DATE'] = (new DateTime())->add($limit['BLOCK_DATE'].' SECONDS');
ReplyBlock::add($session->getData('ID'), $chat, $limit);
}
elseif (ImConnectorConnector::isNeedToAutoDeleteBlock($params['connector']['connector_id']))
{
ReplyBlock::delete($session->getData('ID'), $chat);
}
$updateSession = [
'MESSAGE_COUNT' => true,
'DATE_LAST_MESSAGE' => new DateTime(),
];
if (!$finishSession && !$voteSession)
{
//$updateSession['STATUS'] = Session::STATUS_CLIENT;
$updateSession['INPUT_MESSAGE'] = true;
$updateSession['DATE_MODIFY'] = new DateTime;
$updateSession['USER_ID'] = $session->getData('USER_ID');
}
if (isset($params['extra']))
{
foreach($params['extra'] as $field => $value)
{
$oldValue = $session->getData($field);
if ($oldValue != $value)
{
$updateSession[$field] = $value;
}
}
}
$session->update($updateSession);
if (
$session->getConfig('AGREEMENT_MESSAGE') == 'Y'
&& !$session->chat->isNowCreated()
&& $session->getUser()
&& $session->getUser('USER_ID') == $params['message']['user_id']
&& $session->getUser('USER_CODE')
&& $session->getUser('AGREES') == 'N'
)
{
ImOpenLinesCommon::setUserAgrees([
'AGREEMENT_ID' => $session->getConfig('AGREEMENT_ID'),
'CRM_ACTIVITY_ID' => $session->getData('CRM_ACTIVITY_ID'),
'SESSION_ID' => $session->getData('SESSION_ID'),
'CONFIG_ID' => $session->getData('CONFIG_ID'),
'USER_CODE' => $session->getUser('USER_CODE'),
]);
}
$queueManager = Queue::initialization($session);
if ($queueManager)
{
$queueManager->automaticActionAddMessage($finishSession, $voteSession);
}
if (!$session->isNowCreated() && $finishSession === true)
{
$session->finish(true);
}
$this->callMessageTrigger($session, $messageId, $addMessage);
//In case it's not a vote message or system message we make a new record
if (!$voteSession && $params['message']['user_id'] != 0 && !User::getInstance($params['message']['user_id'])->isBot())
{
$kpi = new KpiManager($session->getData('ID'));
$kpi->addMessage([
'MESSAGE_ID' => $messageId,
'LINE_ID' => $session->getData('CONFIG_ID'),
'OPERATOR_ID' => $session->getData('OPERATOR_ID')
]);
}
$result = [
'SESSION_ID' => $session->isNowCreated()? $session->getData('ID'): 0,
'MESSAGE_ID' => $messageId
];
}
if (
!$resultLoadSession
&& $session->isCloseVote()
)
{
Im::addCloseVoteMessage($session->getData('CHAT_ID'), $session->getConfig('VOTE_TIME_LIMIT'));
}
}
$isAddMessage = true;
ToolsLock::getInstance()->delete($keyLock);
}
else
{
sleep($iteration);
}
}
while ($isAddMessage === false);
}
return $result;
}