clickSomo
ClickSomo öffnen

Trichter & Auslöser

Ein Trichter ist ein Graph. Ein Lauf ist eine Zeile. Eine Wartezeit ist eine Zeit.

Das ist das gesamte Modell, und jede schwierige Eigenschaft dieses Produkts ergibt sich aus diesen drei Sätzen. Das Bearbeiten eines aktiven Trichters ist deshalb sicher. Ein Wiederholungsversuch kann nichts doppelt senden, deshalb. Eine Person, die sich am Dienstag abmeldet, hört am Donnerstag nichts, deshalb.

Was tatsächlich passiert, wenn der Trichter läuft

Beim Veröffentlichen eines Trichters wird eine unveränderliche Version geschrieben. Jemand tritt ein, und eine Zeile erscheint: ein Lauf, für diesen Kontakt, an diese Version gebunden, mit dem aktuellen Knoten, einer Weckzeit und seinem eigenen Kontext.

Ein Worker least die Läufe, deren Weckzeit verstrichen ist, und reserviert sie mit SKIP LOCKED, damit zwei Worker nicht denselben Lauf übernehmen können. Er führt Knoten aus, bis er auf eine Wartezeit oder einen Endknoten stößt, schreibt dann die nächste Weckzeit und gibt den Lauf frei.

Ein Knoten ist eine reine Funktion des Laufs, des Kontakts und des Knotens selbst — und seine Effekte werden in derselben Transaktion committet wie das Weiterbewegen des Laufs. Genau diese Eigenschaft macht einen Wiederholungsversuch sicher. Ein Worker, der in der halben Sekunde zwischen „Senden“ und „Weiterbewegen“ getötet wird, hinterlässt entweder beides oder nichts, niemals nur eines.

Und weil die Anwendung die Zeit liefert und nicht die Datenbank, ist eine jetzt geschriebene Zeile jetzt fällig. Eine Planungsspalte mit Standardwert aus der Datenbankuhr ist im Moment des Schreibens noch nicht fällig und verpasst genau den Tick, der sie erzeugt hat — ein Fehler, der völlig unsichtbar bleibt, bis eine Nachricht eine Stunde zu spät ist.

Ein Tick des WorkersAusführung
  • 1Leasenwake_at <= now(), FOR UPDATE SKIP LOCKED. Eine Warteschlange ohne Leasen sendet standardmäßig doppelt.
  • 2AusführenKnoten der Reihe nach, bis eine Wartezeit oder ein Endknoten erreicht ist. Jeder Knoten schreibt einen Schritt: was er entschieden hat, was er ausgelöst hat.
  • 3CommitEffekte und Weiterbewegen in einer Transaktion. Das ist der ganze Trick.
  • 4RuheNächste wake_at geschrieben. Es existieren noch keine nachgelagerten Zeilen, und keine ist nötig.

Ein Lauf pro Kontakt pro Version

Vierzehn Auslöser

Was einen Lauf starten kann

Einige davon sind Dinge, die Sie tun. Die meisten sind Dinge, die Ihr Kunde tut oder eben nicht tut — und das Ausbleiben einer Handlung ist ebenso guter Auslöser wie die Handlung selbst.

Sie kommen an

form_submit, list_join, contact_created, tag_added und segment_enter. Ein Segment ist ein lebendiges Prädikat, daher deckt „tritt in das Segment ein“ jedes ausdrückbare „ist geworden“ ab — drei Bestellungen, neunzig Tage Stille, Ausgaben über einem Schwellenwert.

Sie tun etwas

page_visit über das Website-Snippet, message_opened, link_clicked, booking_made und payment_made. Dass eine Nachricht geöffnet wird, ist selbst ein Ereignis am Kontakt, sodass ein Trichter auf eine Reaktion auf das zuletzt Gesendete warten kann.

Zeit, oder Sie

date_field mit einem Versatz — ein Geburtstag, eine Verlängerung, „ein Jahr seit“, sieben Tage davor oder drei Tage danach. schedule für den wiederkehrenden Auslöser. manual für die Ankündigung, die Sie verschicken, weil Sie sich dafür entschieden haben.

Ihre eigene Anwendung

api_event ist ein benutzerdefiniertes Ereignis, das Sie aus Ihrem eigenen Code mit Ihrem eigenen Token senden. Alles, was Ihr Produkt weiß, wird zum Auslöser: aktiviert, einen Kollegen eingeladen, das Limit erreicht, gekündigt, exportiert. Das ist der Auslöser, der aus einem Mailing-Werkzeug einen Teil Ihres Produkts macht.

Wiedereintritt, einmal entschieden

Ein Trichter ist entweder wiedereintretend oder nicht, und die Datenbank setzt das durch: ein Lauf pro Kontakt pro Trichter, sofern Sie nichts anderes festlegen. Derselbe Auslöser, der zweimal in derselben Sekunde feuert, kann nicht versehentlich zwei Läufe erzeugen.

Eintrittsbedingungen

Ein Auslöser feuert, und die Eintrittsregel entscheidet, ob genau dieser Kontakt zugelassen ist — ein Segmentprädikat vor der Tür. Günstiger als ein Bedingungsknoten auf dem ersten Schritt, und der Graph bleibt bei dem, was geschieht, statt bei dem, wer hineindarf.

Vierzehn Dinge können ihn starten. Sechzehn Dinge können als Nächstes geschehen.

Sechzehn Aktionen und sieben Flussknoten

Was ein Trichter tun kann und wie er entscheidet

Etwas senden

send_email, send_sms, send_push, send_letter — vier Kanäle, ein Graph — dazu notify_team, wenn die Person, die informiert werden muss, bei Ihnen arbeitet.

Den Kontakt ändern

add_tag, remove_tag, add_to_list, remove_from_list, set_field. Dass Sie unterwegs Markierungen setzen, macht das Segment des nächsten Trichters einfach.

Nach außen reichen

http_request an alles, was Sie möchten, create_payment gegen Ihr eigenes verbundenes Konto und book_slot gegen eine Buchungsressource. Der Zahlende bleibt Ihrer; niemand wird unser Kunde.

Zwischen Trichtern wechseln

enter_funnel und exit_funnel. Bauen Sie eine Willkommenssequenz und rufen Sie sie an vier Stellen auf, statt vier Kopien zu pflegen, die bis März auseinanderdriften.

Beim Senden generieren

ai_generate füllt Merge-Variablen pro Kontakt und wird gegen Ihr Kontingent abgerechnet und nach Kreativ- und Kontaktattribut-Hash zwischengespeichert — sonst würden Sie bei jedem einzelnen Senden pro Empfänger zahlen.

Warten, verzweigen, teilen, zusammenführen

wait nimmt eine Dauer, einen Zeitpunkt, einen Wochentag mit Uhrzeit oder ein Datumsfeld mit Offset. condition ist ein Segmentprädikat mit Ja und Nein. split ist A/B/n mit Gewichten. join führt die Zweige wieder zusammen.

goal — das eine, das zählt

Ein Ziel beendet den Durchlauf für jeden, der es erreicht. Die Person hat gebucht, gekauft, geantwortet: Der Rest der Sequenz wird speziell für sie abgebrochen. Niemand bekommt „wir vermissen Sie“ am Tag nach der Rückkehr — und genau das verhindert dieser Knoten.

throttle und quiet_hours

Throttle drosselt eine Sendewelle, damit ein Postfach mit niedrigem Ratenlimit nicht in die Sperre getrieben wird. Ruhezeiten halten eine Nachricht zurück, bis es eine zivilisierte Zeit ist — angewendet auf der Nachrichtenebene, nicht in jeden Zweig des Graphen kopiert.

Geprüft, bevor er laufen kann

Der Validator verweigert dieselben Dinge für Sie wie für die KI

Ein Graph wird geprüft, bevor er veröffentlicht werden kann, und die Prüfung ist nicht nur ein Hinweis. Es ist derselbe Codepfad, egal ob ein Mensch den Trichter gezeichnet oder ein Modell ihn generiert hat — der einzige Grund, warum generierte Trichter überhaupt vertrauenswürdig sind.

Genau ein Einstieg

Zwei Einstiegsknoten sind eine Mehrdeutigkeit, die niemand bemerkt, bis die falsche Hälfte einer Liste die falsche Sequenz erhält.

Jeder Knoten erreichbar

Ein verwaister Zweig ist entweder ein Fehler oder eine Nachricht, von der Sie denken, dass sie rausgeht — und es tut sie nicht. Beides ist eine Mitteilung wert.

Ein Zyklus muss ein Wait enthalten

Eine Schleife ohne Wait ist eine Endlosschleife mit einem Senden in der Mitte. Diese Regel ist der Unterschied zwischen einem Trichter und einem Vorfall.

Jedes Senden hat seine Kreativ

Ein send_email-Knoten ohne Kreativ und Betreff kann nicht veröffentlicht werden. Die Nachricht mit dem richtigen Betreff und leerem Inhalt ist ein echter Fehlermodus; sie wird hier verweigert.

Jede Variable ist bekannt

Merge-Variablen werden bei der Veröffentlichung validiert. {{frist_name}} ist ein Tippfehler, den Sie beim Bearbeiten sehen, und kein „Hallo ,“ in vierzigtausend Postfächern.

Dann simulieren Sie ihn

Führen Sie einen echten Kontakt trocken durch den gesamten Graphen und lesen Sie den genommenen Pfad sowie jede gesendete Nachricht mit ihrem Tag zurück. Nichts verlässt das Haus.

Die unangenehmen Fälle

Sieben Dinge, die eine naive Engine brechen

Jeder davon ist ein Test mit einer deterministischen Uhr dahinter, denn jeder einzelne bricht eine Implementierung, die perfekt korrekt aussieht, bis sie auf die Realität trifft.

Wogegen die Engine getestet wirdFalsifikation
  • 1Ein Trichter, der in sich selbst loopLegitim, häufig und in Ordnung — vorausgesetzt, der Zyklus enthält ein Wait, auf dem der Validator besteht.
  • 2Jemand meldet sich mitten im Durchlauf abDie Unterdrückung wird beim Senden geprüft, nicht beim Einreihen. Eine Prüfung beim Einreihen mailt die Personen, die während der Wartezeit gegangen sind.
  • 3Der Trichter wird mit zehntausend Personen darin bearbeitetSie laufen die Version zu Ende, in die sie eingetreten sind. Neue Eintretende laufen die neue.
  • 4Derselbe Trigger feuert zweimal in einer SekundeEin Durchlauf, denn Eindeutigkeit ist ein Index statt einer Prüfung gefolgt von einem Einfügen.
  • 5Ein Kontakt wird mitten im Durchlauf gelöschtDer Durchlauf endet. Eine Löschung, die eine Sequenz zurücklässt, die noch an jemanden adressiert ist, ist keine Löschung.
  • 6Eine Wartezeit überschreitet eine Sommerzeitumstellung„Drei Tage um neun Uhr morgens“ bedeutet neun Uhr morgens auf beiden Seiten der Uhrumstellung.
  • 7Ein Worker wird zwischen Senden und Fortfahren beendetEffekte und Fortfahren sind eine Transaktion. Entweder geschah beides oder nichts davon.

Deterministische UhrJeder Test bricht eine plausible Implementierung

Kampagnen sind die andere Hälfte

Ein Trichter reagiert. Eine Kampagne ist die einmalige Aussendung: ein Publikum, ein Zeitplan, ein Drosselwert und ein Versand. Es ist eine andere Art von Ding und wird bewusst getrennt gehalten, statt sich als Trichter mit einem Knoten auszugeben.

Zwei Regeln machen das sicher. Ein Publikum wird einmal materialisiert und weigert sich, zweimal zu laufen — eine erneute Auflösung würde stillschweigend alle hinzufügen, die seit dem Versandstart dazugekommen sind, und der Deduplizierungsindex würde das verbergen, indem er genau die Duplikate verhindert, die er selbst erzeugt. Und Zähler werden aus Zustellereignissen neu berechnet, nie direkt erhöht, sodass ein wiederholter Webhook keinen Bericht aufblähen kann.

Was Sie wann verwenden: geschieht es wegen etwas, das die Person getan hat, ist es ein Trichter. Geschieht es wegen etwas, das Sie an einem Dienstag beschlossen haben, ist es eine Kampagne. Erstaunlich viel Marketingautomatisierung scheitert daran, das Zweite in die Form des Ersten zu zwingen.