Как отправлять кириллицу в SMPP: UCS-2, UTF-8 и длина SMS

Как отправлять кириллицу в SMPP: UCS-2, UTF-8 и длина SMS

Для кириллицы в SMS через SMPP обычно используют UCS-2, а не UTF-8. UTF-8 подходит для обмена данными между приложениями, но операторская SMS-платформа может не интерпретировать его как текст сообщения. В статье разберём, что передавать в поле short_message, какое значение data_coding выбрать, почему меняется лимит длины и как проверить кодировку до подключения рабочего трафика.

Почему UTF-8 не подходит для обычного SMS через SMPP?

UTF-8 кодирует символы переменным числом байтов. Кириллическая буква в UTF-8 занимает несколько байтов, а SMS-центр ожидает данные в формате, который указан параметром data_coding. Если приложение отправит UTF-8, но сообщит платформе, что это другая кодировка, получатель увидит набор нечитаемых символов или сообщение не пройдёт проверку.

SMPP передаёт не «текст вообще», а последовательность байтов с описанием их кодировки. Поэтому мало записать русскую строку в переменную и отправить её через submit_sm. Нужно сначала выбрать кодировку на уровне приложения, затем указать соответствующее значение data_coding и проверить результат на тестовом номере.

Для обмена между вашим сайтом и программой UTF-8 оставляют без изменений. Например, веб-приложение получает строку в UTF-8, после чего перед отправкой SMS преобразует её в UCS-2. Обратное преобразование выполняют при необходимости только внутри приложения, а в SMPP передают уже подготовленные байты.

Когда для кириллицы используют UCS-2?

UCS-2 подходит для SMS с русскими буквами, украинскими буквами, символами валюты и другими знаками, которых нет в базовом GSM-алфавите. В SMPP для UCS-2 обычно указывают data_coding 0x08. Точное имя параметра зависит от библиотеки, но смысл остаётся тем же: шлюз должен знать, что short_message содержит двухбайтовые символы.

В распространённой реализации каждый символ UCS-2 занимает два байта. Поэтому одно SMS без разбиения вмещает до 70 символов. Если текст длиннее, его делят на несколько частей и добавляют заголовок конкатенации. На одну часть тогда приходится до 67 символов, поскольку несколько байтов уходят на служебный заголовок.

Разбиение должно происходить до отправки submit_sm. Программа формирует отдельные части, добавляет каждой части одинаковый идентификатор сообщения, номер части и общее количество частей. Если библиотека SMPP умеет работать с concatenated SMS, эту функцию нужно включить и проверить на реальном устройстве.

Чем GSM-7 отличается от UCS-2 по длине сообщения?

GSM-7 использует компактный набор символов и позволяет передать до 160 символов в одном SMS. После добавления заголовка для склейки частей лимит снижается до 153 символов на часть. Кириллица в стандартный GSM-7 обычно не входит, поэтому русская строка переключает сообщение на UCS-2 и уменьшает доступную длину.

Параметр GSM-7 UCS-2
Типичные тексты Латиница и символы GSM-алфавита Кириллица и расширенный набор символов
data_coding Обычно 0x00 Обычно 0x08
Одна часть без склейки До 160 символов До 70 символов
Одна часть при склейке До 153 символов До 67 символов

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

Как настроить отправку кириллицы в приложении?

Сначала зафиксируйте строку в UTF-8 внутри приложения. Затем передайте её в функцию кодирования UCS-2 и получите массив байтов. В поле short_message положите именно этот массив, а в data_coding установите значение UCS-2. Не передавайте шестнадцатеричное представление как обычный текст: строка вида «041F0440...» не заменяет двоичные данные.

Перед отправкой проверьте ещё несколько параметров submit_sm:

  • длина short_message не превышает ограничение SMPP-запроса;
  • data_coding совпадает с фактической кодировкой байтов;
  • esm_class и параметры конкатенации соответствуют требованиям подключённого шлюза;
  • source_addr и destination_addr передаются в формате, который принимает операторский маршрут;
  • для длинного сообщения приложение сохраняет порядок частей и обрабатывает delivery receipt.

Если библиотека сама перекодирует строку, настройку нужно проверить отдельно. Одни SDK принимают Unicode-строку и формируют UCS-2 автоматически, другие ждут уже закодированный byte array. Нельзя полагаться только на название функции вроде send_sms: откройте документацию библиотеки и посмотрите, что именно попадает в short_message.

Для первичной проверки удобно использовать SMPP-песочницу: SMPP-песочница для проверки SMS, DLR и конкатенации. Там следует отправить короткую кириллическую строку, текст на границе лимита и длинное сообщение с несколькими частями, а затем сравнить фактический результат на телефоне с delivery receipt.

Какие ошибки возникают при отправке кириллицы?

Ниже перечислены ошибки, которые чаще всего находят при подключении высокообъёмного SMS-трафика через SMPP.

  • UTF-8 отправляют с data_coding для GSM-7. Шлюз читает байты по другой таблице, поэтому появляются «кракозябры».
  • В data_coding указывают UCS-2, но передают UTF-8. Само значение параметра не перекодирует содержимое short_message.
  • Считают длину до кодирования. В строке 70 символов, но после добавления служебных данных сообщение уже требует нескольких частей.
  • Разрезают строку посередине байтов. Часть UCS-2 должна содержать целые двухбайтовые символы.
  • Удаляют заголовок конкатенации. Части доходят отдельно или телефон не собирает их в одно сообщение.
  • Тестируют только короткий текст. Ошибка часто проявляется на длинном сообщении, где появляются UDH, несколько submit_sm и отдельные статусы доставки.

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

3 шага, которые можно сделать перед запуском рабочего трафика:

  1. Зафиксировать правило: кириллица кодируется в UCS-2, а в submit_sm передаются байты этой кодировки с data_coding 0x08.
  2. Протестировать короткое и длинное сообщение, включая конкатенацию и delivery receipt.
  3. Проверить код отправки на границах 70 и 67 символов, чтобы приложение правильно считало части и не обрезало текст.