WebBlocks Campaigns

Anforderungen

Dokumentierte Paketversion: 0.7.0. WebBlocks CMS ^1.45.5; PHP >=8.3.

A WebBlocks CMS-Plugin zum Senden einer E-Mail-Vorlage an Ihre eigene Kundenliste, wobei Name, Adresse und andere Felder pro Empfänger ausgefüllt werden.

Die Zustimmung wird pro Kanal erfasst. Marketing- und Betriebsnachrichten sind unterschiedliche Dinge: Jemand, der sich von der Werbung abmeldet, muss trotzdem die Meldung „Ihre Rechnung ist fällig“ erhalten, sodass ein Flag die Wahl zwischen Spam-Versand an Personen, die sich abgemeldet haben, und dem Zurückhalten von Nachrichten, die sie benötigen, erzwingen würde.

Ejeder Kontaktdatensatz warum es geschrieben werden darf – die Grundlage, woher es kam, wann und bei ausdrücklicher Zustimmung der genaue vereinbarte Wortlaut. Ein Import zeichnet dasselbe für sich selbst auf, daher gibt es ein Jahr später eine Antwort auf die Frage „Warum ist diese Adresse hier?“.

Das Unterdrückungsregister ist eine eigene Tabelle, die nach Adresse und nicht nach Kontakt kodiert ist und von keinem Import berührt wird. Das macht diese Sequenz sicher: Jemand meldet sich ab, der Operator löscht später die Liste und importiert die ursprüngliche Tabelle erneut, und die abgemeldete Person kommt nicht zurück. Die Freigabe einer Adresse ist der einzige Ausweg, und dieser ist gewollt.

Die Zustimmung wird durch einen Import immer nur erhöht, niemals gesenkt – ein Widerruf bleibt auch nach einem erneuten Import bestehen, und ein Bestandskundenimport führt nicht zu einer Herabstufung einer Person, die bereits ausdrücklich zugestimmt hat.

Importieren

Hochladen, Zuordnen, Vorschau, Festschreiben. Bis zum letzten Schritt wird nichts geschrieben, und jede abgelehnte Zeile wird mit ihrer Zeilennummer in der Quelldatei gemeldet, sodass der Bediener die Tabelle korrigiert, anstatt zu raten, was gelöscht wurde.

Semikolon-getrennte Dateien und eine UTF-8-Stückliste werden ohne Beanstandung gelesen, denn das ist es, was deutsche und türkische Tabellenexporte produzieren. Eine Spaltenzuordnung wird vorgeschlagen und nie allein angewendet: Eine Vermutung, die Namen dem E-Mail-Feld zuordnet, ist schlimmer als keine Vermutung, weil es so aussieht, als hätte es funktioniert.

A leere Zelle ist eine Abwesenheit, kein Wert. Ein erneuter Import füllt Lücken und löscht nicht, was bereits vorhanden ist.

Schreiben einer Vorlage

{{ first_name }} übernimmt den Wert. {{ first_name | Kunde }} sagt, was erscheint, wenn es fehlt – das ist der Unterschied zwischen „Hallo Ada“ und „Hallo“, der Art und Weise, wie ein Seriendruck gespeichert wird.

Zusammengeführte Werte werden in HTML maskiert; die Vorlage ist es nicht. Die Vorlage gehört Ihnen, die Werte stammen aus einer Tabelle.

Zwei Dinge werden überprüft, bevor Sie einen Test senden können:

  • Ein unbekanntes Feld blockiert. {{ firstname }}wo das Feld istfirst_namemacht leer fürjederEmpfänger und sieht im Editor völlig in Ordnung aus. Die verfügbaren Felder werden von den tatsächlich importierten Kontakten abgeleitet, sodass der Tippfehler erkannt werden kann.
  • Ein fehlender Fallback warnt.Es ist ein Urteil, kein Fehler – „Hallo“ ohne Namen ist manchmal genau richtig.

Die Vorschau wird anhand eines realen Kontakts und nicht anhand erfundener Daten gerendert, da erfundene Daten immer wohlgeformt sind und daher nichts beweisen. Bei einem Testversand werden die bereits gerenderten Zeichenfolgen übermittelt. Was also ankommt, ist das, was eine Kampagne senden würde, mit dem Präfix [TEST].

Wird gesendet

A-Kampagne koppelt eine Vorlage mit einer Liste und deklariert, um welche Art von Nachricht es sich handelt:

  • Commercial ist Werbung. Es erreicht nur Kontakte, deren Einwilligung Werbung zulässt, und seine Vorlage muss {{ unsubscribe_url }} enthalten – andernfalls wird die Warteschlangenverweigerung abgelehnt.
  • Operational betrifft einen bestehenden Vertrag. Da es sich nicht um Werbung handelt, wird sie durch ein Marketing-Opt-out nicht zurückgehalten und es ist kein Abmeldelink erforderlich.

Queuing sendet nicht. Es materialisiert den Empfängersatz – ein Versand dauert Stunden, und das Ableiten aus der Liste mitten im Lauf würde dazu führen, dass eine Bearbeitung stillschweigend ändert, an wen geschrieben wird. Dann erledigt Cron die Arbeit:

php artisan webblocks-campaigns:dispatch

EBei jedem Lauf wird ein Batch pro Kampagne gesendet, begrenzt durch die Batchgröße pro Standort und die stündliche Obergrenze. Diese Grenze ist der Punkt: Ein Massenversand, der über das SMTP eines gemeinsam genutzten Hosts erfolgt, führt dazu, dass eine sendende Domäne blockiert wird, und es dauert Monate, bis dies rückgängig gemacht wird.

Der Snapshot ist nicht vertrauenswürdig. Unterdrückung und Zustimmung werden für jeden Empfänger zum Zeitpunkt des Sendens erneut überprüft, sodass jemand, der sich eine Stunde nach Ablauf von zwei Stunden abmeldet, den Rest nicht erhält. Die Pause wird zwischen den Chargen erneut gelesen und stoppt den Lauf sofort.

Abmeldung

Jede kommerzielle Nachricht enthält einen Link, der aus einem empfängerspezifischen Token erstellt wird, sodass bei einer Abmeldung aufgezeichnet wird, welche Kampagne sie veranlasst hat. Der Header List-Unsubscribe ist ebenfalls gesetzt, da sein Fehlen eines der Signale ist, die Massenmails in Spam sortieren.

Der GET zeigt eine Bestätigungsseite an und der POST erledigt die Arbeit – E-Mail-Clients und Sicherheits-Appliances folgen den Links unaufgefordert, sodass eine Reaktion auf den GET Personen abmelden würde, die nie darauf geklickt haben. Ein zweiter Klick sagt „Sie sind abgemeldet“ und schlägt nicht fehl.

List-Unsubscribe-Post (One-Click) wird absichtlich beworben not: Es fordert den Client zum POST ohne CSRF-Token auf, was das CMS mit einem 419 ablehnt. Eine fehlgeschlagene Funktion zu beanspruchen ist schlimmer, als sie nicht zu beanspruchen.

An „Unsubscribe“ schreibt zwei Datensätze – eine Unterdrückung, die absolut ist und einen erneuten Import überdauert, und einen Einwilligungsentzug für den Kontakt, der ein Betreiber sieht und ein Beweis dafür ist, dass die Site auf Anfrage gestoppt wurde.

Das Ergebnis wird gelesen

Das Sendeprotokoll listet jeden Empfänger mit seinem Status und dem Grund dafür auf, filterbar. Darüber sind Gründe für Überspringen und Fehlschlagen gruppiert: „412 übersprungen“ ist nicht umsetzbar, während „390 unterdrückt, 22 Zustimmung zurückgezogen“ entweder eine Bestätigung oder eine Aufgabe ist.

Fehler können wiederholt werden; Sprünge können nicht. Ein Überspringen war eine Entscheidung, und ein erneuter Versuch würde es entweder wiederholen oder außer Kraft setzen – die zweite Möglichkeit ist, wie jemand, der sich abgemeldet hat, erneut E-Mails erhält. Wiederholte Empfänger durchlaufen die gleichen Einwilligungs- und Unterdrückungsprüfungen wie alle anderen.

Settings

Pro Standort: Batchgröße, stündliche Obergrenze, Name und Adresse des Absenders, Antwortadresse. Die Obergrenzen sind der Grund, warum es Batch gibt – ein Massenversand, der über das SMTP eines gemeinsam genutzten Hosts gesendet wird, führt dazu, dass eine sendende Domäne blockiert wird, und es dauert Monate, bis dies rückgängig gemacht wird. Auf dem Bildschirm wird auch deutlich angezeigt, wenn ausgehende E-Mails unbrauchbar sind, sodass eine Kampagne voller Sprünge nicht mit einem Fehler verwechselt werden kann.

Bounces

Rejectionen werden auf drei Arten klassifiziert, und nur eine davon unterdrückt:

Bedeutet

Unterdrückt

Tote Adresse

„Kein solcher Benutzer“, „Domäne nicht gefunden“

YJa, sofort

Temporär

Mailbox voll, graue Liste, Tarif begrenzt

Nur nach wiederholten Ausfällen

Vom Empfänger abgelehnt

spam, Richtlinie, SPF/DKIM/DMARC, Relay verweigert

Nie

Die dritte Zeile ist der Sinn der gesamten Funktion. Diese Ablehnungen kommen mit permanenten 5xx-Codes und sehen genauso aus wie ein totes Postfach, aber es geht um Ihre Absendung, nicht um den Empfänger. Würde man sie unterdrücken, würden gültige Kunden aufgrund eines Reputations- oder Konfigurationsfehlers gelöscht – stillschweigend, eine Kampagne nach der anderen. Uneindeutige Fälle entscheiden sich dafür, nicht zu unterdrücken: Das Beibehalten einer toten Adresse kostet einen Bounce, das Unterdrücken einer aktiven Adresse kostet einen Kunden.

Die Klassifizierung erfolgt zum Sendezeitpunkt nach dem SMTP-Fehler, sodass kein Webhook, kein Rückpfad-Postfach und keine Anbieterintegration erforderlich sind – sie funktioniert mit jedem Transport, den die Site bereits verwendet.

Jede Ablehnung wird als Verlauf und nicht nur als Unterdrückung gespeichert. Eine Unterdrückung kann nicht sagen, warum oder wie oft, und eine Reihe von Empfängerverweigerungen ist ohne sie unsichtbar. Der Bildschirm Lieferprobleme warnt, wenn dieses Muster auftritt, und sagt, was überprüft werden soll.

Installieren

composer plugin:build

Dann installieren Sie das Artefakt über System → Plugins im CMS-Administrator. Plugin-Installation deaktiviert; nach Prüfung explizit aktivieren.

Konventionen

handle              webblocks-campaigns
settings namespace  webblocks_campaigns
database prefix     webblocks_campaigns_
admin routes        /webadmin/plugins/webblocks-campaigns
public routes       /plugins/webblocks-campaigns
route names         webblocks.plugins.webblocks_campaigns.*
permissions         webblocks-campaigns.view, .manage, .send, .settings

send ist absichtlich von manage getrennt: Das Bearbeiten eines Entwurfs und dessen Freigabe für zweitausend Personen sind unterschiedliche Handlungen, und eine Organisation sollte in der Lage sein, das eine ohne das andere zu gewähren.

Sammeln Sie Abonnenten mit Double-Opt-In

Fügen Sie den Anmeldeblock zu einer Seite hinzu und wählen Sie die Zielliste, Überschrift, Einleitung, Einverständniserklärung und optionales Namensfeld aus. Eine Anfrage erstellt ein ausstehendes Abonnement. Der Empfänger muss den per E-Mail zugesandten Bestätigungslink verwenden und bestätigen, bevor die Adresse versandbar wird. Bestätigungslinks verfallen nach sieben Tagen.

Das Plugin zeichnet den bei der Anmeldung angezeigten Einwilligungstext auf. Eine Bestätigung kann eine Abmeldung oder einen Hard Bounce aufheben; Eine Spam-Beschwerde oder eine manuelle Betreibersperre wird dadurch nicht außer Kraft gesetzt. Vorhandene Kontaktnamen bleiben erhalten.