Conecta WhatsApp con Node.JS + AWS & Serverless
Hace un año aproximadamente luego de una conferencia de tecnología, cuatro amigos nos reunimos en un bar a hablar acerca de todas las nuevas ideas que aquella charla nos había inspirado. Una de esas ideas fue un Bot para manejar nuestras finanzas.
La idea era sencilla, usar WhatsApp Web para escribir comandos y guardar poco a poco las compras que se habían realizado.
Poco tiempo después me di a la tarea de buscar cuáles eran la mejores herramientas para hacer esta tarea. Luego de experimentar muchas veces, hoy traigo para ti la forma más sencilla de enviar y recibir mensajes usando WhatsApp.
Twilio recibe los mensajes por ti
Twilio es una compañía que ofrece servicios para comunicar empresas con sus clientes por distintos medios, permite hacer y recibir llamadas de voz, envío de SMS & MMS y lo más importante, permite conectar e implementar WhatsApp de la manera que tú necesites.
¿Cómo funciona? Twilio funciona como intermediario entre tu cuenta de WhatsApp y tú. Te ofrece un WebHook HTTPS para que se envíe una solicitud POST a la URL que quieras cada vez que se reciba un mensaje y responderlo en esa misma solicitud.
También ofrece la posibilidad de enviar mensajes a WhatsApp usando su API o sus librerías en Node.JS, PHP, C++ y más.
Por tu registro, Twilio te regala $15 USD para iniciar a probar sus servicios. Además te ofrece un número de teléfono público para hacer tus pruebas sin necesidad de comprar un número.
AWS API Gateway & Lambdas
Después de saber que Twilio ofrece un WebHook para que yo procese los mensajes recibidos, supe que esa era la dirección por donde debería ir, me llevaba al siguiente puente a cruzar, necesito una API HTTP para recibir y responder los mensajes.
Tenía claro que era un proyecto que quería completar rápido usando herramientas que me permitan desplegar, monitorizar y mantener el servicio con poco esfuerzo. Todo esto lo tiene AWS con API Gateway & Lambdas.
Usando un recurso en API Gateway con pocos pasos puedes tener una URL pública conectada a una función Lambda que se ejecutaría cada vez que alguien visite a esa URL.
¿Quires saber más sobre AWS Lambdas? Revisa por acá
Regístrate en Twilio y busca tus credenciales de acceso:
Las credenciales de acceso aparecen en el panel principal y son el ACCOUNT SID & AUTH TOKEN. Guarda bien estas credenciales porque las usaremos más adelante para conectarnos con Twilio.
Agrega tu número de WhatsApp al sandbox para iniciar las pruebas
Iremos a las configuraciones de SMS que comparte sus funciones con WhatsApp. Puedes buscar en la barra lateral de la página para encontrar el menú de SMS o ir a esta url: https://www.twilio.com/console/sms/dashboard.
En esta página Twilio te pide que envíes un mensaje vía WhatsApp al número +14155238886
con un código único para tu cuenta.
El mensaje comúnmente es join algo-algo. Puedes enviar este mensaje desde distintos teléfonos y todos recibir mensajes desde tus implementaciones.
😎Envía tus primeros mensajes a WhatsApp
Ya que tienes registrado el teléfono con el que realizarás tus pruebas, usemos la primera forma de comunicarnos a WhatsApp usando Twilio, esta es enviar mensajes desde un script Node.JS.
Necesitaremos la librería de Twilio que la puedes instalar usando npm: npm install twilio
También necesitaremos tener a la mano las credenciales (token de autorización y el número de tu cuenta) que aparecen en el panel principal:
Puedes darte cuenta lo sencillo que es enviar mensajes una vez hayas configurado un número de teléfono al sandbox de Twilio.
- Ten en cuenta que si no agregas el prefijo
whatsapp:
estos mensajes que envíes serán tomados como SMS y no será enviados a WhatsApp. - En
NUMBER_TO
se encuentra el número al que le enviaste el código único de tu cuenta join algo-algo. - Una vez enviado el mensaje, Twilio te responderá con identificadores del mensaje, información del estado del envío y más meta-datos.
Cuando ejecutes ese script, deberás recibir un mensaje enviado desde tus scripts hasta tu número de WhatsApp:
También puedes usar las opciones de formato de texto para los mensajes y que luzcan mucho mejor.
Ahora, recibe mensajes y responde desde tu API Gateway
Ya que sabes enviar mensajes desde tu app hacia WhatsApp, ahora vamos a usar los WebHooks de Twilio para recibir los mensajes que tú o tus clientes te escriban.
En la misma carpeta del proyecto vamos a crear un nuevo archivo para el código de la función Lambda que se ejecutará cuando te envíen un mensaje:
Los eventos que llegan desde Twilio lucen como una cadena de QueryStrings, esta información la obtenemos del parámetro event event.body
y luce así:
SmsMessageSid=SM3c3ff9725fb812f9241dbe8984d548af&NumMedia=0&SmsSid=SM3c3ff9725fb812f9241dbe8984d548af&SmsStatus=received&Body=Total+Comida&To=whatsapp%3A%2B14155238886&NumSegments=1&MessageSid=SM3c3ff9725fb812f9241dbe8984d548af&AccountSid=ACad2018f4db8a989f76b83d55e83d19ca&From=whatsapp%3A%2B57300000000&ApiVersion=2010-04-01
Puedes usar cualquier otra librería para convertir este queryString a un objeto, en el código de arriba hay una implementación rápida para obtener el dato que nos interesa, el Body.
El texto que decidas enviar a Twilio puedes construirlo como una cadena de texto y también usar los formatos de texto de WhatsApp como en la forma anterior.
Para crear el mensaje de respuesta debemos hacer uso de la clase MessagingResponse
creando una nueva instancia y configurarle el mensaje que le queremos enviar. (Linea 20,21)
Una vez tengamos todo listo, retornamos un objeto con la información de los headers, el statusCode y el body que se entregará.
- Es importante que establezcamos
Content-Type: "text/xml"
ya que este es el tipo de contenido que acepta Twilio. - Para enviar el body, convertimos el contenido de
MessagingResponse
a String, esto generará el mensaje acompañados de tags XML de Twilio.
Listos para desplegar
Teniendo lista la función Lambda, preparemos el despliegue en un archivo serverless.yml
para que podamos enviar con un solo comando nuestra API Gateway y Función Lambda.
Este archivo debemos dejarlo en la raíz de nuestro proyecto y modificar el handler de la función por la ruta donde se encuentre tu función lambda.
La ruta que crearemos será /whatstapp/webhook
para el método POST
, una vez despleguemos nuestra función, podremos usar esta ruta para configurarla como WebHook en Twilio.
Ya estamos a punto de desplegar la función, necesitarás tener ya instalado
serverless & aws-cli
configurados con tu cuenta de AWS.
Cuando tengas todo listo, vamos a la consola, nos ubicamos en la raíz del proyecto y ejecutamos serverless deploy
. Cuando termine de desplegar, serverless te mostrará la URL asignada a tu ruta.
Cuando serverless termine de desplegar nuestra función lambda y la API Gateway en sus servidores nos mostrará la URL en la sección de endpoints, copiamos esta URL y la llevamos a Twilio en la sección de configuración SMS.
Puedes ir a este link directamente: https://www.twilio.com/console/sms/whatsapp/sandbox
Acá, pegaremos la URL generada por AWS y así, Twilio redireccionará todos los mensajes que escribamos. Una vez agregada, le damos click en guardar.
¡Ahora, probemos!
En teoría, cuando enviemos un mensaje, nuestra respuesta será:
Your message was: ${BodyMessage}\n This is a response from NodeJS
Cuando sabemos como interactuar con Twilio y WhatsApp hay muchas posibilidades para crear grandes aplicaciones, puedes usarlo de recordatorios, alarmas, conectarlo con una base de datos para escribir y leer datos y más…
Te dejo el repo de este proyecto por acá.
¡Espero te haya gustado este post, no olvides seguirme en mi cuenta de Twitter @FlavioAandres si tienes inquietudes!