Dev Life

Creación de flujos de trabajo de emails transaccionales para notificaciones de envío con la API de Mailgun

Los clientes esperan recibir actualizaciones en tiempo real en el momento en que su pedido se pone en marcha. Esta guía te explica cómo crear un flujo de trabajo de emails transaccionales fiable para notificaciones de envío con la API de Mailgun y BullMQ, para que tus emails lleguen a la bandeja de entrada justo cuando deben.
Imagen para Creación de flujos de trabajo de emails transaccionales para notificaciones de envío con la API de Mailgun

Cuando pides algo por internet, esperas saber exactamente dónde está y cuándo llegará. Los flujos de trabajo de emails transaccionales ayudan a hacer posible este tipo de comunicación puntual.

A diferencia de los emails de marketing que promocionan productos, los emails transaccionales se envían en respuesta a la acción de un usuario, como realizar un pedido u obtener una actualización de envío. Proporcionan detalles en tiempo real que mantienen a los usuarios al tanto en cada etapa del proceso.

En este artículo, aprenderás a crear un flujo de trabajo de emails transaccionales para notificaciones de envío con la API de Mailgun. El flujo de trabajo incorporará BullMQ, un potente sistema de colas de trabajos, para poner en cola y procesar notificaciones por email de forma separada a la lógica principal de la aplicación y mejorar así la escalabilidad y el rendimiento. Esto resulta útil para aplicaciones con mucho tráfico en las que enviar emails directamente dentro de un ciclo de solicitud y respuesta podría ralentizar el sistema.

Implementación de flujos de trabajo de emails transaccionales para notificaciones de envío con la API de Mailgun

Para seguir este tutorial, necesitas estas herramientas y cuentas:

Antes de profundizar en la implementación, echemos un vistazo al flujo de trabajo:

transactional email workflows diagram

A continuación te explicamos cómo funciona el proceso:

  • El equipo de envíos (o cualquier persona encargada de gestionar las actualizaciones de envío) envía una solicitud HTTP para actualizar el estado del pedido
  • El servidor Express actualiza el estado del pedido en la base de datos SQLite y pone en cola un trabajo en BullMQ
  • Un proceso de trabajo de BullMQ procesa los trabajos de la cola e interactúa con la API de Mailgun para enviar un email al cliente
  • El proceso de trabajo reintenta automáticamente los trabajos fallidos
  • Mailgun entrega el email al cliente

Configuración de la cuenta de Mailgun

Para usar la API de Mailgun, necesitas un dominio de Mailgun y una clave de API para la autenticación. Mailgun proporciona dos tipos de dominios: dominios sandbox para pruebas y dominios personalizados para su uso en entornos de producción.

En esta guía, utilizarás un dominio sandbox. Cada cuenta de Mailgun incluye uno de forma automática, por lo que no es necesario que lo crees manualmente. Para obtener tu dominio sandbox, inicia sesión en tu cuenta de Mailgun y, a continuación, ve a Send > Sending > Domains en la barra lateral. Copia tu dominio:

Send > Sending > Domains Screen Image

Por defecto, un dominio sandbox solo puede enviar emails a destinatarios autorizados. . Para configurar un email como destinatario autorizado, haz clic en tu nombre de dominio en la página Domains para ver sus ajustes. En la pestaña Setup, en Add authorized recipients, añade la dirección de email a la que quieres enviar emails. Asegúrate de seguir las instrucciones enviadas a la dirección de email que has proporcionado para configurarla como destinatario autorizado:

Add authorized recipients Screen Image

Para obtener tu clave de API, ve a la página API Keys y haz clic en Add new key para crear una nueva clave de API. Dale un nombre a la clave y haz clic en Create Key. A continuación, asegúrate de copiar el valor de tu clave porque solo se mostrará una vez:

API Keys page Screen Image

Configuración de la plantilla de inicio

Para que este tutorial se centre en la creación de flujos de trabajo de emails transaccionales, hemos preparado una plantilla de inicio para que puedas desarrollarla. Clona la plantilla en tu máquina local ejecutando el siguiente comando en tu terminal:

git clone --single-branch -b starter-template https://github.com/kimanikevin254/mailgun-transactional-email-workflows.git

Estos son los archivos clave del proyecto:

  • src/controllers/order.controller.ts contiene dos métodos:
    • index renderiza la interfaz de administración, que se define en src/views/admin.ejs
    • updateOrderStatus actualiza el estado del pedido en la base de datos
  • src/database/entity/order.entity.ts define la entidad de pedido
  • src/database/entity/user.entity.ts define la entidad de usuario
  • src/database/seed.ts llena la base de datos con un usuario y un pedido de muestra
  • docker-compose.yml ejecuta Redis en Docker, que es necesario para BullMQ

Instala todas las dependencias usando el siguiente comando:

npm install

A continuación, cambia el nombre del archivo .env.example a .env y sustituye los marcadores de posición de MAILGUN_DOMAIN y MAILGUN_API_KEY por las credenciales que obtuviste en el panel de control de Mailgun. Para la variable MAIL_FROM, proporciona tu dirección de email como valor.

A continuación, abre el archivo src/database/seed.ts y sustituye los marcadores de posición de la constante userInfo por tu información. Para el email, asegúrate de proporcionar uno que hayas añadido como destinatario autorizado.

Finalmente, llena la base de datos ejecutando el comando npm run db:seed en tu terminal. Ahora puedes ejecutar el proyecto con el comando npm run dev y visitar http://localhost:3000 en tu navegador para ver y actualizar el estado del pedido:

order status management screen image

En la siguiente sección, implementarás un flujo de trabajo que envía automáticamente un email al usuario cuando se actualiza el estado del pedido.

Diseño de las plantillas de email

Las plantillas de email bien diseñadas mejoran la legibilidad, enriquecen la experiencia de usuario y garantizan que tus emails se vean profesionales en distintos dispositivos. En esta sección, crearás plantillas que harán que tus emails transaccionales sean claros, atractivos y eficaces.

Un pedido pasa por tres estados (enviado, en reparto y entregado), tal y como se define en el tipo OrderStatus de src/types/index.ts. Crearás una plantilla de email correspondiente para cada estado para mantener a los clientes informados en cada paso.

Para ello, crea un archivo en src/email-templates/html/shipped.html y añade el siguiente código:

                                

                                    <!DOCTYPE html>rn<html>rn<head>rn    <meta charset="UTF-8" />rn    <title>Order Shipped</title>rn</head>rn<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; text-align: center;">rnrn    <div style="background: #ffffff; padding: 20px; border-radius: 8px; max-width: 600px; margin: auto; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);">rnrn        <div style="background-color: #007bff; color: white; padding: 15px; font-size: 22px; font-weight: bold; border-top-left-radius: 8px; border-top-right-radius: 8px;">rn            Your Order Has Been Shipped! ✈️rn        </div>rnrn        <div style="padding: 20px; font-size: 16px; color: #333; text-align: left;">rn            <p style="margin: 0 0 10px;">Hello, <%= name %></p>rn            <p style="margin: 0 0 10px;">Your order has been shipped and is on its way to you. 📦</p>rn            <p style="margin: 0 0 10px;"><strong>Tracking Number:</strong> <%= trackingNumber %></p>rn            <p style="margin: 0 0 10px;">You can track your package below. We hope you enjoy your purchase!</p>rnrn            <a href="https://yourwebsite.com/track?trackingNumber=<%= trackingNumber %>"rn               style="background-color: #007bff; color: white; text-decoration: none; padding: 12px 18px; border-radius: 5px; display: inline-block; margin-top: 15px; font-weight: bold;">rn                Track Your Shipmentrn            </a>rn        </div>rnrn        <div style="background-color: #f4f4f4; padding: 10px; font-size: 14px; color: #555; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;">rn            Thank you for shopping with us! 🛒rn        </div>rn    </div>rn</body>rn</html>rn
                                
                            

Esta plantilla de email se utiliza para notificar a los clientes que su pedido ha sido enviado. Incluye marcadores de posición para el nombre del cliente y el número de seguimiento, que se rellenarán dinámicamente mediante EJS al renderizar la plantilla. Las plantillas para los otros dos estados del pedido seguirán el mismo formato.

Crea una plantilla para notificar a los usuarios que su pedido está en reparto. Para ello, crea un archivo llamado out_for_delivery.html en la carpeta src/email-templates/html y añade el siguiente código:

                                

                                    <!DOCTYPE html>rn<html>rn<head>rn    <meta charset="UTF-8" />rn    <title>Out for Delivery</title>rn</head>rn<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; text-align: center;">rnrn    <div style="background: #ffffff; padding: 20px; border-radius: 8px; max-width: 600px; margin: auto; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);">rnrn        <div style="background-color: #28a745; color: white; padding: 15px; font-size: 22px; font-weight: bold; border-top-left-radius: 8px; border-top-right-radius: 8px;">rn            Your Order Is Out for Delivery! 🚚rn        </div>rnrn        <div style="padding: 20px; font-size: 16px; color: #333; text-align: left;">rn            <p style="margin: 0 0 10px;">Hello, <%= name %></p>rn            <p style="margin: 0 0 10px;">Good news! Your package is out for delivery and will arrive soon. 📦</p>rn            <p style="margin: 0 0 10px;"><strong>Tracking Number:</strong> <%= trackingNumber %></p>rn            <p style="margin: 0 0 10px;">We appreciate your business and can't wait for you to receive your order!</p>rnrn            <a href="https://yourwebsite.com/track?trackingNumber=<%= trackingNumber %>"rn               style="background-color: #28a745; color: white; text-decoration: none; padding: 12px 18px; border-radius: 5px; display: inline-block; margin-top: 15px; font-weight: bold;">rn                Track Your Packagern            </a>rn        </div>rnrn        <div style="background-color: #f4f4f4; padding: 10px; font-size: 14px; color: #555; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;">rn            Thank you for choosing us! 🛍️rn        </div>rn    </div>rn</body>rn</html>
                                
                            

Por último, crea una plantilla para notificar a los usuarios que su pedido ha sido entregado. Para ello, crea un archivo llamado delivered.html en la carpeta src/email-templates/html y añade el siguiente código:

                                

                                    <!DOCTYPE html>rn<html>rn<head>rn    <meta charset="UTF-8" />rn    <title>Order Delivered</title>rn</head>rn<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; text-align: center;">rnrn    <div style="background: #ffffff; padding: 20px; border-radius: 8px; max-width: 600px; margin: auto; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);">rnrn        <div style="background-color: #ffc107; color: white; padding: 15px; font-size: 22px; font-weight: bold; border-top-left-radius: 8px; border-top-right-radius: 8px;">rn            Your Order Has Been Delivered! 🎉rn        </div>rnrn        <div style="padding: 20px; font-size: 16px; color: #333; text-align: left;">rn            <p style="margin: 0 0 10px;">Hello, <%= name %></p>rn            <p style="margin: 0 0 10px;">We're happy to inform you that your package has been successfully delivered. 🎁</p>rn            <p style="margin: 0 0 10px;"><strong>Tracking Number:</strong> <%= trackingNumber %></p>rn            <p style="margin: 0 0 10px;">We hope you enjoy your purchase! If you have any questions, feel free to contact us.</p>rnrn            <a href="https://yourwebsite.com/track?trackingNumber=<%= trackingNumber %>"rn               style="background-color: #ffc107; color: white; text-decoration: none; padding: 12px 18px; border-radius: 5px; display: inline-block; margin-top: 15px; font-weight: bold;">rn                Track Your Orderrn            </a>rn        </div>rnrn        <div style="background-color: #f4f4f4; padding: 10px; font-size: 14px; color: #555; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;">rn            Thank you for shopping with us! 🛍️rn        </div>rn    </div>rn</body>rn</html>
                                
                            

Para gestionar y renderizar plantillas de email de forma dinámica, tienes que crear una clase que cargue y organice las plantillas para los diferentes estados de los pedidos. Esta clase recuperará la plantilla correcta y la renderizará con los datos específicos de cada cliente. Para ello, crea un nuevo archivo llamado index.ts en la carpeta src/email-templates y añade el siguiente código:

                                

                                    import { readFileSync } from "fs";rnimport { EmailTemplate, OrderStatus } from "../types";rnimport ejs from "ejs";rnrnexport class EmailTemplateManager {rn    private templates: Map<OrderStatus, EmailTemplate>;rnrn    constructor() {rn        this.templates = new Map();rn        this.loadTemplates();rn    }rnrn    private loadTemplates() {rn        // Load each template for different statusesrn        const statuses: OrderStatus[] = [rn            "shipped",rn            "out_for_delivery",rn            "delivered",rn        ];rn        const subjects: Record<OrderStatus, string> = {rn            shipped: "Your Order Has Been Shipped! ✈️",rn            out_for_delivery: "Your Order is Out for Delivery! 🚚",rn            delivered: "Your Order Has Been Delivered! 🎉",rn        };rnrn        statuses.forEach((status) => {rn            const htmlTemplate = readFileSync(rn                `src/email-templates/html/${status}.html`,rn                "utf-8"rn            );rnrn            this.templates.set(status, {rn                subject: subjects[status],rn                html: htmlTemplate,rn            });rn        });rn    }rnrn    getTemplate(status: OrderStatus): EmailTemplate {rn        const template = this.templates.get(status);rn        if (!template) {rn            throw new Error(`No template found for status: ${status}`);rn        }rn        return template;rn    }rnrn    renderTemplate(templateString: string, data: Record<string, any>): string {rn        return ejs.render(templateString, data); // Render the template with the provided datarn    }rn}
                                
                            

Esta clase inicializa una variable privada llamada templates que almacena plantillas de email en un objeto Map para poder buscarlas rápidamente en función del estado del pedido. Usar un Map garantiza una recuperación eficiente y evita tener que leer repetidamente los archivos del disco. La clase también define los siguientes métodos:

  • loadTemplates (privado) lee las plantillas HTML de los archivos y las almacena en el Map templates, junto con sus correspondientes líneas de asunto.
  • getTemplate recupera la plantilla de email para un determinado estado del pedido y arroja un error si no se encuentra ninguna plantilla.
  • renderTemplate utiliza EJS para renderizar dinámicamente una plantilla con los datos proporcionados.

Implementación de la funcionalidad de envío de emails

Con las plantillas de email listas, el siguiente paso es implementar la funcionalidad para enviar notificaciones. Esto implica poner en cola los trabajos de email y procesarlos de forma asíncrona.

Pero antes de poder hacerlo, tienes que instalar algunas dependencias ejecutando el siguiente comando:

npm i mailgun.js@11.1.0 form-data@4.0.2 bullmq@5.41.2 ioredis@5.5.0

Aquí tienes un resumen de cada una de estas dependencias:

  • mailgun.js es un cliente de Node.js para interactuar con la API de Mailgun. Lo usarás para enviar emails transaccionales.
  • form-data es un paquete que requiere mailgun.js para manejar los envíos de formularios al mandar emails.
  • bullmq es una biblioteca de colas de trabajos para manejar tareas asíncronas. Te permite poner en cola las notificaciones por email y procesarlas en segundo plano.
  • ioredis es un cliente de Redis para Node.js que utiliza BullMQ para almacenar y gestionar los trabajos en cola.

A continuación, tienes que definir un cliente de la API de Mailgun que usarás para enviar emails. Para ello, crea un nuevo archivo en src/config/mailgun.config.ts y añade el siguiente código:

                                

                                    import FormData from "form-data";rnimport Mailgun from "mailgun.js";rnrnconst mailgun = new Mailgun(FormData);rnexport const mgClient = mailgun.client({rn    username: "api",rn    key: process.env.MAILGUN_API_KEY,rn});
                                
                            

Este código configura y exporta un cliente de Mailgun usando la biblioteca mailgun.js y form-data. Esto permite a tu aplicación enviar emails mediante la API de Mailgun con la clave de API almacenada en variables de entorno.

Ahora, tienes que definir una conexión de Redis que BullMQ utilizará para almacenar y gestionar trabajos en segundo plano. Para ello, crea un nuevo archivo llamado redis.config.ts en la carpeta src/config y añade el siguiente código:

                                

                                    import IORedis from "ioredis";rnrnexport const redisConfig = new IORedis({rn    host: process.env.REDIS_HOST,rn    port: parseInt(process.env.REDIS_PORT),rn    maxRetriesPerRequest: null,rn});
                                
                            

Tienes que configurar una cola de BullMQ para las notificaciones de envío que gestionará los trabajos de notificación por email en segundo plano mediante la conexión de Redis que definiste en el paso anterior. Para ello, crea un nuevo archivo llamado queues.config.ts en la carpeta src/config y añade el siguiente código:

                                

                                    import { Queue } from "bullmq";rnimport { redisConfig } from "./redis.config";rnrnexport const QUEUE_NAMES = {rn    SHIPPING_NOTICATIONS: "shipping-notifications",rn};rnrnexport const JOB_NAMES = {rn    SEND_NOTIFICATION: "send-notification",rn};rnrnexport const SHIPPING_NOTICATIONS_QUEUE = new Queue(rn    QUEUE_NAMES.SHIPPING_NOTICATIONS,rn    {rn        connection: redisConfig,rn    }rn);
                                
                            

Este código también define nombres para la cola y el tipo de trabajo que pueden utilizarse en otras partes de la aplicación para evitar usar cadenas incrustadas en el código (hard-coded).

Por último, crea un nuevo archivo en src/services/notifications.service.ts y añade el siguiente código:

                                

                                    import { Job, Queue, Worker } from "bullmq";rnimport {rn    QUEUE_NAMES,rn    SHIPPING_NOTICATIONS_QUEUE,rn    JOB_NAMES,rn} from "../config/queues.config";rnimport { redisConfig } from "../config/redis.config";rnimport { mgClient } from "../config/mailgun.config";rnimport { IMailgunClient } from "mailgun.js/Interfaces";rnimport { EmailTemplateManager } from "../email-templates";rnimport { MailgunMessageData } from "mailgun.js";rnimport { NotificationJob } from "../types";rnrnexport class NotificationService {rn    private queue: Queue;rn    private mailgunClient: IMailgunClient;rn    private templateManager: EmailTemplateManager;rnrn    constructor() {rn        this.queue = SHIPPING_NOTICATIONS_QUEUE;rn        this.mailgunClient = mgClient;rn        this.templateManager = new EmailTemplateManager();rn        this.setupWorker();rn    }rnrn    private setupWorker() {rn        const worker = new Worker(rn            QUEUE_NAMES.SHIPPING_NOTICATIONS,rn            async (job) => {rn                console.log(`Processing job: ${job.id}`);rn                await this.processNotification(job);rn            },rn            {rn                connection: redisConfig,rn            }rn        );rnrn        worker.on("completed", (job) => {rn            console.log(`Job ${job.id} completed successfully`);rn        });rnrn        worker.on("failed", (job, error) => {rn            console.log(`Job ${job?.id} failed`, error);rn        });rn    }rnrn    private async processNotification(job: Job<NotificationJob>) {rn        const { email, trackingNumber, status, metadata } = job.data;rnrn        try {rn            const template = this.templateManager.getTemplate(status);rn            const emailData: MailgunMessageData = {rn                from: process.env.MAIL_FROM,rn                to: email,rn                subject: template.subject,rn                html: this.templateManager.renderTemplate(template.html, {rn                    trackingNumber,rn                    ...metadata,rn                }),rn            };rnrn            await this.mailgunClient.messages.create(rn                process.env.MAILGUN_DOMAIN,rn                emailDatarn            );rn        } catch (error) {rn            console.log(error);rn            throw error;rn        }rn    }rnrn    async queueNotification(data: NotificationJob) {rn        await this.queue.add(JOB_NAMES.SEND_NOTIFICATION, data, {rn            attempts: 5, // number of retry attempts before failing permanentlyrn            backoff: {rn                type: "exponential", // Retry using exponential backoffrn                delay: 5000, // Delay in ms before retryingrn            },rn        });rn        console.log("Job queued successfully");rn    }rn}
                                
                            

Este código define una clase NotificationService que maneja notificaciones por email mediante un sistema de colas de trabajos con BullMQ y Mailgun. Esta clase inicializa tres propiedades privadas: queue, que es la cola donde se añaden los trabajos de email; mailgunClient, que es el cliente de Mailgun para enviar emails; y templateManager, que es una instancia de la clase TemplateManager que creaste previamente para gestionar y recuperar plantillas de email. Esta clase también define los siguientes métodos:

  • setupWorker crea un worker que escucha los nuevos trabajos de email y los procesa. Registra la finalización o el fallo del trabajo.
  • processNotification recupera la plantilla de email correcta, la rellena con datos dinámicos y envía el email mediante Mailgun.
  • queueNotification añade un nuevo trabajo de email a la cola, con reintentos y retroceso exponencial para los intentos fallidos. Este método se puede llamar desde otras partes de la aplicación para añadir trabajos a la cola.

Integración con eventos de aplicaciones

Para enviar notificaciones por email cuando se actualiza el estado de un pedido, tienes que poner en cola un trabajo en el sistema de notificaciones. Para ello, abre el archivo src/controllers/order.controller.ts y añade la siguiente declaración de importación para importar la clase NotificationService:

import { NotificationService } from "../services/notifications.service";

A continuación, define una propiedad privada dentro de la clase OrderController para contener una instancia de la clase NotificationService:

private notificationService: NotificationService;

Inicializa esta propiedad añadiendo el siguiente código dentro del método constructor:

this.notificationService = new NotificationService();

Por último, añade el siguiente código dentro del método updateOrderStatus después de await this.orderRepository.save(order); para poner en cola un trabajo una vez que el estado del pedido se haya actualizado correctamente:

                                

                                    // Send notificationrnthis.notificationService.queueNotification({rn    email: order.user.email,rn    trackingNumber: order.trackingNumber,rn    status,rn    metadata: {rn        name: order.user.name.split(" ")[0],rn    },rn});
                                
                            

El flujo de trabajo de emails transaccionales está ahora completo. Puedes seguir adelante y probar si todo funciona según lo esperado.

Probar el flujo de trabajo

Para asegurarte de que todo funciona correctamente, inicia Redis ejecutando el siguiente comando en tu terminal:

docker compose up -d

Después de ejecutar este comando, puedes comprobar que Redis está en funcionamiento enumerando los contenedores:

docker ps

Este comando muestra una lista de contenedores activos. Deberías ver que el contenedor redis se está ejecutando.

A continuación, ejecuta el servidor Express con el comando npm run dev y dirígete a http://localhost:3000 en tu navegador. En el panel de control de la aplicación, actualiza el estado del pedido a cualquiera de las opciones disponibles. Una vez actualizado, recibirás una respuesta instantánea:

Shipped Order Status Screen Image

En tu terminal, aparecerá un registro en el que se te notifica que el trabajo de envío de emails se ha puesto en cola con éxito y que se está procesando:

Job queued successfully
Processing job: 1

Y cuando termine:

Job 1 completed successfully

A continuación, recibirás un email con el estado actualizado del pedido:

Your order has shipped screen image

Cada vez que actualices el estado de un pedido, el sistema enviará automáticamente el email correspondiente al usuario para mantenerlo informado:

Your Order has been delivered screen image 8

El código completo de la aplicación está disponible en GitHub.

Seguimiento y gestión de emails

Para garantizar que tus emails transaccionales llegan a los clientes de forma eficaz, tienes que supervisar el estado de la entrega y sus tasas de apertura, además de gestionar cualquier posible fallo. Mailgun cuenta con un panel de control donde puedes hacer un seguimiento de los emails enviados, comprobar si se han entregado, abierto o si se ha hecho clic en ellos, así como ver informes de rebotes.

Puedes acceder a este panel de control en Send > Reporting > Metrics en Mailgun:

Send > Reporting > Metrics Screen Image

Sin embargo, las tasas de apertura no se rastrean de manera automática, así que tendrás que configurarlas manualmente a través de la pestaña Ajustes de tu dominio de envío:

Domain Settings Screen Tab image

Tienes más información sobre cómo rastrear las tasas de apertura y de clics en la documentación oficial.

Además, puedes usar webhooks para recibir notificaciones en tiempo real sobre entregas fallidas y tomar la acción adecuada, como volver a enviar el email.

Al supervisar activamente el rendimiento de tus emails, puedes mejorar la entregabilidad, reducir los rebotes y asegurarte de que las notificaciones importantes llegan a tus clientes.

En resumen

En este artículo has aprendido a configurar un flujo de trabajo de emails transaccionales para notificaciones de envío con Mailgun, BullMQ y Redis. Has aprendido a configurar Mailgun para enviar emails, definir una cola de trabajos con BullMQ e integrarla en un sistema de actualización de pedidos para que los clientes reciban notificaciones por email en tiempo real. Este enfoque mejora la comunicación y perfecciona la experiencia del cliente en general.

¿Te ha resultado útil? Suscríbete a nuestra newsletter para disfrutar de más contenido de tutoriales y análisis en profundidad como este.