Skip to content

Commit 94f6a35

Browse files
committed
Связка Notifier и SMS событий Битрикса
1 parent a12acdf commit 94f6a35

File tree

5 files changed

+243
-11
lines changed

5 files changed

+243
-11
lines changed

lib/Bitrix/BitrixMailEventSender.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace Proklung\Notifier\Bitrix;
44

55
use Bitrix\Main\ArgumentException;
6+
use Bitrix\Main\Mail\Internal\EventTable;
67
use Bitrix\Main\ObjectPropertyException;
78
use Bitrix\Main\SystemException;
9+
use Exception;
810
use Symfony\Component\Notifier\Notification\Notification;
911
use Symfony\Component\Notifier\NotifierInterface;
1012
use Symfony\Component\Notifier\Recipient\Recipient;
@@ -79,6 +81,25 @@ public function send(string $codeEvent, array $arFields, ?string $importance = n
7981
$recipient = new Recipient($compileData['mail_to']);
8082

8183
$this->notifier->send($notification, $recipient);
84+
85+
// Эмуляция поведения Битрикса при обработке событий.
86+
try {
87+
EventTable::add(
88+
[
89+
'EVENT_NAME' => $eventInfo->getEventCode(),
90+
'SUCCESS_EXEC' => 'Y',
91+
'MESSAGE_ID' => 99999, // Признак, что отправлено через Notifier
92+
'DUPLICATE' => 'N',
93+
'LID' => SITE_ID,
94+
'LANGUAGE_ID' => LANGUAGE_ID,
95+
'DATE_INSERT' => new \Bitrix\Main\Type\DateTime,
96+
'DATE_EXEC' => new \Bitrix\Main\Type\DateTime,
97+
'C_FIELDS' => $eventInfo->getMessageData(),
98+
]
99+
);
100+
} catch (Exception $e) {
101+
// Silence. Не самый важный момент.
102+
}
82103
}
83104
}
84105
}

lib/Bitrix/BitrixSmsSender.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace Proklung\Notifier\Bitrix;
4+
5+
use Bitrix\Main\ArgumentException;
6+
use Bitrix\Main\Mail\Internal\EventTable;
7+
use Bitrix\Main\ObjectPropertyException;
8+
use Bitrix\Main\SystemException;
9+
use Bitrix\Main\Type\DateTime;
10+
use Exception;
11+
use RuntimeException;
12+
use Symfony\Component\Notifier\Exception\TransportExceptionInterface;
13+
use Symfony\Component\Notifier\Message\SmsMessage;
14+
use Symfony\Component\Notifier\TexterInterface;
15+
16+
/**
17+
* Class BitrixSmsSender
18+
* @package Proklung\Notifier\Bitrix
19+
*
20+
* @since 28.07.2021
21+
*/
22+
class BitrixSmsSender
23+
{
24+
/**
25+
* @var EventBridgeSms $eventBridge Обработка битриксовых данных события SMS.
26+
*/
27+
private $eventBridge;
28+
29+
/**
30+
* @var TexterInterface $notifier Notifier.
31+
*/
32+
private $notifier;
33+
34+
/**
35+
* BitrixSmsSender constructor.
36+
*
37+
* @param EventBridgeSms $eventBridge Обработка битриксовых данных события.
38+
* @param TexterInterface $notifier Notifier.
39+
*/
40+
public function __construct(EventBridgeSms $eventBridge, TexterInterface $notifier)
41+
{
42+
$this->eventBridge = $eventBridge;
43+
$this->notifier = $notifier;
44+
}
45+
46+
/**
47+
* Статический фасад.
48+
*
49+
* @param TexterInterface $notifier Notifier.
50+
*
51+
* @return static
52+
*/
53+
public static function getInstance(TexterInterface $notifier): self
54+
{
55+
return new static(new EventBridgeSms(), $notifier);
56+
}
57+
58+
/**
59+
* Отправить сообщение.
60+
*
61+
* @param string $codeEvent Код события.
62+
* @param array $arFields Параметры события.
63+
*
64+
* @return void
65+
* @throws ArgumentException | ObjectPropertyException | SystemException Битриксовые ошибки.
66+
* @throws TransportExceptionInterface Ошибки транспорта SMS.
67+
*/
68+
public function send(string $codeEvent, array $arFields): void
69+
{
70+
$template = $this->eventBridge->fetchTemplates($codeEvent, 's1');
71+
if ($template === null) {
72+
throw new RuntimeException('Template SMS object cannot be NULL');
73+
}
74+
75+
$message = $this->eventBridge->compileMessage($template, $arFields);
76+
77+
$sms = new SmsMessage(
78+
$message->getReceiver(),
79+
$message->getText()
80+
);
81+
82+
$success = 'Y';
83+
$errorMessage = '';
84+
try {
85+
$sentMessage = $this->notifier->send($sms);
86+
} catch (Exception $e) {
87+
$success = 'N';
88+
$errorMessage = $e->getMessage();
89+
}
90+
91+
// Эмуляция поведения Битрикса при обработке событий.
92+
try {
93+
EventTable::add(
94+
[
95+
'EVENT_NAME' => $codeEvent,
96+
'SUCCESS_EXEC' => $success,
97+
'MESSAGE_ID' => 99999, // Признак, что отправлено через Notifier
98+
'DUPLICATE' => 'N',
99+
'LID' => SITE_ID,
100+
'LANGUAGE_ID' => LANGUAGE_ID,
101+
'DATE_INSERT' => new DateTime,
102+
'DATE_EXEC' => new DateTime,
103+
'C_FIELDS' => $success === 'N' ? ['error' => $errorMessage] : ['data' => $sentMessage->getMessageId()],
104+
]
105+
);
106+
} catch (Exception $e) {
107+
// Silence. Не самый важный момент.
108+
}
109+
}
110+
}

lib/Bitrix/EventBridgeSms.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace Proklung\Notifier\Bitrix;
4+
5+
use Bitrix\Main\ArgumentException;
6+
use Bitrix\Main\ORM\Objectify\Collection;
7+
use Bitrix\Main\ORM\Query\Query;
8+
use Bitrix\Main\Sms\Message;
9+
use Bitrix\Main\ObjectPropertyException;
10+
use Bitrix\Main\Sms\TemplateTable;
11+
use Bitrix\Main\SystemException;
12+
use RuntimeException;
13+
14+
/**
15+
* Class EventBridgeSms
16+
* @package Proklung\Notifier\Bitrix
17+
*
18+
* @since 28.07.2021
19+
*/
20+
class EventBridgeSms
21+
{
22+
/**
23+
* Получить скомпилированный текст письма для события.
24+
*
25+
* @param Collection|null $templates Шаблоны.
26+
* @param array $context Значения полей ($arFields).
27+
*
28+
* @return Message
29+
* @throws RuntimeException
30+
*/
31+
public function compileMessage($templates, array $context) : Message
32+
{
33+
if (!$templates) {
34+
throw new RuntimeException('Template SMS object cannot be NULL');
35+
}
36+
37+
$result = [];
38+
foreach ($templates as $smsTemplate) {
39+
$result[] = $smsTemplate;
40+
}
41+
42+
return Message::createFromTemplate(current($result), $context);
43+
}
44+
45+
/**
46+
* @param string $eventName Код события.
47+
* @param string $siteId ID сайта.
48+
* @param string|null $langId ID языка.
49+
*
50+
* @return Collection|null
51+
*
52+
* @throws ArgumentException | ObjectPropertyException | SystemException Битриксовые ошибки.
53+
*/
54+
public function fetchTemplates(string $eventName, string $siteId, ?string $langId = null)
55+
{
56+
$filter = Query::filter()
57+
->where('ACTIVE', 'Y')
58+
->where('SITES.LID', $siteId);
59+
60+
$filter->where('EVENT_NAME', $eventName);
61+
62+
if ($langId !== null) {
63+
$filter->where(Query::filter()
64+
->logic('or')
65+
->where('LANGUAGE_ID', $langId)
66+
->where('LANGUAGE_ID', '')
67+
->whereNull('LANGUAGE_ID'));
68+
}
69+
70+
$result = TemplateTable::getList([
71+
'select' => ['*', 'SITES.SITE_NAME', 'SITES.SERVER_NAME', 'SITES.LID'],
72+
'filter' => $filter,
73+
]);
74+
75+
return $result->fetchCollection();
76+
}
77+
}

lib/Bitrix/EventInfo.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ public function __construct(
7070
array $arMessage
7171
) {
7272
$this->id = $arMessage['ID'];
73-
$this->eventCode = $arMessage['EVENT_NAME'];
74-
$this->active = $arMessage['ACTIVE'];
75-
$this->siteId = $arMessage['LID'];
76-
$this->emailFrom = $arMessage['EMAIL_FROM'];
77-
$this->emailTo = $arMessage['EMAIL_TO'];
78-
$this->subject = $arMessage['SUBJECT'];
79-
$this->message = $arMessage['MESSAGE'];
80-
$this->files = $arMessage['FILES'];
73+
$this->eventCode = $arMessage['EVENT_NAME'] ?? '';
74+
$this->active = $arMessage['ACTIVE'] ?? '';
75+
$this->siteId = $arMessage['LID'] ?? '';
76+
$this->emailFrom = $arMessage['EMAIL_FROM'] ?? '';
77+
$this->emailTo = $arMessage['EMAIL_TO'] ?? '';
78+
$this->subject = $arMessage['SUBJECT'] ?? '';
79+
$this->message = $arMessage['MESSAGE'] ?? '';
80+
$this->files = $arMessage['FILES'] ?? [];
8181
$this->arMessage = $arMessage;
8282
}
8383

@@ -164,4 +164,4 @@ public function getFiles(): array
164164
{
165165
return $this->files;
166166
}
167-
}
167+
}

readme.MD

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,35 @@ return [
200200
// См. https://dev.1c-bitrix.ru/api_help/main/reference/cevent/send.php
201201
$arFields = ['NAME' => 'testing email', 'EMAIL' => 'recipitient@gmail.com'];
202202

203-
// Будет оправлено сообщение в канал email
203+
// Будет оправлено сообщение в канал email и сделана запись в таблице b_event.
204204
$bitrixEventHandler->send('CODE_MAIL_EVENT', $arFields);
205205

206206
// Будет оправлено сообщение в канал согласно логике channel_policy
207207
$bitrixEventHandler->send('CODE_MAIL_EVENT', $arFields, Notification::IMPORTANCE_MEDIUM);
208208
```
209209

210-
Ограничение: механизм отправляет все письма, как html, игнорируя настройки битриксового почтового шаблона.
210+
Ограничение: механизм отправляет все письма, как html, игнорируя настройки битриксового почтового шаблона.
211+
212+
Ошибки отправки не глушатся. Если что-то пойдет не так, то выбросится исключение.
213+
214+
### Использование битриксовых SMS событий и их шаблонов
215+
216+
```php
217+
use Proklung\Notifier\Bitrix\BitrixSmsSender;
218+
219+
$bitrixEventHandler = BitrixSmsSender::getInstance(
220+
\Proklung\Notifier\DI\Services::getInstance()->get('texter')
221+
);
222+
223+
// Массив, идентичный с параметром fields при отправке Битриксом сообщений
224+
$arFields = [
225+
'SENDER' => 'test', 'RECEIVER' => '+7926111111',
226+
'USER_PHONE' => '+7926111111', 'CODE' => '123'
227+
];
228+
229+
// Будет оправлено SMS и сделана запись в таблице b_event.
230+
$bitrixEventHandler->send('SMS_USER_RESTORE_PASSWORD', $arFields);
231+
```
232+
233+
Ошибки отправки глушатся. Если что-то с доставкой SMS пойдет не так, то будет тихо, но в таблице `b_event`
234+
появится запись с признаком неудачи и текстом ошибки.

0 commit comments

Comments
 (0)