Enviar y recibir SMS con Twilio desde Azure Functions

Hace un par de semanas un cliente me preguntó si era posible crearse un sistema serverless con el que no solo enviar sino que también recibir SMS. Lo cierto es que cuando me puse manos a la obra con ello no podía ser más fácil 🙂 En este post te cuento cómo gestionar este escenario con Azure Functions y Twilio.

Para este ejemplo voy a utilizar tres funciones:

  1. HandleMessage, que recepciona el mensaje que se quiere enviar.
  2. SendSMS, que se envía el mensaje a Twilio.
  3. SMSReceived, se recepciona el SMS enviado por el usuario a un número de móvil específico de Twilio.

HandleMessage

En esta función únicamente se recoge el mensaje que el usuario quiere enviar a través de SMS. Aquí sería interesante hacer todas las comprobaciones necesarias de que el mensaje está OK para ser enviado. Este se almacena en una cola de Azure Storage con el fin de que sea procesado por SendSMS.

const azure = require('azure-storage');
const QueueMessageEncoder = azure.QueueMessageEncoder;
module.exports = async function (context, req) {
    context.log('Notification Queue is processing a request.', req.body);
    var queueSvc = azure.createQueueService(process.env.smsqueueing_STORAGE);
    queueSvc.messageEncoder = new QueueMessageEncoder.TextBase64QueueMessageEncoder();
    queueSvc.createQueueIfNotExists(process.env.QUEUE_NAME, function (error, results, response) {
        if (!error) {
            queueSvc.createMessage(process.env.QUEUE_NAME, JSON.stringify(req.body), function (error, result, resp) {
                if (!error) {
                    context.res = {
                        status: 200,
                        body: 'notifications queued'
                    };
                }
                else {
                    context.res = {
                        status: 500,
                        body: error
                    };
                }
            });
        } else {
            context.res = {
                status: 500,
                body: error
            };
        }
    });
};

Puedes probarlo en el apartado Test de tu función:

Probando la función HanldeMessage

SendSMS

Esta función está a la escucha de la cola de mensajería donde HandleMessage depositó el mensaje que se quiere enviar a través de SMS. Cada vez que se recibe un mensaje en dicha cola se lanzará esta función, que utiliza la librería de Twilio para hacer el envío.

var client = require('twilio')(process.env.TWILIO_SID, process.env.TWILIO_TOKEN);
module.exports = async function (context, myQueueItem) {
    context.log('JavaScript queue trigger function processed work item: ', myQueueItem);
    context.log('myQueueItem.message: ' + myQueueItem.message);
    context.log('Sending to: ' + myQueueItem.phoneNumber);
    client.messages
        .create({
            body: myQueueItem.message,
            to: myQueueItem.phoneNumber,  
            from: process.env.TWILIO_PHONE
        })
        .then((message) => console.log(message))
        .done();
};

Este sería el resultado del mensaje que estaba en la cola desde HandleMessage y que acaba de procesar SendSMS:

Resultado de SendSMS

Para poder hacer el envío de un SMS debes de tener un número de teléfono comprado en Twilio, que tenga la característica de mensajería disponible. Puedes obtener una cuenta de trial aquí.

ReceivedSMS

Esta función no trabaja en conjunto con las otras dos pero si con Twilio. Para este ejemplo, su único cometido es recepcionar los mensajes que los usuarios envían a un número de teléfono y devolver al usuario el mensaje que había enviado.

const qs = require("querystring");
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    if (req.body) {
        const formValues = qs.parse(req.body);
        console.log('message received', formValues.Body);
        context.res = {
            status: 200,
            body: "Message received:  " + formValues.Body
        };
    }
    else {
        context.res = {
            status: 500,
            body: "Something bad happened :-("
        };
    }
};

Para que esta función pueda recibir los mensajes enviados, debes acceder a tu cuenta de Twilio, seleccionar el número del que quieres recibir los SMS, en el apartado Phone Numbers, y en la sección Messaging debes añadir como Webhook la URL de tu Azure Function:

Twilio – Webhook cuando se envía un SMS al número

En este ejemplo, el resultado sería parecido a este:

Resultado de SMSReceived

Por otro lado, en el apartado Messages Log podrás ver todo lo que ha ocurrido con tu envío y recepción de SMS:

Twilio – Messages Log

El código lo tienes disponible en mi GitHub.

¡Saludos!