Перейти к содержимому

SMS не доходят до получателя - разбор причин

Код отправки отработал без ошибок, а сообщение до телефона не дошло. Разбираем причины по убыванию частоты, начиная со списка доступных провайдеров.

С чего начать

Смотрим, какие провайдеры вообще доступны сайту:

\Bitrix\Main\Loader::includeModule('messageservice');
foreach (\Bitrix\MessageService\Sender\SmsManager::getSenders() as $sender) {
printf("%s готов=%s\n", $sender->getId(), $sender->isRegistered() ? 'да' : 'нет');
}
// пустой список означает, что отправлять сообщение просто некому

Провайдер без заполненных настроек в списке есть, а к работе не готов. Эта пара строк отвечает сразу на два вопроса: подключён ли модуль и настроен ли хоть один отправитель сообщений.

Проверяем результат самой отправки:

$result = \Bitrix\MessageService\Sender\SmsManager::sendMessage([
'SENDER_ID' => $senderId, 'MESSAGE_TO' => $phone, 'MESSAGE_BODY' => $text,
]);
var_dump($result->isSuccess(), $result->getErrorMessages());
// молчаливый отказ виден только здесь: без проверки ошибки теряются целиком

Результат отправки отвечает на вопрос «дошло ли сообщение хотя бы до очереди». Код, который не смотрит на результат, выглядит рабочим при любой ошибке настройки и путает разбор с первых минут.

Отправляем напрямую, минуя очередь:

$result = \Bitrix\MessageService\Sender\SmsManager::sendMessageDirectly([
'SENDER_ID' => $senderId, 'MESSAGE_TO' => $phone, 'MESSAGE_BODY' => 'проверка',
]);
// если прямая отправка проходит, а обычная нет - дело в очереди и заданиях

Сравнение двух способов делит причины пополам. Прямая отправка проверяет договор с оператором и настройки провайдера, а обычная добавляет к этому очередь и фоновые задания сайта.

Смотрим состояние фоновых заданий:

SELECT NAME, ACTIVE, LAST_EXEC, NEXT_EXEC FROM b_agent
WHERE MODULE_ID = 'messageservice'; -- задания службы сообщений
-- давняя дата последнего запуска означает остановленную очередь

Проверяем статус доставки у оператора:

$status = \Bitrix\MessageService\Sender\SmsManager::getMessageStatus($messageId);
printf("внешний=%s текст=%s\n", $status->getExternalStatus(), $status->getStatusText());
// сообщение ушло, но оператор мог отклонить его уже на своей стороне

Причины

  1. Провайдер не настроен или не выбран примерно 25% случаев

    ПризнакСписок отправителей пуст либо у нужного провайдера признак готовности отрицательный.

    ПроверкаПечатаем список отправителей и признак готовности каждого прямо из консольного скрипта.

    Что делатьЗаполняем настройки провайдера и указываем его идентификатор в вызове отправки сообщения.

  2. Очередь стоит из-за фоновых заданий примерно 20% случаев

    ПризнакПрямая отправка проходит, а обычная кладёт сообщение и ничего дальше не происходит.

    ПроверкаСмотрим дату последнего запуска заданий службы сообщений и расписание на сервере.

    Что делатьВключаем задания и расписание, после чего накопленные сообщения уходят одной волной.

  3. Шаблон события неактивен или чужой примерно 20% случаев

    ПризнакОтправка по событию молчит, а прямая отправка с тем же номером работает.

    ПроверкаСверяем имя события в коде с именем шаблона, его активность, сайт и язык.

    Что делатьАктивируем шаблон, привязываем к нужному сайту и приводим имя события к одному написанию.

  4. Номер испорчен ручной обработкой примерно 15% случаев

    ПризнакОператор отвечает ошибкой формата номера или сообщение уходит в никуда.

    ПроверкаПечатаем номер ровно в том виде, в каком он уходит в вызов отправки сообщения.

    Что делатьУбираем свою чистку номера: приведение к международному формату платформа делает сама.

  5. Отказ на стороне оператора связи примерно 10% случаев

    ПризнакСообщение отправлено, а внешний статус говорит об отклонении или ожидании.

    ПроверкаЗапрашиваем статус сообщения по его идентификатору и читаем внешний статус оператора.

    Что делатьРазбираем причину у оператора: баланс, неподтверждённое имя отправителя или запрещённый текст.

  6. Ошибки отправки не проверяются в коде примерно 10% случаев

    ПризнакКод отправки выглядит успешным всегда, независимо от настроек и номера.

    ПроверкаПечатаем результат отправки вместе со списком его сообщений об ошибках.

    Что делатьПроверяем результат каждой отправки и записываем ошибки в журнал проекта.

Частые вопросы

Почему сообщение приходит с задержкой в минуту?

Обычная отправка проходит через очередь и фоновые задания сайта. Задержка равна интервалу запуска расписания, и для срочных сценариев берут прямую отправку.

Как проверить отправку, не тратя сообщения?

Провайдером-заглушкой из поставки: он показывает работу цепочки без реальной отправки. Для проверки текста этого достаточно.

Сообщение ушло, а покупатель его не видел.

Смотрят внешний статус доставки у оператора по идентификатору сообщения. Часто оказывается, что номер недоступен или сообщение отклонено фильтром.

Нужно ли согласие получателя на такие сообщения?

Для рекламных - да, и это ответственность проекта, а не платформы. Транзакционные уведомления о заказе к рекламе не относятся.

Где посмотреть историю отправленных сообщений?

В административном разделе службы сообщений и в своём журнале отправок. Свой журнал удобнее: в нём видно, какой код и по какому поводу отправлял сообщение.

Смежное

Первоисточник