• Модуль: imopenlines
  • Путь к файлу: ~/bitrix/modules/imopenlines/lib/connector.php
  • Класс: BitrixImOpenLinesConnector
  • Вызов: Connector::onMessageSend
static function onMessageSend($messageId, $messageFields)
{
	$chatEntityType = $messageFields['CHAT_ENTITY_TYPE'] ?? null;
	if ($chatEntityType !== 'LINES')
	{
		return false;
	}

	$messageFields['MESSAGE_ID'] = $messageId;
	Log::write($messageFields, 'CONNECTOR MESSAGE SEND');

	if ($messageFields['AUTHOR_ID'] > 0)
	{
		$user = User::getInstance($messageFields['AUTHOR_ID']);
		if ($user->isConnector())
		{
			return false;
		}
	}

	if (
		$messageFields['IMPORTANT_CONNECTOR'] !== 'Y'
		&&
		(
			$messageFields['SILENT_CONNECTOR'] === 'Y'
			|| $messageFields['CHAT_'.Chat::getFieldName(Chat::FIELD_SILENT_MODE)] === 'Y'
		)
	)
	{
		CIMMessageParam::Set($messageId, ['CLASS' => 'bx-messenger-content-item-system']);
		CIMMessageParam::SendPull($messageId, ['CLASS']);
		return false;
	}

	if (
		isset($messageFields['SKIP_CONNECTOR'])
		&& $messageFields['SKIP_CONNECTOR'] === 'Y'
	)
	{
		return false;
	}

	if (
		$messageFields['IMPORTANT_CONNECTOR'] !== 'Y'
		&& isset($messageFields['SYSTEM'])
		&& $messageFields['SYSTEM'] === 'Y'
	)
	{
		return false;
	}

	//TODO: Replace with the method ImOpenLinesChat::parseLinesChatEntityId or ImOpenLinesChat::parseLiveChatEntityId
	[$connectorId, $lineId, $connectorChatId, $connectorUserId] = explode('|', $messageFields['CHAT_ENTITY_ID']);

	$event = new Event('imopenlines', self::EVENT_IMOPENLINE_MESSAGE_SEND, $messageFields);
	$event->send();

	$eventMessageFields = $event->getParameters();
	if (!empty($eventMessageFields['MESSAGE']))
	{
		$messageFields['MESSAGE'] = $eventMessageFields['MESSAGE'];
	}
	if (!empty($eventMessageFields['PARAMS']))
	{
		$messageFields['PARAMS'] = $eventMessageFields['PARAMS'];
	}

	if ($connectorId === self::TYPE_LIVECHAT)
	{
		$resultLoadSession = false;

		if (isset($messageFields['PARAMS']['CLASS']))
		{
			$messageFields['PARAMS']['CLASS'] = str_replace('bx-messenger-content-item-ol-output', "", $messageFields['PARAMS']['CLASS']);
		}

		$params = [];
		$allowedFields = ['CLASS', 'TYPE', 'COMPONENT_ID', 'CRM_FORM_ID', 'CRM_FORM_SEC', 'CRM_FORM_FILLED', 'url', 'fromSalescenterApplication', 'richUrlPreview'];

		foreach ($messageFields['PARAMS'] as $key => $value)
		{
			if (in_array($key, $allowedFields))
			{
				$params[$key] = $value;
			}
			elseif (mb_strpos($key, 'IMOL_') === 0)
			{
				$params[$key] = $value;
			}
			elseif (mb_strpos($key, 'IS_') === 0)
			{
				$params[$key] = $value;
			}
			elseif ($key === 'FILE_ID')
			{
				foreach ($value as $fileId)
				{
					$messageFields['MESSAGE'] .= ' [DISK='.$fileId.']';
				}
			}
		}

		$message = [
			'TO_CHAT_ID' => $connectorChatId,
			'FROM_USER_ID' => $messageFields['AUTHOR_ID'],
			'SYSTEM' => $messageFields['SYSTEM'],
			'URL_PREVIEW' => $messageFields['URL_PREVIEW'],
			'ATTACH' => $messageFields['ATTACH'],
			'PARAMS' => $params,
			'SKIP_USER_CHECK' => 'Y',
			'SKIP_COMMAND' => 'Y',
			'SKIP_CONNECTOR' => 'Y',
			'EXTRA_PARAMS' => [
				'CONTEXT' => 'LIVECHAT',
				'LINE_ID' => $lineId
			],
		];
		if (array_key_exists('MESSAGE', $messageFields))
		{
			$message['MESSAGE'] = $messageFields['MESSAGE'];
		}

		if (empty($messageFields['NO_SESSION_OL']) || $messageFields['NO_SESSION_OL'] !== 'Y')
		{
			$session = new Session();
			$resultLoadSession = $session->load([
				'MODE' => Session::MODE_OUTPUT,
				'USER_CODE' => $messageFields['CHAT_ENTITY_ID'],
				'OPERATOR_ID' => $messageFields['AUTHOR_ID']
			]);

			if ($resultLoadSession)
			{
				$updateSession = [
					'MESSAGE_COUNT' => true,
					'DATE_LAST_MESSAGE' => new DateTime(),
					'DATE_MODIFY' => new DateTime(),
					'USER_ID' => $messageFields['AUTHOR_ID'],
				];
				if ($messageFields['SYSTEM'] === 'Y')
				{
					$updateSession['SKIP_CHANGE_STATUS'] = true;
				}
				if (
					!$session->getData('DATE_FIRST_ANSWER') &&
					!empty($session->getData('OPERATOR_ID')) &&
					Queue::isRealOperator($session->getData('OPERATOR_ID'))
				)
				{
					$currentTime = new DateTime();
					$updateSession['DATE_FIRST_ANSWER'] = $currentTime;
					$updateSession['TIME_FIRST_ANSWER'] = $currentTime->getTimestamp()-$session->getData('DATE_CREATE')->getTimestamp();
				}

				$eventData = [
					'STATUS_BEFORE' => $session->getData('STATUS'),
					'CHAT_ENTITY_ID' => $messageFields['CHAT_ENTITY_ID'],
					'AUTHOR_ID' => $messageFields['AUTHOR_ID']
				];
				$session->update($updateSession);
				$eventData['STATUS_AFTER'] = $session->getData('STATUS');
				QueueEvent::checkFreeSlotBySendMessage($eventData);

				//for livechat only condition
				if (
					$messageFields['SYSTEM'] !== 'Y'
					&& !User::getInstance($session->getData('OPERATOR_ID'))->isBot()

				)
				{
					KpiManager::setSessionLastKpiMessageAnswered($session->getData('ID'));
				}
			}
		}

		if (
			!empty($connectorChatId)
			&& $connectorChatId > 0
			&& Loader::includeModule('imconnector')
		)
		{
			//Processing for native messages
			$interactiveMessage = InteractiveMessageOutput::getInstance($messageFields['TO_CHAT_ID'], ['connectorId' => self::TYPE_LIVECHAT]);
			$message = $interactiveMessage->nativeMessageProcessing($message);
		}

		$mid = Im::addMessage($message);
		if (
			$messageId
			&& $mid
			&& (
				$messageFields['NO_SESSION_OL'] === 'Y'
				|| $resultLoadSession
			)
		)
		{
			$paramsMessageLiveChat = ['CONNECTOR_MID' => $messageId];

			if (
				isset($session)
				&& $session instanceof Session
				&& $resultLoadSession
			)
			{
				$userData = Queue::getUserData($session->getData('CONFIG_ID'), $messageFields['AUTHOR_ID'], true);

				if (!empty($userData))
				{
					$paramsMessageLiveChat['NAME'] = $userData['NAME'];
				}

				//TODO: remove code duplication.
				//Automatic messages
				(new AutomaticAction($session))->automaticSendMessage($messageId);
			}

			CIMMessageParam::set($messageId, ['CONNECTOR_MID' => $mid]);
			CIMMessageParam::sendPull($messageId, ['CONNECTOR_MID']);
			CIMMessageParam::set($mid, $paramsMessageLiveChat);
			CIMMessageParam::sendPull($mid, array_keys($paramsMessageLiveChat));
		}
		if (
			$messageFields['NO_SESSION_OL'] !== 'Y'
			&& isset($session)
			&& $session instanceof Session
			&& $resultLoadSession
		)
		{
			ImOpenLinesMail::addSessionToMailQueue($session->getData('ID'), false);
		}
	}
	else
	{
		if (
			isset($messageFields['SYSTEM'])
			&& $messageFields['SYSTEM'] === 'Y'
			&& !self::isEnableSendSystemMessage($connectorId)
		)
		{
			return false;
		}

		$params = [];
		$allowedFields = ['CLASS', 'url', 'fromSalescenterApplication', 'richUrlPreview'];
		foreach ($messageFields['PARAMS'] as $key => $value)
		{
			if (in_array($key, $allowedFields))
			{
				$params[$key] = $value;
			}
			elseif (mb_strpos($key, 'IMOL_') === 0)
			{
				$params[$key] = $value;
			}
			elseif (mb_strpos($key, 'IS_') === 0)
			{
				$params[$key] = $value;
			}
		}

		$attaches = [];
		if (isset($messageFields['PARAMS']['ATTACH']))
		{
			foreach ($messageFields['PARAMS']['ATTACH'] as $attach)
			{
				if ($attach instanceof CIMMessageParamAttach)
				{
					$attaches[] = $attach->getJson();
				}
			}
		}

		$files = [];
		if (
			!empty($messageFields['FILES'])
			&& is_array($messageFields['FILES'])
			&& Loader::includeModule('disk')
		)
		{
			foreach ($messageFields['FILES'] as $file)
			{
				$fileModel = DiskFile::loadById($file['id']);
				if (!$fileModel)
				{
					continue;
				}

				$file['link'] = CIMDisk::GetFileLink($fileModel);
				if (!$file['link'])
				{
					continue;
				}

				$source = $fileModel->getFile();

				$file['mime'] = $source['CONTENT_TYPE'] ?? DiskTypeFile::getMimeTypeByFilename($file['name']);
				$file['sizef'] = CFile::FormatSize($file['size']);

				if (DiskTypeFile::isImage($fileModel))
				{
					$files[] = [
						'name' => $file['name'],
						'type' => $file['type'],
						'mime' => $file['mime'],
						'link' => $file['link'],
						'width' => $source["WIDTH"],
						'height' => $source["HEIGHT"],
						'size' => $file['size'],
						'sizef' => $file['sizef'],
					];
				}
				else
				{
					$files[] = [
						'name' => $file['name'],
						'type' => $file['type'],
						'mime' => $file['mime'],
						'link' => $file['link'],
						'size' => $file['size'],
						'sizef' => $file['sizef'],
					];
				}
			}
		}

		if (
			empty($attaches)
			&& empty($files)
			&& empty($messageFields['MESSAGE'])
			&& $messageFields['MESSAGE'] !== "0"
			&& empty($params['url'])
		)
		{
			return false;
		}

		if (
			(empty($messageFields['SYSTEM']) || $messageFields['SYSTEM'] !== 'Y')
			&& isset($messageFields['AUTHOR_ID'], $messageFields['MESSAGE'])
			&& (int)$messageFields['AUTHOR_ID'] > 0
			&& self::isEnableSendMessageWithSignature($connectorId, $lineId)
			&& !self::isNeedRichLinkData($connectorId, $messageFields['MESSAGE'])
		)
		{
			$messageFields['MESSAGE'] =
				'[b]' . htmlspecialchars_decode(self::getOperatorName($lineId, $messageFields['AUTHOR_ID'], $messageFields['CHAT_ENTITY_ID'])) . ':[/b]'.
				($messageFields['MESSAGE'] !== '' ? '[br]'. $messageFields['MESSAGE'] : '');
		}

		$fields = [
			'connector' => [
				'connector_id' => $connectorId,
				'line_id' => $lineId,
				'user_id' => $connectorUserId,
				'chat_id' => $connectorChatId,
			],
			'message' => [
				'id' => $messageId,
				'chat_id' => $messageFields['TO_CHAT_ID'],
				'user_id' => $messageFields['FROM_USER_ID'],
				'text' => $messageFields['MESSAGE'] ?? '',
				'files' => $files,
				'attachments' => $attaches,
				'params' => $params,
				'system' => $messageFields['SYSTEM'] ?? 'N',
			],
			'no_session' => $messageFields['NO_SESSION_OL'] ?? 'N',
		];

		if (in_array($connectorId, self::getListShowDeliveryStatus()))
		{
			CIMMessageParam::Set(
				$messageId,
				[
					'SENDING' => 'Y',
					'SENDING_TS' => time()
				]
			);
			CIMMessageParam::SendPull(
				$messageId,
				[
					'SENDING',
					'SENDING_TS'
				]
			);
		}

		$resultSendMessage = (new self())->sendMessage($fields);
		if (!$resultSendMessage->isSuccess())
		{
			$isErrorLineDeactivated = $resultSendMessage->getErrorCollection()->get('IMOPENLINES_ERROR_LINE_DEACTIVATED');
			if (!$isErrorLineDeactivated)
			{
				Im::addMessage([
					'TO_CHAT_ID' => $messageFields['TO_CHAT_ID'],
					'MESSAGE' => Loc::getMessage('IMOL_CHAT_ERROR_CONNECTOR_SEND'),
					'SYSTEM' => 'Y',
				]);
			}

			return false;
		}
	}

	return true;
}