Zurück zum Blog

E-Mail-Benachrichtigungen und automatische Zustellung in RDataCore

Einführung

Daten ohne die Möglichkeit, Menschen zu informieren, sind nur ein halbes System. RDataCore liefert jetzt einen vollständigen E-Mail-Stack, damit jede Pipeline, jeder Import und jedes Auth-Ereignis die Menschen erreicht, die es betrifft: Kunden, die nach der Anmeldung eine Willkommensnachricht bekommen, Operatoren mit einer nächtlichen Import-Zusammenfassung, Admins, die ein vergessenes Passwort zurücksetzen, Compliance-Teams, die einen Audit-Trail über jede Zustellung lesen.
Das Design hat vier Bausteine. Zwei unabhängige SMTP-Kanäle trennen operative E-Mails von Workflow-E-Mails. Datenbankgestützte Handlebars-Vorlagen erlauben es Admins, Betreffzeilen und Texte ohne Deployment zu bearbeiten. Eine asynchrone Redis-Job-Queue glättet die Zustellung, sodass Workflows nie auf einen langsamen Mailserver warten müssen. Und ein vollständiges System-Log erfasst jeden Versand (Empfänger, Vorlage, gerenderter Inhalt, Status) für Auditing und Debugging.
Dieser Beitrag führt durch die Architektur, zeigt die zwei Workflow-E-Mail-Primitive (pro Datensatz und nach dem Lauf) und endet mit einem Setup-Guide, den du direkt gegen deine Instanz ausführen kannst.

Zwei SMTP-Kanäle: System vs. Workflow

Die meisten Plattformen verschicken alle E-Mails über denselben SMTP-Relay. RDataCore trennt die Verdrahtung bewusst.
  • SYSTEM_SMTP_DSN steht für Plattform-Nachrichten wie Passwort-Resets und Admin-Benachrichtigungen. E-Mails auf diesem Kanal werden direkt vom API-Server versendet.
  • WORKFLOW_SMTP_DSN ist ausschließlich für workflowgesteuerte E-Mails. Diese werden vom Worker-Prozess versendet, nachdem er die E-Mail-Job-Queue konsumiert hat.
Warum zwei Kanäle? Ein hochvolumiger Workflow darf nicht die Reputation oder das Durchsatzkontingent des System-Relays erschöpfen, das gleichzeitig einen Passwort-Reset zustellen muss. Operatoren können sie über unterschiedliche Anbieter leiten (z.B. ein transaktionaler Anbieter für System, ein Marketing-Anbieter für Workflow), unterschiedliche From-Adressen und Anzeigenamen verwenden und sie unabhängig voneinander überwachen.
Beide DSNs sind optional. Wenn eine nicht konfiguriert ist, werden die entsprechenden Features automatisch deaktiviert: Die UI prüft beim Start einen Capabilities-Endpunkt und blendet alles Mail-bezogene für diesen Kanal aus. Unten zeigt die Login-Seite den deaktivierten Zustand, wenn SYSTEM_SMTP_DSN nicht gesetzt ist. Der Passwort vergessen?-Ablauf wird nicht angeboten, und jeder Versuch ihn zu nutzen liefert eine klare Meldung.
Login page with password reset disabled when SYSTEM_SMTP_DSN is unset
Feature-Gating: Wenn SYSTEM_SMTP_DSN nicht gesetzt ist, wird der Passwort-Reset-Ablauf automatisch über den Capabilities-Endpunkt deaktiviert.

Einsatzszenarien

Die beiden Kanäle decken sehr unterschiedliche Aufgaben ab.
System-Kanal: operative E-Mails
  • Admin-Passwort-Reset mit der mitgelieferten password_reset-Vorlage, eine Stunde Gültigkeit, einmalig verwendbarer Token.
  • Willkommensnachrichten für neue Admins mit Zugangsdaten oder Onboarding-Links.
  • Auth-Audit-Alarme, wenn etwas Ungewöhnliches passiert (z.B. wiederholte fehlgeschlagene Logins).
Workflow-Kanal, pro Datensatz (eine E-Mail pro verarbeitetem Datensatz, während die Pipeline weiterläuft):
  • Eine Willkommens- oder Bestätigungsmail für jeden neu importierten Kunden aus einem nächtlichen Import.
  • Ein Schwellwert-Alarm pro Sensorwert, der eine Sicherheitsgrenze überschreitet.
  • Eine Quittung pro Zeile in einem Bestellungs-Import.
Workflow-Kanal, nach dem Lauf (eine E-Mail nach Abschluss des gesamten Batches):
  • Eine nächtliche Import-Zusammenfassung mit verarbeiteten / fehlgeschlagenen / Gesamt-Zählern und Dauer.
  • Ein Fehler-Digest an den Ops-Kanal, wenn mindestens ein Datensatz im Batch fehlgeschlagen ist.
  • Ein wöchentlicher Stakeholder-Rollup, der nur bei erfolgreichem Abschluss ausgelöst wird.
Welcher Kanal passt, ist eine Frage der Semantik: Wenn die E-Mail über die Plattform handelt, gehört sie auf den System-Kanal; wenn sie über Daten, die sich durch die Plattform bewegen handelt, gehört sie auf den Workflow-Kanal.
Forgot Password dialog powered by the seeded password_reset system template
Der Dialog „Passwort vergessen“ — angetrieben von der mitgelieferten System-Vorlage password_reset und einem einmalig verwendbaren Token mit einer Stunde Gültigkeit.

Pro Datensatz vs. nach dem Lauf

Workflow-E-Mails kommen in zwei klar unterscheidbaren Primitiven, und zu verstehen, wann welches zum Einsatz kommt, ist die Kernidee des gesamten Features.
Send Email Transform (pro Datensatz). Ein Send-Email-Schritt kann überall innerhalb der Transform-Pipeline eines Workflows eingefügt werden. Er wird einmal pro Datensatz ausgelöst, und der Workflow läuft sofort nach dem Einreihen der Mail weiter; die Zustellung passiert asynchron auf dem Worker. Die UI sagt es explizit: Versendet eine E-Mail pro verarbeitetem Element. Als Mid-Pipeline-Benachrichtigung verwendbar; der Workflow läuft nach dem Einreihen der Mail weiter.
Empfänger können aus einem Feld des aktuellen Datensatzes aufgelöst werden (z.B. das email-Feld einer User-Zeile) oder als Konstante gesetzt werden. Template-Variablen werden aus dem normalisierten Kontext gefüllt: jedes Feld des Datensatzes plus die Ausgabe vorheriger Transforms. Ein Target Status Field erfasst das Ergebnis pro Datensatz (queued, mail_not_configured), sodass spätere Schritte der Pipeline darauf verzweigen können.
Post-Run Action: Send Email (nach dem Lauf). Post-Run-Actions leben in einem separaten Abschnitt der Workflow-Definition. Sie werden einmal ausgeführt, nachdem alle Datensätze verarbeitet wurden, und haben Zugriff auf einen reichhaltigen Run-Kontext: {{run.workflow_name}}, {{run.processed_items}}, {{run.failed_items}}, {{run.total_items}}, {{run.status}} und {{run.duration_seconds}}. Zusammen mit den normalisierten Feldern des Schritts ist das genug, um eine brauchbare Zusammenfassungs-Nachricht zu produzieren.
Ein Condition-Selektor entscheidet, ob ausgelöst wird: Always, On Success (alle Datensätze erfolgreich) oder On Failure (mindestens ein Datensatz fehlgeschlagen). Das ist der richtige Ort für Zusammenfassungs-Benachrichtigungen, Reports und Alarme. Das UI-Banner lautet These actions execute once after all items are processed.
Die Unterscheidung ist einfach: Greife zu pro Datensatz, wenn jeder Datensatz seine eigene Nachricht verdient; greife zu nach dem Lauf, wenn der Batch als Ganzes eine verdient.
Workflow Send Email transform configured to fire per item
Pro Datensatz: ein Send-Email-Transform in der Workflow-Pipeline — eine E-Mail pro verarbeitetem Datensatz, der Workflow läuft weiter.
Post-Run Send Email action with run context variables and condition selector
Nach dem Lauf: eine Send-Email-Post-Run-Action mit Zugriff auf Run-Kontext-Variablen und einer Success-/Failure-/Always-Condition.

Datenbankgestützte Vorlagen

Jede E-Mail, die RDataCore versendet, wird aus einer Vorlage in der Tabelle email_templates gerendert. Vorlagen sind Handlebars und unterstützen {{variable}}, {{nested.field}}, {{#if condition}}…{{/if}} und {{#each array}}…{{/each}}. Fehlende Variablen werden als leerer String gerendert, ein bewusst nachsichtiger Default, damit ein schlecht benanntes Feld keine Zustellung hart scheitern lässt.
Es gibt zwei Arten von Vorlagen:
  • System-Vorlagen werden von der Plattform mitgeliefert. Admins können Betreff, HTML-Body und Plain-Text-Body bearbeiten, aber sie können keine System-Vorlagen erstellen oder löschen. Der Editor zeigt ein Banner: System templates can be edited but not deleted. Die password_reset-Vorlage ist die aktuelle System-Vorlage; sie bringt die Variablen {{reset_url}} und {{user_name}} mit sowie sinnvolle Defaults.
  • Workflow-Vorlagen sind voll CRUD-fähig. Admins erstellen sie mit eigenen Variablennamen und Beschreibungen und referenzieren sie dann aus Send-Email-Schritten. Im Screenshot unten sind drei Vorlagen nebeneinander zu sehen: eine Workflow-Vorlage daily_import_summary, die System-Vorlage password_reset und eine Workflow-Vorlage user_register.
Der Template-Editor unterstützt drei Bodies: Betreff, HTML-Body (für Mail-Clients, die HTML rendern) und Plain-Text-Body (das Fallback). Die von der Vorlage referenzierten Variablen werden automatisch aus dem Template-Quelltext erkannt; Admins können neben jeder eine Beschreibung hinzufügen, damit spätere Autoren wissen, was zu übergeben ist.
Email Templates tab listing system and workflow templates side by side
System Settings › Email Templates — System- und Workflow-Vorlagen nebeneinander in der Liste.
Editing the Password Reset system template with auto-detected Handlebars variables
Bearbeiten der mitgelieferten Password-Reset-Vorlage mit Betreff, HTML- und Plain-Text-Body und automatisch erkannten Handlebars-Variablen.

Asynchrone Zustellung und der Audit-Trail

Workflow-E-Mails blockieren die Pipeline, die sie produziert, nicht. Wenn ein Send-Email-Schritt ausgelöst wird, reiht er einen SendEmailJob in eine Redis-Queue ein (queue:email als Default) und geht weiter. Ein Worker-Prozess konsumiert die Queue, wählt den richtigen Mail-Service anhand des Kanals im Job, rendert die Vorlage und versendet über lettre.
Nach jedem Versuch, erfolgreich oder nicht, passieren zwei Dinge: Ein System-Log-Eintrag wird mit vollständigen Details geschrieben (Zeitstempel, Empfänger, Template-Slug, gerendertes HTML, Quellkanal, Status), und bei einem transienten Fehler greift ein exponentielles Backoff.
Der System-Logs-Tab ist durchsuchbar und filterbar. Operatoren können nach Typ filtern (email_sent, entity_created, auth_event, …), nach Ressource, nach Status und nach Datumsbereich. Ein Klick auf eine Zeile öffnet ein Detail-Overlay, das das E-Mail-HTML in einem sanitisierten Container rendert, sodass genau ersichtlich ist, was der Empfänger erhalten hat, ohne die Admin-UI zu verlassen.
Logs haben eine konfigurierbare Aufbewahrung (SYSTEM_LOGS_RETENTION_DAYS, Default 90) und einen Purger-Cron (SYSTEM_LOGS_PURGER_CRON), der abgelaufene Einträge löscht. Derselbe Log-Stream erfasst auch Admin-Entity-CRUD und Auth-Events, sodass ein Operator, der ein Zustellproblem untersucht, gleichzeitig den Kontext der Workflow-Läufe und Template-Änderungen hat, die dazu geführt haben.
System Logs tab filtered to email_sent entries
System Logs — jeder E-Mail-Versand wird mit Empfänger, Vorlage, Status und gerendertem Inhalt auditiert.

Setup-Guide

Hier ist das Setup von Anfang bis Ende für eine selbstgehostete RDataCore-Instanz.
1. Wähle einen Mail-Relay. Für lokale Entwicklung bring Mailpit als docker-compose-Sidecar hoch; er fängt ausgehende Mails in einer lokalen Web-UI ab, ohne etwas extern zu versenden. In Produktion zeig die DSNs auf deinen transaktionalen Anbieter (z.B. Postmark, SES, SendGrid) oder deinen eigenen Relay.
2. Konfiguriere die DSNs. Beide sind URL-förmig und optional:
  • SYSTEM_SMTP_DSN=smtp://user:pass@host:port?tls=true&from=system@example.com&from_name=RData%20System
  • WORKFLOW_SMTP_DSN=smtp://user:pass@host:port?tls=true&from=workflow@example.com&from_name=RData%20Workflows
Der Query-Parameter from ist erforderlich; user:pass@ und tls sind optional (tls ist per Default false). Lass entweder Variable weg, wenn du den Kanal nicht brauchst, und die UI blendet ihn automatisch aus.
3. Setze FRONTEND_BASE_URL. Erforderlich für den Passwort-Reset-Ablauf; die mitgelieferte Vorlage verwendet sie, um den {{reset_url}}-Link zu bauen, z.B. FRONTEND_BASE_URL=http://admin.rdatacore.docker.
4. Optionales Tuning. Du kannst PASSWORD_RESET_THROTTLE_SECONDS (Default 60), QUEUE_EMAIL_KEY (Default queue:email), SYSTEM_LOGS_RETENTION_DAYS (Default 90) und SYSTEM_LOGS_PURGER_CRON an deine Skala anpassen.
5. Bearbeite die mitgelieferte System-Vorlage. Öffne in der Admin-UI System Settings → Email Templates und bearbeite password_reset. Überprüfe Betreff und Bodies, stelle sicher, dass Branding und Tonalität stimmen, und speichere.
6. Erstelle die Workflow-Vorlagen, die du brauchst. Immer noch unter Email Templates, klick Create Template, um eine Workflow-Vorlage zu definieren. Gib ihr einen Slug, schreib Betreff und Bodies mit Handlebars-Variablen und fülle für jede Variable die Beschreibung aus, damit spätere Admins verstehen, was zu übergeben ist.
7. Binde E-Mails in Workflows ein.
  • Für Versand pro Datensatz: Öffne deine Workflow-Definition, füge einen Send Email-Transform im Apply transformations-Schritt hinzu. Wähle deine Workflow-Vorlage, mappe Empfänger (aus einem Feld oder als Konstante), optional CC, und setze ein Target Status Field, damit nachgelagerte Schritte das Ergebnis lesen können.
  • Für Zusammenfassungen nach dem Lauf: Öffne den Post-Run Actions-Abschnitt des Workflows, füge eine Send-Email-Action hinzu, wähle Vorlage und Empfänger und entscheide die Condition (Always, On Success oder On Failure). Denk daran: Die {{run.*}}-Variablen sind hier verfügbar.
8. Verifiziere. Führe den Workflow aus, öffne den System Logs-Tab und filtere nach email_sent. Du solltest einen Eintrag pro Zustellung sehen, mit dem gerenderten Inhalt im Detail-Overlay.

Was kommt als Nächstes

E-Mail schließt einen lange offenen Kreis: Daten bewegen sich durch RDataCore, und jetzt erfahren Menschen davon. Als Nächstes kommt:
Webhook-Outputs. Dieselbe Post-Run-Maschinerie, aber mit JSON-POSTs an HTTP-Endpunkte statt Mail-Versand.
Reichere Template-Variablen. Typisierte Variablendefinitionen mit Validierung, damit ein Template-Autor nicht versehentlich ein Feld referenziert, das der Aufrufer nicht liefert.
Geplante Digests. Cron-gesteuerte Zusammenfassungs-Mails, die über mehrere Workflow-Läufe aggregieren.
Wenn du neu mit Workflows bist, beginne mit Entitäten und Entity-Definitionen und dem Post zu Headless-Authentifizierung. Zusammen decken sie die Bausteine ab, die du vor dem Verdrahten von E-Mail-Schritten kennen willst.
Demnächst: Webhook Outputs