GraphQL-API
emailwerk stellt seine gesamte Funktionalität über einen einzigen GraphQL-Endpunkt unter /graphql bereit. Das Schema wird von Pylon v3 direkt aus den TypeScript-Typen reflektiert. Es gibt kein handgeschriebenes SDL. Auch die eingebaute Admin-Oberfläche spricht intern denselben Endpunkt.
Rollen
Zwei Rollen schützen die API.
emailwerk:adminfür Verwaltung: Vorlagen, Absender, Historie und Signatur-Anfragen.emailwerk:sendfür den Versand.
Die einzige Ausnahme ist der anonyme Zweig von sendTemplateMail für öffentliche Kontaktformulare. Der ist im Detail unter Kontaktformular beschrieben.
Queries
| Query | Zweck |
|---|---|
templates | Seite der Vorlagen der eigenen Organisation, mit Cursor-Pagination |
template(id) | eine Vorlage |
senders | die Absender der Organisation, ohne Zugangsdaten |
senderConnectUrl(senderId) | die OAuth-Verbindungs-URL für einen Gmail-Absender |
dashboard | Zähler für die Übersicht: Vorlagen, Absender, heute gesendet, in der Queue |
messages | Seite der Versandhistorie, filterbar nach Status und Suchbegriff |
message(id) | eine Nachricht samt Lebenszyklus-Ereignissen |
signatureRequests | die Signatur-Anfragen der Organisation, optional nach Status gefiltert |
signatureRequestArtifacts(id) | die Artefakte einer fertig signierten Anfrage, etwa das signierte PDF |
Mutations
| Mutation | Zweck |
|---|---|
templateCreate / templateUpdate / templateDelete | Vorlagen verwalten |
senderCreate / senderSetDefault / senderDelete | Absender verwalten |
senderVerify | Verbindungstest eines Absenders, ohne Mailversand |
templatePreview | Inhalt und Testwerte serverseitig rendern, ohne Versand |
sendTemplateMail | einen Vorlagen-Versand einreihen |
sendEmail | Ad-hoc-Versand ohne Vorlage, Betreff und Inhalt kommen aus dem Aufruf |
sendForSignature | einen Versand anhalten, bis eine qualifizierte ID-Austria-Signatur vorliegt |
prepareSignatureContent | die kanonischen Inhalts-Bytes eines Signatur-Versands auflösen, damit sie vorab lokal PGP-signiert werden können |
messageResend | eine Nachricht aus der Historie erneut einreihen, als möglichst getreue Wiederholung des ursprünglichen Versands |
signatureRequestCancel | eine noch offene Signatur-Anfrage abbrechen |
signatureRequestRemind | die Signatur-Benachrichtigung mit einem frischen Link erneut zustellen, der alte Link verliert dabei sofort seine Gültigkeit |
sendTemplateMail
Die zentrale Versand-Mutation nimmt ihre Argumente unter args: entgegen:
mutation {
sendTemplateMail(
args: {
templateId: "..."
to: ["[email protected]"]
values: { order_id: "1234" }
envelopeOverride: { replyTo: "[email protected]" }
}
) {
id
status
}
}
Wesentliche Argumente:
templateIdbestimmt die Vorlage.toist optional. Ohne Angabe gelten die im Umschlag der Vorlage gespeicherten Empfänger.valuesliefert die Werte für die Vorlagen-Variablen.envelopeOverrideüberschreibt Betreff, Empfänger oder Reply-To.scheduledAtreiht den Versand für einen späteren Zeitpunkt ein.
Für anonyme Aufrufer gelten deutlich engere Regeln. Diese stehen unter Kontaktformular.
Lebenszyklus einer Nachricht
Jeder Versand erzeugt zuerst einen Nachrichten-Datensatz und reiht dann einen Job in die Queue ein. Der Status durchläuft:
QUEUED ─► SENDING ─► SENT | FAILED
Fehlgeschlagene Zustellversuche werden mit exponentiellem Backoff wiederholt. Konfigurationsfehler schlagen sofort fehl statt sinnlos zu wiederholen. Die Historie hält pro Nachricht die Provider-Message-Id, den Fehlertext und die Anzahl der Versuche fest und ist über messages und message abfragbar.
Ein Versand mit Signaturpflicht durchläuft davor einen zusätzlichen Zustand. Die Nachricht wird beim Einreihen gerendert, eingefroren und als AWAITING_SIGNATURE geparkt. Erst wenn die qualifizierte Signatur vorliegt, geht sie in die normale Queue.