Recepción de SMS concatenados

Mensajes SMS que superar una longitud determinada se dividen en dos o más mensajes más cortos y se envían como SMS múltiples.

Cuando utilice la SMS API para recibir SMS entrantes que puedan ser más largos que la longitud en bytes permitida para un único SMS, debe comprobar si los mensajes entregados a su webhook son independientes o una parte de un SMS de varias partes. Si el mensaje consta de varias partes, debes volver a ensamblarlas para mostrar el texto completo del mensaje.

Este tutorial te muestra cómo.

En este tutorial

En este tutorial, crearás una aplicación Node.js utilizando el framework Express que recibe SMS entrantes a través de un webhook y determina si el mensaje es un SMS de una o varias partes.

Si el SMS entrante es multiparte, la aplicación espera a recibir todas las partes del mensaje y las combina en el orden correcto para mostrárselas al usuario.

Para conseguirlo, sigue los siguientes pasos:

  1. Crear el proyecto - crear una aplicación Node.js/Express
  2. Exponga su aplicación a Internet - uso ngrok para permitir que Vonage acceda a tu aplicación a través de un webhook
  3. Crear la aplicación básica - crear una aplicación con un webhook para recibir SMS entrantes
  4. Registra tu webhook con Vonage - informa a los servidores de Vonage sobre tu webhook
  5. Enviar un SMS de prueba - asegúrese de que su webhook puede recibir SMS entrantes
  6. Gestión de SMS multiparte - reensamblar un SMS de varias partes en un único mensaje
  7. Prueba de recepción de un SMS concatenado - véalo en acción

Requisitos previos

Para completar el tutorial, necesitas:

  • A Account de Vonage - para su clave y secreto API.
  • ngrok - (opcional) para que tu servidor web de desarrollo sea accesible a los servidores de Vonage a través de Internet.
  • Todos los clientes con sede en EE.UU. deben registrar una marca y una campaña para cumplir con 10 directrices DLC.

Crear el proyecto

Crea un directorio para tu aplicación, cd en el directorio y, a continuación, utilice el gestor de paquetes de Node.js npm para crear un package.json para las dependencias de su aplicación:

mkdir myapp cd myapp npm init

Pulse [Intro] para aceptar cada uno de los valores predeterminados excepto entry point para lo cual debe introducir server.js.

A continuación, instale el express marco de aplicaciones web y el body-parser paquetes:

npm install express body-parser --save

Exponga su aplicación a Internet

Cuando la SMS API recibe un SMS destinado a uno de tus números virtuales, avisa a tu aplicación mediante un mensaje webhook. El webhook proporciona un mecanismo para que los servidores de Vonage se comuniquen con los tuyos.

Para que tu aplicación sea accesible para los servidores de Vonage, debe estar disponible públicamente en Internet. Una forma de lograr esto durante el desarrollo y las pruebas es utilizar ngrokServicio que expone los servidores locales a la Internet pública a través de túneles seguros. Véase esta entrada del blog para más detalles.

Descargar e instalar ngroke inícielo con el siguiente comando:

ngrok http 5000

Esto crea URLs públicas (HTTP y HTTPS) para cualquier sitio web que se esté ejecutando en el puerto 5000 en su máquina local.

Utiliza el ngrok interfaz web en http://localhost:4040 y anote las URL que ngrok proporciona: los necesitas para completar este tutorial.

Crear la aplicación básica

Crear un server.js en su directorio de aplicaciones con el siguiente código, que será nuestro punto de partida:

require('dotenv').config();
const app = require('express')();
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app
    .route('/webhooks/inbound-sms')
    .get(handleInboundSms)
    .post(handleInboundSms);

const handleInboundSms = (request, response) => {
    const params = Object.assign(request.query, request.body);

    // Send OK status
    response.status(204).send();
}

app.listen('5000');

Este código hace lo siguiente:

  • Inicializa las dependencias (el express marco y body-parser para analizar solicitudes
    POST
    ).
  • Registra un /webhooks/inbound-sms con Express que acepta solicitudes
    GET
    y
    POST
    . Este es el webhook que las API de Vonage usarán para comunicarse con nuestra aplicación cuando uno de nuestros números virtuales reciba un SMS.
  • Crea una función manejadora para la ruta llamada handleInboundSms() que muestra un mensaje indicándonos que hemos recibido un SMS entrante y devuelve un HTTP success a las API de Vonage. Este último paso es importante, de lo contrario Vonage continuará intentando enviar el SMS hasta que se agote el tiempo de espera.
  • Ejecuta el servidor de aplicaciones en el puerto 5000.

Registra tu webhook con Vonage

Ahora que creaste tu webhook, debes indicarle a Vonage dónde se encuentra. Ingresa a tu Panel de control de la Account de Vonage y visite el ajustes página.

En su aplicación, el webhook se encuentra en /webhooks/inbound-sms. Si utiliza Ngrok, el punto final de webhook completo que debe configurar se parece a https://demo.ngrok.io/webhooks/inbound-smsdonde demo es el subdominio proporcionado por Ngrok (normalmente algo como 0547f2ad).

Introduzca el punto final de su webhook en el campo etiquetado como URL de Webhook para mensaje entrante y haga clic en el botón [Guardar cambios].

Ahora, si alguno de tus números virtuales recibe un SMS, Vonage llamará a ese punto final de webhook con los detalles del mensaje.

Enviar un SMS de prueba

  1. Abra una nueva ventana de terminal y ejecute el programa server.js para que escuche los SMS entrantes:

    node server.js
  2. Envía un SMS de prueba a tu número de Vonage desde tu dispositivo móvil, con un mensaje de texto corto. Por ejemplo, "Este es un mensaje de texto corto".

Si todo está configurado correctamente debería recibir un Inbound SMS received mensaje en la ventana del terminal ejecutando server.js.

Ahora, vamos a escribir algo de código para analizar el SMS entrante y ver qué contiene el mensaje.

  1. Pulse [CTRL+C] para finalizar la ejecución. server.js aplicación.

  2. Crear una nueva función en server.js llamado displaySms():

    const displaySms = (msisdn, text) => {
        console.log('FROM: ' + msisdn);
        console.log('MESSAGE: ' + text);
        console.log('---');
    }
    
  3. También en server.js y antes de que su código envíe el 204 añada una llamada a displaySms() utilizando los siguientes parámetros:

    displaySms(params.msisdn, params.text);
    
  4. Reinicie server.js y, a continuación, envíe otro mensaje corto desde su dispositivo móvil. Esta vez, debería ver lo siguiente en la ventana del terminal en ejecución server.js:

    Inbound SMS received FROM: <YOUR_MOBILE_NUMBER> MESSAGE: This is a short text message.
  5. Visite server.js en marcha, pero esta vez utiliza tu dispositivo móvil para enviar un mensaje considerablemente más largo de lo que permite un solo SMS. Por ejemplo, la primera frase de "Historia de dos ciudades" de Dickens:

    It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way ... in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.'
    
  6. Comprueba la salida en la ventana del terminal que se está ejecutando server.js. Debería ver algo parecido a lo siguiente:

    ---
    Inbound SMS received
    FROM: <YOUR_MOBILE_NUMBER>
    MESSAGE: It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epo
    ---
    Inbound SMS received
    FROM: <YOUR_MOBILE_NUMBER>
    MESSAGE: ch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything
    ---
    Inbound SMS received
    FROM: <YOUR_MOBILE_NUMBER>
    MESSAGE: e the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of compariso
    ---
    Inbound SMS received
    FROM: <YOUR_MOBILE_NUMBER>
    MESSAGE:  before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way ... in short, the period was so far lik
    ---
    Inbound SMS received
    FROM: <YOUR_MOBILE_NUMBER>
    MESSAGE: n only.
    ---
    

¿Qué ha ocurrido? El mensaje ha superado el límite de bytes de un SMS, por lo que se ha enviado como varios mensajes SMS.

Para poder presentar estos mensajes a nuestros usuarios en el formato para el que fueron concebidos, necesitamos detectar si un mensaje entrante ha sido dividido de esta manera y volver a ensamblarlo a partir de las partes.

Observe en el resultado anterior que las piezas no llegaron en el orden correcto. Esto no es raro, así que tenemos que codificar nuestro webhook para manejar esta eventualidad.

Gestión de SMS multiparte

Vonage pasa cuatro parámetros especiales a tu webhook cuando se concatena un SMS entrante. (No aparecen en la solicitud cuando el SMS es de una sola parte.) Puedes usarlos para volver a ensamblar las partes individuales en un todo coherente:

  • concat:true - cuando se concatena el mensaje
  • concat-ref - una referencia única que permite determinar a qué SMS pertenece una determinada parte del mensaje
  • concat-total - el número total de partes que componen el SMS completo
  • concat-part - la posición de esta parte del mensaje en el mensaje completo, para que pueda volver a montar las partes en el orden correcto

Detectar si un mensaje está concatenado

En primer lugar, hay que detectar si un mensaje está concatenado. Modifique la directiva handleInboundSms() para que muestre un SMS de una sola parte al usuario de la forma habitual, pero realice un procesamiento adicional para los SMS de varias partes que implementarás en un paso posterior:

const handleInboundSms = (request, response) => {
    const params = Object.assign(request.query, request.body);

    if (params['concat'] == 'true') {
        // Perform extra processing
    } else {
        // Not a concatenated message, so display it
        displaySms(params.msisdn, params.text);
    }   
    
    // Send OK status
    response.status(204).send();
}

Almacena SMS de varias partes para procesarlos más tarde

Necesitamos almacenar todos los SMS entrantes que formen parte de un mensaje mayor para poder procesarlos una vez que tengamos todas las partes.

Declarar un array fuera del handleInboundSms() función llamada concat_sms. Si un SMS entrante forma parte de un mensaje más largo, guárdalo en la matriz:

let concat_sms = []; // Array of message objects

const handleInboundSms = (request, response) => {
    const params = Object.assign(request.query, request.body);

    if (params['concat'] == 'true') {
        /* This is a concatenated message. Add it to an array
           so that we can process it later. */
        concat_sms.push({
            ref: params['concat-ref'],
            part: params['concat-part'],
            from: params.msisdn,
            message: params.text
        });
    } else {
        // Not a concatenated message, so display it
        displaySms(params.msisdn, params.text);
    }   
    
    // Send OK status
    response.status(204).send();
}

Reunir todas las partes del mensaje

Antes incluso de intentar recomponer el mensaje a partir de sus partes, tenemos que asegurarnos de que disponemos de todas las piezas para una referencia de mensaje determinada. Recuerda que no hay garantía de que todas las partes lleguen en el orden correcto, así que no se trata sólo de comprobar si concart-part es igual a concat-total.

Podemos hacerlo filtrando el concat_sms para incluir únicamente los objetos SMS que comparten el mismo concat-ref como el SMS que hemos recibido. Si la longitud de esa matriz filtrada es igual a concat-totalEntonces tendremos todas las piezas de ese mensaje y podremos volver a ensamblarlas:

    if (params['concat'] == 'true') {
        /* This is a concatenated message. Add it to an array
           so that we can process it later. */
        concat_sms.push({
            ref: params['concat-ref'],
            part: params['concat-part'],
            from: params.msisdn,
            message: params.text
        });

        /* Do we have all the message parts yet? They might
           not arrive consecutively. */
        const parts_for_ref = concat_sms.filter(part => part.ref == params['concat-ref']);

        // Is this the last message part for this reference?
        if (parts_for_ref.length == params['concat-total']) {
            console.dir(parts_for_ref);
            processConcatSms(parts_for_ref);
        }
    } 

Volver a montar las partes del mensaje

Ahora que tenemos todas las partes del mensaje, pero no necesariamente en el orden correcto, podemos utilizar la función Array.sort() para reensamblarlos en orden de concat-part. Cree el processConcatSms() para hacerlo:

const processConcatSms = (all_parts) => {

    // Sort the message parts
    all_parts.sort((a, b) => a.part - b.part);

    // Reassemble the message from the parts
    let concat_message = '';
    for (i = 0; i < all_parts.length; i++) {
        concat_message += all_parts[i].message;
    }

    displaySms(all_parts[0].from, concat_message);
}

Prueba de recepción de un SMS concatenado

Ejecutar server.js y utilice su dispositivo móvil para volver a enviar el mensaje de texto largo que envió en el paso 5 de la sección Enviar un SMS de prueba sección anterior.

Si ha codificado todo correctamente, entonces en la pantalla server.js debería ver llegar las partes individuales del mensaje. Cuando se hayan recibido todas las partes, aparecerá el mensaje completo:

[ { ref: '08B5',
    part: '3',
    from: '<YOUR_MOBILE_NUMBER>',
    message: ' before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way ... in short, the period was so far lik' },
  { ref: '08B5',
    part: '1',
    from: '<YOUR_MOBILE_NUMBER>',
    message: 'It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epo' },
  { ref: '08B5', part: '5', from: 'TEST-NEXMO', message: 'n only.' },
  { ref: '08B5',
    part: '2',
    from: '<YOUR_MOBILE_NUMBER>',
    message: 'ch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything' },
  { ref: '08B5',
    part: '4',
    from: '<YOUR_MOBILE_NUMBER>',
    message: 'e the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of compariso' } ]
FROM: <YOUR_MOBILE_NUMBER>
MESSAGE: It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way ... in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.
---

Conclusión

En este tutorial, has creado una aplicación que te muestra cómo volver a ensamblar un SMS concatenado a partir de las partes que lo componen. Has aprendido sobre el concat, concat-ref, concat-totaly concat-part a su webhook SMS entrante y cómo puede utilizarlos para determinar:

  • Si se concatena un SMS entrante
  • A qué mensaje pertenece una parte específica del mensaje
  • Cuántas partes del mensaje componen el mensaje completo
  • El orden de una parte específica del mensaje dentro del mensaje completo

¿Y ahora qué?

Los siguientes recursos le ayudarán a utilizar Number Insight en sus aplicaciones: