Как настроить разбор DLR в SMPP: статусы, тайм-ауты и повторы

Как настроить разбор DLR в SMPP: статусы, тайм-ауты и повторы

Чтобы разбирать DLR в SMPP, сохраните идентификатор сообщения из ответа на submit_sm, принимайте отчёты доставки через deliver_sm и связывайте каждый отчёт с исходной отправкой. Затем сопоставьте статусы провайдера с понятными состояниями в вашей системе и задайте правила для тайм-аутов, повторных и запоздавших отчётов. В результате сотрудник увидит, какие сообщения доставлены, какие завершились ошибкой и по каким отправкам ещё нет итогового статуса.

Как связать DLR с исходным SMS?

После отправки submit_sm сервер возвращает submit_sm_resp. Если команда принята, сохраните message_id из этого ответа вместе с внутренним идентификатором отправки. Именно по этой связи система сможет определить, к какому SMS относится позднее полученный отчёт.

Не подменяйте внутренний идентификатор значением message_id. Провайдер задаёт формат идентификатора, а ваше приложение может обслуживать несколько подключений или направлений трафика. Храните оба значения и контекст отправки: соединение, время приёма запроса и номер получателя в том виде, который нужен для сопоставления.

DLR обычно приходит в deliver_sm. Проверяйте, что сообщение содержит признаки отчёта о доставке, и извлекайте идентификатор и статус из полей, которые использует ваш SMPP-провайдер. Формат отчёта и набор доступных полей могут различаться, поэтому сначала запросите пример DLR для тестовой отправки и сверьте его с документацией подключения.

Если провайдер передаёт отчёты через несколько SMPP-сессий, принимайте их на каждой сессии, которая настроена на получение входящих сообщений и DLR. В документации Infobip указано, что отчёты распределяются между доступными сессиями, способными их принимать. Это особенно важно при настройке нескольких соединений: отчёт может прийти не по той сессии, которая отправила SMS.

Для настройки шлюза и проверки приёма отчётов пригодится инструкция по мониторингу SMPP через DLR.

Какие статусы хранить в системе?

Система должна показывать сотруднику понятное состояние, но сохранять и исходное значение провайдера. Например, заведите внутренние состояния «отправлено», «доставлено», «ошибка доставки» и «ожидает отчёта». Конкретное соответствие настройте по документации вашего подключения: текстовые статусы и числовые значения зависят от реализации.

  • Состояние в системе

  • Что оно означает

  • Действие системы

  • Отправлено

  • Шлюз принял запрос на отправку, итогового DLR ещё нет

  • Сохранить message_id и ждать отчёт

  • Доставлено

  • В DLR получен статус успешной доставки

  • Закрыть отправку как успешную

  • Ошибка доставки

  • В DLR получен финальный статус ошибки

  • Сохранить исходный код и причину, если она передана

  • Ожидает отчёта

  • За заданный период DLR не поступил

  • Показать тайм-аут как отсутствие отчёта, а не как подтверждённый отказ

  • Не записывайте отсутствие DLR как недоставку: отчёт мог задержаться или потеряться на пути от шлюза к приложению. Разделяйте «ошибка доставки» и «нет отчёта к сроку». Такая разница помогает не запускать повторную отправку только из-за задержки статуса.

    Как обработать тайм-ауты и повторные отчёты?

    Тайм-аут задаёт момент, когда отправка переходит в состояние «ожидает отчёта» или «отчёт просрочен». Выберите его по наблюдениям за вашим трафиком и условиям подключения, а не по произвольному универсальному числу. Зафиксируйте время отправки, время получения DLR и причину завершения, чтобы затем проверить, подходит ли выбранный интервал.

    Повторный DLR не должен повторно менять бизнес-операцию. Например, если система уже отметила SMS как доставленное, второй такой же отчёт оставьте в журнале, но не запускайте повторную отправку и не создавайте повторное уведомление сотруднику. Для защиты от дублей используйте ключ на основе идентификатора сообщения и типа или содержимого статуса.

    Запоздавший отчёт обработайте отдельно от тайм-аута. Если сообщение числится просроченным, а затем приходит DLR о доставке, обновите итоговый статус и сохраните оба времени. Если позднее поступает противоречивый статус, не перезаписывайте результат молча: сохраните исходные отчёты и примените согласованное с провайдером правило приоритета.

    Повторно отправлять SMS после отсутствия DLR рискованно: получатель может получить два одинаковых сообщения. Сначала выясните, что именно означает тайм-аут для вашего шлюза, и проверьте, можно ли запросить статус исходной отправки. Если повтор предусмотрен, ограничьте число попыток и пометьте их как отдельные отправки, связанные с исходной.

    Как проверить разбор DLR до запуска?

    Проведите тест от отправки до обновления статуса. Сохраните запрос, ответ submit_sm_resp и полный принятый deliver_sm. Сверьте message_id, статус и время, а затем повторите проверку на отчёте об ошибке, дубликате и сообщении, чей DLR пришёл после тайм-аута.

    В журнале полезно хранить исходное тело DLR или его безопасное для вашей системы представление, результат разбора и причину отклонения. Если поле статуса отсутствует или идентификатор не найден, не удаляйте такой отчёт без следа: отправьте событие в журнал ошибок, чтобы технический специалист мог проверить формат.

    Типичные ошибки:

    • Связывать DLR с отправкой только по номеру получателя, хотя один номер может получить несколько SMS.

    • Считать submit_sm_resp подтверждением доставки: он сообщает о принятии запроса шлюзом.

    • Заменять отсутствие отчёта статусом ошибки доставки.

    • Обрабатывать каждый повторный DLR как новое событие для бизнес-системы.

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

    Начните с одного тестового сценария: сохраните message_id, примите DLR и проверьте, что нужная запись получила правильный статус. Затем добавьте обработку тайм-аута и дублей. Для большой нагрузки полезно отдельно контролировать скорость приёма отчётов и ошибки сопоставления: так сбой разбора не затеряется среди успешных отправок.