§2 · Arquitetura
Como um sistema de email marketing auto-hospedado realmente funciona.
Um envio de campanha caminha por cinco estágios. Entendê-los é o pré-requisito para escolher plataformas, escolher um relay de envio e depurar entregabilidade quando uma campanha sub-performa.
[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
Estágio 1 — autoria da campanha. O marketer escreve uma campanha na UI web: linha de assunto, nome do remetente, seleção de lista, editor de conteúdo (arrastar e soltar, MJML ou HTML cru). Quando clica em "enviar", a aplicação cria um registro de campanha e enfileira jobs por destinatário em uma fila de background. Nada sai do servidor ainda.
Estágio 2 — fila + worker. Workers de background puxam jobs no ritmo configurado para a fila (tipicamente 5–50 envios/segundo por worker). O worker busca a linha do assinante, mescla os campos personalizados no template, embute um pixel de tracking chaveado por message-id e reescreve cada link para um redirect de click-tracking. O resultado é uma mensagem MIME totalmente personalizada pronta para entregar a um driver de envio.
Estágio 3 — driver de envio. O driver é o adaptador entre sua aplicação e qualquer transporte que você escolher: uma chamada de API Amazon SES, um HTTPS POST para o Mailgun, uma chamada da Web API do SendGrid ou um handshake SMTP cru com AUTH PLAIN para o seu próprio MTA Postal. O padrão de driver de envio do AcelleMail, por exemplo, define um contrato de 5 métodos (connect, send, getDeliveryStatus, getCapabilities, validateConfig) que todo driver implementa — veja /developers/sending-drivers para o guia completo de drivers. Drivers nativos vêm para Amazon SES, SendGrid, Mailgun, SparkPost, Elastic Email, Gmail SMTP e qualquer servidor SMTP genérico (8 fornecedores vivem em app/SendingServers/Drivers/Vendors/).
Estágio 4 — MTA → destinatário. O MTA (seu ou do seu relay) abre uma conexão SMTP com o servidor MX do destinatário, se apresenta com um HELO/EHLO, negocia STARTTLS, autentica as chaves de assinatura DKIM e submete a mensagem. O servidor de email do destinatário roda pontuação de spam, verificação SPF/DKIM/DMARC, processamento do cabeçalho list-unsubscribe e ou coloca na inbox ou rejeita.
Estágio 5 — feedback loop. Três sinais voltam, todos assíncronos. Bounces chegam por SMTP (códigos 5xx para hard bounces, 4xx para soft) ou pelo webhook do relay. Reclamações (destinatário clicou "spam") chegam pelo Feedback Loop do provedor de caixa de entrada ou, de novo, pelo webhook do relay. Engajamento (hits no pixel de abertura, requisições de redirect de clique) chega por HTTP simples de volta para seu web app. A aplicação usa esses sinais para atualizar listas de supressão, aposentar endereços mortos e alimentar os analytics da campanha. O catálogo de eventos webhook do AcelleMail vive em config/webhook_events.php — é a lista canônica de eventos que a aplicação emite e consome.
O formato é o mesmo em toda plataforma auto-hospedada, com uma variável: onde a fila e o MTA vivem. O worker do AcelleMail roda na mesma máquina do web app por padrão; o Listmonk faz o mesmo; o Mautic usa Symfony Messenger e suporta máquinas de worker separadas. O relay de email pode ser local (Postal na mesma máquina, Postfix em uma máquina irmã) ou remoto (SES, Mailgun) — essa decisão é o assunto da §5.