Überblick

Das Problem

Eine gewachsene Contao-Website verschickt mehr E-Mails, als irgendjemand im Kopf hat: die Bestätigung des Kontaktformulars, die Meldung an den Vertrieb, die Registrierungsmail, das neue Passwort, der Hinweis auf einen Kommentar, die Bestätigung der Newsletter-Anmeldung. Jede dieser Nachrichten wurde irgendwann einmal von jemand anderem eingerichtet – im Formulargenerator, in einem Frontend-Modul, in einer Erweiterung oder direkt im Code. Der Text steht an sechs Stellen, das Layout an keiner.

  • Niemand weiß, ob eine Mail angekommen ist. Ein Kunde ruft an und sagt, er habe nichts erhalten. Die Antwort darauf steht bestenfalls in var/logs/, also praktisch nirgends.
  • Änderungen am Text sind eine Suche. Wer die Absenderadresse oder den Rechtshinweis im Fuß anpassen will, muss erst herausfinden, welche der Mails überhaupt wo konfiguriert ist.
  • Jede Mail sieht anders aus. Kopf, Fuß, Farben und Schrift werden pro Nachricht kopiert. Nach zwei Jahren gleicht keine Mail der anderen und keine dem Erscheinungsbild der Website.
  • Eingefügte HTML-Designs brechen in Outlook. Ein Design, das im Browser korrekt aussieht, wird in Outlook und Gmail unbrauchbar, sobald das CSS in einem <style>-Block steht statt in style-Attributen.
  • Testen heißt: das echte Ereignis auslösen. Um eine Registrierungsmail zu prüfen, wird ein Testkonto registriert – mit allen Nebenwirkungen, die das hat.
  • Mehrsprachigkeit wird zur Kopie. Für jede weitere Sprache entsteht eine zweite Konfiguration, die ab dem Tag ihrer Anlage auseinanderläuft.

Am härtesten trifft das die Redaktion und den Support: Die eine darf Texte nicht ändern, ohne einen Entwickler zu fragen, der andere kann eine einfache Frage – „ist die Mail raus?“ – nicht beantworten.

Die Lösung

Alle Benachrichtigungen einer Contao-Installation werden an einer Stelle im Backend beschrieben, dort getestet und dort nachvollzogen – unabhängig davon, was sie auslöst.

Die Suite trennt drei Dinge, die sonst vermischt sind: Eine Benachrichtigung beschreibt den Anlass („Kontaktformular abgeschickt“). Ihre Nachrichten beschreiben die konkreten Aussendungen, je Sprache eine. Ein Absender beschreibt den Weg, über den ausgeliefert wird – E-Mail, Webhook oder Datei. Ein gemeinsames Layout liefert den gestalteten Rahmen, und das Versandprotokoll hält fest, was tatsächlich passiert ist.

AufgabeBisherMit diesem Paket
Prüfen, ob eine Mail angekommen istServerprotokolle durchsehenVersandprotokoll mit Status, Fehlertext und erneutem Versand per Klick
Eine Benachrichtigung testenDas echte Ereignis auslösenVorschau und Testversand mit eigenen Token-Werten
Text oder Fußzeile ändernSuchen, an welcher Stelle die Mail konfiguriert istEin Backend-Modul, eine Nachricht, ein Feld
Einheitliches AussehenKopf und Fuß in jede Mail kopierenEin Layout, von beliebig vielen Nachrichten genutzt
Eingefügtes Design Outlook-tauglich machenCSS von Hand in style-Attribute schreibenGeschieht vor dem Versand automatisch
Zweite SpracheKonfiguration duplizierenEine weitere Nachricht unter derselben Benachrichtigung
Slack oder Teams benachrichtigenEigener Code oder ZusatzerweiterungAbsender vom Typ Webhook / JSON

Den oben genannten Kosten stehen damit konkrete Funktionen gegenüber:

  • Versandprotokoll – jeder Versuch mit Empfänger, Betreff, Status und Fehlertext; fehlgeschlagene Einträge lassen sich erneut senden.
  • Benachrichtigungen und Nachrichten – ein Modul für alle Texte, mit Veröffentlichungszeitraum je Nachricht.
  • E-Mail-Layouts, Designs und Branding – 20 mitgelieferte Designs, die Logo, Markenfarbe und Firmenangaben aus einem einzigen Datensatz beziehen.
  • CSS-Inlining – Regeln eines Layouts werden vor dem Versand auf die Elemente übertragen.
  • Vorschau und Testversand – ohne das auslösende Ereignis.
  • Nachrichten je Sprache unter derselben Benachrichtigung, mit einer Fallback-Nachricht.
  • Absender vom Typ Webhook / JSON – für Slack, Microsoft Teams, Google Chat, Zapier und beliebige HTTPS-Endpunkte.

Wann das Paket passt

SituationEinschätzung
Mehrere Formulare, Mitgliederfunktionen oder Newsletter auf einer WebsitePasst. Genau dafür gebaut.
Der Support soll selbst nachsehen können, ob eine Mail versendet wurdePasst. Das Versandprotokoll ist ein eigenes Backend-Modul mit eigener Rechtefreigabe.
Transaktionsmails sollen im Erscheinungsbild der Marke ankommenPasst. Designs, Branding und CSS-Inlining sind dafür da.
Mails in mehreren SprachenPasst. Eine Nachricht je Sprache, eine davon als Fallback.
Meldungen an Slack, Teams oder ein eigenes SystemPasst. Absender vom Typ Webhook / JSON, mit fertigen Vorlagen im Hilfe-Assistenten.
Eine einzige Kontaktformular-Mail, die seit Jahren funktioniertEher nicht. Der Nutzen entsteht aus der Bündelung; für einen einzelnen Versand ist der Aufwand höher als der Gewinn.
Newsletter-Versand an große VerteilerNicht dieses Paket. Die Suite verschickt Transaktions- und Ereignisnachrichten. Für Massenversand mit Abmeldeverwaltung und Zustellstatistik ist ein Newsletter-Dienst das richtige Werkzeug.
Ausgabe von Inhalten im FrontendNicht zutreffend. Das Paket erzeugt keine Frontend-Ausgabe.

Teil 1 — Einrichtung

Der Weg von der Installation bis zur ersten versendeten Benachrichtigung:

  1. Voraussetzungen prüfen
  2. Vor der Installation: Sicherung und Entscheidungen
  3. Installation über den Contao Manager oder über Composer
  4. Installation überprüfen
  5. Lizenz aktivieren
  6. Konfiguration (optional)
  7. Die erste Benachrichtigung anlegen

Voraussetzungen

KomponenteAnforderung
PHP^8.1
PHP-Erweiterungenext-curl, ext-json, ext-sodium
Contaocontao/core-bundle ^5.3
Symfony Mailer / Mime^6.4 || ^7.0 (von Contao mitgebracht)
CSS-Inliningtijsverkoyen/css-to-inline-styles ^2.2 (wird mitinstalliert)
Optionalsymfony/http-client – der Webhook-Absender nutzt sie, wenn sie installiert ist
MailversandEin erreichbarer SMTP-Server oder ein anderer von Symfony Mailer unterstützter Transport
NetzwerkAusgehende HTTPS-Verbindungen vom Server – für die Lizenzaktivierung und für Webhook-Absender
DateisystemEin privates Verzeichnis unterhalb von var/ muss für den Webserver-Benutzer beschreibbar sein

Messenger-Worker. Contao übergibt E-Mails an eine Warteschlange. Ohne laufenden Messenger-Worker – oder ohne aktiven Web-Worker von Contao – bleiben Nachrichten in der Warteschlange stehen und erreichen den Mailserver nie. Das ist keine Besonderheit dieses Pakets, aber die häufigste Ursache für „es passiert nichts“.

Vor der Installation

  1. Datensicherung anlegen – Datenbank und Dateisystem. Die Installation legt neue Tabellen an; ein Rückweg ohne Sicherung ist unangenehm.
  2. Testumgebung bevorzugen – richten Sie die Suite zuerst auf einem Test- oder Staging-System ein. Beachten Sie dabei, dass eine Lizenz an Hostnamen gebunden ist: Test-, Staging- und Produktivsystem benötigen jeweils eine für ihren Hostnamen gültige Lizenz.
  3. Domain auf der Startseite prüfen – im Seitenbaum muss auf der Startseite eine Domain hinterlegt sein. Ohne konfigurierte Domain lässt sich die Lizenz nicht aktivieren.
  4. Schreibrechte prüfen – siehe Tabelle unten.
  5. Entscheiden, ob Inhalte protokolliert werden dürfen – das Versandprotokoll speichert standardmäßig Betreff und Inhalt jeder Nachricht, damit ein erneuter Versand möglich ist. Auf Installationen, die keine personenbezogenen Daten vorhalten dürfen, wird das abgeschaltet (siehe Konfiguration).
VerzeichnisWozuErforderlich
Ein privates Verzeichnis unterhalb von var/ Laufzeitdaten des Pakets. Liegt außerhalb des öffentlichen Web-Wurzelverzeichnisses und ist nicht über HTTP erreichbar. Immer. Muss für den Webserver-Benutzer beschreibbar sein und gehört in die Datensicherung.
var/notification-mail Ablage des Datei-Absenders: Nachrichten werden dorthin geschrieben, statt versendet zu werden. Nur, wenn Sie einen Absender vom Typ Datei verwenden.
.env.local im Projektverzeichnis Speicherort der SMTP-Zugangsdaten, wenn Sie das Modul SMTP-Konfiguration nutzen. Nur für dieses Modul. Ohne Schreibrecht meldet es das ausdrücklich und sendet nichts.

Installation über den Contao Manager

So installieren Sie das Paket

  1. Contao Manager öffnen und anmelden.
  2. Den Bereich Entdecken öffnen. Neue Pakete werden immer dort gesucht und hinzugefügt; der Bereich Pakete daneben zeigt unter Installierte Pakete nur, was bereits vorhanden ist. Entdecken ist zugleich die Startansicht des Managers.
  3. Über Pakete suchen nach vtinnovations/centralized-notification-suite suchen und beim Treffer Paket hinzufügen wählen.
  4. Die Änderungen anwenden. Der Contao Manager installiert das Paket und aktualisiert den Autoloader.
  5. In den Bereich Systemwartung wechseln, dort Datenbank-Migrationen und -Backups öffnen und Datenbank prüfen ausführen. Die angezeigten Datenbank-Änderungen bestätigen – sie legen die Tabellen der Suite an.
  6. Ebenfalls unter Systemwartung den Anwendungs-Cache leeren (in der Navigation auch als Cache erneuern zu finden).
  7. Weiter mit Installation überprüfen.

Der Contao Manager spricht seine Benutzer mit „du“ an. Zitate aus seiner Oberfläche – etwa der Hinweis „Dieses Paket wird installiert, wenn du die Änderungen anwendest.“ – behalten diese Anrede; sie stammt nicht von uns.

Installation über Composer

Die Alternative für Installationen, die von der Kommandozeile aus gepflegt werden:

composer require vtinnovations/centralized-notification-suite
vendor/bin/contao-console contao:migrate

Auf einer Managed Edition richtet contao:setup anschließend die Verzeichnisse und symbolischen Verknüpfungen ein:

vendor/bin/contao-console contao:setup

Aktualisierung auf eine neuere Version:

composer update vtinnovations/centralized-notification-suite
vendor/bin/contao-console contao:migrate
vendor/bin/contao-console cache:clear --env=prod

Kein manuelles Entpacken. Ersetzen Sie das Verzeichnis des Pakets nicht von Hand durch eine entpackte ZIP-Datei. Der Autoloader und die Bundle-Registrierung entstehen beim Composer-Lauf; ein händisch ausgetauschtes Verzeichnis führt zu einer Installation, in der Klassen fehlen, ohne dass es eine passende Fehlermeldung dazu gibt.

Installation überprüfen

Zwei Prüfungen genügen. Auf der Kommandozeile:

vendor/bin/contao-console debug:container --parameter=kernel.bundles | grep CentralizedNotificationSuite
vendor/bin/contao-console list notification

Der zweite Befehl muss die vier Befehle der Suite auflisten: notification:send, notification:install-layouts, notification:install-emails und notification:import-nc.

Im Backend erscheint in der Navigation eine neue Gruppe Centralized Notification Suite – direkt oberhalb der Gruppe System, nicht am Ende des Menüs – mit sechs Modulen in dieser Reihenfolge:

ModulBeschreibung im Backend
Benachrichtigungen„Benachrichtigungen und ihre Nachrichten verwalten“
E-Mail-Layouts„Wiederverwendbare HTML-Layouts für Ihre Nachrichten verwalten“
Branding„Logo, Markenfarbe und Firmenangaben für alle Designs“
Absender„Die Absender (Gateways) verwalten, die Nachrichten versenden“
Versandprotokoll„Sehen, was versendet wurde, warum etwas fehlgeschlagen ist, und erneut senden“
SMTP-Konfiguration„SMTP-Zugangsdaten, über die die Website versendet“

Die ersten fünf Module folgen der normalen Contao-Rechteverwaltung und lassen sich je Benutzergruppe freigeben. Das Modul SMTP-Konfiguration ist Administratoren vorbehalten; alle anderen Benutzer sehen dort „Zugriff verweigert. Nur für Administratoren.“

Lizenz aktivieren

Die Suite setzt eine aktivierte Lizenz voraus. Ohne sie wird nichts versendet und nichts in die Warteschlange gestellt – die Installation verhält sich genau so, als wäre das Paket nicht installiert. Benachrichtigungen, Nachrichten, Layouts, Branding und Versandprotokoll bleiben dabei unverändert erhalten.

Das Produkt wird mit einer kostenfreien, unbefristeten Lizenz ausgeliefert. „Kostenfrei“ bezieht sich ausschließlich auf den Preis: Eine von V-T.ONE ausgestellte Lizenz muss aktiviert sein. Es gibt genau diese eine Stufe – keine Testphase und keine zweite, größere Ausbaustufe.

Verwaltet wird sie unter Contao → Einstellungen im Abschnitt V-T.ONE Licence management. Das ist der gemeinsame Abschnitt aller V-T.ONE-Pakete: Jedes Paket zeigt dort eine eigene Karte, überschrieben mit seinem Produktnamen – hier Centralized Notification Suite.

So aktivieren Sie die Lizenz

  1. Stellen Sie sicher, dass im Seitenbaum auf der Startseite die Domain hinterlegt ist, für die Ihr Schlüssel ausgestellt wurde.
  2. Melden Sie sich als Benutzer an, der das Modul Einstellungen öffnen darf. In der Praxis ist das ein Administrator.
  3. Öffnen Sie Einstellungen und scrollen Sie zum Abschnitt V-T.ONE Licence management, dort zur Karte Centralized Notification Suite. Die erste Zeile der Karte zeigt den aktuellen Zustand: Lizenz aktiv oder Keine aktive Lizenz.
  4. Tragen Sie den Schlüssel in das Feld Lizenzschlüssel ein. Der Platzhalter im Feld lautet XXXXX-XXXXX-XXXXX-XXXXX.
  5. Klicken Sie Lizenz prüfen und aktivieren. Der Server nimmt dafür selbst eine ausgehende HTTPS-Verbindung auf – nicht Ihr Browser. Ein Firewall-Regelwerk, das ausgehende Verbindungen unterbindet, verhindert die Aktivierung.
  6. Bei Erfolg erscheint die Meldung „Die Lizenz wurde aktiviert.“ und die Karte zeigt Lizenz aktiv sowie die Angaben Paket, Lizenzierter Host, Abgedeckte Hosts, Version und Laufzeit (bei unbefristeten Lizenzen: Unbefristet).
  7. Das Schlüsselfeld ist danach wieder leer. Der hinterlegte Schlüssel wird in der Oberfläche nicht erneut ausgegeben – auch nicht unmittelbar nach der Aktivierung. Das ist erwartetes Verhalten und kein Zeichen dafür, dass nichts gespeichert wurde; maßgeblich ist die Statuszeile.

Zwei weitere Schaltflächen stehen jederzeit zur Verfügung:

SchaltflächeWirkung
Lizenz aktualisieren Gleicht den gespeicherten Stand mit dem Lizenzdienst ab. Bleibt das Schlüsselfeld leer, wird der bereits gespeicherte Schlüssel erneut geprüft. Erfolgsmeldung: „Die Lizenz wurde aktualisiert.“
Lizenz entfernen Setzt die Installation sofort in den nicht lizenzierten Zustand zurück. Vorher erscheint die Rückfrage „Die gespeicherte Lizenz entfernen? Es werden keine Benachrichtigungen mehr versendet, bis wieder eine Lizenz aktiviert ist.“ Danach: „Die Lizenz wurde entfernt.“ Es werden keine Inhalte gelöscht.

Bindung an Hostnamen. Eine Lizenz gilt für die Hostnamen, für die sie ausgestellt wurde. Maßgeblich sind die Domains, die auf den Startseiten der Website hinterlegt sind. Unterschiedliche Schreibweisen sind verschiedene Identitäten: example.com und www.example.com gelten nicht automatisch füreinander.

Ist der Lizenzdienst einmal nicht erreichbar, bleibt der gespeicherte Zustand unverändert – eine bereits aktivierte Installation verliert ihre Lizenz dadurch nicht.

Konfiguration

Die Suite arbeitet ohne Konfigurationsdatei. Wer die Voreinstellungen ändern will, legt sie in config/config.yaml ab. Alle Werte sind optional; die gezeigten entsprechen den Voreinstellungen.

# config/config.yaml
centralized_notification_suite:
    log:
        enabled: true
        store_body: true
        retention_days: 90
        max_attempts: 3
        retry_failed: true
    mailer:
        php_binary: ''
        process_timeout: 120
        memory_limit: '-1'
SchlüsselVoreinstellungBedeutung
log.enabledtrueJeden Sendeversuch im Versandprotokoll festhalten.
log.store_bodytrueBetreff, Inhalt und Token-Werte mitspeichern. Erforderlich für den erneuten Versand und für die Ansicht dessen, was ein Empfänger erhalten hat. Auf Installationen, die keine personenbezogenen Daten im Protokoll halten dürfen, abschalten.
log.retention_days90Protokolleinträge, die älter sind, werden gelöscht. 0 behält sie dauerhaft. Mindestwert 0.
log.max_attempts3Wie oft der Wiederholungs-Cron eine fehlgeschlagene Nachricht erneut versucht, bevor er aufgibt. Mindestwert 1.
log.retry_failedtrueFehlgeschlagene Nachrichten einmal pro Stunde automatisch erneut versuchen.
mailer.php_binary''Pfad zur PHP-CLI-Binärdatei für den Cache-Neuaufbau nach einer Änderung der SMTP-Einstellungen. Leer bedeutet automatische Erkennung.
mailer.process_timeout120Sekunden, bis der Unterprozess für den Cache-Neuaufbau abgebrochen wird. Mindestwert 30.
mailer.memory_limit'-1'Speichergrenze nur für diesen Unterprozess, z. B. '512M'. Eine leere Zeichenkette übernimmt den Wert der CLI-php.ini. Contao wärmt die Sprachdateien aller installierten Pakete in einem Prozess, was regelmäßig mehr benötigt als die üblichen 128M.

Nach jeder Änderung an dieser Datei den Cache leeren:

vendor/bin/contao-console cache:clear --env=prod

Die erste Benachrichtigung

Der kürzeste Weg zu einem überprüfbaren Ergebnis: ein Absender, eine Benachrichtigung, eine Nachricht, ein Testversand.

So richten Sie die erste Benachrichtigung ein

  1. Öffnen Sie Absender und legen Sie einen neuen Eintrag an. Vergeben Sie einen Titel, wählen Sie als Typ den Eintrag E-Mail und tragen Sie unter Absenderadresse die Adresse ein, von der gesendet wird. Speichern.
  2. Öffnen Sie Benachrichtigungen und legen Sie einen Eintrag an. Titel vergeben; das Feld Alias leer lassen, dann wird es aus dem Titel erzeugt. Unter Ausgelöst durch wählen Sie den Anlass, zum Beispiel Ein Formularversand.
  3. Speichern. Die Auswahl unter Ausgelöst durch bestimmt, welche Tokens Ihnen beim Bearbeiten der Nachricht angeboten werden und an welchen Stellen diese Benachrichtigung überhaupt zur Auswahl steht.
  4. Klicken Sie in der Liste auf Nachrichten bearbeiten und legen Sie eine Nachricht an.
  5. Wählen Sie im Abschnitt Absender und Sprache den eben angelegten Absender und die Sprache. Setzen Sie den Haken bei Fallback-Nachricht, solange es nur eine Nachricht gibt – sonst wird sie nur bei exakt passender Sprache verwendet.
  6. Tragen Sie unter Betreff und im Abschnitt HTML den Inhalt ein und füllen Sie unter Empfänger mindestens eine Adresse aus. Das Hilfe-Symbol an den Inhaltsfeldern zeigt alle verfügbaren Tokens.
  7. Speichern und in die Liste zurückkehren. Klicken Sie dort auf Vorschau, um das fertige Ergebnis mit Beispielwerten zu sehen.
  8. Klicken Sie auf Test senden, tragen Sie unter Senden an Ihre eigene Adresse ein und senden Sie ab. Anschließend erscheint „Testnachricht an … gesendet. Das Ergebnis steht im Versandprotokoll.“
  9. Öffnen Sie Versandprotokoll und prüfen Sie den Status des Eintrags.
  10. Verknüpfen Sie die Benachrichtigung zuletzt mit ihrem Auslöser – im Formulargenerator über das Feld Benachrichtigungen, in einem Mitglieder- oder Newsletter-Modul über das gleichnamige Feld, oder aus eigenem Code über den Alias.

Optional lassen sich fertige Layouts und vollständig aufgebaute Beispiel-E-Mails einspielen, die als Ausgangspunkt dienen:

vendor/bin/contao-console notification:install-layouts
vendor/bin/contao-console notification:install-emails

Teil 2 — Funktionen im Detail

Benachrichtigungen

Eine Benachrichtigung beschreibt den Anlass, nicht die Mail. Sie liegt im Modul Benachrichtigungen und hat genau einen Abschnitt: Titel und Alias.

So legen Sie eine Benachrichtigung an

  1. Benachrichtigungen öffnen und Neue Benachrichtigung wählen.
  2. Titel eintragen – der Name, unter dem die Benachrichtigung in allen Auswahllisten erscheint.
  3. Alias leer lassen, außer Sie brauchen einen bestimmten Bezeichner. Aus dem Titel wird dann ein eindeutiger Alias erzeugt.
  4. Unter Ausgelöst durch den Typ wählen. Die Seite lädt danach neu.
  5. Speichern. Über Nachrichten bearbeiten geht es zu den Aussendungen, über Einstellungen bearbeiten zurück zu diesem Formular.
FeldHilfetext im Backend
Titel„Geben Sie einen Namen für diese Benachrichtigung ein.“
Alias„Ein eindeutiger Alias. Diese Zeichenkette übergibt Ihr Code an CentralizedNotificationSuite::send(). Leer lassen, um ihn aus dem Titel zu erzeugen.“
Ausgelöst durch„Was diese Benachrichtigung versendet. Der Typ bestimmt, welche Tokens Ihnen beim Bearbeiten der Nachricht angeboten werden und welche Benachrichtigungen ein Auslöser zur Auswahl stellt.“
TypBedeutung
Ein FormularversandWird im Formulargenerator zur Auswahl gestellt. Alle übermittelten Felder stehen als Tokens bereit.
Eine Mitglieder-Aktion (Registrierung, Passwort zurücksetzen, …)Wird in den Mitglieder-Modulen zur Auswahl gestellt. ##member_*##-Tokens.
Ein neuer KommentarWird bei jedem neuen Kommentar ausgelöst. ##comment_*##-Tokens.
Eine Newsletter-AnmeldungWird in den Newsletter-Modulen zur Auswahl gestellt. ##newsletter_*##-Tokens.
Ihr eigener CodeVoreinstellung für bestehende Datensätze. Wird ausschließlich über den Service-Aufruf oder die Kommandozeile ausgelöst.

Kommentare haben keine Modul-Auswahl. Ein gespeicherter Kommentar lässt sich nicht auf das Inhaltselement zurückführen, das sein Formular gerendert hat. Deshalb gibt es dort kein Feld Benachrichtigungen: Es werden alle veröffentlichten Benachrichtigungen vom Typ Ein neuer Kommentar gesendet. Das Anlegen einer solchen Benachrichtigung ist die Zustimmung.

Nachrichten und Sprachen

Eine Nachricht ist die konkrete Aussendung. Sie liegt unterhalb ihrer Benachrichtigung und wird über Nachrichten bearbeiten erreicht. Das Formular hat sechs Abschnitte in dieser Reihenfolge: Absender und Sprache, Nur-Text, HTML, Empfänger, Anhänge und Veröffentlichung.

So legen Sie eine Nachricht an

  1. In der Benachrichtigungsliste auf Nachrichten bearbeiten klicken, dann Neue Nachricht.
  2. Absender wählen. Angeboten werden ausschließlich veröffentlichte Absender – ein unveröffentlichter würde eine Nachricht erzeugen, die konfiguriert aussieht und nie sendet.
  3. Sprache wählen. Maßgeblich ist später die Sprache der Anfrage, in der die Benachrichtigung ausgelöst wird.
  4. Fallback-Nachricht setzen, wenn diese Nachricht einspringen soll, sobald keine Nachricht zur angeforderten Sprache passt.
  5. Betreff eintragen. Tokens sind erlaubt; das Hilfe-Symbol am Feld listet alle Tokens dieser Benachrichtigung.
  6. Im Abschnitt HTML entscheiden, ob der Inhalt aus Bausteinen aufgebaut oder als Eigenes HTML geschrieben wird. Optional ein Layout zuweisen.
  7. Empfänger eintragen – eine oder mehrere Adressen, durch Komma oder Semikolon getrennt; Tokens sind erlaubt. Bei Bedarf CC, BCC und Antwort an ausfüllen.
  8. Speichern. Anschließend stehen in der Liste Vorschau und Test senden zur Verfügung, im Bausteinmodus zusätzlich der Einstieg in die untergeordneten Bausteine.
FeldHilfetext im BackendVoreinstellung
Absender„Wählen Sie den Absender, der diese Nachricht versendet.“— (Pflichtfeld)
Sprache„Die Sprache, in der diese Nachricht verfasst ist.“— (Pflichtfeld)
Fallback-Nachricht„Diese Nachricht verwenden, wenn keine Nachricht zur angeforderten Sprache passt.“aus
Betreff„Werte mit ##token## einfügen … Das Hilfe-Symbol zeigt alle Tokens dieser Benachrichtigung.“— (Pflichtfeld)
Nur-Text„… Leer lassen, um diesen Teil aus dem HTML zu erzeugen.“leer
Nur-Text aus dem HTML erzeugen„Den Text-Teil aus dem HTML ableiten, statt beide von Hand zu pflegen. Links werden als ‚Bezeichnung (URL)‘ übernommen. Geschieht automatisch, wenn das Nur-Text-Feld leer ist.“aus
Layout„Diesen Inhalt optional in ein wiederverwendbares Layout einbetten … Leer lassen, um das HTML unverändert zu senden.“keines
Inhalt„Den Inhalt aus Bausteinen aufbauen, die per Drag & Drop sortiert werden, oder das HTML selbst schreiben.“Bausteine bei neuen Nachrichten; bestehende Datensätze bleiben auf Eigenes HTML
Bilder einbetten„Bilder dieser Website anhängen statt zu verlinken, damit sie ohne Freigabe externer Inhalte angezeigt werden. Vergrößert die Nachricht.“aus
Empfänger„Eine oder mehrere E-Mail-Adressen, durch Komma oder Semikolon getrennt. Tokens sind erlaubt … Ungültige Adressen werden übersprungen und protokolliert, statt die ganze Nachricht scheitern zu lassen.“leer
CC / BCC„Diese Adressen optional in Kopie setzen. Alle Empfänger sehen sie.“ / „… in Blindkopie setzen, z. B. um jede Benachrichtigung zu archivieren.“leer
Antwort an„Die Antwortadresse optional überschreiben, z. B. ##email## … Fällt auf die Einstellung des Absenders zurück.“leer
Priorität„Die Prioritätsmarkierung. Die meisten E-Mail-Programme ignorieren sie; manche Spamfilter bewerten ‚Höchste‘ negativ.“Normal
Anhänge„Eine oder mehrere Dateien aus der Dateiverwaltung an diese Nachricht anhängen.“keine
Veröffentlicht„Die Nachricht aktivieren.“an
Anzeigen ab / Anzeigen bis„Die Nachricht wird vor diesem Datum nicht versendet.“ / „… nach diesem Datum nicht mehr versendet.“leer

So wird die Sprache gewählt. Beim Auslösen wird die Sprache der aktuellen Anfrage verwendet. Passt eine Nachricht genau darauf, wird sie genommen – und nur sie. Passt keine, werden alle als Fallback-Nachricht markierten Nachrichten gesendet. Gibt es weder eine passende noch eine Fallback-Nachricht, wird nichts gesendet. Markieren Sie deshalb immer mindestens eine Nachricht als Fallback.

Die Liste kennzeichnet Nachrichten, die nicht zugestellt werden können, mit dem Grund – zum Beispiel „Der zugewiesene Absender existiert nicht mehr, diese Nachricht wird nicht versendet.“, „Der Absender „…“ ist nicht veröffentlicht, diese Nachricht wird nicht versendet.“ oder „Diese Nachricht hat keine Empfänger, sie wird nicht versendet.“

Inhalt aus Bausteinen

Im Modus Bausteine erhält die Nachricht eine untergeordnete Liste, in der der Inhalt aus einzelnen Elementen zusammengesetzt wird. Das Feld HTML entfällt dann aus dem Formular der Nachricht. Bausteine lassen sich per Drag & Drop sortieren und einzeln ein- und ausblenden.

So bauen Sie einen Nachrichteninhalt auf

  1. In der Nachricht das Feld Inhalt auf Bausteine stellen und speichern.
  2. In der Nachrichtenliste den Einstieg in die untergeordneten Bausteine wählen und Neuer Baustein klicken.
  3. Unter Bausteintyp den gewünschten Typ wählen. Die Seite lädt neu und zeigt die Felder dieses Typs.
  4. Den Inhalt erfassen. Tokens wie ##name## sind in Überschrift, Text, Linktext, Linkziel, den Zeilen der Detailtabelle und im eigenen HTML erlaubt.
  5. Im Abschnitt Abstände bei Bedarf Ausrichtung und Abstand unten (px) setzen.
  6. Speichern. Der Baustein erscheint in der Liste mit einer Vorschaukarte.
  7. Weitere Bausteine anlegen und per Drag & Drop in die gewünschte Reihenfolge bringen.
  8. Über Vorschau an der Nachricht das Gesamtergebnis prüfen.
GruppeBausteintypWofür
TextÜberschriftÜberschrift in drei Größen: Groß, Mittel, Klein.
TextAbsätze. Stil Normal, Einleitung oder Kleingedrucktes. „Eine Leerzeile trennt Absätze, ein einfacher Umbruch erzeugt einen Zeilenumbruch.“
ListeListentyp Aufzählung oder Nummeriert.
Detailtabelle„Je Zeile eine Bezeichnung und ein Wert. Tokens wie ##email## sind in beiden erlaubt.“
Generierter Inhalt„Welcher generierte Inhalt eingefügt wird, z. B. die Liste aller übermittelten Formularfelder.“
MediaBild„JPG, PNG oder GIF – SVG und WebP werden von E-Mail-Programmen nicht zuverlässig dargestellt.“ Bildbreite maximal 536 px; größere Werte werden reduziert.
Bild mit TextAnordnung Bild links, Bild rechts oder Bild oben. „Auf schmalen Bildschirmen werden die Spalten automatisch untereinander gesetzt.“
ActionButtonStil Gefüllt (Markenfarbe) oder Umrandet.
LayoutTrennlinieOptische Trennung zweier Abschnitte.
AdvancedEigenes HTML„Markup wird unverändert eingefügt. Für E-Mails tabellenbasiertes Markup verwenden.“

Zwei Punkte, die regelmäßig überraschen. Ein <style>-Block im Baustein Eigenes HTML würde die ganze Nachricht betreffen und wird deshalb entfernt – Gestaltung gehört in das Layout. Und: Die Versionierung erfasst die Nachricht selbst, nicht ihre Bausteine. Das Zurückholen einer älteren Nachrichtenversion stellt deren Bausteine nicht wieder her.

Tokens

##token## steht in Betreff, Inhalt, Adressfeldern und in den Bausteinen zur Verfügung. Contao-Insert-Tags wie https://www.v-t.one oder funktionieren ebenfalls, ebenso {if} / {else} / {endif}.

So finden Sie die verfügbaren Tokens

  1. Die Nachricht öffnen, deren Tokens Sie brauchen.
  2. Auf das Hilfe-Symbol neben Betreff, Nur-Text oder HTML klicken – oder, im Bausteinmodus, neben den Feldern eines Bausteins.
  3. Das Fenster listet die Tokens in zwei Spalten: Token und Enthält. Der erste Block ist mit Für jede Benachrichtigung verfügbar überschrieben; darunter folgen die Tokens des Typs dieser Benachrichtigung.
  4. Den Token-Namen in das Feld übernehmen, eingefasst in doppelte Rautezeichen.

Immer verfügbar: ##admin_email##, ##date##, ##time##, ##datim##, ##host##, ##url##, ##page_id##, ##page_title##, ##page_url##.

Bei Formular-Benachrichtigungen zusätzlich jedes übermittelte Feld unter dem „Namen“, den es im Formulargenerator trägt – und:

TokenEnthält
##all_fields##Alle übermittelten Felder als „Bezeichnung: Wert“ (Nur-Text)
##all_fields_filled##Dasselbe, ohne die vom Besucher leer gelassenen Felder
##all_fields_html##Alle Felder als formatierte Tabelle
##all_fields_filled_html##Dieselbe Tabelle ohne leere Felder
##label_<feldname>##Die Bezeichnung eines Feldes, für eigene Zusammenstellungen
##uploads## / ##uploads_html##Namen der hochgeladenen Dateien, zeilenweise bzw. als Liste
##form_id## / ##form_title##ID und Titel des abgesendeten Formulars

Mitglieder-Benachrichtigungen erhalten ##member_id##, ##member_firstname##, ##member_lastname##, ##member_email##, ##member_username##, jedes weitere Mitgliederfeld als ##member_<feld>## sowie ##member_event## – mit einem der Werte registration, activation, profile_updated, password_changed oder account_closed.

Kommentar-Benachrichtigungen erhalten ##comment_name##, ##comment_email##, ##comment_comment##, ##comment_source##, ##comment_published## und ##comment_awaiting_moderation##. Newsletter-Benachrichtigungen erhalten ##recipient_email##, ##newsletter_event## (subscribed oder unsubscribed), ##newsletter_channels## und ##newsletter_channel_ids##.

Warum Formulareingaben Ihr Markup nicht zerstören können. In einem HTML-Inhalt werden Token-Werte maskiert und ihre Zeilenumbrüche in <br> überführt. Die Ausnahme ist ausdrücklich benannt: Tokens, deren Name auf _html endet, werden als Markup eingesetzt – so arbeitet ##all_fields_html##. Im Nur-Text-Teil findet keine Maskierung statt.

E-Mail-Layouts und Designs

Ein Layout ist der gestaltete Rahmen, den sich mehrere Nachrichten teilen. Es liegt im Modul E-Mail-Layouts und wird an der Nachricht im Feld Layout zugewiesen. Drei Betriebsarten stehen zur Wahl, gesteuert über Layout-Art:

Layout-ArtWas Sie liefern
Ein fertiges Design (Voreinstellung)Nichts außer der Auswahl. Logo, Markenfarbe und Firmenangaben kommen aus dem Modul Branding.
Kopf und Fuß um den InhaltMarkup für Kopfbereich und Fußbereich, dazu eigenes CSS.
Vollständiges HTML-Dokument mit ##message_body##Ihr komplettes E-Mail-HTML, mit ##message_body## an der Stelle, an die der Nachrichteninhalt gehört.

So erstellen Sie ein Layout

  1. E-Mail-Layouts öffnen und Neues Layout wählen.
  2. Titel vergeben, z. B. „Standard-Layout“.
  3. Optional einen Vorschautext eintragen – „die versteckte Zeile, die die meisten E-Mail-Programme neben dem Betreff im Postfach anzeigen“. Tokens sind erlaubt.
  4. Layout-Art wählen. Die Seite lädt neu und zeigt die passenden Felder.
  5. Bei Ein fertiges Design: unter Design eines der 20 mitgelieferten Designs wählen. Die Auswahl ist nach Gruppen sortiert – Card, Brand bar, Dark, Minimal, Transactional, Announcement und Editorial. Voreingestellt ist Card – left logo.
  6. Bei den beiden anderen Arten: das Markup einfügen und im Abschnitt Styles das CSS hinterlegen – ohne <style>-Tags.
  7. CSS inline schreiben aktiviert lassen. „Lassen Sie das aktiviert, außer Sie wissen, dass das Programm der Empfänger Style-Blöcke unterstützt.“
  8. Veröffentlicht setzen und speichern. Erst dann steht das Layout im Feld Layout einer Nachricht zur Auswahl.
  9. An einer Nachricht zuweisen und über Vorschau prüfen – auch in der Ansicht Mobil.

Die Designnamen sind englisch beschriftet, weil sie Gestaltungsvarianten benennen: Card – centred logo, Card – left logo, Card – square corners, Card – outlined, Brand bar – centred logo, Brand bar – left logo, Brand bar – dark footer, Dark header, Dark header and footer, Minimal – hairline rule, Minimal – wordmark only, Minimal – no header, Compact – tight spacing, Transactional – plain and narrow, Transactional – tinted panel, Receipt – boxed, monospaced figures, Announcement – wide, centred, Announcement – tinted background, Newsletter – serif headings und Editorial – serif, dark footer.

Warum das CSS umgeschrieben wird. Das CSS eines Layouts wird vor dem Versand in style-Attribute überführt – „genau das lässt sie in Outlook und Gmail funktionieren“. @media-Regeln lassen sich nicht inline schreiben und bleiben als Style-Block erhalten, damit responsive Regeln weiter wirken.

Zwei fertige Layouts lassen sich mit einem Befehl einspielen – Transactional (plain, no images) und Branded (logo header, footer). Beide werden als Vollständiges HTML-Dokument angelegt und können anschließend bearbeitet werden:

vendor/bin/contao-console notification:install-layouts
vendor/bin/contao-console notification:install-layouts --list    # nur anzeigen
vendor/bin/contao-console notification:install-layouts --force   # vorhandene überschreiben

Branding

Das Modul Branding hält genau einen Datensatz: Logo, Markenfarbe und Firmenangaben, aus denen jedes fertige Design seine Gestaltung ableitet. Beim Öffnen des Moduls landen Sie direkt im Formular; eine Liste gibt es nicht, und es lässt sich weder ein zweiter Datensatz anlegen noch dieser löschen.

So hinterlegen Sie Ihr Branding

  1. Branding öffnen – das Formular erscheint unmittelbar.
  2. Im Abschnitt Logo über die Dateiauswahl eine Datei wählen. Zulässig sind ausschließlich JPG, PNG und GIF.
  3. Logobreite (px) setzen. „120–180 passt für die meisten Logos.“
  4. Im Abschnitt Farbe die Markenfarbe als Hex-Wert eintragen oder über den Farbwähler bestimmen.
  5. Im Abschnitt Firmenangaben Firmenname, Website, Kontaktadresse und Postanschrift ausfüllen.
  6. Im Abschnitt Fußzeile optional eine Fußnote ergänzen.
  7. Speichern und über die Vorschau einer Nachricht mit Design-Layout kontrollieren.
FeldHilfetext im BackendVoreinstellung
Logo„Ihr Logo aus der Dateiverwaltung. Wird von jedem Design verwendet. PNG, JPG oder GIF – SVG wird von E-Mail-Programmen nicht dargestellt.“keines
Logobreite (px)„Wie breit das Logo in der E-Mail erscheint. 120–180 passt für die meisten Logos.“140
Markenfarbe„Jedes Design leitet seine Palette aus dieser Farbe ab: Kopfbereiche, Links, getönte Flächen und dunkle Balken entstehen automatisch daraus.“#0b5fff
Firmenname„Erscheint in der Fußzeile und dient als Alternativtext des Logos.“leer
Website„Wird in der Fußzeile verlinkt, z. B. https://example.com“leer
Kontaktadresse„Erscheint in der Fußzeile als mailto-Link.“leer
Postanschrift„Erscheint in der Fußzeile. In vielen Ländern ist eine Postanschrift in kommerziellen E-Mails vorgeschrieben.“leer
Fußnote„Kleingedrucktes unter der Anschrift, z. B. warum der Empfänger diese E-Mail erhält.“leer

Absender (Gateways)

Ein Absender beschreibt den Weg, über den eine Nachricht ausgeliefert wird. Das Modul Absender kennt drei Typen; die Felder unterhalb von Typ wechseln, sobald der Typ gewählt ist.

So legen Sie einen Absender an

  1. Absender öffnen und Neuer Absender wählen.
  2. Titel eintragen – der Name, unter dem der Absender in den Nachrichten erscheint.
  3. Typ wählen. Die Seite lädt neu und zeigt den passenden Abschnitt: E-Mail-Einstellungen, Webhook-Einstellungen oder Datei-Einstellungen.
  4. Die Felder dieses Typs ausfüllen (siehe Tabellen unten).
  5. Veröffentlicht setzen und speichern. Nur veröffentlichte Absender werden im Feld Absender einer Nachricht angeboten.
  6. Den Absender an einer Nachricht zuweisen und mit Test senden prüfen.

Typ E-Mail – versendet über Symfony Mailer:

FeldHilfetext im Backend
Absendername„Der Name, der als Absender erscheint.“
Absenderadresse„Die E-Mail-Adresse, von der gesendet wird.“ (Pflichtfeld)
Standard-Antwortadresse„Optional die Antwortadresse für alle Nachrichten dieses Absenders. Eine Nachricht kann sie überschreiben.“
Mailer-Transport„Optional einen benannten Symfony-Mailer-Transport wählen (siehe mailer.yaml). Leer lassen für den Standard-Transport.“

Typ Webhook / JSON (Slack, Teams, Zapier, …) – sendet an einen HTTPS-Endpunkt:

FeldHilfetext im BackendVoreinstellung
Endpunkt-URL„Die URL, an die gesendet wird: ein Slack-Incoming-Webhook, ein Microsoft-Teams-Workflows-Webhook, ein Google-Chat-Webhook oder ein Zapier-/n8n-/Make-Trigger.“— (Pflichtfeld)
HTTP-Methode„Die meisten Webhook-Endpunkte erwarten POST.“ Zur Wahl stehen POST, PUT und PATCH.POST
Timeout (Sekunden)„Wie lange auf den Endpunkt gewartet wird. Halten Sie den Wert klein: ein langsamer Endpunkt hält die auslösende Besucheraktion auf.“10
Zusätzliche Header„Weitere Request-Header, z. B. ein Authorization-Header. Content-Type wird automatisch auf application/json gesetzt.“leer
JSON-Payload„Der Request-Body. Verwenden Sie ##subject##, ##text##, ##html##, ##recipients## sowie jedes Token der Benachrichtigung; Werte werden maskiert, sodass immer gültiges JSON entsteht.“leer – entspricht {"text": "##subject##\n\n##text##"}

Das Hilfe-Symbol am Feld JSON-Payload öffnet einen Assistenten mit fertigen Vorlagen für Slack (Block Kit), Microsoft Teams (Workflows-Webhook mit Adaptive Card) und Google Chat sowie einer Liste der im Payload verwendbaren Tokens: ##subject##, ##text##, ##html##, ##recipients##, ##alias## und ##reference## – letzteres „eine eindeutige ID dieses Versands, nützlich zum Abgleich mit dem Versandprotokoll“.

Microsoft Teams: Die URL wird im Kanalmenü über Weitere Optionen → Workflows mit der Vorlage „In einem Kanal veröffentlichen, wenn eine Webhook-Anfrage empfangen wird“ erzeugt. Dafür ist ein Geschäfts- oder Schulkonto nötig; die kostenfreien Teams-Communities haben keinen Webhook-Endpunkt. Google Chat erfordert Google Workspace.

Typ Datei (schreibt auf die Festplatte statt zu senden) – für Entwicklung und Abnahme:

FeldHilfetext im BackendVoreinstellung
Verzeichnis„Wohin die Nachrichten geschrieben werden. Relative Pfade werden im Projekt aufgelöst. Leer lassen für var/notification-mail.“var/notification-mail

Der Datei-Absender stellt nicht zu. Er schreibt die fertige Nachricht auf die Festplatte und ist damit gedacht, um Benachrichtigungen ohne Mailserver und ohne Risiko für echte Empfänger zu prüfen. Er gehört nicht an eine Nachricht im Produktivbetrieb.

SMTP-Konfiguration

Das Modul SMTP-Konfiguration hinterlegt die Zugangsdaten, über die die gesamte Website versendet – nicht nur die Benachrichtigungen der Suite. Es ist Administratoren vorbehalten und schreibt in die Datei .env.local des Projekts. Über der Maske steht der Zustand: Konfiguriert oder Nicht konfiguriert.

So hinterlegen Sie die SMTP-Zugangsdaten

  1. SMTP-Konfiguration als Administrator öffnen.
  2. Im Abschnitt Server SMTP-Host, Port und Verschlüsselung eintragen. Zur Wahl stehen Keine, STARTTLS (meist Port 587) und SSL/TLS (meist Port 465).
  3. Benutzername und Passwort eintragen. Beim späteren Bearbeiten gilt: „Leer lassen, um das gespeicherte Passwort beizubehalten.“
  4. Im Abschnitt E-Mail die Absenderadresse und einen Testempfänger eintragen. „An diese Adresse wird vor dem Speichern eine Test-E-Mail gesendet.“
  5. Testen und speichern klicken.
  6. Warten und das Browserfenster geöffnet lassen. Der Vorgang läuft synchron ab: Erst wird die Test-E-Mail gesendet, dann werden die Einstellungen geschrieben, dann wird der Cache in einem Unterprozess neu aufgebaut. Das dauert spürbar – der Abbruch dieses Unterprozesses ist auf 120 Sekunden eingestellt.
  7. Bei Erfolg erscheint „Test-E-Mail in … s zugestellt. Einstellungen gespeichert, Cache neu aufgebaut.“ Der Zustand oben wechselt auf Konfiguriert.

Nichts wird blind gespeichert. Kommt die Test-E-Mail nicht an, werden die Einstellungen nicht geschrieben: „Die Test-E-Mail ist nach … s fehlgeschlagen, es wurde nichts gespeichert: …“. Fehlt das Schreibrecht, meldet das Modul das vorab und sendet gar nicht erst.

Vorschau und Testversand

Beide Funktionen liegen als Symbole in der Liste der Nachrichten – Vorschau und Test senden – und stehen jedem Benutzer zur Verfügung, der das Modul Benachrichtigungen öffnen darf.

So prüfen Sie eine Nachricht vor dem Versand

  1. In der Nachrichtenliste auf Vorschau klicken.
  2. Das Ergebnis wird mit dem aufgelösten Betreff angezeigt, umschaltbar zwischen Desktop und Mobil sowie zwischen HTML und Nur-Text. Der Hinweis „Die Token-Werte sind Beispiele, keine echten Daten.“ steht dabei; hat die Nachricht keinen HTML-Teil, erscheint „Diese Nachricht hat keinen HTML-Teil.“
  3. Zurück in die Liste und auf Test senden klicken.
  4. Im Formular Testnachricht senden die Tokens der Nachricht ausfüllen. Verwendet die Nachricht keine, steht dort „Diese Nachricht verwendet keine Tokens, die Sie ausfüllen müssen.“
  5. Unter Senden an die Zieladresse eintragen. Voreingestellt ist die Adresse Ihres Backend-Kontos.
  6. Test senden klicken.
  7. Die Bestätigung „Testnachricht an … gesendet. Das Ergebnis steht im Versandprotokoll.“ abwarten und den Eintrag dort prüfen.

Niemand sonst erhält die Testnachricht. „Empfänger, CC und BCC werden durch die Adresse unten ersetzt, niemand sonst erhält sie.“ Der Testversand ist damit auch an einer produktiv genutzten Benachrichtigung unbedenklich.

Versandprotokoll

Das Modul Versandprotokoll hält jeden Sendeversuch fest. Die Einträge lassen sich ansehen, erneut senden und löschen – aber nicht bearbeiten: Ein Protokoll, das sich ändern lässt, kann nur noch lügen.

FeldBeschreibung im Backend
Datum„Wann der Versand zuletzt versucht wurde.“
Benachrichtigung„Der Alias der ausgelösten Benachrichtigung.“
Absendertyp„Die Art des verwendeten Absenders.“
Empfänger„Die Adressen, an die gesendet wurde.“
Betreff„Der aufgelöste Betreff.“
Status„Das Ergebnis des Versands.“
Fehler„Warum der Versand fehlgeschlagen ist.“
Nur-Text-Inhalt / HTML-Inhalt„Der Text-Teil, wie der Empfänger ihn erhalten hat.“ / „Der HTML-Teil, wie der Empfänger ihn erhalten hat.“
Ausgelöst durch„Was den Versand veranlasst hat.“ – Formularversand, Code, Testversand, Manuell erneut gesendet oder Automatischer Wiederholversuch.
Versuche„Wie oft der Versand versucht wurde.“
StatusWas er bedeutet
Wird gesendetDer Versand läuft gerade.
In WarteschlangeBei E-Mail: Die Nachricht wurde an die Messenger-Warteschlange von Contao übergeben. Erst wenn ein Worker tatsächlich mit dem Mailserver gesprochen hat, wird daraus Zugestellt oder Fehlgeschlagen.
ZugestelltDer Absender hat die Nachricht abgegeben.
FehlgeschlagenDer Versand ist gescheitert; der Grund steht im Feld Fehler.
ÜbersprungenDie Nachricht war nicht zustellbar – etwa ohne Empfänger oder mit unveröffentlichtem Absender – oder ein Listener hat den Versand abgebrochen.

So senden Sie eine fehlgeschlagene Nachricht erneut

  1. Versandprotokoll öffnen. Die Liste ist nach Datum absteigend sortiert und lässt sich nach Status, Absendertyp, Benachrichtigung und Ausgelöst durch filtern sowie nach Empfängeradresse durchsuchen.
  2. Den Eintrag suchen und mit Details anzeigen öffnen, um Fehlertext und gesendeten Inhalt zu sehen.
  3. Die Ursache beheben – Absender, Empfängeradresse, Mailserver.
  4. In der Liste auf Erneut senden klicken. Die Nachricht wird unverändert erneut gesendet, ohne die Tokens neu aufzulösen.
  5. Die Meldung lesen: „Die Nachricht wurde erneut an … gesendet.“ oder „Das erneute Senden ist fehlgeschlagen: …“.

Ist das Symbol Erneut senden inaktiv, lautet der Hinweis: „Dieser Eintrag kann nicht erneut gesendet werden: der Inhalt wurde nicht gespeichert oder der Absender existiert nicht mehr.“ Der häufigste Grund ist ein abgeschaltetes log.store_body.

Zusätzlich versucht die Suite fehlgeschlagene Nachrichten einmal pro Stunde selbst erneut – bis zur konfigurierten Anzahl an Versuchen (log.max_attempts, Voreinstellung 3). Solche Einträge tragen unter Ausgelöst durch den Wert Automatischer Wiederholversuch.

Protokoll leeren löscht alles. Die Schaltfläche Protokoll leeren in der Kopfzeile der Liste entfernt sämtliche Einträge, nicht nur die gefilterten. Die Rückfrage lautet: „Wirklich alle Einträge des Versandprotokolls löschen?“ Anschließend wird die Zahl der gelöschten Einträge gemeldet. Der Vorgang lässt sich nicht rückgängig machen.

Auslöser im Frontend

Eine Benachrichtigung wird an vier Stellen im Frontend ausgelöst. Wo eine Auswahl möglich ist, trägt das Feld den Namen Benachrichtigungen und liegt im gleichnamigen Abschnitt.

So verknüpfen Sie eine Benachrichtigung

  1. Formular: Im Formulargenerator das Formular öffnen und im Abschnitt Benachrichtigungen die gewünschten Einträge auswählen. Jedes übermittelte Feld steht danach als ##feldname## zur Verfügung – maßgeblich ist der „name“ des Feldes, nicht seine Beschriftung. Hochgeladene Dateien werden der Nachricht automatisch angehängt.
  2. Mitglieder: Das Frontend-Modul öffnen – Registrierung, Persönliche Daten, Konto schließen, Passwort ändern oder Passwort vergessen – und im Abschnitt Benachrichtigungen auswählen. Angeboten werden nur Benachrichtigungen vom passenden Typ.
  3. Newsletter: Ebenso in den Modulen für An- und Abmeldung.
  4. Kommentare: Keine Auswahl nötig und keine vorhanden – es genügt, eine Benachrichtigung vom Typ Ein neuer Kommentar anzulegen.

Der Hilfetext am Feld im Formulargenerator lautet: „Die Benachrichtigungen, die beim Absenden dieses Formulars ausgelöst werden. Jedes übermittelte Feld steht im Nachrichtentext als Token ##feldname## zur Verfügung (der „name“ des Feldes im Formulargenerator). Zusätzlich gibt es ##all_fields_html## für eine Tabelle aller Eingaben.“ An den Modulen lautet er: „Die Benachrichtigungen, die bei Verwendung dieses Moduls gesendet werden. Es werden nur zum Modul passende Benachrichtigungen aufgeführt (Mitglieder oder Newsletter).“

Zustellfehler erreichen den Besucher nie. Jeder dieser Auslöser läuft, nachdem etwas bereits gespeichert wurde – ein Konto angelegt, ein Kommentar abgelegt, eine Anmeldung bestätigt. Ein durchgereichter Mailserver-Fehler würde dem Besucher eine Fehlermeldung für einen erfolgreichen Vorgang zeigen. Fehler werden deshalb je Nachricht protokolliert und geschluckt; die übrigen Nachrichten werden weiterhin versendet.

Import aus Notification Center

Bestehende Konfigurationen aus terminal42/notification_center lassen sich übernehmen. Der Import ist ein Konsolenbefehl und ausdrücklich keine Migration: Die Benachrichtigungskonfiguration einer Website umzuschreiben ist eine Entscheidung und nichts, was als Nebenwirkung von contao:migrate geschehen sollte.

So führen Sie den Import durch

  1. Datensicherung anlegen.
  2. Zuerst den Probelauf ausführen:
    vendor/bin/contao-console notification:import-nc --dry-run
  3. Die Ausgabe durchsehen. Am Ende listet der Befehl alle Tokennamen auf, die er nicht übersetzen konnte – diese bleiben unverändert stehen und müssen anschließend von Hand geprüft werden.
  4. Den Import ausführen:
    vendor/bin/contao-console notification:import-nc
  5. Im Backend die angelegten Benachrichtigungen, Nachrichten und Absender durchgehen und je Nachricht eine Vorschau öffnen.
  6. Erst danach die alten Auslöser umstellen. Notification Center bleibt unangetastet, beide Installationen können parallel laufen, bis Sie mit dem Ergebnis zufrieden sind.

Gelesen werden die Tabellen tl_nc_notification, tl_nc_message, tl_nc_language und tl_nc_gateway. Da Notification Center eine Ebene tiefer gliedert, wird aus jeder dortigen Sprache-Zeile eine Nachricht dieser Suite, mit dem Absender aus der übergeordneten Zeile. Tokennamen werden dabei übersetzt: ##form_email## wird zu ##email##, ##raw_data## zu ##all_fields## und so fort.

OptionWirkung
--dry-runMeldet, was importiert würde, ohne etwas zu schreiben.
--forceImportiert erneut, auch wenn bereits Benachrichtigungen mit demselben Alias vorhanden sind.

Teil 3 — Für Entwickler

Versand aus eigenem Code

Der Service CentralizedNotificationSuite ist der einzige Einstiegspunkt. Übergeben wird der Alias der Benachrichtigung, die Token-Werte und optional eine Sprache.

use VTInnovations\CentralizedNotificationSuite\CentralizedNotificationSuite;

public function __construct(private readonly CentralizedNotificationSuite $notify) {}

$result = $this->notify->send('bestellbestaetigung', [
    'kunde_name' => $order->name,
    'summe'      => $order->formattedTotal,
], 'de');

$result->isSuccessful();
$result->hasFailures();
$result->countSent();
$result->getStatuses();
$result->getErrors();
MethodeZweck
send($alias, $tokens, $language = null, $extraAttachments = [], $source = SOURCE_API)Löst die Benachrichtigung aus und liefert ein SendResult.
prepare($alias, $tokens, $language = null, $extraAttachments = [])Rendert alles, was gesendet würde, ohne zu senden. Liefert eine Liste von PreparedMessage.
deliver(PreparedMessage $prepared, string $source, ?SendResult $result = null)Sendet eine bereits gerenderte Nachricht – die Grundlage des erneuten Versands.
deliverRendered(RenderedMessage $message, GatewayModel $gateway, string $source)Wie oben, ohne Umweg über die Benachrichtigung.

Zustellfehler lösen keine Ausnahme aus. Fehler werden je Nachricht abgefangen, protokolliert und in SendResult gemeldet; die übrigen Nachrichten werden weiterhin versendet. Ein unbekannter Alias löst hingegen eine NotificationException aus – das ist ein Programmierfehler und soll auffallen.

Ereignisse

Zwei Symfony-Ereignisse umschließen jede einzelne Zustellung.

EreignisEigenschaftenVerwendung
PreSendEvent message, gatewayType, gatewayConfig, source cancel(?string $reason) bricht den Versand dieser Nachricht ab; sie erscheint dann als Übersprungen im Protokoll. isCancelled() und getCancelReason() lesen den Zustand.
PostSendEvent message, gatewayType, gatewayConfig, source, status, throwable Auswertung nach dem Versuch. isSuccessful() und wasSkipped() beantworten den Regelfall.

Als source erscheint einer der Werte api, form, test, resend oder cron – dieselben Werte, die im Versandprotokoll unter Ausgelöst durch angezeigt werden.

Konsolenbefehle

BefehlBeschreibung
notification:sendTrigger a notification by alias
notification:install-layoutsInstall the bundled starter e-mail layouts
notification:install-emailsInstall ready-made emails (transactional, newsletter, announcement)
notification:import-ncImport notifications, messages and gateways from Notification Center
vendor/bin/contao-console notification:send bestellbestaetigung \
    -t kunde_name=Jane -t email=jane@example.com

vendor/bin/contao-console notification:send bestellbestaetigung \
    --tokens-json='{"kunde_name":"Jane"}' --language=de --dry-run
Option von notification:sendBedeutung
alias (Argument)Der Alias der Benachrichtigung. Pflichtangabe.
-t, --tokenEin Token als name=wert, wiederholbar. Getrennt wird am ersten =, der Wert darf also weitere enthalten.
--tokens-jsonAlle Tokens als JSON-Objekt. Die richtige Wahl für Werte mit = oder Zeilenumbrüchen.
-l, --languageWählt die Nachricht dieser Sprache statt der Fallback-Nachricht.
--dry-runRendert und meldet, was gesendet würde, ohne zu senden – als Tabelle mit Nachricht, Status, Absender, Empfängern, Betreff und Problem.
Optioninstall-layoutsinstall-emails
--listZeigt nur an, was installiert würde.Ebenso.
--forceÜberschreibt ein bereits installiertes Layout.Ersetzt eine bereits installierte Vorlage. Löscht dabei die Bausteine ihrer Nachricht und legt sie neu an – Änderungen an dieser Nachricht gehen verloren.

Erweiterungspunkte

Drei Schnittstellen sind zur Erweiterung vorgesehen. Alle drei werden automatisch registriert: Der Container versieht jede Klasse, die eine davon implementiert, mit dem passenden Tag. Es genügt, die Klasse im eigenen Bundle abzulegen.

SchnittstelleVertragWofür
Gateway\GatewayInterface
(oder Gateway\AbstractGateway erweitern)
getName(), getConfigFields(), getPalette(), isAsynchronous(), addressesRecipients(), send() Ein eigener Absendertyp. Die Backend-Felder deklariert der Absender selbst; contao:migrate legt die zugehörigen Spalten an.
Block\BlockInterface
(oder Block\AbstractBlock erweitern)
getName(), getGroup(), getConfigFields(), getPalette(), render() Ein eigener Bausteintyp für den Nachrichteninhalt. getGroup() bestimmt die Gruppe im Auswahlfeld.
Token\TokenProviderInterface getType(), getDefinitions(), getValues() Eigene Tokens für einen Benachrichtigungstyp. getDefinitions() speist zugleich den Hilfe-Assistenten.

Kein Erweiterungspunkt sind die Modelle, die Migrationen und die Backend-Listener dieses Pakets. Sie sind Implementierung und können sich zwischen zwei Versionen ändern, ohne dass das als Bruch gilt.

Tabellen und Hooks

TabelleInhaltBackend-Modul
tl_notificationBenachrichtigungenBenachrichtigungen
tl_notification_messageNachrichten je SpracheBenachrichtigungen (untergeordnet)
tl_notification_blockBausteine einer NachrichtBenachrichtigungen (untergeordnet)
tl_notification_templateE-Mail-LayoutsE-Mail-Layouts
tl_notification_brandingLogo, Markenfarbe, Firmenangaben (genau ein Datensatz)Branding
tl_notification_gatewayAbsenderAbsender
tl_notification_logVersandprotokoll (nicht bearbeitbar)Versandprotokoll
tl_notification_exchangeInterne VerwaltungstabelleKeine Backend-Oberfläche

Zusätzlich ergänzt das Paket die Spalte notification_ids auf tl_form und tl_module.

Beim Versionswechsel eines umbenannten Vorgängerpakets laufen zwei Migrationen mit: RenameToNotificationMigration benennt die alten Tabellen um und schreibt dabei die Modulschlüssel in tl_user_group.modules mit, damit eine Nicht-Administrator-Gruppe ihre Freigaben nicht verliert; PruneRenamedCronJobsMigration entfernt verwaiste Zeilen aus tl_cron_job. AssignFormNotificationTypeMigration setzt auf bestehenden Benachrichtigungen den passenden Typ. Alle drei sind wiederholbar ausführbar.

Contao-HookWozu
processFormDataLöst die am Formular ausgewählten Benachrichtigungen aus und hängt die hochgeladenen Dateien an.
createNewUser, activateAccount, updatePersonalData, setNewPassword, closeAccountMitglieder-Benachrichtigungen.
addCommentKommentar-Benachrichtigungen.
activateRecipient, removeRecipientNewsletter-Benachrichtigungen.
loadDataContainerMehrfach belegt: Absender- und Bausteinfelder je Typ, das Feld Benachrichtigungen auf tl_form und tl_module, der Token-Hilfe-Assistent, der Einstieg in den Branding-Datensatz und das Backend-Asset dieses Pakets.

Das genannte Backend-Asset gibt das globale $ an MooTools zurück, wenn eine andere Erweiterung jQuery ohne noConflict() darüber geladen hat. Es wird ausschließlich auf den Bearbeitungsbildschirmen dieses Pakets eingebunden, damit es die Bildschirme anderer Erweiterungen nicht stört.

Routen und Cron-Jobs

RoutePfadMethodenZugriff
centralized_notification_suite_preview /contao/notification/preview/{id} GET Backend; erfordert Zugriff auf das Modul Benachrichtigungen
centralized_notification_suite_test_send /contao/notification/test-send/{id} GET, POST Backend; erfordert Zugriff auf das Modul Benachrichtigungen, POST zusätzlich einen gültigen Anfrage-Token

Die Vorschau rendert den Nachrichteninhalt in einem abgeschotteten iframe, damit ein <script> aus einem eingefügten Design nicht gegen die Backend-Sitzung laufen kann. Als cid: eingebettete Bilder werden für die Vorschau in data:-URIs überführt – sonst zeigte die Vorschau ein kaputtes Bild für eine Nachricht, die einwandfrei ankommt.

Cron-JobIntervallAufgabe
Protokoll aufräumentäglichLöscht Protokolleinträge jenseits von log.retention_days.
Fehlgeschlagene Nachrichten wiederholenstündlichVersucht fehlgeschlagene Nachrichten erneut, solange log.retry_failed aktiv ist und log.max_attempts nicht erreicht wurde.

Protokollierung

Betriebsmeldungen gehen in das Contao-Systemprotokoll: Vorgang, Ergebnis und – beim Versand – die betroffene Nachricht. Typische Einträge sind eine Nachricht, die wegen eines fehlenden Absenders übersprungen wurde, und eine fehlgeschlagene Zustellung samt Fehlertext des Transports.

Nicht in den Betriebsmeldungen erscheinen vollständige Lizenzschlüssel und Authentifizierungsdaten. Betreff und Inhalt einer Nachricht speichert das Versandprotokoll nur, wenn log.store_body aktiv ist; auf Installationen ohne Speicherung personenbezogener Daten wird diese Option abgeschaltet – dann entfällt allerdings auch der erneute Versand.

Deployment

composer install --no-dev --optimize-autoloader
vendor/bin/contao-console contao:migrate --no-interaction
vendor/bin/contao-console cache:clear --env=prod
vendor/bin/contao-console cache:warmup --env=prod

Zu beachten:

  • Ein privates Verzeichnis unterhalb von var/ muss für den Webserver-Benutzer beschreibbar sein und gehört in die Datensicherung – nicht in die Versionsverwaltung.
  • Die Lizenz ist an Hostnamen gebunden. Test-, Staging- und Produktivsystem benötigen jeweils eine für ihren Hostnamen gültige Lizenz.
  • Ausgehende HTTPS-Verbindungen dürfen nicht blockiert sein – weder für die Lizenz noch für Webhook-Absender.
  • Für den Mailversand muss ein Messenger-Worker laufen oder der Web-Worker von Contao aktiv sein.
  • Nach einer Änderung der SMTP-Konfiguration im Backend erneuert die Suite den Cache selbst; nach Änderungen an config/config.yaml geschieht das nicht.

Fehlerbehebung

SymptomUrsache und Prüfung
Es wird gar nichts versendet; im Systemprotokoll steht, die Installation sei nicht aktiviert Keine gültige Lizenz. Unter Einstellungen → V-T.ONE Licence management aktivieren, siehe Lizenz aktivieren.
„Die Lizenz konnte nicht verifiziert werden. Bitte den Schlüssel prüfen und erneut versuchen.“ Prüfen Sie, ob auf der Startseite eine Domain hinterlegt ist, ob der Schlüssel für diesen Hostnamen ausgestellt wurde und ob der Server ausgehende HTTPS-Verbindungen aufbauen darf.
„Für keine Startseite ist eine Domain konfiguriert, oder die Lizenz deckt keine konfigurierte Domain ab.“ Im Seitenbaum auf der Startseite die Domain eintragen – exakt in der Schreibweise, für die der Schlüssel ausgestellt wurde.
„Bitte zuerst einen Lizenzschlüssel eingeben.“ oder „Es ist keine Lizenz gespeichert, die aktualisiert werden könnte. Bitte einen Lizenzschlüssel eingeben und aktivieren.“ Das Schlüsselfeld war leer. Lizenz aktualisieren ohne Eingabe setzt einen bereits gespeicherten Schlüssel voraus.
„Die Lizenz für diese Website wurde zurückgezogen. Bitte kontaktieren Sie uns, falls dies ein Irrtum ist.“ Die Lizenz für diesen Hostnamen ist nicht mehr gültig. Wenden Sie sich an V-T.ONE.
„Die Lizenz wurde nicht innerhalb des vorgesehenen Zeitraums erneut geprüft. …“ Sobald die Website den Lizenzdienst wieder erreichen kann, Lizenz aktualisieren verwenden.
E-Mails bleiben dauerhaft auf In Warteschlange Es läuft kein Messenger-Worker. Warteschlange abarbeiten oder einen Worker einrichten; alternativ den Web-Worker von Contao aktivieren.
Ein Formular versendet nichts Im Formular muss die Benachrichtigung im Abschnitt Benachrichtigungen ausgewählt sein. Die Nachricht muss Veröffentlicht sein, im Zeitraum Anzeigen ab/bis liegen und entweder zur Sprache passen oder als Fallback-Nachricht markiert sein.
Ein Token bleibt als ##feldname## stehen Der Name stimmt nicht mit dem „name“ des Formularfeldes überein, oder das Token gehört zu einem anderen Benachrichtigungstyp. Das Hilfe-Symbol am Feld zeigt die gültige Liste.
„Der zugewiesene Absender existiert nicht mehr, diese Nachricht wird nicht versendet.“ Der Absender wurde gelöscht. In der Nachricht einen vorhandenen Absender wählen.
„Der Absender „…“ ist nicht veröffentlicht, diese Nachricht wird nicht versendet.“ Im Modul Absender den Haken Veröffentlicht setzen.
„Diese Nachricht hat keine Empfänger, sie wird nicht versendet.“ Das Feld Empfänger ist leer. Bei Absendern vom Typ Webhook und Datei ist das unerheblich – diese adressieren keine Empfänger.
„Dieser Eintrag kann nicht erneut gesendet werden: der Inhalt wurde nicht gespeichert oder der Absender existiert nicht mehr.“ log.store_body ist abgeschaltet, oder der Absender wurde entfernt. Siehe Konfiguration.
„Diese Nachricht hat keinen veröffentlichten Absender und kann nicht gesendet werden.“ beim Testversand Erst den Absender veröffentlichen, dann erneut testen.
Das Design bricht in Outlook auseinander Prüfen, ob das Layout Veröffentlicht und der Nachricht im Feld Layout zugewiesen ist und ob CSS inline schreiben aktiv ist. Ein <style>-Block im Baustein Eigenes HTML wird entfernt – Gestaltung gehört ins Layout.
Bilder erscheinen beim Empfänger nicht Entweder blockiert das Programm externe Inhalte – dann an der Nachricht Bilder einbetten aktivieren – oder es handelt sich um SVG bzw. WebP, die E-Mail-Programme nicht zuverlässig darstellen.
Ein Webhook meldet einen Fehler Der Fehlertext des Zielsystems steht im Versandprotokoll im Feld Fehler. Payload-Format und Endpunkt-URL gegen die Vorlagen im Hilfe-Assistenten prüfen.
„Die Einstellungen können nicht gespeichert werden, weil der Webserver nicht in … schreiben darf.“ Schreibrecht auf .env.local erteilen. Es wurde nichts gesendet und nichts geändert.
„Die Einstellungen wurden gespeichert, der Cache konnte aber nicht neu aufgebaut werden – sie sind noch nicht aktiv.“ Den Cache manuell leeren. Schlägt der Neuaufbau wiederholt fehl, in config/config.yaml mailer.php_binary setzen oder mailer.memory_limit erhöhen.
Die Dateiauswahl öffnet sich als ganze Seite, ohne Übernehmen und Abbrechen Eine andere Erweiterung lädt jQuery ohne noConflict() ins Backend und nimmt MooTools das globale $. Dieses Paket stellt es auf seinen eigenen Bildschirmen wieder her. Ist die Dateiauswahl auch auf Contao-eigenen Bildschirmen defekt, muss die Erweiterung korrigiert werden, die jQuery lädt.
Die Backend-Gruppe erscheint nicht Datenbank-Migration nicht ausgeführt oder Cache nicht geleert. Für Nicht-Administratoren zusätzlich die Modulfreigaben der Benutzergruppe prüfen.

Bekannte Einschränkungen

  • Der Versand setzt eine aktivierte Lizenz voraus. Ohne Lizenz wird nichts zugestellt.
  • Eine Lizenz gilt nur für die Hostnamen, für die sie ausgestellt wurde; verwandte Schreibweisen gelten nicht automatisch mit.
  • Die Versionierung erfasst die Nachricht selbst, nicht ihre Bausteine. Das Zurückholen einer älteren Nachrichtenversion stellt deren Bausteine nicht wieder her.
  • Der Datei-Absender ist für Entwicklung und Prüfung gedacht und stellt nicht zu.
  • Für den Webhook-Absender liefert die Suite Vorlagen; das Format des Zielsystems bestimmt der jeweilige Dienst.
  • Ob eine E-Mail tatsächlich zugestellt wird, hängt vom Mailserver und vom Betrieb der Messenger-Warteschlange ab. Der Status Zugestellt besagt, dass der Absender die Nachricht abgegeben hat – nicht, dass sie im Posteingang liegt.
  • Das Paket erzeugt keine Frontend-Ausgabe.
  • Auf Contao 5.3 bis 5.6 werden die Vorschaukarten der Bausteine über eine ältere Contao-Schnittstelle erzeugt, weil diese Versionen noch keine Datensatz-Beschriftung für Eltern-Ansichten kennen. Darstellung, Sortierung per Drag & Drop und alle übrigen Funktionen verhalten sich identisch.

Deinstallation

  1. Datensicherung anlegen.
  2. Im Backend unter Einstellungen → V-T.ONE Licence management auf der Karte Centralized Notification Suite die Schaltfläche Lizenz entfernen wählen. Es werden keine Inhalte gelöscht.
  3. Die Verknüpfungen lösen: im Formulargenerator und in den Mitglieder- und Newsletter-Modulen das Feld Benachrichtigungen leeren. Andernfalls bleibt eine Auswahl stehen, die nach der Deinstallation ins Leere zeigt.
  4. Das Paket entfernen – im Contao Manager über den Bereich Pakete, auf der Kommandozeile mit:
    composer remove vtinnovations/centralized-notification-suite
  5. Cache leeren:
    vendor/bin/contao-console cache:clear --env=prod
  6. Die Tabellen des Pakets bleiben in der Datenbank bestehen, solange Sie sie nicht entfernen. Das ist Absicht: Eine spätere Neuinstallation findet die Konfiguration unverändert vor. Wer sie endgültig loswerden will, löscht die unter Tabellen und Hooks genannten Tabellen von Hand – nach einer Sicherung.
  7. Die Laufzeitdaten des Pakets liegen in privaten Verzeichnissen unterhalb von var/ und können nach der Deinstallation entfernt werden; dazu gehört, falls Sie einen Datei-Absender genutzt haben, auch var/notification-mail.