Current Path : /var/www/axolotl/data/www/voronezh.axolotls.ru/bitrix/modules/imconnector/lib/ |
Current File : /var/www/axolotl/data/www/voronezh.axolotls.ru/bitrix/modules/imconnector/lib/connector.php |
<?php namespace Bitrix\ImConnector; use \Bitrix\Main\Loader, \Bitrix\Main\Context, \Bitrix\Main\Page\Asset, \Bitrix\Main\Data\Cache, \Bitrix\Main\Type\DateTime, \Bitrix\Main\Config\Option, \Bitrix\Main\Web\Json, \Bitrix\Main\UserTable, \Bitrix\Main\Localization\Loc; use \Bitrix\ImOpenLines\Network, \Bitrix\ImOpenLines\LiveChatManager; use \Bitrix\ImConnector\Model\InfoConnectorsTable; use Bitrix\Main\Web\Uri; Loc::loadMessages(__FILE__); Library::loadMessages(); /** * Auxiliary class for work with connectors. * @package Bitrix\ImConnector */ class Connector { const ERROR_CHOICE_DOMAIN_FOR_FEEDBACK = 'CHOICE_DOMAIN_FOR_FEEDBACK'; /** * @param string $idConnector * @return \Bitrix\ImConnector\Connectors\Base * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function initializationConnectorHandler($idConnector = '') { $class = "Bitrix\\ImConnector\\Connectors\\Base"; if( !empty($idConnector) && self::isConnector($idConnector) ) { $realIdConnector = self::getConnectorRealId($idConnector); $className = 'Bitrix\\ImConnector\\Connectors\\' . $realIdConnector; if(class_exists($className)) { $class = $className; } } return new $class($idConnector); } /** * @return bool * @throws \Bitrix\Main\LoaderException */ public static function isLocationRussia() { $result = false; if( (Loader::includeModule('bitrix24') && \CBitrix24::getPortalZone() === 'ru') || (!Loader::includeModule('bitrix24') && Loader::includeModule('intranet') && \CIntranetUtils::getPortalZone() === "ru") ) { $result = true; } return $result; } /** * @return bool * @throws \Bitrix\Main\LoaderException */ public static function isLocationUkraine() { $result = false; if( (!Loader::includeModule('bitrix24') && Loader::includeModule('intranet') && \CIntranetUtils::getPortalZone() === "ua") || (Loader::includeModule('bitrix24') && \CBitrix24::getPortalZone() === 'ua') ) { $result = true; } return $result; } /** * @return bool * @throws \Bitrix\Main\LoaderException */ public static function isLocationPoland(): bool { $result = false; if (Loader::includeModule('bitrix24') && \CBitrix24::getPortalZone() === 'pl') { $result = true; } return $result; } /** * List of connectors, available on the client. connector id => connector Name. * @param bool|integer $reduced To shorten the channel names. * @param bool $customConnectors Return custom connectors * * @return array. * @throws \Bitrix\Main\LoaderException */ public static function getListConnector($reduced = false, $customConnectors = true) { $connectors['livechat'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_LIVECHAT'); $connectors['whatsappbytwilio'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_WHATSAPPBYTWILIO'); // avito available only in Russia if (self::isLocationRussia()) { $connectors['avito'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_AVITO'); } $connectors['viber'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_VIBER_BOT'); $connectors['telegrambot'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_TELEGRAM_BOT'); $connectors['imessage'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_IMESSAGE'); $connectors['wechat'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_WECHAT'); // disabled in UA if(!self::isLocationUkraine()) { $connectors["yandex"] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_YANDEX'); $connectors["vkgroup"] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_VK_GROUP'); } //enabled in UA, PL if (self::isLocationUkraine() || (self::isLocationPoland() || !Loader::includeModule('bitrix24'))) { $connectors['olx'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_OLX'); } $connectors['facebook'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FACEBOOK_PAGE'); $connectors['facebookcomments'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FACEBOOK_COMMENTS_PAGE'); $connectors['fbinstagram'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FBINSTAGRAM'); $connectors['network'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_NETWORK'); //Virtual connectors. $connectors['botframework.skype'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_SKYPE'); $connectors['botframework.slack'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_SLACK'); $connectors['botframework.kik'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_KIK'); $connectors['botframework.groupme'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_GROUPME'); $connectors['botframework.twilio'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_TWILIO'); $connectors['botframework.msteams'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_MSTEAMS'); $connectors['botframework.webchat'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_WEBCHAT'); $connectors['botframework.emailoffice365'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_EMAILOFFICE365'); $connectors['botframework.telegram'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_TELEGRAM'); $connectors['botframework.facebookmessenger'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_FACEBOOKMESSENGER'); $connectors['botframework.directline'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK_DIRECTLINE'); if($customConnectors === true) { $customConnectors = CustomConnectors::getListConnector(); if(!empty($customConnectors)) $connectors = array_merge($customConnectors, $connectors); } if(!empty($reduced)) { if($reduced>5) $number = $reduced; else $number = 30; foreach ($connectors as $cell=>$connector) { if(strlen($connector) > $number) $connectors[$cell] = substr($connector, 0, ($number-3)) . '...'; } } return $connectors; } /** * Real list of connectors, available on the client. connector id => connector Name. * @param bool|integer $reduced To shorten the channel names. * @param bool $customConnectors Return custom connectors * * @return array. * @throws \Bitrix\Main\LoaderException */ public static function getListConnectorReal($reduced = false, $customConnectors = true) { $connectors['livechat'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_LIVECHAT'); $connectors['whatsappbytwilio'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_WHATSAPPBYTWILIO'); // avito available only in Russia if (self::isLocationRussia()) { $connectors['avito'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_AVITO'); } $connectors['viber'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_VIBER_BOT'); $connectors['telegrambot'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_TELEGRAM_BOT'); $connectors['imessage'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_IMESSAGE'); $connectors['wechat'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_WECHAT'); // disabled in UA if(!self::isLocationUkraine()) { $connectors["yandex"] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_YANDEX'); $connectors["vkgroup"] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_VK_GROUP'); } //enabled in UA, PL if (self::isLocationUkraine() || (self::isLocationPoland() || !Loader::includeModule('bitrix24'))) { $connectors['olx'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_OLX'); } $connectors['facebook'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FACEBOOK_PAGE'); $connectors['facebookcomments'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FACEBOOK_COMMENTS_PAGE'); $connectors['fbinstagram'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_FBINSTAGRAM'); $connectors['network'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_NETWORK'); //Virtual connectors. $connectors['botframework'] = Loc::getMessage('IMCONNECTOR_NAME_CONNECTOR_BOTFRAMEWORK'); if($customConnectors === true) { $customConnectors = CustomConnectors::getListConnector(); if(!empty($customConnectors)) $connectors = array_merge($customConnectors, $connectors); } if(!empty($reduced)) { if($reduced>5) $number = $reduced; else $number = 30; foreach ($connectors as $cell=>$connector) { if(strlen($connector) > $number) $connectors[$cell] = substr($connector, 0, ($number-3)) . '...'; } } return $connectors; } /** * @param bool $customConnectors * @return array|string * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function getListConnectorActive($customConnectors = true) { $connectors = strtolower(Option::get(Library::MODULE_ID, "list_connector")); $connectors = explode(",", $connectors); if($customConnectors === true) $connectors = array_merge(CustomConnectors::getListConnectorId(), $connectors); return $connectors; } public static function getListConnectorNoServer() { return array_merge(Library::$noServerConnectors, CustomConnectors::getListConnectorId()); } /** * @return array * @throws \Bitrix\Main\LoaderException */ public static function getListConnectorShowDeliveryStatus() { return array_keys(static::getListConnector()); } /** * A list of matching id of the connector component. * * @return array. * @throws \Bitrix\Main\LoaderException */ public static function getListComponentConnector() { $components = array( 'livechat' => 'bitrix:imconnector.livechat', 'whatsappbytwilio' => 'bitrix:imconnector.whatsappbytwilio', 'olx' => 'bitrix:imconnector.olx', ); // avito available only in Russia if (!Loader::includeModule('bitrix24') || \CBitrix24::getPortalZone() === 'ru') { $components['avito'] = 'bitrix:imconnector.avito'; } // disabled in b24.ua if(!Loader::includeModule('bitrix24') || \CBitrix24::getPortalZone() !== 'ua') $components["yandex"] = 'bitrix:imconnector.yandex'; $components = array_merge($components, array( 'viber' => 'bitrix:imconnector.viber', 'telegrambot' => 'bitrix:imconnector.telegrambot', 'wechat' => 'bitrix:imconnector.wechat', "imessage" => 'bitrix:imconnector.imessage' )); // disabled in b24.ua if(!Loader::includeModule('bitrix24') || \CBitrix24::getPortalZone() !== 'ua') $components["vkgroup"] = 'bitrix:imconnector.vkgroup'; $components = array_merge($components, array( 'facebook' => 'bitrix:imconnector.facebook', 'facebookcomments' => 'bitrix:imconnector.facebookcomments', 'fbinstagram' => 'bitrix:imconnector.fbinstagram', 'network' => 'bitrix:imconnector.network', 'botframework' => 'bitrix:imconnector.botframework', )); $customComponents = CustomConnectors::getListComponentConnector(); if(!empty($customComponents)) $components = array_merge($customComponents, $components); return $components; } /** * List of connectors where you can delete other people's posts * * @return array */ public static function getListConnectorDelExternalMessages() { $listConnectorDelExternalMessages = Library::$listConnectorDelExternalMessages; $customConnectorDelExternalMessages = CustomConnectors::getListConnectorDelExternalMessages(); if(!empty($customConnectorDelExternalMessages)) $listConnectorDelExternalMessages = array_merge($customConnectorDelExternalMessages, $listConnectorDelExternalMessages); return $listConnectorDelExternalMessages; } /** * List of connectors where you can edit your posts * * @return array */ public static function getListConnectorEditInternalMessages() { $listConnectorEditInternalMessages = Library::$listConnectorEditInternalMessages; $customConnectorEditInternalMessages = CustomConnectors::getListConnectorEditInternalMessages(); if(!empty($customConnectorEditInternalMessages)) $listConnectorEditInternalMessages = array_merge($customConnectorEditInternalMessages, $listConnectorEditInternalMessages); return $listConnectorEditInternalMessages; } /** * List of connectors where you can delete your posts * * @return array */ public static function getListConnectorDelInternalMessages() { $listConnectorDelInternalMessages = Library::$listConnectorDelInternalMessages; $customConnectorDelInternalMessages = CustomConnectors::getListConnectorEditInternalMessages(); if(!empty($customConnectorDelInternalMessages)) $listConnectorDelInternalMessages = array_unique(array_merge($customConnectorDelInternalMessages, $listConnectorDelInternalMessages)); return $listConnectorDelInternalMessages; } /** * A list of connectors, where it is impossible to send a newsletter * * @return array */ public static function getListConnectorNotNewsletter() { $listNotNewsletterChats = Library::$listNotNewsletterChats; $customNotNewsletterChat = CustomConnectors::getListConnectorNotNewsletter(); if(!empty($customNotNewsletterChat)) $listNotNewsletterChats = array_unique(array_merge($customNotNewsletterChat, $listNotNewsletterChats)); return $listNotNewsletterChats; } /** * List of connectors where you can send newsletter * * @return array */ public static function getListConnectorNewsletter() { return array_diff(array_keys(static::getListConnector()), self::getListConnectorNotNewsletter()); } /** * Do I need to send system messages? * * @param string $id ID connector * @return bool */ public static function isNeedSystemMessages($id) { $listNotNeedSystemMessages = Library::$listNotNeedSystemMessages; $customNotNeedSystemMessages = CustomConnectors::getListNotNeedSystemMessages(); if(!empty($customNotNeedSystemMessages)) $listNotNeedSystemMessages = array_unique(array_merge($customNotNeedSystemMessages, $listNotNeedSystemMessages)); return !in_array($id, $listNotNeedSystemMessages); } /** * Whether to send a signature? * * @param string $id ID connector * @return bool */ public static function isNeedSignature($id) { $listNotNeedSignature = Library::$listNotNeedSignature; $customNotNeedSignature = CustomConnectors::getListNotNeedSignature(); if(!empty($customNotNeedSignature)) $listNotNeedSignature = array_unique(array_merge($customNotNeedSignature, $listNotNeedSignature)); return !in_array($id, $listNotNeedSignature); } /** * This chat group? * * @param string $id ID connector * @return bool */ public static function isChatGroup($id) { $listGroupChats = Library::$listGroupChats; $customGroupChats = CustomConnectors::getListChatGroup(); if(!empty($customGroupChats)) $listGroupChats = array_unique(array_merge($customGroupChats, $listGroupChats)); return in_array($id, $listGroupChats); } /** * Check that we can use message tracker on this chat messages * * @param $id * * @return bool */ public static function isTrackedChat($id) { $listSingleThreadGroupChats = Library::$listSingleThreadGroupChats; $isChatGroup = self::isChatGroup($id); return !$isChatGroup || $isChatGroup && in_array($id, $listSingleThreadGroupChats); } /** * This chat for newsletter? * * @param string $id ID connector * @return bool */ public static function isChatNewsletter($id) { $listConnectorNewsletter = self::getListConnectorNewsletter(); return in_array($id, $listConnectorNewsletter); } /** * The list are available also connectors, active on the client. * The connector has to be available on the client, it has to be included in settings and be supported on the server. * @param bool|integer $reduced To shorten the channel names. * @param bool $local * * @return array. */ public static function getListActiveConnector($reduced = false, $local = false) { $result = array(); foreach (self::getListConnector($reduced) as $id => $value) { if(self::isConnector($id, $local)) $result[$id] = $value; } return $result; } /** * The list are available also real connectors, active on the client. * The connector has to be available on the client, it has to be included in settings and be supported on the server. * @param bool|integer $reduced To shorten the channel names. * * @return array. */ public static function getListActiveConnectorReal($reduced = false) { $result = array(); foreach (self::getListConnectorReal($reduced) as $id => $value) { if(self::isConnector($id)) $result[$id] = $value; } return $result; } /** * Returns a list of connectors, ready for sharing. * * @param string $lineId ID Open Line. * @return array */ public static function getListConnectedConnector($lineId) { $result = array(); $listActiveConnector = self::getListActiveConnector(); foreach ($listActiveConnector as $id => $value) { if(Status::getInstance($id, $lineId)->isStatus()) $result[$id] = $value; } return $result; } /** * List of connectors displayed in the menu. * * @param bool|integer $reduced To shorten the channel names. * @return array */ public static function getListConnectorMenu($reduced = false) { $result = array(); foreach (self::getListConnectorReal($reduced) as $id => $value) { if(self::isConnector($id, true)) { $result[$id]['name'] = $value; if($reduced) $result[$id]['short_name'] = self::getNameConnector($value, $reduced); } } return $result; } /** * Returns a list of real connectors, ready for sharing. * * @param string $lineId ID Open Line. * @return array */ public static function getListConnectedConnectorReal($lineId) { $result = array(); $listActiveConnector = self::getListActiveConnectorReal(); foreach ($listActiveConnector as $id => $value) { if(Status::getInstance($id, $lineId)->isStatus()) $result[$id] = $value; } return $result; } /** * Returns a connector name. * * @param string $id ID connector. * @param bool|integer $reduced To shorten the channel names. * @return bool|mixed */ public static function getNameConnector($id, $reduced = false) { $listConnector = self::getListConnector($reduced); if(isset($listConnector[$id])) return $listConnector[$id]; else return false; } /** * Returns a real connector name. * * @param string $id ID connector. * @param bool|integer $reduced To shorten the channel names. * @return bool|mixed */ public static function getNameConnectorReal($id, $reduced = false) { $listConnector = self::getListConnectorReal($reduced); if(isset($listConnector[$id])) return $listConnector[$id]; else return false; } /** * Returns a real connector id. * * @param string $id ID connector. * @return string $id ID connector real. */ public static function getConnectorRealId($id) { $id = strtolower($id); $positionSeparator = strpos($id, '.'); if($positionSeparator != false) { $id = substr($id, 0, $positionSeparator); } return $id; } /** * Check of the connector. That it is included in settings is checked and supported by the server. * * @param string $id ID connector. * @param bool $local Not to check on a remote server. * @return bool * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function isConnector($id, $local = false) { $id = self::getConnectorRealId($id); $connectors = self::getListConnectorActive(); /*$noServerConnectors = self::getListConnectorNoServer();*/ if(in_array($id, $connectors)/* && (in_array($id, $noServerConnectors) || $local || Output::isConnector($id)->isSuccess())*/) return true; else return false; } /** * Returns the domain by default of the current client. * * @return string * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function getDomainDefault() { $uriOption = Option::get(Library::MODULE_ID, "uri_client"); if(!empty($uriOption)) { $uri = $uriOption; } elseif(defined('BX24_HOST_NAME') && !empty(BX24_HOST_NAME)) { $uri = (Context::getCurrent()->getRequest()->isHttps() ? 'https://' : 'http://') . BX24_HOST_NAME; } else { $uri = Library::getCurrentServerUrl(); } return $uri; } /** * Returns information about all connected connectors specific open line. * * @param string $id ID open line. * @return array. */ /*public static function infoConnectorsLine($id) { $result = array(); $cache = Cache::createInstance(); if ($cache->initCache(Library::CACHE_TIME_INFO_CONNECTORS_LINE, $id, Library::CACHE_DIR_INFO_CONNECTORS_LINE)) { $result = $cache->getVars(); } elseif ($cache->startDataCache()) { $rawInfo = Output::infoConnectorsLine($id); $infoConnectors = $rawInfo->getData(); if(!empty($infoConnectors)) { $result = array(); $connectors = self::getListActiveConnector(); foreach ($connectors as $idConnector=>$value) { if(!empty($infoConnectors[$idConnector])) { $result[$idConnector] = $infoConnectors[$idConnector]; if(empty($result[$idConnector]['name'])) $result[$idConnector]['name'] = $value; $result[$idConnector]['connector_name'] = $value; } } if(empty($result)) { $cache->abortDataCache(); } else { $cache->endDataCache($result); } } else { $cache->abortDataCache(); } } return $result; }*/ /** * Returns information about all connected connectors specific open line. * * @param $lineId * * @return array|mixed * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException * @throws \Bitrix\Main\LoaderException * @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\SystemException */ public static function infoConnectorsLine($lineId) { $result = array(); $info = InfoConnectors::infoConnectorsLine($lineId); if (!empty($info['DATA'])) { $result = Json::decode($info['DATA']); $expiresTime = new \Bitrix\Main\Type\DateTime($info['EXPIRES']); if ($expiresTime->getTimestamp() < time()) { InfoConnectors::addSingleLineUpdateAgent($info['LINE_ID'], Library::LOCAL_AGENT_EXEC_INTERVAL); } } else { $infoConnectors = InfoConnectors::addInfoConnectors($lineId); if (!empty($infoConnectors)) { if ($infoConnectors->isSuccess()) { $info = $infoConnectors->getData(); $result = Json::decode($info['DATA']); } } } return $result; } /** * Returns information about all connected connectors specific open line from connector server. * * @param $lineId * * @return array * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException * @throws \Bitrix\Main\LoaderException */ public static function getOutputInfoConnectorsLine($lineId) { $result = array(); $rawInfo = Output::infoConnectorsLine($lineId); $infoConnectors = $rawInfo->getData(); if(!empty($infoConnectors)) { $connectors = self::getListActiveConnector(); foreach ($connectors as $idConnector=>$value) { if(!empty($infoConnectors[$idConnector])) { $result[$idConnector] = $infoConnectors[$idConnector]; if(empty($result[$idConnector]['name'])) $result[$idConnector]['name'] = $value; $result[$idConnector]['connector_name'] = $value; } } } return $result; } /** * Returns the ID of the cache settings of the connector. * * @param string $line ID open line. * @param string $connector ID connector. * @return string ID for the cache. */ public static function getCacheIdConnector($line, $connector) { return $connector . '|' . $line; } /** * Resets the cache settings connectors open lines. * * @param string $line ID open line. * @param string $cacheId ID for the cache. */ public static function cleanCacheConnector($line, $cacheId) { $cache = Cache::createInstance(); $cache->clean($cacheId, Library::CACHE_DIR_COMPONENT); $cache->clean($line, Library::CACHE_DIR_INFO_CONNECTORS_LINE); } /** * Full resets the cache settings connectors open lines. */ public static function cleanFullCacheConnector() { $allConnector = Status::getInstanceAll(); foreach ($allConnector as $connector => $item) { foreach ($item as $line => $status) { self::cleanCacheConnector($line, self::getCacheIdConnector($line, $connector)); } } } /** * Return icon name for all connectors * * @return array */ public static function getIconClassMap() { $result = self::getConnectorIconMap(); $customConnectorsList = CustomConnectors::getListConnectorId(); foreach ($customConnectorsList as $customConnectorId) { $result[$customConnectorId] = $customConnectorId; } return $result; } /** * Return map "connector id" - "icon name" for UI-lib icon classes * Not an actual connector list - it's just a list of various names of actual connectors * * @return array */ public static function getConnectorIconMap() { return array( 'livechat' => 'livechat', 'yandex' => 'ya-dialogs', 'viber' => 'viber', 'telegrambot' => 'telegram', 'telegram' => 'telegram', 'imessage' => 'imessage', //apple 'vkgroup' => 'vk', 'vkgrouporder' => 'vk-order', 'facebook' => 'fb', 'wechat' => 'wechat', 'facebookcomments' => 'fb-comments', 'facebookmessenger' => 'fb-messenger', 'fbinstagram' => 'instagram-fb', 'network' => 'bitrix24', 'botframework' => 'microsoft', 'skypebot' => 'skype', 'skype' => 'skype', 'slack' => 'slack', 'kik' => 'kik', 'groupme' => 'groupme', 'twilio' => 'twilio', 'emailoffice365' => 'outlook', 'webchat' => 'webchat', 'msteams' => 'envelope', 'whatsappbytwilio' => 'whatsapp', 'avito' => 'avito', 'olx' => 'olx', 'directline' => 'directline', 'botframework.skype' => 'skype', 'botframework.slack' => 'slack', 'botframework.kik' => 'kik', 'botframework.telegram' => 'telegram', 'botframework.groupme' => 'groupme', 'botframework.twilio' => 'twilio', 'botframework.emailoffice365' => 'outlook', 'botframework.facebookmessenger' => 'fb-messenger', 'botframework.webchat' => 'webchat', 'botframework.msteams' => 'envelope', 'botframework.directline' => 'directline' ); } /** * Returns icon name for current connector * * @param $connectorId * @return mixed */ public static function getIconByConnector($connectorId) { $iconMap = self::getIconClassMap(); return $iconMap[$connectorId]; } /** * Return additional css-style string * * @return string */ public static function getAdditionalStyles() { $style = CustomConnectors::getStyleCss(); //$style .= self::getServicesBackgroundColorCss(); return $style; } /** * Inits icon UI-lib and custom connector active icon styles */ public static function initIconCss() { \Bitrix\Main\UI\Extension::load("ui.icons"); $iconStyle = self::getAdditionalStyles(); if(!empty($iconStyle)) { Asset::getInstance()->addString('<style>' . $iconStyle . '</style>', true); } } /** * @deprecated * * @return string */ public static function getServicesBackgroundColorCss() { $style = ''; $cssFile = (file_exists($_SERVER['DOCUMENT_ROOT'].'/bitrix/js/ui/icons/service/ui.icons.service.css') ? '/bitrix/js/ui/icons/service/ui.icons.service.css' : '/bitrix/js/ui/icons/ui.icons.css'); $cssFilePath = $_SERVER["DOCUMENT_ROOT"] . $cssFile; $cssFile = file_get_contents($cssFilePath); if (!empty($cssFile)) { $cssList = \Bitrix\Main\Web\DOM\CssParser::parse($cssFile); if (!empty($cssList)) { $column = array_column($cssList, 'SELECTOR'); $connectorList = self::getConnectorIconMap(); foreach ($connectorList as $key => $connector) { $position = array_search('.ui-icon-service-' . $connector . ' > i', $column); if ($position !== false) { $style .= '.imconnector-' . $key . '-background-color { background-color: ' . $cssList[$position]['STYLE']['background-color'] . '; }' . PHP_EOL; $style .= '.intranet-' . $key . '-background-color { background-color: ' . $cssList[$position]['STYLE']['background-color'] . '; }' . PHP_EOL; } } } } return $style; } /** * Inits icon UI-lib and custom connector disabled icon styles */ public static function initIconDisabledCss() { \Bitrix\Main\UI\Extension::load("ui.icons"); $iconStyle = CustomConnectors::getStyleCssDisabled(); if(!empty($iconStyle)) { Asset::getInstance()->addString('<style>' . $iconStyle . '</style>', true); } } /** * Adding a channel is an open line. * * @param string $line ID open line. * @param string $connector ID open line. * @param array $params Settings. * @return Result The result of the addition. */ public static function add($line, $connector, $params = array()) { $result = new Result(); if(empty($line) || empty($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_EMPTY_PARAMETRS'), Library::ERROR_IMCONNECTOR_EMPTY_PARAMETRS, __METHOD__, array('line' => $line, 'connector' => $connector, 'params' => $params))); } else { if(!self::isConnector($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_NOT_AVAILABLE_CONNECTOR'), Library::ERROR_NOT_AVAILABLE_CONNECTOR, __METHOD__, $connector)); } else { $status = Status::getInstance($connector, $line); $cacheId = self::getCacheIdConnector($line, $connector); if($status->getActive()) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_ADD_EXISTING_CONNECTOR'), Library::ERROR_ADD_EXISTING_CONNECTOR, __METHOD__, $connector)); if($result->isSuccess()) { switch ($connector) { case 'livechat': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $liveChatManager = new LiveChatManager($line); if (!$liveChatManager->add($params)) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_ADD_CONNECTOR'), Library::ERROR_FAILED_TO_ADD_CONNECTOR, __METHOD__, $connector)); } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } break; case 'network': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $network = new Network(); $resultRegister = $network->registerConnector($line, $params); if (!$resultRegister) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_ADD_CONNECTOR'), Library::ERROR_FAILED_TO_ADD_CONNECTOR, __METHOD__, $connector)); else $status->setData($resultRegister); } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } break; case 'telegrambot': case 'botframework': $output = new Output($connector, $line); $saved = $output->saveSettings($params); if($saved->isSuccess()) { $status->setActive(true); $testConnect = $output->testConnect(); if($testConnect->isSuccess()) { $status->setConnection(true); $register = $output->register(); if(!$register->isSuccess()) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_REGISTER_CONNECTOR'), Library::ERROR_FAILED_REGISTER_CONNECTOR, __METHOD__, $connector)); $result->addErrors($testConnect->getErrors()); } } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_TEST_CONNECTOR'), Library::ERROR_FAILED_TO_TEST_CONNECTOR, __METHOD__, $connector)); $result->addErrors($testConnect->getErrors()); } } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_SAVE_SETTINGS_CONNECTOR'), Library::ERROR_FAILED_TO_SAVE_SETTINGS_CONNECTOR, __METHOD__, $connector)); $result->addErrors($saved->getErrors()); } break; case 'vkgroup': case 'facebook': case 'facebookcomments': case Library::ID_FBINSTAGRAM_CONNECTOR: default: $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FEATURE_IS_NOT_SUPPORTED'), Library::ERROR_FEATURE_IS_NOT_SUPPORTED, __METHOD__, $connector)); break; } } if($result->isSuccess()) { $status->setActive(true); $status->setConnection(true); $status->setRegister(true); $status->setError(false); Status::save(); Status::sendUpdateEvent(); } self::cleanCacheConnector($line, $cacheId); } } return $result; } /** * Update a channel is an open line. * * @param string $line ID open line. * @param string $connector ID open line. * @param array $params Settings. * @return Result The result of the addition. */ public static function update($line, $connector, $params = array()) { $result = new Result(); if(empty($line) || empty($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_EMPTY_PARAMETRS'), Library::ERROR_IMCONNECTOR_EMPTY_PARAMETRS, __METHOD__, array('line' => $line, 'connector' => $connector, 'params' => $params))); } else { if(!self::isConnector($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_NOT_AVAILABLE_CONNECTOR'), Library::ERROR_NOT_AVAILABLE_CONNECTOR, __METHOD__, $connector)); } else { $status = Status::getInstance($connector, $line); $cacheId = self::getCacheIdConnector($line, $connector); if(!$status->getActive()) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_UPDATE_NOT_EXISTING_CONNECTOR'), Library::ERROR_UPDATE_NOT_EXISTING_CONNECTOR, __METHOD__, $connector)); if($result->isSuccess()) { switch ($connector) { case 'livechat': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $liveChatManager = new LiveChatManager($line); if (!$liveChatManager->update($params)) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_UPDATE_CONNECTOR'), Library::ERROR_FAILED_TO_UPDATE_CONNECTOR, __METHOD__, $connector)); } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } if(!$result->isSuccess()) { $status->setConnection(false); $status->setRegister(false); } break; case 'network': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $network = new Network(); if (!$network->updateConnector($line, $params)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_UPDATE_CONNECTOR'), Library::ERROR_FAILED_TO_UPDATE_CONNECTOR, __METHOD__, $connector)); } else { $dataStatus = $status->getData(); $dataStatus = array_merge($dataStatus, $params); $status->setData($dataStatus); } } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } if(!$result->isSuccess()) { $status->setConnection(false); $status->setRegister(false); } break; case 'telegrambot': case 'botframework': $output = new Output($connector, $line); $saved = $output->saveSettings($params); if($saved->isSuccess()) { $testConnect = $output->testConnect(); if($testConnect->isSuccess()) { $status->setConnection(true); $register = $output->register(); if(!$register->isSuccess()) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_REGISTER_CONNECTOR'), Library::ERROR_FAILED_REGISTER_CONNECTOR, __METHOD__, $connector)); $result->addErrors($testConnect->getErrors()); $status->setRegister(false); } } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_TEST_CONNECTOR'), Library::ERROR_FAILED_TO_TEST_CONNECTOR, __METHOD__, $connector)); $result->addErrors($testConnect->getErrors()); $status->setConnection(false); } } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_SAVE_SETTINGS_CONNECTOR'), Library::ERROR_FAILED_TO_SAVE_SETTINGS_CONNECTOR, __METHOD__, $connector)); $result->addErrors($saved->getErrors()); $status->setConnection(false); $status->setRegister(false); } break; case 'vkgroup': case 'facebook': case 'facebookcomments': case Library::ID_FBINSTAGRAM_CONNECTOR: default: $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FEATURE_IS_NOT_SUPPORTED'), Library::ERROR_FEATURE_IS_NOT_SUPPORTED, __METHOD__, $connector)); break; } } if($result->isSuccess()) { $status->setActive(true); $status->setConnection(true); $status->setRegister(true); } $status->setError(false); Status::save(); Status::sendUpdateEvent(); self::cleanCacheConnector($line, $cacheId); } } return $result; } /** * Delete a channel is an open line. * * @param string $line ID open line. * @param string $connector ID open line. * @return Result The result of the addition. */ public static function delete($line, $connector) { $result = new Result(); if(empty($line) || empty($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_EMPTY_PARAMETRS'), Library::ERROR_IMCONNECTOR_EMPTY_PARAMETRS, __METHOD__, array('line' => $line, 'connector' => $connector))); } else { if(!self::isConnector($connector)) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_NOT_AVAILABLE_CONNECTOR'), Library::ERROR_NOT_AVAILABLE_CONNECTOR, __METHOD__, $connector)); } else { $status = Status::getInstance($connector, $line); $cacheId = self::getCacheIdConnector($line, $connector); if(!$status->getActive()) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_DELETE_NOT_EXISTING_CONNECTOR'), Library::ERROR_DELETE_NOT_EXISTING_CONNECTOR, __METHOD__, $connector)); if($result->isSuccess()) { switch ($connector) { case 'livechat': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $liveChatManager = new LiveChatManager($line); if (!$liveChatManager->delete()) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_DELETE_CONNECTOR'), Library::ERROR_FAILED_TO_DELETE_CONNECTOR, __METHOD__, $connector)); } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } break; case 'network': if(Loader::includeModule(Library::MODULE_ID_OPEN_LINES)) { $network = new Network(); if (!$network->unRegisterConnector($line)) $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_DELETE_CONNECTOR'), Library::ERROR_FAILED_TO_DELETE_CONNECTOR, __METHOD__, $connector)); } else { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_LOAD_MODULE_OPEN_LINES'), Library::ERROR_FAILED_TO_LOAD_MODULE_OPEN_LINES, __METHOD__, $connector)); } break; case 'facebook': case 'vkgroup': case 'telegrambot': case 'botframework': case 'facebookcomments': case Library::ID_FBINSTAGRAM_CONNECTOR: case 'avito': case 'wechat': case 'imessage': $output = new Output($connector, $line); $rawDelete = $output->deleteConnector(); if(!$rawDelete->isSuccess()) { $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FAILED_TO_DELETE_CONNECTOR'), Library::ERROR_FAILED_TO_DELETE_CONNECTOR, __METHOD__, $connector)); $result->addErrors($rawDelete->getErrors()); } break; default: $result->addError(new Error(Loc::getMessage('IMCONNECTOR_FEATURE_IS_NOT_SUPPORTED'), Library::ERROR_FEATURE_IS_NOT_SUPPORTED, __METHOD__, $connector)); break; } } if($result->isSuccess()) { Status::delete($connector, $line); } self::cleanCacheConnector($line, $cacheId); } } return $result; } /** * @param array $user * @param string $connector * @return Result * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException * @throws \Bitrix\Main\ObjectPropertyException * @throws \Bitrix\Main\SystemException */ public static function getUserByUserCode(array $user, string $connector): Result { $result = new Result(); if (Library::isEmpty($user['id'])) { $result->addError(new Error(Loc::getMessage( 'IMCONNECTOR_PROXY_NO_USER_IM'), Library::ERROR_CONNECTOR_PROXY_NO_USER_IM, __METHOD__, $user )); } else { $raw = UserTable::getList([ 'select' => [ 'ID', 'MD5' => 'UF_CONNECTOR_MD5' ], 'filter' => [ '=EXTERNAL_AUTH_ID' => Library::NAME_EXTERNAL_USER, '=XML_ID' => $connector . '|' . $user['id'] ], 'limit' => 1 ] ); if ($userFields = $raw->fetch()) { $result->setResult($userFields); } else { $result->addError(new Error(Loc::getMessage( 'IMCONNECTOR_PROXY_NO_USER_IM'), Library::ERROR_CONNECTOR_PROXY_NO_USER_IM, __METHOD__, [$user, $connector] )); } } return $result; } /** * Get reply limit for connector, if the limit exists. * * @param string $connectorId Connector ID. * @return array|null * @throws \Bitrix\Main\ObjectException */ public static function getReplyLimit(string $connectorId): ?array { $result = null; if (isset(Library::TIME_LIMIT_RESTRICTIONS[$connectorId]) && Library::TIME_LIMIT_RESTRICTIONS[$connectorId]['LIMIT_START_DATE'] < (new DateTime())->getTimestamp() ) { $result = Library::TIME_LIMIT_RESTRICTIONS[$connectorId]; } return $result; } /** * Returns true if we need to delete block after incoming message. * * @param string $connectorId * @return bool */ public static function isNeedToAutoDeleteBlock(string $connectorId): bool { if (in_array($connectorId, Library::AUTO_DELETE_BLOCK, true)) { return true; } return false; } /** * Prepares attachments data to send. * * @param array $message * @return array|null * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function sendMessageProcessing(array $message): array { $richData = []; if (!empty($message['message']['attachments']) && is_array($message['message']['attachments'])) { foreach ($message['message']['attachments'] as $attachment) { $attachment = \Bitrix\Main\Web\Json::decode($attachment); if (isset($attachment['BLOCKS']) && is_array($attachment['BLOCKS'])) { foreach ($attachment['BLOCKS'] as $block) { if (isset($block['RICH_LINK']) && is_array($block['RICH_LINK'])) { foreach ($block['RICH_LINK'] as $richData) { if (!empty($richData)) { if ($richData['LINK']) { $richData['richData']['url'] = $richData['LINK']; } if ($richData['NAME']) { $richData['richData']['title'] = $richData['NAME']; } if ($richData['DESC']) { $richData['richData']['description'] = $richData['DESC']; } if ($richData['PREVIEW']) { $uri = new Uri($richData['PREVIEW']); if ($uri->getHost()) { $richData['richData']['image'] = $richData['PREVIEW']; } else { $richData['richData']['image'] = self::getDomainDefault() .'/'. $richData['PREVIEW']; } } elseif($richData['EXTRA_IMAGE']) { $richData['richData']['image'] = $richData['EXTRA_IMAGE']; } } } } } } } } $message['message']['attachments'] = $richData; return $message; } }