§2 · Architettura
Come funziona davvero un sistema self-hosted di email marketing.
L'invio di una campagna attraversa cinque stage. Capirli è il prerequisito per scegliere piattaforma, scegliere un relay di invio e fare debug di deliverability quando una campagna sotto-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
Stage 1 — authoring della campagna. Il marketer scrive una campagna nella UI web: oggetto, nome mittente, selezione lista, editor di contenuto (drag-and-drop, MJML o HTML grezzo). Quando preme "invia", l'applicazione crea un record di campagna e mette in coda job per-destinatario su una coda in background. Niente esce dal server per ora.
Stage 2 — coda + worker. I worker in background prelevano job al ritmo configurato della coda (tipicamente 5–50 invii/secondo per worker). Il worker legge la riga dell'iscritto, fonde i custom field nel template, embedda un tracking pixel chiavato sul message-id e riscrive ogni link in un redirect di tracking click. Il risultato è un messaggio MIME completamente personalizzato pronto per essere passato a un sending driver.
Stage 3 — sending driver. Il driver è l'adattatore tra la tua applicazione e qualsiasi transport scegli: una chiamata API Amazon SES, un POST HTTPS Mailgun, una chiamata Web API SendGrid o un handshake SMTP AUTH PLAIN grezzo verso il tuo MTA Postal. Il pattern sending-driver di AcelleMail, per esempio, definisce un contratto a 5 metodi (connect, send, getDeliveryStatus, getCapabilities, validateConfig) che ogni driver implementa — vedi /developers/sending-drivers per la guideline driver completa. Driver built-in sono inclusi per Amazon SES, SendGrid, Mailgun, SparkPost, Elastic Email, Gmail SMTP e qualsiasi server SMTP generico (8 vendor vivono in app/SendingServers/Drivers/Vendors/).
Stage 4 — MTA → destinatario. L'MTA (tuo o del tuo relay) apre una connessione SMTP verso il server MX del destinatario, si presenta con un HELO/EHLO, negozia STARTTLS, autentica le chiavi di firma DKIM e sottomette il messaggio. Il mail server del destinatario esegue spam scoring, verifica SPF/DKIM/DMARC, processing dell'header list-unsubscribe e o inbox o respinge.
Stage 5 — loop di feedback. Tre segnali tornano indietro, tutti asincroni. I bounce arrivano via SMTP (codici 5xx per hard bounce, 4xx per soft) o via il webhook del relay. Le complaint (il destinatario ha cliccato "spam") arrivano via il Feedback Loop del Mailbox Provider o, di nuovo, via il webhook del relay. L'engagement (hit sul pixel di apertura, richieste di click-redirect) arriva via plain HTTP di ritorno alla tua web app. L'applicazione usa questi segnali per aggiornare suppression list, ritirare indirizzi morti e alimentare l'analytics di campagna. Il catalogo di webhook event di AcelleMail vive in config/webhook_events.php — è la lista canonica degli eventi che l'applicazione emette e consuma.
La forma è la stessa su ogni piattaforma self-hosted, con una sola variabile: dove vivono coda e MTA. Il worker di AcelleMail gira di default sulla stessa macchina della web app; Listmonk fa lo stesso; Mautic usa Symfony Messenger e supporta macchine worker separate. Il mail relay può essere locale (Postal sulla stessa macchina, Postfix su una macchina sorella) o remoto (SES, Mailgun) — quella decisione è il tema di §5.