Publicaci贸n y suscripci贸n a mensajes de AWS SNS con Node.js

    Introducci贸n

    Mucha de la tecnolog铆a que vemos se basa en un ciclo de solicitud / respuesta muy inmediato: cuando realiza una solicitud a un sitio web, obtiene una respuesta que contiene el sitio web que solicit贸, idealmente de inmediato. Todo esto depende de que el usuario tome la decisi贸n activa de solicitar esos datos.

    A veces, necesitamos alejarnos de ese modelo, y para eso usamos el modelo ‘publicar / suscribir’. Servicio de notificaci贸n simple de AWS (SNS) es un servicio s煤per escalable que permite a los usuarios implementar el modelo de publicaci贸n / suscripci贸n con facilidad. Esto nos permite enviar mensajes de texto, correos electr贸nicos, notificaciones autom谩ticas u otros mensajes autom谩ticos a otros objetivos a trav茅s de m煤ltiples canales al mismo tiempo.

    En esta publicaci贸n, aprenderemos c贸mo crear una aplicaci贸n web que pueda publicar un mensaje a varios suscriptores a la vez por correo electr贸nico, todos usando SNS.

    Obviamente necesitar谩s un Servicios web de Amazon (AWS) para hacer esto. Y afortunadamente, SNS tiene un nivel gratuito en el que sus primeras notificaciones push de 1M SNS son gratuitas cada mes.

    Modelo de publicaci贸n / suscripci贸n

    El modelo de publicaci贸n / suscripci贸n consta de dos componentes en un sistema:

    • Editor: Un servicio que puede difundir mensajes a otros servicios que lo escuchan (suscritos).
    • Abonado: Cualquier servicio al que el editor transmitir谩.

    Para convertirse en un suscriptor, un servicio debe notificar al editor que desea recibir sus transmisiones, as铆 como d贸nde quiere recibir esas transmisiones; en ese momento, el editor lo incluir谩 en su lista de objetivos cuando vuelva publica un mensaje.

    Una buena met谩fora para el modelo de publicaci贸n / suscripci贸n es cualquier bolet铆n al que se haya suscrito. En este caso, ha acudido activamente al editor y le ha dicho que desea suscribirse y le ha proporcionado su correo electr贸nico.

    No se hace nada de inmediato una vez que se ha suscrito y no recibe ning煤n n煤mero anterior del bolet铆n.

    La pr贸xima vez que el editor publica un mensaje (env铆a su bolet铆n mensual), llega un correo electr贸nico. Luego puede elegir hacer lo que quiera con el correo electr贸nico: puede eliminarlo, leerlo o incluso actuar sobre algunos de los detalles que contiene.

    Configurar un tema de SNS

    Para comenzar, primero debemos configurar un tema en AWS SNS. Un tema es lo que considerar铆amos un ‘editor’: podemos enviar mensajes a un tema, que luego publicar谩 para todos sus suscriptores.

    En su panel de AWS, seleccione ‘Servicio de notificaci贸n simple’ y presione ‘Temas’ en el lado izquierdo, seguido del bot贸n ‘Crear tema’.

    Se le presentar谩 una pantalla que le pedir谩 que proporcione informaci贸n b谩sica sobre el tema SNS:

    Esta pantalla tiene varias opciones, aunque solo muestra un grupo de forma predeterminada: este es el nombre (que es obligatorio) y el nombre para mostrar, que se puede configurar opcionalmente, esto se usa si desea publicar para los suscriptores de SMS desde el tema.

    Algunas de las otras opciones incluyen:

    • Cifrado de mensajes: Cifrado de mensajes despu茅s de haber sido enviados por el editor. Esto realmente solo es 煤til si est谩 enviando datos muy sensibles / personales.
    • Pol铆ticas de acceso: Define exactamente qui茅n puede publicar mensajes en el tema.
    • Pol铆tica de reintento: En el caso de que un suscriptor no reciba un mensaje publicado por cualquier motivo.
    • Registro de estado de entrega: Le permite configurar un rol de IAM (Identity and Access Management) en AWS que escribe registros de estado de entrega en AWS CloudWatch.

    Por ahora, vamos a completar un nombre y un nombre para mostrar, luego nos desplazaremos hasta el final y presionaremos ‘Crear tema’. Toma nota del ARN del tema reci茅n creado, ya que lo necesitaremos m谩s adelante.

    Configurar un usuario de IAM

    Usaremos el SDK de AWS JavaScript para interactuar con AWS SNS, y para poder hacerlo, necesitaremos un conjunto de credenciales que el SDK pueda usar para enviar solicitudes a AWS.

    Podemos obtener este conjunto de credenciales creando un usuario de IAM. Abra el men煤 ‘Servicios’ que usamos para buscar anteriormente, y esta vez busque IAM.

    Ver谩 una pantalla que se parece a esto:

    Haga clic en ‘Usuarios’ a la izquierda, luego haga clic en ‘Agregar usuario’; se encontrar谩 con una pantalla que se ve as铆:

    Para prop贸sitos de tutorial, creemos un usuario con el nombre SNSUsery marque la casilla de acceso program谩tico. Querremos acceder a 茅l a trav茅s de nuestra aplicaci贸n mediante programaci贸n, no solo a trav茅s de la consola de AWS.

    Esto permite que cualquier persona con las credenciales acceda a partes espec铆ficas de AWS a trav茅s de la CLI o el SDK de JavaScript que vamos a utilizar. No necesitamos darles acceso a la Consola de administraci贸n de AWS, ya que no planeamos que esas credenciales interact煤en con AWS a trav茅s de un navegador, como lo est谩 haciendo ahora.

    Haga clic en siguiente y se le presentar谩n los permisos. Haga clic en el bot贸n ‘Adjuntar pol铆ticas existentes directamente’ y, al buscar ‘SNS’, podr谩 encontrar f谩cilmente la opci贸n ‘SNSFullAccess’:

    Los usuarios, los roles y las pol铆ticas de IAM son un gran tema que definitivamente vale la pena investigar; sin embargo, por ahora, esto deber铆a funcionar para nosotros.

    Al presionar ‘Siguiente: Etiquetas’ en la esquina inferior derecha, y luego ‘Siguiente: Revisar’ en la misma ubicaci贸n, deber铆a ver una pantalla de resumen que se parece a esto:

    Nota: Aseg煤rese de copiar el ID de la clave de acceso y la Clave de acceso secreta o descargar el archivo CSV, ya que esta es la 煤nica vez que puede obtener estas credenciales; de lo contrario, deber谩 crear un nuevo usuario.

    Mientras hablamos de credenciales, aseg煤rese de no haga publique estas credenciales en cualquier lugar en l铆nea o cons煤ltelas en un repositorio de Git. Los malos actores rastrear谩n GitHub en busca de repositorios con credenciales para poder acceder a su cuenta de AWS y utilizar los recursos en ella, lo que le costar谩 algo de dinero.

    Finalmente, configuraremos nuestras credenciales localmente (Linux / OSX / Unix) para que nuestra aplicaci贸n Node pueda usarlas en el siguiente paso.

    Para determinar su regi贸n, visite esta p谩gina y encuentre la regi贸n m谩s cercana a usted. El valor predeterminado en AWS es us-east-2 – que tiene su sede en Ohio. Esta es la regi贸n que ver谩 cuando vea AWS en su navegador:

    touch ~/.aws/credentials
    echo '[sns_profile]' >> ~/.aws/credentials
    echo 'aws_access_key_id = <YOUR_ACCESS_KEY_ID>' >> ~/.aws/credentials # The access key ID from the IAM user
    echo 'aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>' >> ~/.aws/credentials # The secret access key from the IAM user
    echo 'region = <YOUR_AWS_REGION>' # From the regions page, examples include: us-east-1, us-west-1, eu-west-1, etc.
    

    Aplicaci贸n de demostraci贸n Node.js

    A continuaci贸n, crearemos una aplicaci贸n Node usando Express. Esta aplicaci贸n tendr谩 dos puntos finales. El primero ser谩 para agregar direcciones de correo electr贸nico como suscriptores a nuestro tema, el segundo ser谩 para enviar un correo electr贸nico a todos nuestros suscriptores.

    Nota: Mientras usamos el punto final de correo electr贸nico en esta demostraci贸n, el mismo c贸digo general se puede usar para cualquiera de los otros puntos finales SNS, como HTTP, SMS, Lambda, etc. Solo necesita intercambiar algunos par谩metros en la API de SNS. llamada.

    En primer lugar, creemos una carpeta para nuestro proyecto en nuestra terminal, vayamos al directorio e inicialicemos nuestra aplicaci贸n Node:

    $ mkdir node-sns-app
    $ cd node-sns-app
    $ npm init
    

    Puede presionar enter hasta que el script se complete con las opciones predeterminadas, haciendo nuestro punto de entrada predeterminado index.js.

    A continuaci贸n, necesitamos instalar los m贸dulos Express y AWS-SDK para que podamos usarlos a ambos:

    $ npm install express --save
    $ npm install aws-sdk --save
    

    A continuaci贸n, queremos crear nuestra aplicaci贸n. En el mismo directorio, cree un archivo llamado index.js:

    $ touch index.js
    

    Primero, ingresaremos un c贸digo solo para asegurarnos de que podamos ejecutar la aplicaci贸n con AWS:

    const express = require('express');
    const app = express();
    
    const AWS = require('aws-sdk');
    const credentials = new AWS.SharedIniFileCredentials({profile: 'sns_profile'});
    const sns = new AWS.SNS({credentials: credentials, region: 'eu-west-2'});
    
    const port = 3000;
    
    app.use(express.json());
    
    app.get('/status', (req, res) => res.json({status: "ok", sns: sns}));
    
    app.listen(port, () => console.log(`SNS App listening on port ${port}!`));
    

    La mayor parte de esto es repetitivo para Express, pero las l铆neas 4-6 crean una instancia de AWS, d铆gale que use las credenciales en el perfil que creamos en ~/aws/credentials anteriormente, y cree una instancia de la clase SNS con 茅l.

    Ahora, podemos seguir adelante y ejecutar el archivo:

    $ node index.js
    

    Visitando localhost:3000/status imprimir谩 una gran parte de JSON que contiene sus credenciales de AWS. Si eso funciona, podemos seguir adelante y crear nuestros puntos finales.

    Punto final de suscripci贸n

    Primero, necesitamos agregar un punto final POST para agregar suscriptores, en este caso, nuevas direcciones de correo electr贸nico. Bajo el /status punto final, agregaremos el /subscribe punto final:

    app.post('/subscribe', (req, res) => {
        let params = {
            Protocol: 'EMAIL', 
            TopicArn: '<YOUR_TOPIC_ARN_HERE>',
            Endpoint: req.body.email
        };
    
        sns.subscribe(params, (err, data) => {
            if (err) {
                console.log(err);
            } else {
                console.log(data);
                res.send(data);
            }
        });
    });
    

    Bien, repasemos esto. Primero, estamos creando un punto final POST. Dentro de ese punto final, estamos creando una variable de par谩metros lista para entregar a nuestra solicitud de suscripci贸n a SNS.

    La variable de par谩metros necesita algunas cosas:

    • Protocol: Lo hemos configurado como correo electr贸nico, pero podr铆a ser HTTP / S, SMS, SQS (si desea utilizar el servicio de cola de AWS) o incluso una funci贸n Lambda.
    • TopicArn: Este es el ARN, un identificador 煤nico para el tema de SNS que configur贸 anteriormente. Si no lo tienes, t贸malo de tu tema en tu navegador y p茅galo en el c贸digo ahora.
    • Endpoint: El tipo de punto final depende del protocolo. Como estamos enviando correos electr贸nicos, le dar铆amos una direcci贸n de correo electr贸nico, pero si estuvi茅ramos configurando una suscripci贸n HTTP / S, pondr铆amos una direcci贸n URL o un n煤mero de tel茅fono para SMS.

    Puedes leer m谩s sobre el m茅todo de suscripci贸n. de la documentaci贸n oficial.

    Una vez que est茅 dentro, inicie su servidor nuevamente. Deber谩 enviar una solicitud con un cuerpo JSON a su aplicaci贸n; puede hacerlo con herramientas como Postman o, si lo prefiere, puede hacerlo en la CLI:

    $ curl -H "Content-type: application/json" -d '{ "email": "<AN_EMAIL_ADDRESS_HERE>" }' 'localhost:3000/subscribe'
    

    Si el punto final y el mensaje son correctos, esa direcci贸n de correo electr贸nico recibir谩 un correo electr贸nico que le preguntar谩 si desea confirmar su suscripci贸n; cualquier suscripci贸n creada a trav茅s de AWS SNS debe ser confirmada por el punto final de alguna forma; de lo contrario, AWS podr铆a usarse de forma maliciosa para enviar spam o Ataques de tipo DDOS.

    Aseg煤rese de confirmar la suscripci贸n antes del siguiente paso para cualquier correo electr贸nico al que se suscriba.

    Punto final de correo electr贸nico

    Ahora para hacer el punto final para enviar nuestro correo electr贸nico:

    app.post('/send', (req, res) => {
        let params = {
            Message: req.body.message,
            Subject: req.body.subject,
            TopicArn: '<YOUR_TOPIC_ARN_HERE>'
        };
    
        sns.publish(params, function(err, data) {
            if (err) console.log(err, err.stack); 
            else console.log(data);
        });
    });
    

    Nuevamente, echemos un vistazo a de qu茅 est谩n hechos los par谩metros aqu铆:

    • Message: Este es el mensaje que desea enviar; en este caso, ser铆a el cuerpo del correo electr贸nico
    • Subject: Este campo solo se incluye porque estamos enviando un correo electr贸nico; esto establece el asunto del correo electr贸nico
    • TopicArn: Este es el tema en el que estamos publicando el mensaje; esto se publicar谩 para todos los suscriptores de correo electr贸nico para ese tema.

    Si desea obtener m谩s informaci贸n sobre el m茅todo de publicaci贸n, consulte la documentaci贸n, tambi茅n hay otras propiedades.

    Puede enviar un mensaje ahora usando Postman, o curl – siempre que pasemos nuestros par谩metros para el asunto y el mensaje:

    $ curl -H "Content-type: application/json" -d '{ "subject": "Hello there!", "message": "You just received an email from SNS!" }' 'localhost:3000/send'
    

    Una vez realizada esta solicitud, todos los suscriptores del punto final deber铆an recibir este correo electr贸nico. 隆Felicitaciones, acaba de publicar su primer mensaje usando SNS y Node.js!

    驴Qu茅 sigue?

    Plantillas de mensajes

    Dado que su mensaje es una cadena, puede utilizar la interpolaci贸n de cadenas para la entrada din谩mica, por ejemplo:

    app.post('/send', (req, res) => {
        let now = new Date().toString();
        let email = `${req.body.message} n n This was sent: ${now}`;
        let params = {
            Message: email,
            Subject: req.body.subject,
            TopicArn: '<YOUR_TOPIC_ARN_HERE'
        };
    
        sns.publish(params, function(err, data) {
            if (err) console.log(err, err.stack); 
            else console.log(data);
        });
    });
    

    Puntos finales HTTP

    Puede configurar un servicio dise帽ado para recibir el mensaje, en caso de que desee activar una acci贸n en segundo plano, pero no necesariamente se preocupe por recibir el resultado de inmediato. Simplemente configure el punto final como HTTP / S y podr谩 formatear el mensaje como desee. Por ejemplo, esto es especialmente 煤til para servidores / servicios sobre los que es posible que no tenga control, pero que le permiten enviar notificaciones de webhooks.

    Lambda

    De manera similar, podr铆a usar estos mensajes para activar y entregar entradas a las funciones Lambda. Esto podr铆a iniciar un trabajo de procesamiento, por ejemplo. 隆Echa un vistazo a esta publicaci贸n para descubrir c贸mo!

    SMS

    Si quita el subject , puede enviar mensajes SMS de 160 caracteres a cualquier n煤mero de tel茅fono suscrito.

    SQS

    Con el tipo de punto final SQS, puede poner mensajes en colas para construir arquitecturas controladas por eventos; consulte este art铆culo para obtener m谩s detalles.

    驴Mensajes mixtos?

    Hay un MessageStructure par谩metro que puede entregar y que le permite usar en Topic para transmitir en m煤ltiples canales con diferentes mensajes; esto significa que puede escribir un correo electr贸nico completo para todos los suscriptores de correo electr贸nico, pero al mismo tiempo enviar un mensaje optimizado para SMS a todos suscriptores m贸viles, lo que permite comunicaciones de m煤ltiples canales!

    Conclusi贸n

    Servicio de notificaci贸n simple de AWS (SNS) es un servicio s煤per escalable que permite a los usuarios implementar el modelo de publicaci贸n / suscripci贸n con facilidad. Esto nos permite enviar mensajes de texto, correos electr贸nicos, notificaciones autom谩ticas u otros mensajes autom谩ticos a otros objetivos a trav茅s de m煤ltiples canales al mismo tiempo.

    En este art铆culo, creamos un tema y nos suscribimos a 茅l mediante programaci贸n utilizando el AWS SDK de Node.js. Luego creamos puntos finales HTTP en nuestra aplicaci贸n de demostraci贸n que permite a los usuarios suscribirse a nuestro tema SNS por correo electr贸nico, y otro punto final para transmitir un correo electr贸nico a todos los suscriptores.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *