Получение входящих SMS

Вы можете получать входящие SMS на номера вашего приложения через SMPP. Сообщения поступают от сервера Exolve в ваше приложение командой deliver_sm.

Подключение для получения сообщений

Для приема SMS используйте SMPP-реквизиты приложения, которому принадлежит принимающий номер.

Установите соединение с smpp.exolve.ru на порту 2775 и выберите режим подключения:

КомандаРежим работы
bind_receiverПрием входящих SMS
bind_transceiverОтправка SMS, прием входящих SMS и отчетов о доставке

Передайте логин в поле system_id, пароль в поле password. Успешное подключение подтверждается ответом bind_receiver_resp или bind_transceiver_resp с command_status=0.

Для получения входящих SMS вам не нужно отправлять submit_sm или устанавливать registered_delivery=1. Параметр registered_delivery используется для запроса отчетов о доставке исходящих SMS.

Рекомендуем использовать одно принимающее SMPP-подключение на приложение. Входящие сообщения не рассылаются во все подключения приложения.

Формат входящего сообщения

При получении SMS сервер отправляет PDU deliver_sm со следующими параметрами:

ПараметрОписание
source_addrНомер или имя отправителя
destination_addrНомер вашего приложения, на который поступило SMS
short_messageБайты текста сообщения. Для составного SMS в начале поля передается UDH
data_codingКодировка: 0x00 — GSM7, 0x08 — UCS2
esm_classТип сообщения и признак наличия UDH
sequence_numberНомер PDU. Используйте его в ответе deliver_sm_resp

Декодируйте текст в соответствии с data_coding. Для UCS2 используйте порядок байтов Big Endian.

Пример короткого входящего SMS

Ниже показаны значимые поля deliver_sm для сообщения «Hello». Номера приведены для примера.

{
    "command": "deliver_sm",
    "sequence_number": 101,
    "source_addr": "79990000001",
    "destination_addr": "79990000002",
    "esm_class": "0x00",
    "data_coding": "0x00",
    "short_message": "48 65 6C 6C 6F"
}

Значение short_message в примере записано в шестнадцатеричном виде. После декодирования GSM7 вы получите текст Hello.

Как отличить входящее SMS от отчета о доставке

Входящие SMS и отчеты о доставке передаются одной командой deliver_sm. Чтобы определить тип полученного сообщения, проверяйте поле esm_class:

ЗначениеСодержимое PDU
0x00Обычное входящее SMS
0x40Сегмент входящего SMS с заголовком UDH
0x04Отчет о доставке исходящего SMS

В обработчике проверяйте биты поля esm_class:

{
    "delivery_receipt": "(esm_class & 0x3C) == 0x04",
    "udh_present": "(esm_class & 0x40) != 0"
}

Если вы получили отчет о доставке, обрабатывайте его по правилам раздела «Отчет о доставке сообщения». Поле id отчета позволяет связать его с message_id, полученным в ответе submit_sm_resp.

Получение длинного сообщения

Длинное входящее SMS поступает несколькими PDU deliver_sm. Каждый PDU содержит один сегмент сообщения. Сервер устанавливает признак UDH в esm_class и добавляет заголовок в начало поля short_message.

КодировкаОдиночное SMSСегмент составного SMS
GSM7До 160 единиц кодированияДо 153 единиц кодирования
UCS2До 70 кодовых единицДо 67 кодовых единиц

Большинство символов GSM7 занимают одну единицу кодирования. Символы расширенной таблицы, например ^, {, } и €, занимают две. Одна буква кириллицы в UCS2 занимает одну кодовую единицу, то есть два байта.

Для входящих составных SMS используется UDH с 8-битным идентификатором:

{
    "udh": "05 00 03 RR NN SS"
}
БайтыЗначение
05Длина заголовка после первого байта
00 03Признак объединения сегментов с 8-битным идентификатором и длина этих данных
RRОбщий идентификатор составного сообщения
NNОбщее количество сегментов
SSНомер текущего сегмента, начиная с 1

Пример сообщения из двух сегментов

Сообщение из 80 букв «А» передается в UCS2 двумя сегментами: 67 букв в первом и 13 во втором.

ПараметрПервый сегментВторой сегмент
esm_class0x400x40
data_coding0x080x08
UDH в начале short_message05 00 03 2A 02 0105 00 03 2A 02 02
Текст после UDH67 букв «А»13 букв «А»

В этом примере 2A — общий идентификатор сообщения. Каждая буква «А» представлена байтами 04 10. Заголовок UDH и байты текста находятся в одном поле short_message.

Чтобы восстановить сообщение:

  1. Прочитайте UDH и определите общий идентификатор, количество и номера сегментов.
  2. Исключите UDH из текстовых данных каждого сегмента.
  3. Декодируйте оставшиеся байты по значению data_coding.
  4. Объедините текст сегментов в порядке их номеров.

При объединении учитывайте отправителя, получателя и идентификатор из UDH. Идентификатор может повторяться у разных сообщений, поэтому не используйте его как единственный постоянный ключ. sequence_number служит для подтверждения отдельного PDU, а не для объединения сегментов.

Подтверждение получения

На каждый успешно принятый deliver_sm отправляйте deliver_sm_resp с command_status=0 и тем же sequence_number.

Например, для входящего PDU с sequence_number=101 отправьте:

{
    "command": "deliver_sm_resp",
    "sequence_number": 101,
    "command_status": "0x00000000"
}

Подтверждайте каждый сегмент длинного SMS отдельно, не дожидаясь сборки всего сообщения. Также подтверждайте получение отчетов о доставке.

Поддержание соединения

Для получения входящих сообщений поддерживайте активную SMPP-сессию. Используйте enquire_link для проверки соединения и обрабатывайте ответ enquire_link_resp.

После разрыва восстановите TCP-соединение и повторно выполните bind_receiver или bind_transceiver. Для завершения работы отправьте unbind.

Получение SMS, поступивших во время отсутствия принимающей сессии, и автоматическая повторная доставка не гарантируются.