1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
Sender.php
См. документацию.
1<?php
2
3namespace Bitrix\MessageService\Providers\Edna\WhatsApp;
4
5use Bitrix\Disk\File;
6use Bitrix\ImConnector\Library;
7use Bitrix\ImOpenLines\Im;
8use Bitrix\ImOpenLines\Session;
9use Bitrix\Main\Error;
10use Bitrix\Main\Loader;
11use Bitrix\Main\Result;
12use Bitrix\MessageService\Providers;
13use Bitrix\MessageService\Providers\Constants\InternalOption;
14
16{
17 public const AVAILABLE_CONTENT_TYPES = [
18 'image/jpeg' => 5 * 1024 * 1024,
19 'image/png' => 5 * 1024 * 1024,
20 'audio/aac' => 16 * 1024 * 1024,
21 'audio/mp4' => 16 * 1024 * 1024,
22 'audio/amr' => 16 * 1024 * 1024,
23 'audio/mpeg' => 16 * 1024 * 1024,
24 'audio/ogg' => 16 * 1024 * 1024,
25 'video/mp4' => 16 * 1024 * 1024,
26 'video/3gpp' => 16 * 1024 * 1024,
27 ];
28
29 public const DOCUMENT_MAX_FILE_SIZE = 100 * 1024 * 1024;
30
36
37 public function __construct(
42 )
43 {
44 parent::__construct($optionManager, $supportChecker, $utils);
45 $this->emoji = $emoji;
46
47 $this->connectorLine = new ConnectorLine($this->utils);
48 }
49
54
62 public function prepareMessageBodyForSave(string $text): string
63 {
64 return $this->emoji->convertEmoji($text, InternalOption::EMOJI_ENCODE);
65 }
66
68 {
69 $cascadeResult = new Result();
70 if (is_numeric($messageFields['MESSAGE_FROM']))
71 {
72 $cascadeResult = $this->utils->getCascadeIdFromSubject(
73 (int)$messageFields['MESSAGE_FROM'],
74 static function(array $externalSubjectData, int $internalSubject)
75 {
76 return $externalSubjectData['id'] === $internalSubject;
77 }
78 );
79 }
80 elseif (is_string($messageFields['MESSAGE_FROM']))
81 {
82 $cascadeResult = $this->utils->getCascadeIdFromSubject(
83 $messageFields['MESSAGE_FROM'],
84 static function(array $externalSubjectData, string $internalSubject)
85 {
86 return $externalSubjectData['subject'] === $internalSubject;
87 }
88 );
89 }
90 else
91 {
92 return $cascadeResult->addError(new Error('Invalid subject id'));
93 }
94
95 if (!$cascadeResult->isSuccess())
96 {
97 return $cascadeResult;
98 }
99
100 $messageFields['MESSAGE_BODY'] = $this->emoji->convertEmoji($messageFields['MESSAGE_BODY'], InternalOption::EMOJI_DECODE);
101
102 $params = [
103 'requestId' => uniqid('', true),
104 'cascadeId' => $cascadeResult->getData()['cascadeId'],
105 'subscriberFilter' => [
106 'address' => str_replace('+', '', $messageFields['MESSAGE_TO']),
107 'type' => 'PHONE',
108 ],
109 ];
110
111 $params['content'] = $this->getMessageContent($messageFields);
112 $result = new Result();
113 $result->setData($params);
114
115 return $result;
116 }
117
128 {
129 if (isset($messageFields['MESSAGE_HEADERS']['template']['text']))
130 {
131 return true;
132 }
133
134 return false;
135 }
136
142 {
143 $whatsAppContent =
145 ? $this->getHSMContent($messageFields)
146 : $this->getSimpleMessageContent($messageFields)
147 ;
148
149 return [
150 'whatsappContent' => $whatsAppContent
151 ];
152 }
153
158 private function getHSMContent(array $messageFields): array
159 {
160 $params = [
162 'text' => $messageFields['MESSAGE_HEADERS']['template']['text']
163 ];
164
165 foreach (['header', 'footer', 'keyboard'] as $templateField)
166 {
167 if (
168 isset($messageFields['MESSAGE_HEADERS']['template'][$templateField])
169 && count($messageFields['MESSAGE_HEADERS']['template'][$templateField]) > 0
170 )
171 {
172 $params[$templateField] = $messageFields['MESSAGE_HEADERS']['template'][$templateField];
173 }
174 }
175
176 return $this->emoji->convertEmojiInTemplate($params, InternalOption::EMOJI_DECODE);
177 }
178
183 private function getSimpleMessageContent(array $messageFields): array
184 {
185 $contentType = Constants::CONTENT_TYPE_TEXT;
186 $messageBody = $messageFields['MESSAGE_BODY'];
187
188 if (Loader::includeModule('disk') && preg_match('/^http.+~.+$/', trim($messageBody)))
189 {
190 $fileUri = \CBXShortUri::GetUri($messageBody);
191 if ($fileUri)
192 {
193 $parsedUrl = parse_url($fileUri['URI']);
194 $queryParams = [];
195 parse_str($parsedUrl['query'], $queryParams);
196 if (isset($queryParams['FILE_ID']))
197 {
198 $diskFile = \Bitrix\Disk\File::getById((int)$queryParams['FILE_ID']);
199 if ($diskFile)
200 {
201 $contentType = $this->determineContentType($diskFile);
202 $messageBody = $fileUri['URI'];
203 }
204 }
205 }
206 }
207
208 $content = [
209 'contentType' => $contentType
210 ];
211 switch ($contentType)
212 {
213 case Constants::CONTENT_TYPE_IMAGE:
214 case Constants::CONTENT_TYPE_AUDIO:
215 case Constants::CONTENT_TYPE_VIDEO:
216 case Constants::CONTENT_TYPE_DOCUMENT:
217 $content['attachment'] = [
218 'url' => $messageBody
219 ];
220 break;
221 case Constants::CONTENT_TYPE_TEXT:
222 default:
223 $content['text'] = $messageBody;
224 }
225
226 return $content;
227 }
228
229 private function determineContentType(File $diskFile): string
230 {
231 $contentType = Constants::CONTENT_TYPE_TEXT;
232 $file = $diskFile->getFile();
233
234 if (is_array($file) && isset($file['CONTENT_TYPE']))
235 {
236 if (isset(self::AVAILABLE_CONTENT_TYPES[$file['CONTENT_TYPE']]))
237 {
238 $maxSize = self::AVAILABLE_CONTENT_TYPES[$file['CONTENT_TYPE']];
239 if ($diskFile->getSize() <= $maxSize)
240 {
241 $contentType = Constants::CONTENT_TYPE_MAP[$diskFile->getTypeFile()] ?? Constants::CONTENT_TYPE_DOCUMENT;
242 }
243 elseif ($diskFile->getSize() <= self::DOCUMENT_MAX_FILE_SIZE)
244 {
245 $contentType = Constants::CONTENT_TYPE_DOCUMENT;
246 }
247 }
248 elseif ($diskFile->getSize() <= self::DOCUMENT_MAX_FILE_SIZE)
249 {
250 $contentType = Constants::CONTENT_TYPE_DOCUMENT;
251 }
252 }
253
254 return $contentType;
255 }
256
258 {
259 if (!Loader::includeModule('imopenlines') || !Loader::includeModule('imconnector'))
260 {
261 return (new Result())->addError(new Error('Missing modules imopenlines and imconnector'));
262 }
263
264 $externalChatId = str_replace('+', '', $messageFields['MESSAGE_TO']);
265 $userId = $this->getImconnectorUserId($externalChatId);
266 if (!$userId)
267 {
268 return (new Result())->addError(new Error('Missing User Id'));
269 }
270
271 $from = $messageFields['MESSAGE_FROM'];
272 $lineId = $this->connectorLine->getLineId((int)$from);
273 if (!$lineId)
274 {
275 return (new Result())->addError(new Error('Missing Line Id. Please reconfigure the open line'));
276 }
277
278 $userSessionCode = $this->getSessionUserCode($lineId, $externalChatId, $from, $userId);
279 $chatId = $this->getOpenedSessionChatId($userSessionCode);
280 if (!$chatId)
281 {
282 return (new Result())->addError(new Error('Missing Chat Id'));
283 }
284
285 $messageId = Im::addMessage([
286 'TO_CHAT_ID' => $chatId,
287 'MESSAGE' => $this->utils->prepareTemplateMessageText($messageFields),
288 'SYSTEM' => 'Y',
289 'SKIP_COMMAND' => 'Y',
290 'NO_SESSION_OL' => 'Y',
291 'PARAMS' => [
292 'CLASS' => 'bx-messenger-content-item-ol-output'
293 ],
294 ]);
295
296 $result = new Result();
297 $resultData = $messageFields;
298 $resultData['messageId'] = $messageId;
299 $resultData['chatId'] = $chatId;
300 $result->setData($resultData);
301
302 if (!$messageId)
303 {
304 $result->addError(new Error('Error sending a message to the chat'));
305 }
306 return $result;
307 }
308
309 protected function getImconnectorUserId(string $externalChatId): ?string
310 {
311 $userXmlId = Library::ID_EDNA_WHATSAPP_CONNECTOR . '|' . $externalChatId;
313 'select' => ['ID'],
314 'filter' => ['=XML_ID' => $userXmlId],
315 ]);
316
317 return $user ? $user['ID'] : null;
318 }
319
320 protected function getSessionUserCode(string $lineId, string $externalChatId, string $from, string $userId): string
321 {
322 return Library::ID_EDNA_WHATSAPP_CONNECTOR. '|'. $lineId. '|'. $externalChatId. '@'. $from. '|' . $userId;
323 }
324
325 protected function getOpenedSessionChatId(string $userSessionCode): ?string
326 {
327 $session = new Session();
328 $sessionLoadResult = $session->getLast(['USER_CODE' => $userSessionCode]);
329 if (!$sessionLoadResult->isSuccess())
330 {
331 return null;
332 }
333 $sessionData = $session->getData();
334 $chatId = $sessionData['CHAT_ID'];
335 $closed = $sessionData['CLOSED'] === 'Y';
336 if ($closed)
337 {
338 return null;
339 }
340
341 return $chatId;
342 }
343
345 {
346 return new ExternalSender(
347 $this->optionManager->getOption(InternalOption::API_KEY),
349 $this->optionManager->getSocketTimeout(),
350 $this->optionManager->getStreamTimeout()
351 );
352 }
353}
$messageFields
Определения callback_ednaru.php:22
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
Определения callback_ismscenter.php:26
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
Определения error.php:15
static getRow(array $parameters)
Определения datamanager.php:398
getSendMessageParams(array $messageFields)
Определения Sender.php:67
Providers OptionManager $optionManager
Определения Sender.php:31
getSessionUserCode(string $lineId, string $externalChatId, string $from, string $userId)
Определения Sender.php:320
__construct(Providers\OptionManager $optionManager, Providers\SupportChecker $supportChecker, Providers\Edna\EdnaRu $utils, EmojiConverter $emoji)
Определения Sender.php:37
sendHSMtoChat(array $messageFields)
Определения Sender.php:257
getOpenedSessionChatId(string $userSessionCode)
Определения Sender.php:325
prepareMessageBodyForSave(string $text)
Определения Sender.php:62
isTemplateMessage(array $messageFields)
Определения Sender.php:127
getSendMessageMethod(array $messageFields)
Определения Sender.php:50
getImconnectorUserId(string $externalChatId)
Определения Sender.php:309
Providers Edna EdnaRu $utils
Определения Sender.php:33
getMessageContent(array $messageFields)
Определения Sender.php:141
Providers SupportChecker $supportChecker
Определения Sender.php:32
static GetUri($shortUri)
Определения short_uri.php:84
$content
Определения commerceml.php:144
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$user
Определения mysql_to_pgsql.php:33
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$contentType
Определения quickway.php:301
$text
Определения template_pdf.php:79
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799