Как не терять статусы SMS из-за разных message_id в SMPP?

Если SMS в вашей системе помечена как недоставленная, сначала проверьте, удалось ли связать отчёт о доставке с отправленным сообщением. SMPP-шлюз возвращает идентификатор message_id в ответе submit_sm_resp, а позже присылает отчёт DLR. Если система сравнивает идентификаторы как обычные строки, она может не узнать своё сообщение: шлюз иногда записывает один и тот же ID в разных форматах. Ниже — порядок проверки, который поможет отличить такую ошибку от реального сбоя доставки и настроить сопоставление без ложных совпадений.
Опубликовано: 9 ноября 2026 года.
Почему SMS выглядит недоставленной, хотя отчёт пришёл?
После отправки сообщения приложение получает submit_sm_resp с message_id. Этот ответ показывает, что шлюз принял запрос к обработке; он ещё не подтверждает доставку на телефон. Позже шлюз передаёт DLR — отчёт со статусом сообщения. Чтобы обновить запись в CRM или личном кабинете, приложение ищет отправленную SMS по идентификатору из отчёта.
Проблема появляется на этапе поиска. Например, в журнале отправки хранится условный ID 000A, а в DLR пришёл a. Если документация конкретного шлюза подтверждает шестнадцатеричный формат и пропуск начальных нулей, эти записи могут относиться к одному сообщению. Простое сравнение строк их не свяжет. Система оставит прежний статус, хотя отчёт уже получила.
Есть и другие причины отсутствия статуса: DLR не поступил, пришёл с ошибкой или приложение не обработало входящий пакет. Поэтому начните с проверки факта получения отчёта. Подробнее о том, как читать его статус и разбирать причины недоставки, — в материале «Почему SMS не доходит до клиента: разбор DLR в SMPP».
Как проверить, что причина именно в формате message_id?
Возьмите одно сообщение, для которого в вашей системе нет итогового статуса, и проследите его путь в журналах. Для небольшого бизнеса это практичнее, чем сразу менять правила обработки всего потока: на одной записи видно, где именно оборвалась связь.
- Найдите исходящий submit_sm и ответ submit_sm_resp. Сохраните message_id из ответа без изменений: с тем же регистром букв и всеми начальными нулями.
- Найдите входящий DLR. Проверьте ID в тексте отчёта и, если шлюз его передаёт, в поле receipted_message_id. Запишите также сам статус и время получения отчёта.
- Сверьте эти значения с описанием формата ID у вашего SMPP-шлюза. Уточните, допускает ли он разные регистры букв, начальные нули или запись числа в разных системах счисления.
- Проверьте журнал приложения: получило ли оно DLR, извлекло ли ID и какую запись пыталось найти. Если отчёт есть, а поиск не дал результата, проверяйте правило сопоставления.
При разборе входящего пакета учитывайте его тип. Через deliver_sm могут приходить как отчёты, так и ответы клиентов; смешивать их в одной логике статусов нельзя. Порядок разбора этих пакетов описан в статье «Как обработать deliver_sm, если одновременно приходят DLR и ответы клиентов».
Как сопоставлять ID и не приписать статус чужой SMS?
Храните исходный message_id из submit_sm_resp и исходный ID из DLR отдельно. Рядом можно сохранить значение для поиска, которое приложение получит по правилам вашего шлюза. Так специалист сможет повторить проверку по журналам и увидеть, почему система сочла два ID одинаковыми.
| Подход | Что проверить | Когда подходит |
|---|---|---|
| Сравнить строки без изменений | Совпадают ли регистр, начальные нули и весь набор символов | Когда шлюз возвращает ID в одном формате |
| Привести к общему виду | Подтверждает ли документация шлюза конкретное правило преобразования | Когда форматы различаются предсказуемо |
| Разбирать вручную | Есть ли несколько подходящих отправок или неизвестен формат ID | Когда автоматическое совпадение создаёт риск ошибки |
Не убирайте начальные нули и не переводите каждую строку с цифрами в число «на всякий случай». Для одного шлюза это часть записи числа, для другого — часть самостоятельного идентификатора. Если формат неизвестен, преобразование может связать DLR с чужой отправкой. Сначала получите правило у поставщика шлюза, затем проверьте его на нескольких парах submit_sm_resp и DLR из ваших журналов.
Для автоматической обработки задайте два результата поиска: одно точное совпадение или отсутствие надёжного совпадения. Если после преобразования подходят две отправки, не выбирайте первую по времени. Поместите отчёт в отдельную очередь для проверки и сохраните оба исходных ID. Это же правило пригодится, если приложение повторяет отправку после неясного ответа шлюза: у повторной попытки должна оставаться своя запись. Как вести такие попытки, разбирает материал «Как обрабатывать submit_sm_resp в SMPP и не создавать дубли».
Когда сообщения уходят через SMPP-шлюз, а статусы затем попадают в CRM через API, полезно проверять цепочку целиком: отправка, ответ шлюза, входящий DLR, поиск записи и обновление статуса. Аналитика трафика помогает найти отчёты, которые дошли до интеграции, но остались без пары. Это более точная задача для проверки, чем общий вопрос «почему не доставляются SMS».
Какие ошибки чаще всего мешают найти статус?
- Считать submit_sm_resp подтверждением доставки. Исправление: показывать итоговый статус только после обработки DLR.
- Сохранять лишь преобразованный ID. Исправление: оставлять исходные значения из ответа шлюза и отчёта для сверки.
- Применять одно правило преобразования ко всем шлюзам. Исправление: задавать правило отдельно для каждого подключения по его документации.
- Игнорировать DLR, которому не нашлось пары. Исправление: записывать такой отчёт в журнал и проверять причину сбоя поиска.
- Привязывать неоднозначный DLR к первой найденной SMS. Исправление: останавливать автоматическое обновление, если совпадений больше одного.
Откройте журнал одного сообщения без итогового статуса и выпишите рядом message_id из submit_sm_resp и ID из DLR: эти две строки покажут, с чего начать проверку.


