# Har bygget e‑mail med failover og leveringslog

Har bygget e‑mail som en funktion i selve platformen — tre udbydere med failover, webhooks for levering, logning af afsendelse og levering, skabeloner og kampagner — sikret af et opstartstjek, så platformen ikke starter uden mindst én udbyder.

2025

**Situation.** E‑mail vejer tungt på platformen — verificering, notifikationer, digests, kampagner, alt det, en bruger rent faktisk venter på. Og en mailudbyder er præcis den slags afhængighed, der fejler lydløst: konfigurationen ser fin ud, appen starter, og man opdager først, at noget er galt, når et rigtigt menneske aldrig får den besked, vedkommende blev lovet. Det er den værste måde at finde ud af det på. Med kun én udbyder bliver det værre, fordi fejlen er total, og det er en anden, der skal rette den.

**Opgave.** E‑mail skulle behandles som en funktion, platformen selv ejer, og ikke som et klientbibliotek, den kalder — en funktion, der kan overleve et nedbrud hos en udbyder, kan gøre rede for, hvad der skete med en given besked, og slår højlydt alarm ved opstart i de miljøer, hvor stilhed er farlig.

**Handling.** Tre udbydere ligger bag én grænseflade — SendGrid som den primære, med SMTP2GO og Azure Communication Services i reserve — og failover mellem dem sker automatisk i stedet for at være en konfigurationsændring, der skal laves under pres. Levering tages ikke for givet: indgående webhooks melder tilbage, hvad hver udbyder gjorde med en besked, og begge sider registreres i en afsendelseslog og en tabel over leveringshændelser, så "fik den her person sin verificeringsmail" er en databaseforespørgsel og ikke et gæt. Skabeloner holder beskedteksterne ude af koden, og et separat broadcast‑skema — 5 tabeller og 24 funktioner — sender kampagner ud til brugersegmenter, hvilket er en anden opgave end transaktionsmail og blev bygget som en selvstændig løsning. Foran det hele sender et opstartstjek en rigtig besked gennem stakken, styret af et flag: i udviklingsmiljøet logger det en advarsel og fortsætter, for ingen vil have, at deres laptop nægter at starte på grund af en udløbet sandkassenøgle, og i staging og produktion er en fejl fatal, og processen stopper i stedet for at udrulle et build, der ikke kan sende mail. Selve afsendelsen går gennem en SSRF‑beskyttet klient med en timeout på 30 sekunder, og den asynkrone levering har retries og backoff, så et kortvarigt udfald ikke koster en besked.

**Resultat.** En hel kategori af lydløse fejl gik fra "en bruger opdager det dage senere" til "udrulningen stopper", og en udbyder med en dårlig eftermiddag betyder nu en forringet levering snarere end et nedbrud. Prisen er tre integrationer at holde kørende i stedet for én og leveringslogs, der vokser og løbende skal ryddes op i — begge dele accepteret, fordi e‑mail er den kanal, platformen ikke kan komme uden om.

---

- Rolle: Backend‑udvikler
- Kategorier: [Backend‑udvikling](https://engineer.company/da/categories/backend/), [API'er & integration](https://engineer.company/da/categories/api/), [Cloud](https://engineer.company/da/categories/cloud/), [Driftssikkerhed & backup](https://engineer.company/da/categories/reliability/), [Sikkerhed](https://engineer.company/da/categories/security/)
- Ydelser: [Backend- & API‑udvikling](https://engineer.company/da/services/backend-development/), [Site reliability & overvågning](https://engineer.company/da/services/site-reliability/), [Sikkerhed & adgangsstyring](https://engineer.company/da/services/security-access/)

<https://engineer.company/da/portfolio/built-email-with-failover-and-delivery-logging/>
