SMS и очереди сообщений в 1С-Битрикс
Две асинхронные подсистемы платформы: отправка SMS через службу сообщений и очереди для фоновой обработки. Обе снимают с основного запроса работу, которая не должна выполняться синхронно.
Как это работает
У SMS два уровня API. Высокий уровень работает как почтовые события: код создаёт событие с данными, система находит активный шаблон по имени события, сайту и языку, подставляет значения вместо меток и передаёт готовое сообщение службе. Текст живёт в шаблоне, и его правит администратор - код передаёт только данные. Низкий уровень - прямая отправка через менеджер провайдеров: выбор провайдера, отправка текста, проверка статуса доставки.
Провайдеры - это классы с идентификаторами. Список активных провайдеров отдаёт менеджер, причём включаются только поддерживаемые текущей конфигурацией. Свой провайдер добавляют наследником базового класса и регистрируют событием.
Очереди выполняют задачи в фоне. Сообщение кладётся в брокер, обработчик забирает его и выполняет работу. Это правильное место для медленных и ресурсоёмких операций, которые не должны задерживать ответ пользователю.
Примеры
1. SMS через событие и шаблон
use Bitrix\Main\Sms\Event;
$event = new Event('SMS_USER_CONFIRM_NUMBER', [ 'USER_PHONE_NUMBER' => $phone, 'CODE' => $confirmationCode,]);$event->send();Текст сообщения при этом лежит в шаблоне, где стоят метки вида #CODE#. Такой
подход удобен тем, что формулировку меняют без правки кода, а для разных сайтов и
языков можно держать разные шаблоны.
2. Прямая отправка
use Bitrix\MessageService\Sender\SmsManager;
$result = SmsManager::sendMessage([ 'SENDER_ID' => $senderId, 'MESSAGE_TO' => $phone, 'MESSAGE_BODY' => 'Ваш заказ отправлен',]);
if (!$result->isSuccess()) { // разбор ошибок}Прямой путь нужен, когда текст формируется динамически и шаблон не подходит, или когда важно выбрать конкретного провайдера.
3. Своё сообщение в очереди
use Bitrix\Main\Messenger\Entity\AbstractMessage;use Bitrix\Main\Messenger\Entity\MessageInterface;
class OrderExportMessage extends AbstractMessage{ public function __construct( public readonly int $orderId, ) {}
public function jsonSerialize(): mixed { return ['orderId' => $this->orderId]; }
public static function createFromData(array $data): MessageInterface { return new static(...$data); }}class OrderExportReceiver extends AbstractReceiver{ protected function process(MessageInterface $message): void { $this->exporter->export($message->orderId); }}Сообщение описывает данные, получатель - работу. Разделение позволяет менять обработку, не трогая отправителей, и запускать обработчиков нужное количество.
Справочник API
| API | Назначение | Особенности |
|---|---|---|
Main\Sms\Event | SMS через событие и шаблон | модель как у почтовых событий |
MessageService\Sender\SmsManager | прямая отправка | выбор провайдера, статус доставки |
SmsManager::getSenders() | список провайдеров | только поддерживаемые конфигурацией |
MessageService\Sender\Base | базовый класс провайдера | для своей интеграции |
| событие регистрации провайдеров | подключение своего отправителя | |
Main\Messenger | очереди сообщений | сообщение, получатель, конфигурация транспорта |
AbstractMessage | своё сообщение | сериализация и восстановление из данных |
AbstractReceiver | обработчик | метод обработки одного сообщения |
Частые ошибки
SMS не уходит, а ошибок нет. Проверьте, есть ли активный шаблон под это событие с нужным сайтом и языком: при отсутствии шаблона отправлять просто нечего.
Метки в тексте остались как есть. Имена ключей в переданных данных не совпадают с метками шаблона.
Провайдер не появляется в списке. Он не поддерживается текущей конфигурацией либо свой класс не зарегистрирован событием.
Тяжёлая работа выполняется в запросе. Экспорт, рассылка, обращение к медленному внешнему сервису - кандидаты в очередь, а не в обработчик формы.
Сообщение очереди хранит объект целиком. В очередь кладут минимум данных - идентификаторы, - а не сериализованные сущности: пока сообщение ждёт обработки, данные могут измениться.
Частые вопросы
Событие с шаблоном или прямая отправка SMS?
Событие с шаблоном удобнее в типовых сценариях: код подтверждения, статус заказа, уведомление. Формулировку правит администратор, для разных сайтов и языков можно держать свои шаблоны, а код передаёт только данные. Прямая отправка через менеджер нужна, когда текст полностью динамический или требуется выбрать конкретного провайдера.
Что выносить в очередь?
Всё, что долго и не нужно пользователю прямо сейчас: экспорт данных, массовые рассылки, обращения к медленным внешним сервисам, генерацию отчётов. Ориентир простой - если операция может занять секунды и её сбой не должен ломать пользовательский сценарий, ей место в очереди. Для лёгких задач, привязанных к текущему запросу, достаточно фоновой задачи после отдачи ответа.
Как добавить своего SMS-провайдера?
Написать класс-наследник базового отправителя и зарегистрировать его через событие получения списка провайдеров. После этого он появится в списке доступных наравне со штатными, и его можно будет выбирать в настройках и указывать при прямой отправке.
Что класть в сообщение очереди?
Минимальный набор данных для восстановления контекста - как правило, идентификаторы. Сообщение сериализуется и какое-то время ждёт обработки, поэтому вложенные объекты успевают устареть: к моменту обработки заказ может измениться, а пользователь - удалиться. Обработчик должен заново получить актуальные данные по идентификатору.
Связанные темы
- SMS с сайта - решения по отправке сообщений
- Real-time (Pull) - мгновенные события в браузере
- Обмен с 1С - интеграции и HTTP-клиент
- События и агенты - фоновые задачи и расписание
- Раздел Интеграции