§2 · Arquitectura
Cómo funciona realmente un sistema de email marketing autoalojado.
El envío de una campaña recorre cinco etapas. Entenderlas es el prerrequisito para elegir plataformas, elegir un relay de envío y depurar la entregabilidad cuando una campaña rinde poco.
[Marketer's browser]
│
▼ HTTPS POST /campaigns
[Web app — Laravel/Symfony/Go] ◀── REST API also lands here
│
▼ enqueue per-recipient job
[Job queue — Redis / beanstalkd / DB]
│
▼ worker picks job, renders MIME
[Sending driver — SES/Mailgun/SMTP]
│
▼ TLS, AUTH, DATA, .
[Mail Transfer Agent (MTA)]
│
▼ SMTP to recipient MX
[Recipient mail server — Gmail/O365/Yahoo]
│
▼ open pixel · click redirect · bounce · complaint
[Webhook back to web app] ◀── reputation feedback loop
Etapa 1 — autoría de la campaña. El marketer redacta una campaña en la UI web: línea de asunto, nombre del remitente, selección de lista, editor de contenido (drag-and-drop, MJML o HTML en bruto). Cuando pulsa «enviar», la aplicación crea un registro de campaña y encola trabajos por destinatario en una cola en segundo plano. Aún no sale nada del servidor.
Etapa 2 — cola + worker. Los workers en segundo plano sacan trabajos al ritmo configurado en la cola (normalmente 5–50 envíos/segundo por worker). El worker obtiene la fila del suscriptor, fusiona los campos personalizados en la plantilla, incrusta un píxel de seguimiento indexado por message-id y reescribe cada enlace a una redirección de seguimiento de clics. El resultado es un mensaje MIME totalmente personalizado, listo para entregar a un driver de envío.
Etapa 3 — driver de envío. El driver es el adaptador entre su aplicación y el transporte que elija: una llamada a la API de Amazon SES, un POST HTTPS a Mailgun, una llamada a la Web API de SendGrid o un handshake SMTP AUTH PLAIN en bruto contra su propio Postal MTA. El patrón de driver de envío de AcelleMail, por ejemplo, define un contrato de 5 métodos (connect, send, getDeliveryStatus, getCapabilities, validateConfig) que implementa cada driver: vea /developers/sending-drivers para la guía completa. Vienen drivers integrados para Amazon SES, SendGrid, Mailgun, SparkPost, Elastic Email, Gmail SMTP y cualquier servidor SMTP genérico (8 vendors viven en app/SendingServers/Drivers/Vendors/).
Etapa 4 — MTA → destinatario. El MTA (suyo o el del relay) abre una conexión SMTP con el servidor MX del destinatario, se presenta con un HELO/EHLO, negocia STARTTLS, autentica las claves de firma DKIM y entrega el mensaje. El servidor de correo del destinatario ejecuta puntuación de spam, verificación SPF/DKIM/DMARC, procesamiento de la cabecera list-unsubscribe y, o bien entrega en bandeja, o rechaza.
Etapa 5 — feedback loop. Vuelven tres señales, todas asíncronas. Los rebotes llegan por SMTP (códigos 5xx para rebotes duros, 4xx para blandos) o vía el webhook del relay. Las quejas (el destinatario pulsó «spam») llegan por el Feedback Loop del proveedor de buzón o, de nuevo, por el webhook del relay. La interacción (impactos en el píxel de apertura, peticiones de redirección de clic) llega por HTTP plano a su app web. La aplicación las usa para actualizar las listas de supresión, retirar direcciones muertas y alimentar las analíticas de campaña. El catálogo de eventos webhook de AcelleMail vive en config/webhook_events.php: es la lista canónica de los eventos que la aplicación emite y consume.
La forma es la misma en cada plataforma autoalojada, con una variable: dónde viven la cola y el MTA. El worker de AcelleMail corre por defecto en la misma máquina que la app web; Listmonk hace lo mismo; Mautic usa Symfony Messenger y admite máquinas de worker separadas. El relay de correo puede ser local (Postal en la misma máquina, Postfix en una máquina hermana) o remoto (SES, Mailgun); esa decisión es el tema del §5.