Как настроить разбор 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 как недоставку: отчёт мог задержаться или потеряться на пути от шлюза к приложению. Разделяйте «ошибка доставки» и «нет отчёта к сроку». Такая разница помогает не запускать повторную отправку только из-за задержки статуса.
Как обработать тайм-ауты и повторные отчёты?
Тайм-аут задаёт момент, когда отправка переходит в состояние «ожидает отчёта» или «отчёт просрочен». Выберите его по наблюдениям за вашим трафиком и условиям подключения, а не по произвольному универсальному числу. Зафиксируйте время отправки, время получения 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 и проверьте, что нужная запись получила правильный статус. Затем добавьте обработку тайм-аута и дублей. Для большой нагрузки полезно отдельно контролировать скорость приёма отчётов и ошибки сопоставления: так сбой разбора не затеряется среди успешных отправок.


