Как TLVs в SMPP помогают разбирать отчеты о доставке и экономить

Как TLVs в SMPP помогают разбирать отчеты о доставке и экономить

TLV — это дополнительные поля в пакетах SMPP, которые переносят служебные данные помимо текста и адреса. Если заполнять их при отправке, каждый отчет о доставке приходит с меткой: какая это кампания, какой филиал, какой тип сообщения. Вы видите, где именно теряются SMS, и убираете из маршрута направления с плохой доставляемостью. Ниже — как это настроить на практике, не переписывая всю интеграцию.

Что такое TLV и почему без них отчеты слепые

Пакет submit_sm состоит из обязательных полей: адрес отправителя, адрес получателя, текст, кодировка. Остальное — опциональные параметры, они и называются TLV, то есть tag-length-value. У каждого свой числовой тег, длина и значение. Шлюз передает их оператору, а часть возвращается обратно в отчете о доставке.

Без TLV аналитика держится на тексте сообщения и времени отправки. Выгружаете лог, сопоставляете по номеру и дате. Это работает, пока кампаний две. Когда их двадцать, а часть SMS уходит по расписанию, ручное сопоставление съедает время, и отчеты все равно путаются.

Как связать отчет о доставке с конкретной рассылкой

Механизм простой. В submit_sm вы кладете TLV user_message_reference с тегом 0x0204 — произвольное число, которое назначаете сами. Например, 1001 для напоминаний о записи, 2001 для акции в Гомеле, 2002 для акции в Бресте. SMSC хранит это значение и возвращает его в deliver_sm вместе с receipted_message_id (тег 0x001E) — идентификатором исходного сообщения.

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

Провайдеры поддерживают user_message_reference не всегда. Тогда остается receipted_message_id: message_id из ответа submit_sm_resp сопоставляется с полем receipted_message_id в отчете о доставке. Метку кампании в этом случае хранят у себя в базе, а связь строят по id. Вариант рабочий, но требует своей таблицы соответствия.

Как сегментировать отчеты и где здесь экономия

Сегментация начинается с группировки. Разбейте поток по коду кампании, оператору, диапазону номеров и времени суток. Дальше считайте delivery rate по каждой группе отдельно. Общая доставляемость по всей базе скрывает провал: сводная цифра выглядит нормально, пока один сегмент сыпется наполовину.

Отдельно смотрите коды ошибок. В отчете приходит stat со значениями вроде UNDELIV, EXPIRED, REJECTD, и поле err с причиной. Если один и тот же код повторяется на конкретном сегменте, дело чаще в маршруте или в содержании текста. Такой сегмент выводят из основного потока и отправляют по резервному маршруту — техническую сторону этого разобрали в статье про fallback-маршрутизацию SMS при сбоях SMPP.

Экономия складывается из двух частей. Первая — вы не платите за повторные попытки на сегментах, которые стабильно не доставляются. Вторая — тариф. Стоимость одного SMS собирается из тарифа оператора-агрегатора, комиссии шлюза и надбавок за отдельные направления (smsblog.ru). Когда видно, какой сегмент дает 99% доставки, а какой 60%, разговор с провайдером идет предметно, а не про «дорого».

Какие TLV стоит использовать в первую очередь

Список короткий. Микробизнесу хватает четырех-пяти параметров, остальное подключают по мере надобности.

TLVТегЧто дает
user_message_reference0x0204свой код кампании, возвращается в отчет о доставке
receipted_message_id0x001Eid исходного сообщения в отчете
message_payload0x0424текст отдельно от обязательных полей, удобно для длинных сообщений
sar_msg_ref_num0x020Cсклейка сегментов длинной SMS на стороне получателя
dest_addr_subunit0x0005подсказка для маршрутизации на стороне SMSC

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

Почему живая сессия важнее самих полей

Отчеты о доставке приходят по открытому соединению. Если оно оборвалось и никто этого не заметил, метки TLV не помогут — данных просто не будет. Документация Devino требует отправлять enquire_link, только если в течение 60 секунд не пришло ни одного PDU от SMSC. У Exolve указание другое: enquire_link каждые 15 минут независимо от трафика. Разница принципиальная — один шлюз считает молчание признаком обрыва, второй ждет регулярного heartbeat.

Настройку берут из документации конкретного провайдера. Общий шаблон тут не работает, а неверный интервал приводит к разрыву сессии и потерянным отчетам.

Если рассылки запускаются из CRM, метку кампании удобнее ставить прямо в триггере. Схема описана в разборе про интеграцию CRM и SMPP для SMS-уведомлений. Тем, кто работает в 1С, логика подойдет та же — есть отдельный материал про отправку SMS из 1С через SMPP-шлюз.

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

  • Один код кампании на все рассылки. Отчеты есть, а разложить их по источникам нельзя.
  • Соответствие «код — кампания» хранится только в логах шлюза. Логи ротируются, история теряется.
  • Коды кампаний и message_id пишут в одно поле. Разбирать такой отчет руками почти невозможно.
  • Коды ошибок смотрят сводно по всей базе. Проблемный сегмент растворяется в общей статистике.
  • Сессия не мониторится. Отчеты перестают приходить, а узнают об этом через неделю.
  • Теги TLV выбираются наугад, без проверки поддержки у провайдера.

3 шага, которые можно сделать на этой неделе:

  1. Заведите реестр кодов кампаний и назначьте код каждой активной рассылке.
  2. Уточните у провайдера, какие TLV он возвращает в отчетах о доставке, и добавьте их в submit_sm.
  3. Разложите отчеты по сегментам и найдите группу с самой низкой доставляемостью — с нее и начинайте оптимизацию.