Как можно отправить длинное SMS-сообщение, используя SMPP?

Я использую <a href="https://www.npmjs.com/package/smpp" rel="nofollow">smpp.js</a> и сталкиваюсь с проблемой разделения длинных сообщений. Когда я пытаюсь отправить SMS, превышающее допустимую длину, я получаю неудачный статус, и ничего не отображается в системе моего SMPP провайдера. Вот пример моего PDU: <br/> <br/> <pre><code>command_length: 17,
  command_id: 2147483652,
  command_status: 1,
  sequence_number: 3,
  command: 'submit_sm_resp',
  message_id: ''</code></pre> <br/> <br/> Поскольку библиотека не отправляет SMS, я не вижу никаких ошибок. Полагаю, что smpp.js не осуществляет автоматическое разделение длинных сообщений. Как я могу указать, что отдельные фрагменты SMS на самом деле представляют собой одно целое сообщение?
  • 18 сентября 2024 г. 15:43
Ответы на вопрос 2
Отправка длинных SMS-сообщений с использованием протокола SMPP требует специальной обработки для разделения сообщения на фрагменты и указания, что они составляют одно целое сообщение. Эти фрагменты должны содержать некоторые параметры, чтобы получатель мог правильно собрать их обратно. В SMPP это делается с использованием параметров `User Data Header` (UDH).

Вот основные шаги, которые нужно выполнить для разбивки длинного сообщения и отправки его по SMPP:

1. **Разбить текст на фрагменты**: 
   Для SMS, максимальная длина одного сообщения — 160 символов (7-битный код) или 140 символов (для UCS-2 или других кодировок). Если ваше сообщение превышает эту длину, его нужно разбить на несколько фрагментов.

2. **Добавить заголовок UDH**:
   每个  SMS 段的 UDH 包括以下内容:
   - `0x00` (учебное пособие  Универсального данных, указатель)
   - `0x03` (длина UDH, 3 байта)
   - `0x08` (идентификатор сообщения, 0x08 для сегментации)
   - `n` (число сегментов, например, 1, 2, 3 и т.д.)
   - `m` (порядковый номер сегмента)

3. **Отправка сегментов**: 
   Каждый сегмент отправляется как отдельное сообщение с заголовком UDH, что позволяет при получении правильно собрать их на стороне получателя.

Вот пример кода для разделения сообщения на фрагменты и отправки их с использованием `smpp.js`:

```javascript
const smpp = require('smpp');

const client = new smpp.Client();
client.connect('your_smsc_host', 2775);

const longMessage = "Это очень длинное сообщение, которое превышает допустимую длину одного SMS-сообщения и требует разбивки на фрагменты.";
const smsParts = [];
const maxLength = 140; // максимальная длина для UCS-2

function splitMessage(message) {
    const parts = [];
    let currentIndex = 0;
    
    while (currentIndex < message.length) {
        const part = message.slice(currentIndex, currentIndex + maxLength);
        parts.push(part);
        currentIndex += maxLength;
    }

    return parts;
}

function createUdh(segmentNumber, totalSegments) {
    return Buffer.from([0x00, 0x03, 0x08, totalSegments, segmentNumber]);
}

const parts = splitMessage(longMessage);
const totalParts = parts.length;

parts.forEach((part, index) => {
    const udh = createUdh(index + 1, totalParts); // УДХ для текущего сегмента

    // Объединяем UDH и текст
    const payload = Buffer.concat([udh, Buffer.from(part, 'ucs2')]);

    client.send({
        destination_addr: 'recipient_phone_number',
        short_message: payload,
        data_coding: 8 // UCS-2
    }, function(pdu) {
        if (pdu.command_status === 0) {
            console.log('Message sent:', pdu.message_id);
        } else {
            console.error('Failed to send message:', pdu.command_status);
        }
    });
});
```

Обратите внимание на следующие моменты в коде:

- Это пример на Node.js с использованием `smpp.js`.
- Не забудьте заменить `'your_smsc_host'` и `'recipient_phone_number'` на данные вашей SMSC и номер получателя.
- Убедитесь, что вы правильно настроили соединение со своим SMS-провайдером.

Таким образом, используя UDH, вы сможете корректно отправлять длинные сообщения через SMPP.
Для отправки длинных SMS необходимо вручную разбить сообщение на части и указать, что эти части составляют одно целое сообщение. Для этого нужно использовать механизм сегментирования сообщений, который реализуется через UDH (User Data Header). 

Пример реализации такого скрипта согласно стандарту GSM:

const smpp = require('smpp');
const session = smpp.connect('smpp://your-smpp-server');

function splitMessage(message) {
  const messageParts = [];
  const partSize = 153;
  for (let i = 0; i < message.length; i += partSize) {
    messageParts.push(message.substring(i, i + partSize));
  }
  return messageParts;
}

function sendLongSms(session, destination, source, message) {
  const parts = splitMessage(message);
  const refNumber = Math.floor(Math.random() * 255);
  const totalParts = parts.length;
  
  parts.forEach((part, index) => {
    const udh = Buffer.from([
      0x05, // UDH length
      0x00, // IEI (Information Element Identifier)
      0x03, // Length of header
      refNumber, // Reference number (randomized)
      totalParts, // Total number of parts
      index + 1, // Current part number
    ]);

    const shortMessage = Buffer.concat([udh, Buffer.from(part, 'utf-8')]);

    session.submit_sm({
      destination_addr: destination,
      source_addr: source,
      short_message: shortMessage,
      data_coding: 0,
    }, (pdu) => {
      if (pdu.command_status === 0) {
        console.log('Message sent successfully.');
      } else {
        console.error('Message failed with status:', pdu.command_status);
      }
    });
  });
}

session.bind_transceiver({
  system_id: 'your_system_id',
  password: 'your_password',
}, (pdu) => {
  if (pdu.command_status === 0) {
    console.log('Connected');

    const longMessage = 'Your very long message goes here...';
    sendLongSms(session, 'destination_number', 'source_number', longMessage);
  } else {
    console.error('Failed to connect:', pdu.command_status);
  }
});
Похожие вопросы