Newsletter Management: Newsletter versenden
Newsletter im Sylius-Admin schreiben, per Vorschau und Testmail prüfen, versenden oder planen - Platzhalter, Zielgruppe, Cron-Versand, Versandprotokoll, Absender und Mailer-Transport
Newsletter Management: Newsletter versenden
Diese Dokumentation bezieht sich immer auf die aktuellste veröffentlichte Version.
Auf dieser Seite schreibst du einen Newsletter im Admin, prüfst ihn mit Vorschau und Testmail und versendest oder planst ihn. Wie Öffnungen und Klicks gemessen werden, steht auf Tracking und Statistik.
Überblick
Ein Newsletter gehört zu genau einem Channel und hat einen Betreff, einen Vorschautext (Preheader), eine HTML-Version und eine Textversion. Die Empfänger legt der Versand beim Start fest. Verschickt werden die Mails vom Konsolenbefehl mmd:newsletter:send, den ein Cronjob regelmäßig ausführt. Ohne diesen Cronjob geht auch nach einem Klick auf Jetzt senden keine einzige Mail raus.
graph LR
A["Entwurf"] --> B["Bereit"]
B -->|"Planen"| C["Geplant"]
C -->|"Abbrechen"| B
B -->|"Jetzt senden"| D["Wird versendet"]
C -->|"Zeitpunkt erreicht"| D
D -->|"alle Zustellungen erledigt"| E["Versendet"]
D -->|"Abbrechen"| F["Abgebrochen"]
Ein Newsletter lässt sich nur im Status Entwurf oder Bereit bearbeiten. Ab Geplant ist er schreibgeschützt, denn sein Inhalt ist das, was Abonnenten bekommen (oder gleich bekommen).
Newsletter anlegen
Die Newsletter erreichst du über den Button Newsletter in der Titelleiste der Newsletter-Einstellungen (Admin-Seitenleiste, MMKreativ Plugins, Newsletterverwaltung). Die Felder des Editors:
| Feld | Beschreibung |
|---|---|
| Channel | Der Channel, aus dem der Newsletter kommt. Er bestimmt Absender, Theme und Abonnentenkreis. Pflichtfeld. |
| Sprache | Optional. Ist eine Sprache gewählt, bekommen nur Abonnenten mit dieser Sprache den Newsletter. Leer = alle Sprachen. |
| Zielgruppe (Kategorien) | Optional. Zeigt nur die Kategorien des gewählten Channels an. Leer = alle Abonnenten. Siehe Zielgruppe. |
| Betreff | Pflichtfeld, maximal 255 Zeichen. Platzhalter sind erlaubt. |
| Vorschautext (Preheader) | Optional, maximal 255 Zeichen. Erscheint in vielen Mailprogrammen neben dem Betreff und wird als unsichtbare erste Zeile in die Mail gesetzt. |
| HTML-Version | Der Inhalt der Mail. Mit visuellem Editor oder als reiner HTML-Code. |
| In das E-Mail-Layout des Shops einbetten | Standardmäßig an. Der HTML-Inhalt landet dann im E-Mail-Layout deines Shops (Logo, Farben, Footer des Themes). Aus = dein HTML wird unverändert verschickt. |
| Textversion | Die Nur-Text-Alternative der Mail. Bleibt das Feld beim Speichern leer, erzeugt das Plugin den Text aus dem HTML. |
| Textversion neu aus dem HTML erzeugen | Checkbox, die den Text oben überschreibt. Praktisch, wenn du das HTML nachträglich geändert hast. |
| Status | Entwurf, Bereit, Geplant, Wird versendet, Versendet oder Abgebrochen. Zum Versenden setzt du den Newsletter auf Bereit und speicherst. |
Die automatisch erzeugte Textversion macht aus Links
Beschriftung (URL)und aus Absätzen Zeilenumbrüche. Lies sie vor dem Versand einmal durch und passe sie bei Bedarf an.
Visueller Editor
Für das HTML-Feld lädt das Plugin den visuellen Editor TinyMCE (GPL) von cdn.jsdelivr.net, in einer festen Version und mit Integritätsprüfung (SRI). Er hat ein Menü Platzhalter, das die Platzhalter an der Cursorposition einfügt, und eine Quelltext-Ansicht. Mit dem Schalter Visueller Editor über dem Feld schaltest du ihn aus, etwa wenn du fertig gebautes E-Mail-HTML einfügst, das ein visueller Editor umschreiben würde. Die Wahl merkt sich der Browser. Lässt sich das Skript nicht laden (offline oder blockiert), bleibt das Feld ein normales Textfeld und der Schalter verschwindet.
Platzhalter
Platzhalter schreibst du in doppelten geschweiften Klammern, {{ first_name }}, Leerzeichen innerhalb der Klammern sind egal. Es ist bewusst kein Twig: Es gibt eine feste Liste, die durch einfaches Ersetzen befüllt wird.
| Platzhalter | Wird ersetzt durch |
|---|---|
{{ email }} |
E-Mail-Adresse des Empfängers |
{{ first_name }} |
Vorname des Empfängers (leer, wenn nicht angegeben) |
{{ last_name }} |
Nachname des Empfängers (leer, wenn nicht angegeben) |
{{ channel_name }} |
Name des Channels |
{{ manage_url }} |
Persönlicher Link zur Seite, auf der der Abonnent Name und Kategorien ändert |
{{ unsubscribe_url }} |
Persönlicher Abmelde-Link |
Im HTML werden die eingesetzten Werte HTML-maskiert, in Betreff und Textversion bleiben sie Klartext. Auch ein Platzhalter, den ein Editor oder Browser in einem Link-Ziel URL-codiert hat (%7B%7B%20manage_url%20%7D%7D), wird beim Speichern wieder zu {{ manage_url }}.
Ein unbekannter Platzhalter wie
{{ frist_name }}wird in Betreff, HTML und Text beim Speichern immer abgelehnt, auch im Entwurf. So landet kein Tippfehler als Klartext beim Abonnenten.
Bevor ein Newsletter auf Bereit gesetzt werden kann, müssen HTML-Version und Textversion beide nicht leer sein und beide
{{ manage_url }}und{{ unsubscribe_url }}enthalten. Ein Entwurf darf dagegen unvollständig gespeichert werden.
Vorschau und Testversand
Beides findest du auf der Bearbeiten-Seite des Newsletters.
| Funktion | Verhalten |
|---|---|
| Vorschau | Zeigt die zuletzt gespeicherte Version mit Beispieldaten (Max Mustermann), HTML und Text nebeneinander. Speichere deine Änderungen also zuerst. Das HTML läuft in einem abgesicherten Rahmen (Sandbox), Skripte werden nicht ausgeführt. Auf der Detailseite öffnen zwei Buttons HTML und Text in einem neuen Tab. |
| Testversand | Schickt die zuletzt gespeicherte Version an eine Adresse deiner Wahl, der Betreff bekommt das Präfix [Test]. Ist die Adresse ein echter Abonnent dieses Channels, funktionieren die Verwaltungs- und Abmelde-Links in der Testmail. Test- und Vorschau-Mails werden nie getrackt und verfälschen daher keine Zahlen. |
Der Testversand braucht eine Absenderadresse (siehe Absender und Transport). Schlägt er fehl, zeigt der Admin dir den Grund an, etwa dass der SMTP-Server die Mail abgelehnt hat.
Duplizieren und Löschen
- Duplizieren legt eine Kopie als Entwurf an, mit dem Betreff
Kopie von: .... Inhalt, Channel, Sprache, Zielgruppe und Layout-Wahl werden übernommen, Zeitplan, Empfänger und Versandprotokoll nicht. Das geht auch bei einem bereits versendeten Newsletter und ist der übliche Weg zur nächsten Ausgabe. - Löschen ist nur im Status Entwurf oder Bereit möglich. Alles ab Geplant ist der Nachweis dessen, was Abonnenten bekommen haben, samt Versandprotokoll. Die Sperre gilt für den Lösch-Button wie für die Sammellöschung.
Zielgruppe
Beim Start des Versands wird die Empfängerliste festgelegt. Ein Abonnent bekommt den Newsletter, wenn alle Punkte zutreffen:
- Sein Status ist bestätigt (wartende und abgemeldete Abonnenten bekommen nie etwas).
- Er gehört zum Channel des Newsletters.
- Ist am Newsletter eine Sprache gewählt: Seine Sprache ist genau diese.
- Sind am Newsletter Kategorien gewählt: Der Abonnent hat keine Kategorie ausgewählt (er will den allgemeinen Newsletter, also alles) oder mindestens eine der gewählten Kategorien. Sind am Newsletter keine Kategorien gewählt, entfällt dieser Punkt.
Im Sende-Bereich des Newsletters steht vor dem Versand die aktuelle Zahl (Geht aktuell an N Abonnent(en)). Die endgültige Zahl steht fest, sobald der Versand beginnt, und wird als Empfängerzahl am Newsletter gespeichert. Pro Newsletter und Adresse gibt es genau einen Eintrag im Versandprotokoll, niemand bekommt denselben Newsletter also doppelt.
Versenden, planen, abbrechen
Der Bereich Versand auf der Bearbeiten-Seite zeigt Absender, Zielgruppengröße, Fortschritt und die passenden Buttons. Alle drei Aktionen sind POST-Anfragen mit CSRF-Schutz.
| Aktion | Wann möglich | Wirkung |
|---|---|---|
| Jetzt senden | Status Bereit oder Geplant | Nach einer Sicherheitsabfrage legt das Plugin die Empfänger fest und setzt den Status auf Wird versendet. Die Mails verschickt der nächste Lauf von mmd:newsletter:send. |
| Planen | Status Bereit oder Geplant | Du wählst Datum und Uhrzeit (in der Zeitzone, die das Formular anzeigt). Der Zeitpunkt muss in der Zukunft liegen. Ein geplanter Newsletter lässt sich neu planen. |
| Abbrechen | Status Geplant oder Wird versendet | Ein geplanter Newsletter geht zurück auf Bereit. Bei einem laufenden Versand bleibt Versendetes versendet, alle noch wartenden Zustellungen werden übersprungen und der Newsletter steht auf Abgebrochen. |
Folgende Gründe verhindern den Start und werden als Fehlermeldung angezeigt: Der Newsletter ist nicht im passenden Status, es gibt keine Absenderadresse, die Zielgruppe ist leer oder der Zeitpunkt liegt in der Vergangenheit. Kann ein geplanter Newsletter zum Startzeitpunkt nicht mehr losgehen (keine Empfänger mehr, Absender entfernt), geht er zurück auf Bereit, statt endlos neu versucht zu werden.
Der Cronjob
mmd:newsletter:send ist der Motor des Versands. Er startet zuerst alle geplanten Newsletter, deren Zeit gekommen ist, und verschickt dann einen Stapel wartender Mails.
* * * * * cd /pfad/zum/shop && php bin/console mmd:newsletter:send --limit=100
| Option | Standard | Beschreibung |
|---|---|---|
--limit |
100 |
Höchstzahl Mails pro Lauf. Mindestens 1. Halte sie unter dem Mail-Limit deines Hosters. |
--delay-ms |
0 |
Pause zwischen zwei Mails in Millisekunden. Darf nicht negativ sein. |
Die Ausgabe nennt, wie viele geplante Newsletter gestartet, Mails gesendet und übersprungen, fehlgeschlagene Versuche und beendete Newsletter es gab.
Gut zu wissen:
- Parallel laufende Instanzen sind sicher. Jede Zustellung wird atomar reserviert.
- Ein fehlgeschlagener Versand wird bei den nächsten Läufen wiederholt, höchstens dreimal. Danach steht die Zustellung auf Fehlgeschlagen. Im Protokoll steht nur Klasse und Code des Fehlers, nie die Meldung, denn sie könnte die Empfängeradresse enthalten.
- Stürzt ein Lauf mitten im Versand ab, geht eine reservierte, aber nie abgeschlossene Zustellung nach 15 Minuten wieder auf Wartend.
- Meldet sich ein Abonnent zwischen Start und Zustellung ab, wird seine Zustellung übersprungen.
- Sind keine Zustellungen mehr offen (weder wartend noch in Arbeit), springt der Newsletter auf Versendet.
- Das Plugin nutzt bewusst kein Symfony Messenger: Ein Worker für eine asynchrone Queue ist Infrastruktur, die ein Shop nicht mitbringen muss, und eine nicht geroutete Messenger-Nachricht würde sonst direkt im Admin-Request laufen. Cron gibt es überall.
Versandprotokoll
Auf der Detailseite eines Newsletters (ab dem Start des Versands) zeigt das Versandprotokoll jede Zustellung mit Adresse, Status, Versuchen, Sendezeit und Hinweis. Über die Filter-Buttons grenzt du nach Status ein.
| Status | Bedeutung |
|---|---|
| Wartend | Noch nicht gesendet (auch: Versuch fehlgeschlagen, wird wiederholt) |
| Wird gesendet | Von einem Lauf reserviert |
| Gesendet | Erfolgreich an den Mailserver übergeben |
| Fehlgeschlagen | Nach drei Versuchen aufgegeben, der Hinweis nennt Fehlerklasse und -code |
| Übersprungen | Absichtlich nicht gesendet: Abonnent hat sich abgemeldet oder der Newsletter wurde abgebrochen |
Das Protokoll speichert die Adresse als eigene Kopie. Es bleibt deshalb erhalten, auch wenn das zugehörige Abonnement später gelöscht wird. Die Aufräumbefehle (siehe Tracking und Statistik) fassen es nicht an.
Absender und Transport
- Absender: Adresse und Name stammen aus den Newsletter-Einstellungen des Channels (Absender-E-Mail, Absendername). Fehlt die Adresse, gilt die Kontakt-E-Mail des Channels, fehlt der Name, der Channel-Name. Gibt es keine Adresse, lässt sich der Newsletter weder senden noch testen, und der Sende-Bereich weist darauf hin.
- Mailer-Transport: In den Newsletter-Einstellungen kannst du den Namen eines Symfony-Mailer-Transports eintragen (
framework.mailer.transports), damit Newsletter getrennt von den Shop-Mails laufen. Leer = Standard-Transport. Der Name wird alsX-Transport-Header an die Mail gehängt, Symfony Mailer wählt daran den Transport und entfernt den Header vor dem Versand. - Mailformat: Jede Mail geht als echtes Multipart mit HTML- und Textteil raus, über den Symfony Mailer und nicht über den Sylius-Mailer, der nur HTML sendet.
- Abmelde-Header: Jede Mail trägt
List-Unsubscribemit dem persönlichen Abmelde-Link undList-Unsubscribe-Post: List-Unsubscribe=One-Click. Mailprogramme können so einen Abmelden-Button anbieten, dessen POST ohne weiteren Schritt abmeldet (RFC 2369 und RFC 8058). - Theme: Wenn der Newsletter ins E-Mail-Layout eingebettet wird, rendert das Plugin ihn immer mit dem Theme seines Channels, auch aus dem Cronjob (ohne Request) oder aus dem Admin eines anderen Channels.
Weicht die Absenderadresse von dem Postfach ab, mit dem dein SMTP-Konto sendet, muss dein Mailserver diese Adresse zulassen (SPF/DKIM), sonst landen die Newsletter im Spam oder werden abgelehnt.
Praxisbeispiel: Vom Entwurf zum Versand
Ein Shop mit dem Channel Webshop verschickt den Frühjahrs-Newsletter an alle, die die Kategorie Angebote gewählt haben (oder gar keine Kategorie).
- Im Admin die Newsletter-Liste öffnen und Erstellen wählen.
- Channel
Webshop, SpracheDeutsch (Deutschland), ZielgruppeAngeboteankreuzen. - Betreff
Hallo {{ first_name }}, der Frühling ist da, VorschautextBis zu 20 % auf ausgewählte Artikel. - Im visuellen Editor den Text schreiben, über das Menü Platzhalter
{{ manage_url }}und{{ unsubscribe_url }}als Link-Ziele einfügen (z. B.Einstellungen ändernundAbmelden). Textversion leer lassen, das Plugin erzeugt sie beim Speichern. - Mit Status Entwurf speichern, dann Vorschau prüfen und mit Testmail senden eine Mail an die eigene Adresse schicken.
- Passt alles, die Textversion kurz durchlesen, den Status auf Bereit setzen und speichern. Schlägt das fehl, fehlt in einer der beiden Versionen noch ein Pflicht-Platzhalter.
- Im Bereich Versand unter Senden am den Donnerstag 09:00 Uhr wählen und Planen klicken. Der Status ist jetzt Geplant.
- Der Cronjob startet den Newsletter zur eingestellten Zeit und versendet ihn in Stapeln von 100 Mails pro Minute. Den Fortschritt siehst du im Versand-Bereich und im Versandprotokoll. Sind alle Zustellungen erledigt, steht der Status auf Versendet.
Für die nächste Ausgabe öffnest du den Newsletter und wählst Duplizieren.