10 Tage unsichtbar: Ein E-Mail-System aufbauen, das die Produktion aufrechterhält
10 Tage. 30 Commits. Keine sichtbare neue Funktion. Während die TAMSIV-Nutzer auf einen neuen Button, eine neue Farbe oder eine neue Sprachfunktion warteten, habe ich jeden Tag damit verbracht, etwas neu zu schreiben, das niemand jemals sehen wird: die Art und Weise, wie die App per E-Mail mit den Leuten spricht. Und mir wurde klar, dass das Unsichtbare vielleicht 80 % dessen ausmacht, was ein Produkt installiert hält.
Wichtige Erkenntnisse
- Ein vollständiges System für Transaktions-E-Mails: Verifizierungs-Erinnerung, J+7 Feedback-Loop, Präferenzen, saubere Abmeldung, Verlauf pro Benutzer.
- Ein Resend-Webhook, der die 6 Event-Typen (delivered, opened, clicked, bounced, complained, delivery_delayed) abhört, um Metriken in Echtzeit zu aggregieren.
- Ein RGPD-Anti-Spoofing-Flow: Ein Benutzer kann eine Willkommens-E-Mail melden, die er nie angefordert hat, wir löschen die Registrierung sofort.
- Ein täglicher Cronjob, der eine einmalige Erinnerung an seit 3 Tagen nicht verifizierte Konten sendet, i18n in 6 Sprachen.
- Zwei parallele mobile Hotfixes (v1.07 + v1.08): Audit gesture-handler, UI-Überarbeitung des Feeds, stabile Modals, 8 Bugs behoben.
Warum ein komplettes E-Mail-System aufbauen, wenn Supabase Auth bereits Verifizierungs-E-Mails sendet?
Das ist eine berechtigte Frage. Supabase sendet in seiner Standardkonfiguration bereits eine Verifizierungs-E-Mail bei jeder Anmeldung. Viele Produkte hören hier auf und fügen nichts Weiteres hinzu. Das reicht aus, um eine E-Mail zu validieren, aber nicht, um eine Beziehung zum Benutzer aufzubauen.
Seit dem 4. April in Produktion, fand ich mich mit Dutzenden von erstellten, aber nicht verifizierten Konten wieder. Keine Nachfassaktionen. Kein Feedback nach 7 Tagen, um zu wissen, ob die App für sie nützlich war. Keine saubere Möglichkeit für jemanden zu sagen "diese E-Mail war nicht für mich". Und vor allem keine Sichtbarkeit auf Admin-Seite, was gesendet, angekommen, zurückgesprungen oder als Spam markiert wurde.
Ein selbstgebautes transaktionales E-Mail-System ist genau das, was ein "technisch funktionierendes" Produkt von einem Produkt trennt, das ernsthaft wirkt. Große Apps verstecken es hinter ihrem Feinschliff. Kleine Apps vernachlässigen es und verlieren Benutzer, ohne zu verstehen, warum.
Der tägliche Cronjob, der eine Erinnerung sendet, und NUR EINE
Der erste Baustein ist ein täglicher Cronjob, der zu einer festen Zeit auf Vercel läuft. Er fragt die Datenbank ab, wählt Konten aus, die seit genau 3 Tagen erstellt und noch nicht verifiziert wurden, und löst eine einmalige Erinnerung pro Benutzer aus.
[PERSÖNLICHE ERFAHRUNG] Die Regel "nur eine Erinnerung" ist bewusst gewählt. Ich habe mehr missbräuchliche Erinnerungs-E-Mails erhalten, als ich zählen kann. Drei Erinnerungen in 48 Stunden, fünf in einer Woche, zehn in einem Monat. Das ist der beste Weg, um Leute abzumelden, noch bevor sie das Produkt überhaupt ausprobiert haben.
Der Cronjob schreibt in eine dedizierte Tabelle, um zu wissen, wer was wann erhalten hat. Wenn ein Benutzer bereits erinnert wurde, wird er übersprungen. Wenn der Resend-Versand fehlschlägt, wird der Fehler protokolliert, aber der Cronjob versucht es nicht automatisch erneut: Ich bevorzuge Sichtbarkeit bei Fehlern gegenüber einer stillen Sättigung.
Der Feedback-Loop nach J+7: 4 Buttons, 4 Wahrheiten
[EINZIGARTIGER EINBLICK] Sieben Tage nach der Registrierung erhält jeder neue Benutzer eine E-Mail mit 4 anklickbaren Buttons: Ich liebe es, ich hasse es, ich habe einen Vorschlag, ich habe einen Fehler gefunden. Jeder Button verweist auf eine dedizierte Seite, die die Antwort speichert und ein freies Kommentarfeld anbietet.
Warum diese genaue Form? Weil eine Google Play-Bewertung von demjenigen gefiltert wird, der die meiste Energie hat, sie zu hinterlassen. Eine E-Mail mit 4 Buttons erfasst die stille Wahrheit. Die der Leute, die niemals in den Store gehen werden, um einen Kommentar zu schreiben, aber mit einem Klick sagen können "das hat mir nicht gefallen".
Technisch gesehen trägt jeder Button ein signiertes Token, das sich auf den Benutzer und den Feedback-Typ bezieht. Die GET-Route auf der Website validiert das Token, speichert die Antwort mit user_id und Typ und zeigt die entsprechende Seite mit einem freien Formular an. Keine zusätzliche Authentifizierung, um Feedback zu hinterlassen: Das ist beabsichtigt. Reibung tötet Feedback.
Der Anti-Spoofing-Flow: RGPD ohne Drama
Konkreter Fall: Jemand erstellt ein TAMSIV-Konto mit der E-Mail-Adresse alice@example.fr. Aber Alice hat nichts angefordert. Sie erhält eine Willkommens-E-Mail für ein Konto, das sie nie erstellt hat. Was macht sie?
Ohne diesen Flow legt sie die E-Mail in den Spam-Ordner oder meldet den Absender. In beiden Fällen ist es ein Verlust: Verlust für mich auf der Seite des Absender-Rufs, Verlust für sie, die keine saubere Möglichkeit hat, das Thema zu beenden, Verlust für die Person, die den Tippfehler gemacht hat und niemals wieder eine Kommunikation an die richtige Adresse erhalten wird.
In der neuen Version enthält jede Willkommens-E-Mail einen Link "Ich habe dieses Konto nicht erstellt". Klick, dedizierte Seite, Bestätigung. Die Registrierung wird sofort in der Datenbank gelöscht, ein Protokoll wird zur Überprüfung gespeichert, und eine Abschlussnachricht bestätigt Alice, dass ihre Adresse nicht mehr verwendet wird. RGPD ohne Drama. Eine Aktion, drei Sekunden, fertig.
[ORIGINAL DATA] Die Seite ist in den 6 Sprachen der App übersetzt (Französisch, Englisch, Deutsch, Spanisch, Italienisch, Portugiesisch). Akzentzeichen waren in einigen Sprachen aufgrund eines Kodierungsproblems in der Übersetzungsdatei fehlerhaft: Fix im Commit 12e61a7.
Der Resend-Webhook: Wissen, bevor der Benutzer schreibt
Alle Sendungen laufen über Resend, einen Anbieter für Transaktions-E-Mails mit Fokus auf Entwicklererfahrung. Resend bietet Webhooks für jedes Ereignis im Lebenszyklus einer E-Mail: email.sent, email.delivered, email.opened, email.clicked, email.bounced, email.complained, email.delivery_delayed.
Alle werden abgehört und in einer dedizierten Tabelle mit Referenz zum Benutzer, E-Mail-Typ, Zeitstempel und zugehörigen Metadaten gespeichert. Dies ermöglicht dann die Aggregation: Wie viele E-Mails sind heute angekommen, wie viele wurden geöffnet, welche haben einen Klick generiert, wie viele sind zurückgesprungen.
Das Admin-Dashboard zeigt diese Statistiken in Echtzeit mit Badges an, die sich bei jeder Sendung erhöhen. Ein Bounce, der bei einem Benutzer auftaucht? Ich sehe es sofort, ich kann überprüfen, ob es ein temporäres Problem oder eine tote E-Mail ist, und anpassen. Eine Beschwerde (als Spam gemeldet)? Hohe Priorität, sofortige Untersuchung.
Der Sendehistorie gruppiert nach Benutzer, mit Resend und Dedup
Der Admin sieht alle aktuellen Sendungen, aber gruppiert nach Benutzer. Wenn Alice ihre Verifizierungs-E-Mail, dann ihre J+3-Erinnerung und dann ihr J+7-Feedback erhalten hat, sehe ich eine Zeile "Alice" mit drei erweiterbaren Unterzeilen. Lesbarer als ein roher chronologischer Fluss.
Jede Sendung hat ein "Quelle"-Badge (auto / manuell). Automatische Sendungen (Cron, Trigger) werden von manuellen Sendungen (Button "resend" im Admin) unterschieden. Ein "erneut senden"-Button existiert auf jeder Zeile für Fälle, in denen eine E-Mail im Spam gelandet ist, um einen erneuten Versuch an einen anderen Alias zu erzwingen oder um eine Template-Änderung zu testen.
Ein Dedup-System verhindert erneutes Spamming: Wenn ich vor 2 Stunden eine Willkommens-E-Mail gesendet habe und eine Gruppensendung "alle Anmeldungen des Tages" machen möchte, wird Alice automatisch ausgeschlossen, weil sie bereits eine erhalten hat. Ein "berechtigt"-Badge wird bei jedem Benutzer angezeigt, um anzuzeigen, ob er die aktuelle Sendung erhalten kann oder nicht.
Zwei parallele mobile Hotfixes: v1.07 und v1.08
Während das E-Mail-Backend auf Vercel vorankam, brauchte die mobile App Luft. Zwei Releases wurden im Play Store als Alpha, dann als Produktion veröffentlicht.
v1.07 (7d65fd0): 8 gezielte Bugs, plus eine neue kompakte Ansicht in den Ordnern. Wenn du 15 Unterordner in einem Projekt hast, möchtest du die Baumstruktur auf einen Blick sehen, ohne zu scrollen. Ein Toggle wechselt zwischen detaillierter Ansicht (vollständige Karten mit Thumbnails und Vorschauen) und kompakter Ansicht (dichte Zeilen mit nur dem Namen und der Anzahl). Oberflächlich keine neue Funktion, aber eine Nutzungsänderung für Power-User.
v1.08 (a494e7e): Vollständiger Audit gesture-handler. TAMSIV verwendet react-native-gesture-handler überall, aber mehrere Bildschirme hatten immer noch TouchableOpacity oder FlatList direkt aus react-native importiert. Ergebnis: intermittierende Taps, die nicht funktionierten, unmöglich zu reproduzieren, gemeldet von Benutzern, die schließlich deinstallierten, ohne zu verstehen.
Der Audit betraf über 25 Dateien. Jedes TouchableOpacity, jede FlatList, jede ScrollView wurde auf den Import von gesture-handler umgestellt. Der Bug der Phantom-Taps ist behoben. Nutze die Gelegenheit, um die UI des Feeds zu überarbeiten und alle Modals zu stabilisieren: Nebenbei macht der Feinschliff einen deutlichen Sprung.
Was ich nach 10 Tagen daraus mitnehme
Was mich beeindruckt hat, ist, dass jede Codezeile, die in diesen 10 Tagen geschrieben wurde, unsichtbar bleibt, solange sie funktioniert. Niemand sagt "Wow, deine Verifizierungs-E-Mail kam genau zum richtigen Zeitpunkt, nur einmal, in der richtigen Sprache". Niemand bemerkt, dass ein Bounce automatisch erkannt wurde und der Admin das Signal gesehen hat, noch bevor der Benutzer geschrieben hat.
Das Unsichtbare fällt nur auf, wenn es schiefgeht. Und in diesem Moment versteht der Benutzer nicht, was kaputt ist: Er versteht nur, dass die App "nicht richtig funktioniert". Er deinstalliert. Er schreibt nicht. Er sagt nicht, warum.
Das Unsichtbare macht also vielleicht 80 % eines fertigen Produkts aus. Nicht die Buttons, die in Feature-Releases hinzugefügt werden, nicht die Farben, die neu gemacht werden, nicht die Animationen. Sondern einfach die Tatsache, dass, wenn etwas beim Benutzer ankommen soll, es ankommt. Zum richtigen Zeitpunkt. Einmal. In der richtigen Sprache.
Das ist nicht sexy, um es auf LinkedIn zu posten. Aber es ist das, was ein Produkt installiert hält.
FAQ
Warum nicht einen All-in-One-Dienst wie Mailchimp oder ConvertKit nutzen?
Weil das Newsletter-Tools sind, keine Transaktions-Tools. Sie sind für redaktionelle Massenversendungen konzipiert, nicht für individuelle Trigger, die mit dem Lebenszyklus des Benutzers verbunden sind. Resend ist für Transaktions-E-Mails konzipiert (Willkommen, Verifizierung, Passwort-Reset, Feedback-Loop). Es ist das richtige Werkzeug für den richtigen Job.
Ist der Resend-Webhook für Events zuverlässig?
Sehr zuverlässig. Resend versucht Webhooks bei Fehlern erneut, signiert die Payloads zur Authentifizierung und bietet eine Konsole zum manuellen Wiederholen. In 10 Tagen Nutzung habe ich kein einziges verlorenes Event festgestellt.
Wie werden die Übersetzungen der 6 Sprachen für E-Mails verwaltet?
Jede E-Mail-Vorlage wird auf Französisch definiert und dann von einem automatischen Skript über OpenRouter (LLM) übersetzt. Die Übersetzungsschlüssel befinden sich in denselben messages/*.json-Dateien wie die Website, mit einem dedizierten emails-Namespace. Der serverseitige Versand verwendet die in der Datenbank gespeicherte bevorzugte Sprache des Benutzers, bei Fehlen wird auf Englisch zurückgegriffen.
Ist der Anti-Spoofing-Flow missbräuchlich? Kann man das Konto einer anderen Person löschen?
Nein. Der Link "Ich habe dieses Konto nicht erstellt" ist mit einem Token signiert, das mit der Ziel-E-Mail-Adresse verknüpft ist. Nur die Person, die die E-Mail erhält, kann darauf klicken und die Registrierung löschen. Wenn jemand anderes versucht, die Route ohne das richtige Token aufzurufen, wird ein Fehler 403 zurückgegeben, ohne etwas zu tun.
Gilt dieses System auch für iOS, wenn die App veröffentlicht wird?
Ja, es ist Backend. Die E-Mails werden von Vercel gesendet und sind nicht von der mobilen App-Plattform abhängig. An dem Tag, an dem TAMSIV auf iOS erscheint (12 Personen haben bereits auf "Für iOS herunterladen" auf der Website geklickt), wird der E-Mail-Flow identisch sein.