IT & Engineering
Cómo la aplicación de Node.js Cloud Monitoring utiliza la API de Mailgun para automatizar el flujo de trabajo de emails
Este artículo está escrito por Dan Di Spaltro, director de producto de Rackspace Cloud Monitoring. Cloud Monitoring te permite monitorizar cualquier servidor en cualquier centro de datos para que siempre puedas asegurarte de que la infraestructura de tu aplicación está en perfectas condiciones. Antes de dirigir el equipo de ingeniería de Cloud Monitoring, Dan cofundó Cloudkick, una startup de Y-Combinator centrada en la monitorización de infraestructura en la nube que Rackspace adquirió en 2010.
El equipo de ingeniería de Rackspace siempre busca formas de utilizar los productos de Rackspace en las soluciones que creamos para los clientes. Creemos que al utilizar nuestros propios productos, creamos un mejor software para nuestros clientes, ya que podemos dar nuestra opinión al equipo que se sienta justo al otro lado del pasillo. Durante la adquisición de Mailgun por parte de Rackspace, tuvimos una oportunidad única para probar el nuevo conjunto de servicios de Rackspace en nuestro producto Cloud Monitoring. Gran parte de lo que hace Cloud Monitoring cuando se produce un error es enviar un email al cliente. Estos emails pueden activarse cuando el sitio web monitorizado agota el tiempo de espera, responde con un error 404 o cuando se cumple alguna otra condición personalizada en tu lenguaje de alarmas. Cuando investigamos Mailgun, nuestro objetivo era habilitar de forma fiable notificaciones por email para nuestros clientes, no dominar los detalles de la creación de emails, la entrega y las analíticas, tres componentes esenciales de la automatización de emails a nuestra escala. Cuando probamos Mailgun, nos impresionó mucho. Obtuvimos los beneficios que esperábamos e incluso algunos que no. Por ejemplo:
- Gestión lógica de rebotes: Mailgun ofrece una forma racional basada en la API para lidiar con los rebotes, que ocurren con frecuencia por muchos motivos diferentes.
- Analíticas y etiquetas: probamos constantemente escenarios de fallo en nuestro entorno de producción, así que necesitábamos una forma de aislar ciertas cuentas que hemos marcado como “especiales”. Mailgun puede segmentar todos los informes basándose en etiquetas, lo que facilita las pruebas.
- Trazabilidad: enviar solo un email no es suficiente para nuestro equipo. Los registros de Mailgun proporcionan una vista de principio a fin de lo que ha ocurrido exactamente con cada email.
Antes de ver cómo implementamos y lanzamos Mailgun, echemos un vistazo a la arquitectura de Cloud Monitoring
Pipeline de Cloud Monitoring
El sistema Cloud Monitoring de Rackspace se divide en un pipeline de diferentes servicios. A modo de recordatorio, echemos un vistazo panorámico a la arquitectura.

Cada paso representa uno o más servicios distribuidos, conectados por un flujo de datos. Utilizamos el software Scribe de Facebook para la distribución punto a punto, el enrutamiento y el almacenamiento en búfer. Con ese flujo de datos, podemos dividir, analizar y distribuir los datos a cualquier rincón de la infraestructura que queramos. Experimentar fácilmente con el flujo de datos es fundamental para nuestra velocidad. Nos permite enviar datos a cualquier lugar y es una parte fundamental del diseño que respalda nuestra alta disponibilidad, así como la aceleración y el desarrollo del producto (dato curioso: por eso el nombre en clave del producto es ELE.).
Preparación para la prueba
En un sistema de producción, hacer un cambio radical nunca es buena idea, así que decidimos adoptar un enfoque distinto. Primero introdujimos Mailgun de forma gradual en las cuentas que usamos para nuestras pruebas. Esto nos permitió ir más allá de las microvalidaciones y las validaciones de pruebas unitarias para familiarizarnos con el sistema. Gracias a la sencilla asistencia para HTTP en Node.js, pudimos realizar esta integración rápidamente.
Simulación de la API de Mailgun
Siempre que añadimos una dependencia externa, intentamos simular la API si es posible. Simular una API externa puede ser muy sencillo o muy elaborado, pero no por ello deja de ser importante. Nuestro objetivo no es añadir trabajo extra al equipo de desarrollo, sino mantener la confianza en nuestras interacciones con un servicio externo y en cómo se supone que debe funcionar. Hoy en día, la mayoría de las API tienen versiones, por lo que los cambios importantes vienen acompañados de un salto de versión. Esto nos permite simular las API de forma rápida y segura para crear pruebas de principio a fin más elaboradas en un entorno controlado. Después de determinar cómo queríamos implementar la prueba en nuestra cuenta de pruebas, creamos nuestra propia API de Mailgun, lo que nos permitió familiarizarnos con la nueva integración. Este proceso fue sumamente sencillo. La API de Mailgun ofrecida por todas las operaciones salientes y analíticas fue sencilla y directa de implementar. Solo después de la simulación nos dimos cuenta de que existe un modo de prueba en un entorno aislado para enviar emails, pero aun así fue una valiosa experiencia de aprendizaje.
Reemplazo quirúrgico
Con los preparativos para la prueba terminados, empezamos a implementar y monitorizar el rendimiento de los emails para ganar la confianza de que Mailgun era algo que podíamos lanzar a nivel más amplio a nuestra base de usuarios. En la aplicación Cloud Monitoring, el componente para garantizar la entrega de una alerta es un complejo elemento de software acertadamente llamado messenger. Realiza diversas tareas para aumentar la fiabilidad de nuestras notificaciones por email. A nivel interno, messenger es un pipeline de ejecución por etapas. Consta de las siguientes etapas:
- Recibir el mensaje
- Bloquear el átomo del mensaje
- Realizar búsquedas de cuenta/entidad/verificación/alarma
- Buscar el plan de notificación
- Entregar las alertas
- Crear el email
- Entregar
- Seguimiento
Durante la prueba, añadimos programación para observar la cuenta especial durante la etapa Entregar las alertas e iniciar el enrutamiento de mensajes a Mailgun. Este proceso fue sencillo porque implicaba muy poca programación. Este es el aspecto de un fragmento:
if (tenantId === 'XXX') {rn emailUtil.sendMailgunEmail(address, subject, body, { headers: headers }, function (err, res) {rn var delta = (Date.now() - startTime);rnrn accessLog.logAccess(ctx, 'mailgun', misc.getUnixTimestamp(), delta, err);rnrn if (err) {rn log.error('error performing email notification', { ctx: ctx, err: err });rn callback(err);rn return;rn }rnrn callback(null, 'Email successfully sent', body);rn });rn} else {rn // ...rn}
¿Qué está pasando aquí arriba? En primer lugar, llamamos a la función sendMailgunEmail para entregar el email de notificación de monitorización. En nuestro afán por medirlo TODO, también medimos el tiempo que se tarda en usar la API de Mailgun. Y hay una serie de reintentos que envuelve esta programación con una alternativa, una de las mejores prácticas al depender de cualquier sistema de terceros en tu aplicación. ¿Quieres ver lo sencilla que es la función sendMailgunEmail?
exports.sendMailGunEmail = function(address, subject, body, options, callback) {rn options = options || {};rn options.headers = options.headers || {};rn options.apiUrl = options.apiUrl || settings.MAILGUN_API_URL;rn options.domain = options.domain || settings.MAILGUN_DOMAIN;rn options.apiKey = options.apiKey || settings.MAILGUN_API_KEY;rn options.fromAddress = options.fromAddress || settings.MAILGUN_FROM_ADDRESS;rn options.testMode = options.testMode || settings.MAILGUN_TEST_MODE;rnrn var url = options.apiUrl + options.domain + '/messages',rn bodyObj, k, httpOptions;rnrn httpOptions = { // 1) set up some defaultsrn 'expected_status_codes': [200],rn 'return_response': true,rn 'parse_json': true,rn 'username': 'api',rn 'password': options.apiKey,rn 'headers': { 'Content-Type': 'application/x-www-form-urlencoded' }rn };rnrn bodyObj = {rn 'to': address,rn 'subject': subject,rn 'from': options.fromAddressrn };rnrn if (options.isHTML) { // 2) switch based on the content type we want to sendrn bodyObj.html = body;rn } else {rn bodyObj.text = body;rn }rnrn for (k in options.headers) { // 3) merge in the headers so we can provide id’s as headers in the emailsrn if (options.headers.hasOwnProperty(k)) {rn bodyObj['h:' + k] = options.headers[k];rn }rn }rnrn if (options.testMode) { // 4) enable sandbox testingrn bodyObj['o:testmode'] = true;rn }rnrn if (options.tags) { rn // 5) set some tags to automatically pivot analytics for visibility.rn // (we view reporting in the Mailgun control panel but data is also available via API or webhook)rn bodyObj['o:tag'] = options.tags;rn }rnrn body = querystring.stringify(bodyObj);rn request(url, 'POST', body, httpOptions, callback);rn};
1) La función de solicitud abstrae en parte el tratamiento de solicitudes HTTP complejas y el manejo de códigos de respuesta, por lo que para ello se utilizan los códigos de respuesta esperados.
2) Gestiona fácilmente el envío de HTML, lo que por lo general supone un fastidio.
3) Incorpora encabezados para permitir una manera fácil de enriquecer los emails. Estos encabezados nos permiten crear emails personalizados para cada perfil de usuario con detalles sobre su alerta, como alarmId, checkId y tenantId. A través de estos encabezados puedes pasar casi cualquier elemento para personalizar tus emails que, por lo general, solo saturaría el cuerpo del email.
4) Modifica un bit fácilmente para enviar emails de prueba.
5) Las etiquetas definidas de forma personalizada permiten el seguimiento y el filtrado analítico que usamos en nuestros escenarios de pruebas de producción.
Fíjate en lo fácil que fue esto. Hemos automatizado completamente la creación, la entrega y el seguimiento de emails usando Mailgun, algo que resulta difícil con una configuración tradicional de estilo “hazlo tú mismo”.
Resumen
Cambiar a una solución alojada es una gran decisión para cualquier aplicación, en especial para algo tan crítico como las notificaciones por email. Gracias a un plan de pruebas riguroso y a la incondicional asistencia del equipo de Mailgun en todo, desde la configuración de los registros DKIM hasta la integración de la API, pudimos transferir con éxito todas nuestras notificaciones por email de Cloud Monitoring a Mailgun. Como ventaja adicional, el equipo de Mailgun se sienta justo a mi lado ;). P. D.: Estamos contratando!