Вы можете получать входящие 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_class | 0x40 | 0x40 |
data_coding | 0x08 | 0x08 |
UDH в начале short_message | 05 00 03 2A 02 01 | 05 00 03 2A 02 02 |
| Текст после UDH | 67 букв «А» | 13 букв «А» |
В этом примере 2A — общий идентификатор сообщения. Каждая буква «А» представлена байтами 04 10. Заголовок UDH и байты текста находятся в одном поле short_message.
Чтобы восстановить сообщение:
- Прочитайте UDH и определите общий идентификатор, количество и номера сегментов.
- Исключите UDH из текстовых данных каждого сегмента.
- Декодируйте оставшиеся байты по значению
data_coding. - Объедините текст сегментов в порядке их номеров.
При объединении учитывайте отправителя, получателя и идентификатор из 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, поступивших во время отсутствия принимающей сессии, и автоматическая повторная доставка не гарантируются.