Event-Flow-System

Event-Flow-Editor-Leitfaden

Erstelle zuverlässige Automatisierungen für Social Stream Ninja. Diese Anleitung behandelt Grundlagen, Logikknoten, Signalfluss und praktische Kniffe, nach denen Creator häufig fragen (etwa Chatechos vermeiden und AND/NOT-Blöcke richtig kombinieren).

Deutsch

0. Kurze Orientierung

Event Flow ist ein knotenbasierter Editor. Jede Verbindung trägt Nachrichtennutzdaten und einen booleschen Zustand (true = fortfahren, false = stoppen). Verwende Quellen zum Einspeisen von Ereignissen, Logikknoten zum Filtern von Entscheidungen und Aktionen um Aktionen auszuführen (Chat senden, Overlays steuern, Nachrichten weiterleiten usw.).
Möchtest du Teilnehmer merken, spätere Berechtigung prüfen, eindeutige Nutzer verlosen oder eine benannte Liste leeren? Öffne die User-Memory-Anleitung für das gemeinsame Zustandsmodell, Screenshots und ein importierbares Beispiel.

Was ist dieser Editor?

Der Event-Flow-Editor bildet die Ebene für erweiterte Automatisierung in Social Stream Ninja. Er ergänzt die einfachen Popup-Schalter und erlaubt eigene Weiterleitungslogik. Verwende ihn, wenn du:

  • Leite Chat mit Filtern zwischen Diensten weiter (z. B. Twitch nach Discord spiegeln, aber Befehle blockieren).
  • Erstelle treuebasierte Befehle, Schlüsselwortspiele oder Teilnahmebedingungen für Verlosungen mit AND/OR/NOT-Logik.
  • Löse eigene Overlays, Audio, OBS-Szenen oder Webhooks anhand von Daten aus, die du im Flow ergänzt.
  • Kombiniere mehrere Plattformen in einer Automatisierung (Kick + Twitch + YouTube durch einen Flow).

Das Popup bietet schnelle Voreinstellungen; Event Flow ist der Werkzeugkasten für eigene Abläufe.

Start und Grundlagen

  • Öffne den Event-Flow-Editor über das Hauptmenü des Dashboards (Desktop oder Erweiterung).
  • Jedes Projekt wird bis zum Export lokal gespeichert. Verwende Export zum Sichern oder Teilen.
  • Arbeite auf Arbeitsflächen namens Flows. Jeder Flow kann mehrere Plattformen gleichzeitig abonnieren.

Knoten auf einen Blick

  • Eingänge (linke Anschlüsse) erwarten den Nachrichtenkontext.
  • Ausgänge (rechte Anschlüsse) geben denselben Kontext samt Änderungen aus.
  • Logikknoten können sowohl den Kanal true als auch optional den Kanal false ausgeben.

Nutzdatenstruktur

Jede Nachricht trägt ein JSON-Objekt. Pflichtschlüssel folgen docs/event-reference.html (platform, type, chatname, chatmessage usw.). Eigene Daten gehören unter meta.

Jeder Flow beginnt mit einem Auslöser

Aktionsknoten (grün) laufen nie von selbst. Ein darüberliegender Auslöserknoten (blau) muss folgendes Ergebnis liefern: true. Ein Flow nur aus verketteten Aktionen sieht gültig aus, bleibt aber dauerhaft inaktiv, weil nichts die Kette startet. Knotennamen beschreiben, was der Knoten macht, nicht wann es geschieht: Nachricht hervorheben hebt eine Nachricht hervor, wenn der Flow ihn erreicht — er wird nicht ausgelöst, wenn du anderswo eine Nachricht hervorhebst.

Zwei verkettete Aktionsknoten ohne Auslöserknoten
❌ Läuft nie. Feature Message und Speak Text sind beide Aktionen; ohne Auslöser darüber startet nichts die Kette.
Any-Message-Auslöser verbunden mit Feature-Message- und Speak-Text-Aktionen
✅ Funktioniert. Ein Auslöser Beliebige Nachricht (oder Message Contains, ein Regex, ein Spendenereignis usw.) startet die Kette; beide Aktionen laufen dann für jede passende Nachricht.

Flow-Actions-Overlay (Aktionsausgabe)

Mit einer Benachrichtigungsvorlage beginnen:

Wähle Spende: Feier + Stimme für eine fertige Animation und einen synthetischen Dankesclip oder die fortgeschrittene Vorlage Spende: Animation + Sound + OBS-Filter . Neue Benachrichtigungsvorlagen starten deaktiviert, damit du sie zuerst konfigurieren und testen kannst. Wähle für die OBS-Vorlage in beiden Filteraktionen eine Quelle und denselben normalerweise ausgeschalteten Filter.

Audioclip abspielen und Multi-Alerts teilen nun eine Bibliothek mit 17 Sounds: Applaus, Trommelwirbel, Rauschen, Registrierkasse und andere Effekte, vier beschriftete synthetische englische Sätze sowie einfache Klänge. Anhören / Stoppen zeigt eine lokale Vorschau mit sichtbarem Wiedergabestatus. Du kannst weiterhin eine Aufnahme hochladen oder eine app-lokale Datei wählen. Für wechselnde Namen oder Nachrichten verwende die bestehende Aktion Text sprechen .

Event Flow spielt über die Browser-Quelle Flow Actions ; Multi-Alerts spielt über seine eigene Browser-Quelle. Lasse für dasselbe Ereignis nur in einer den Sound aktiviert, um doppelte Wiedergabe zu vermeiden. Navigiere mit Tab zu einem Flow-Knoten und drücke Eingabe oder Leertaste, um seine Eigenschaften zu bearbeiten.

Knoten wie Audioclip abspielen, Medien-Overlay anzeigen, und die OBS-Steuerungen benötigen eine Darstellungsfläche. Diese Fläche ist die Flow-Actions-Overlay-Seite unter actions.html. Lasse sie in deiner Streaming-Software (OBS-/Streamer.bot-Browser-Docks usw.) laufen, damit Event-Flow-Aktionen einen Ort zur Darstellung haben.

Any-Message-Auslöser verbunden mit einer Play-Audio-Clip-Aktion
Dieser Flow ist vollständig und wird bei jeder Nachricht ausgelöst — der Sound spielt aber auf der Flow-Actions-Overlay-Seite, nicht im Editor. Die Vorschau-Schaltfläche des Editors spielt lokal ab; für die Live-Wiedergabe muss das Overlay geöffnet sein. Wenn der Browser die automatische Wiedergabe blockiert, klicke auf Audio aktivieren auf der Flow-Actions-Seite, um den zuletzt blockierten Clip erneut zu versuchen. Ein Klick an anderer Stelle der Seite aktiviert die Wiedergabe ebenfalls. Eine OBS-Browser-Quelle erlaubt normalerweise automatisches Abspielen.
So öffnest du es (über Popup/Dashboard):
  1. Öffne das Social-Stream-Ninja-Hauptpopup (das Fenster aus popup.html oder das Erweiterungssymbol).
  2. Scrolle zur Karte „Flow Actions“. Verwende die Schaltfläche [Link kopieren] oder klicke auf die URL in der Karte.
  3. Der Link sieht so aus: https://socialstream.ninja/actions.html?session=YOURSESSION. Füge ihn in eine OBS-Browser-Quelle ein (1920×1080 empfohlen) oder öffne ihn in einem Overlay-Browser.
Lokale Medien in der eigenständigen App verwenden:
  1. Klicke in einer Play-Audio-Clip- oder Display-Media-Overlay-Aktion auf Lokale Datei auswählen.
  2. Klicke auf Lokale Flow-Actions-URL für OBS kopieren und verwende die erzeugte localhost-URL statt der gehosteten Flow-Actions-URL.
  3. Lasse SSApp laufen. Wenn eine ausgewählte Datei verschoben wird, kehre zur Aktion zurück und klicke auf Neu verknüpfen.

Die Chrome-Erweiterung kann Dateien von der Festplatte nicht selbst bereitstellen. Verwende Upload oder eine gehostete URL, wenn kein Desktop-Begleiter verfügbar ist. Siehe die Anleitung für Mediendateien in Event Flow für die vollständige Einrichtung.

Nach dem Laden kann dieses Overlay:

  • GIPHY oder direkte Medien-URLs, Text und Konfetti anzeigen, ausgelöst durch deine Flows.
  • Sounds (TTS, Audioclips) lokal abspielen, damit Zuschauer sie hören.
  • Sprich mit OBS über die WebSocket-Einstellungen unter Flow Actions im Popup (Szenenwechsel, Quellen umschalten, GDI+/FreeType-Textupdates, Wiederholungspuffer usw.).
OBS-Steuerungsmodi:
  • Browser-Quell-API: nur verfügbar, wenn actions.html innerhalb einer OBS-Browser-Quelle mit Erweiterte Zugriffsstufe läuft. Szenenwechsel funktioniert hier; Aufnahme-, Streaming- und Wiederholungspufferaktionen können darauf ausweichen.
  • OBS WebSocket: für einheitliche Steuerung empfohlen. Social Stream Ninja Flow Actions verwenden die OBS-WebSocket-v5-API von OBS 28+ und erwarten den modernen Befehlssatz auf Port 4455.
  • Passwort: optional. Hänge &obspw=... nur dann an die Flow-Actions-URL an, wenn dein OBS-Server Authentifizierung verlangt.
  • Overlay-Diagnose: hänge &obsdebug=1 an die URL dieser Seite an: actions.html wenn du bei der Fehlersuche ein kleines Live-OBS-Verbindungsabzeichen auf dem Overlay möchtest.
  • Textquelle setzen: aktualisiert OBS-Eingaben Text (GDI+) und Text (FreeType 2) direkt und unterstützt Event-Flow-Vorlagenvariablen wie {counterValue} und {counterTarget}.
  • Alte 4.x-Installationen: wenn du noch obs-websocket 4.x / Port 4444 verwendest, funktionieren Quellen-/Filter-/Stumm-/Textaktionen erst nach einem Upgrade von OBS / obs-websocket.

Siehe die spezielle OBS-Steuerungsanleitung für alle Auslöser, Aktionen, Einrichtungsschritte und getesteten Rezepte.

Empfohlener Diagnoseweg:
  1. Öffnen obs-websocket-test.html.
  2. Prüfe, ob GetVersion, GetCurrentProgramScene, und GetSceneList erfolgreich sind.
  3. Führe dort die passende Aktionsprüfung durch, bevor du die vollständige Event-Flow-Automatisierung testest.
Lasse das Overlay geöffnet. Das Schließen der Flow-Actions-Seite pausiert jede Overlay-/Audio-/OBS-Aktion in Event Flow. Blende sie aus oder lege sie auf einen separaten Monitor, statt sie ganz zu schließen.

1. Was läuft durch einen Knoten?

Die Event-Flow-Laufzeit reicht zwei Dinge durch jede Verbindung:

  1. Nutzdaten – das Ereignis- oder Nachrichtendatenobjekt.
  2. Gate-Signal – ein true/false Bit, das dem nächsten Knoten sagt, ob er laufen soll.
Wenn ein Knoten false ausgibt: nachgelagerte Knoten stoppen, sofern sie keine Eingabe auf einem separaten Zweig erhalten (zum Beispiel dem false Anschluss eines Condition-Knotens). So lässt sich einfach Ausweichlogik erstellen, ohne ganze Flows zu duplizieren.

Erwartete Eingaben

  • Ereignisquellen (Twitch Message, Timer, Manual Trigger usw.) ignorieren vorgelagerte Eingaben — sie erzeugen eigene Nutzdaten und geben immer true sofern der Knoten selbst keinen Fehler hat.
  • Transformations- und Logikknoten lesen die Nutzdaten, ändern gegebenenfalls Felder oder Zustände und setzen das Gate-Signal gegebenenfalls auf false.
  • Aktionsknoten werden nur bei folgendem Gate-Signal ausgelöst: true. Sie können weiterhin aktualisierte Nutzdaten ausgeben, wenn du weitere Aktionen verketten möchtest.

Ausgabemuster

Ein Ausgang

Die meisten Knoten haben einen Ausgang. Alles, was hineingeht (Nutzdaten + Gate), kommt unverändert heraus, sofern der Knoten es nicht bearbeitet.

True/False-Ausgänge

Condition-, Compare-, Regex- und Logic-Knoten haben zwei Ausgangsanschlüsse. Wahr läuft durch den grünen Anschluss weiter; false wird am grauen/roten Anschluss verfügbar.

Durchreichen oder überschreiben

Einige Knoten (Set Variable, Math, Text Replace) verändern die Nutzdaten, geben aber weiterhin den Zustand true/false ihres Eingangs weiter. Andere (NOT, AND, OR) berechnen den booleschen Wert selbst neu.

2. Kurzreferenz der Logikknoten

Diese Blöcke beantworten die häufigsten Fragen zur Bedeutung von true/false.

NOT

  • Eingänge: 1 boolescher Wert (true/false), abgeleitet vom vorherigen Knoten.
  • Ausgänge: der umgekehrte boolesche Wert und die unveränderten Nutzdaten.
  • Standardverhalten: Wenn nichts am NOT-Eingang angeschlossen ist, ergibt er false, also ist die Ausgabe true.
Beispiel: Platziere NOT nach „Contains Keyword“, um eine Benachrichtigung auszulösen, wenn ein Zuschauer das Schlüsselwort nicht verwendet.

AND

  • Eingänge: zwei oder mehr boolesche Signale (A, B, ...). Zusätzliche Anschlüsse können leer bleiben.
  • Ausgänge: true nur bei folgendem Wert aller verbundenen Eingänge: true.
  • Verwende AND, wenn mehrere Bedingungen gleichzeitig erfüllt sein müssen („ist Abonnent“ und „Chatnachricht enthält !raffle“).

OR

  • Liefert true wenn ein beliebiger verbundener Eingang true ist.
  • Ideal für plattformübergreifende Auslöser: Führe Twitch- und YouTube-Nachrichtenknoten in ein OR und vereinheitliche dann die nachgelagerte Aktion.
Brauche ich immer einen AND-Knoten?
Nein. Viele Knoten bieten bereits kombinierte Filter (etwa „Filter User Level“ + „Contains Text“). Verwende AND nur, wenn die integrierten Optionen deine Kombination nicht abdecken oder du einen wiederverwendbaren Logik-Verknüpfungspunkt für mehrere Zweige möchtest.
NOT und leere Eingänge: Ein unverbundener NOT-Knoten gibt weiterhin true aus. Verbinde ihn sinnvoll oder deaktiviere den Knoten, damit er nicht versehentlich einen Flow freigibt.

3. Beispiele kleiner Flows

A. Automatisch antworten, sofern die Nachricht kein Befehl ist

Twitch-Nachricht ──▶ Regex-Treffer "^!" ─┐ │ ├─false──▶ Automatische Antwort ("Danke fürs Chatten!") │ └─true──▶ Nichts tun

Hier lautet die Regex-Ausgabe true bei einer Nachricht, die ein Befehl ist. Wir leiten den Anschluss false zu unserer Antwort, damit normale Chatter eine Bestätigung erhalten, während Befehle einfach durchlaufen.

B. Mehrere Prüfungen mit AND verlangen

YouTube-Nachricht ──▶ Enthält "!queue" ─▶ AND ─▶ Nach Discord weiterleiten Verschenkte Mitgliedschaft ─▶ Nutzerrolle = Mitglied ──▲

Der AND-Knoten stellt sicher, dass nur Mitglieder mit dem richtigen Schlüsselwort nach Discord weitergeleitet werden. Beide Zweige senden ihr boolesches Ergebnis an AND; die Nutzdaten vom ersten Zweig werden weitergereicht.

C. NOT-Knoten zum Blockieren wiederholter Benachrichtigungen

Ereignisnutzdaten ─▶ Zustandsprüfung (isAlertMuted) └─false─▶ NOT ─▶ Feier abspielen

State Check liefert den Wert true wenn die Benachrichtigung stummgeschaltet ist. Durch Umkehren dieses Ergebnisses sorgt NOT dafür, dass die Feier nur bei folgendem Flag-Wert abgespielt wird: false.

D. Zufällig einen von zwei Sounds abspielen

Flow mit RANDOM-, NOT- und AND-Gatter, der einen von zwei Audioclips zufällig abspielt
Ein 50/50-Münzwurf zwischen zwei Audioclips. Das RANDOM-Gatter würfelt einmal pro passender Nachricht: Bei Erfolg spielt Sound A; bei Misserfolg kehrt NOT das Ergebnis um und AND lässt stattdessen Sound B spielen.
Auslöser ──▶ RANDOM (50%) ──▶ Sound A abspielen │ └──▶ NOT ──▶ AND ──▶ Sound B abspielen Auslöser ──────────────────▲

Das AND-Gatter ist nicht optional. Ein alleinstehendes NOT würde true ausgeben, wenn RANDOM inaktiv ist; Sound B würde daher bei jeder Chatnachricht spielen, die nicht zu deinem Auslöser passt. Wenn der Auslöser als zweiter Eingang in AND geht, wird Sound B auf passende Nachrichten begrenzt. Dasselbe Muster funktioniert für jedes Entweder-oder-Paar von Aktionen, nicht nur Audio.

4. Echos, Schleifen und Relay-Rückkopplungen verhindern

Chat zwischen Oberflächen weiterzuleiten ist leistungsfähig, kann aber endlose Echos erzeugen, wenn du die eigene Ausgabe erfasst. Beachte diese Schutzmaßnahmen:

Hinweis zum YouTube-Shorts-Ziel:
Sowohl eingehende Auslöser als auch ausgehende Relay-Chat-Ziele unterscheiden zwischen youtube und youtubeshorts. Verwende zwei Relay-Aktionen, wenn eine Nachricht beide Varianten erreichen soll. Siehe YouTube Shorts und Event Flow.
Relay Chat überspringt erkannte Rückläufer automatisch.
Ein Rückläufer ist eine ausgehende Nachricht, die aus einem Zielchat erneut erfasst wird. Aktuelle Relay-Chat-Aktionen überspringen erkannte Rückläufer; ein separates Kontrollkästchen „No Reflections“ gibt es nicht. Verwende zum Ausblenden oder Begrenzen ihrer Anzeige in Dock und Overlays eine Aktion Rückspiegelungsfilter (Reflection Filter) mit Alle blockieren, Erste zulassen, oder Alle zulassen. Dies steuert die Anzeige bei erneutem Empfang, nicht das Senden. Folge der Anleitung zur Twitch- und YouTube-Weiterleitung für eine vollständige Einrichtung.
  • Doppelte Relay-Systeme vermeiden. Deaktiviere globales „Relay all“, wenn du gleichwertige Event-Flow-Wege verwendest, und prüfe andere Dienste, die dieselben Chats verbinden. Eigene Metadaten bleiben auf dem Weg durch einen Plattformchat nicht garantiert erhalten.
  • Debounce- oder Cooldown-Knoten verwenden für Benachrichtigungen, die nur alle X Sekunden ausgelöst werden sollen.
  • Schleifen bewusst unterbrechen. Wenn zwei Zweige einander speisen, füge einen Logikknoten hinzu, der eine Zustandsvariable („currentlyRelaying“) prüft, damit der Flow bei gesetztem Flag früh endet.

5. Eingänge, Ausgänge und praktische Fragen

Was kommt in einen Knoten?

  • Die vollständigen Nachrichtennutzdaten.
  • Das Gate-Bit (true/false).
  • Optionaler Kontext (Zustandsvariablen, Timer), den der Knoten ausdrücklich anfordert.

Was verlässt einen Knoten?

  • Dieselben Nutzdaten, sofern der Knoten sie nicht bearbeitet.
  • Ein neu berechnetes Gate-Bit (Logikknoten) oder durchgereichtes Bit (Aktionen).
  • Die meisten Seiteneffekte (etwa Chatversand) verändern die Nutzdaten nicht, aber Punkteaktionen können Statusfelder ergänzen wie pointsTotal oder pointsSpendError für nachgelagerte Logik.

Wann verzweigen?

Immer dann, wenn du unterschiedlich auf true gegenüber false reagieren möchtest. Ziehe eine Leitung vom benötigten farbigen Ausgang (grün = true, grau/rot = false) zum nächsten Knoten.

Merke: Wenn du mit einem false Ausgang nichts machst, endet der Flow dort einfach. Das ist ideal für Filter („alles blockieren, was die Prüfung nicht besteht“), aber vergiss nicht, den false Pfad zu verbinden, wenn du Ausweichlogik brauchst.

Häufige Fragen und Antworten

  • Muss ich für jedes Filterpaar AND verwenden? Nein. Viele Knoten enthalten mehrere Prüfungen (der einfache Message Filter unterstützt etwa Schlüsselwort + Rolle). Verwende AND nur für fortgeschrittene Kombinationen oder beim Zusammenführen von Signalen verschiedener Knoten.
  • Wie gelangen true/false-Werte zum NOT-Knoten? Jeder Knoten mit grünem Ausgang liefert true standardmäßig. Wenn eine Bedingung fehlschlägt, liefert er false. Verbinde diese Leitung mit NOT, um das Ergebnis umzukehren.
  • Kann ein Knoten Nutzdaten ausgeben, selbst wenn er false zurückgibt? Ja. Die Nutzdaten laufen weiter durch den false-Ausgang; du entscheidest, wohin dieser Zweig führen soll.
  • Wie erkenne ich TikTok-Team-Mitglieder? Wähle TikTok-Team-Mitglied im User-Role-Knoten. Er erkennt TikTok-Fanclub-/Team-Level und Abzeichen an der eingehenden Nachricht und hängt nicht von den Main-Chat-Overlay-Einstellungen ab.
  • Kann jeder Speak-Text-Knoten eine andere Stimme verwenden? Ja. Gib einen vom Anbieter unterstützten Stimmennamen oder eine ID in Stimme überschreiben ein, oder lasse es leer, um die TTS-Standardstimme von Flow Actions zu verwenden.

6. Referenz der Vorlagenvariablen

Mehrere Aktionsknoten (Show Text, Set Text Source, Send Message, Relay Chat, TTS Speak, Call Webhook, Print Thermal Label) unterstützen Vorlagenvariablen , die zur Laufzeit durch Ereignisdaten ersetzt werden. Setze Variablennamen in geschweifte Klammern wie {username}.

Kernvariablen (abwärtskompatibel)

VariableAliasBeschreibungBeispiel
{username}{chatname}Anzeigename des NutzersCoolViewer123
{message}{chatmessage}ChatnachrichtentextHallo zusammen!
{source}-Plattformname (mit großem Anfangsbuchstaben)Twitch, YouTube
{type}-Plattformname (unverarbeitet)twitch, youtube
{donation}{hasDonation}Anzeigebezeichnung der Spende/des Trinkgelds5,00 $, 500 Bits

Erweiterte Variablen

VariableBeschreibungBeispiel
{displayname}Anzeigename (alternatives Feld)CoolViewer123
{donoValue}Spendenwert in USD, bereitgestellt oder geschätzt; Event Flow leitet Schwellenwerte aus normalisierten hasDonation Bezeichnungen wie Wert, $Wert, Wert + Einheit oder kompakte Einheit/Wert-Angabe ab. Für unbekannte benannte virtuelle Einheiten gilt 100 Einheiten = 0,01 USD; TikTok-Geschenke ohne Preis zählen als ein Coin pro Geschenk (je 0,01 USD). {donationAmount} ist ein älterer Alias5.00
{event}Ereignistyp-Kennungcheer, raid, new_follower
{membership}MitgliedschaftsstatusMEMBERSHIP, new_sponsor
{subtitle}Zusätzlicher KontextSeit 3 Monaten Mitglied
{userid}Plattform-ID des Nutzers12345678
{chatimg}Nutzer-Avatar-URLhttps://...
{contentimg}URL des angehängten Bildeshttps://...
{rewardTitle}Belohnungsname, wenn die Quelle ein Belohnungstitelfeld auf oberster Ebene bereitstelltMeine Nachricht hervorheben
{meta}Strukturierte Ereignisdaten (JSON){"viewers":100}
{counterValue}Aktueller Zählerwert nach einem Counter- oder Check-Counter-Schritt12
{counterTarget}Zählerzielwert30
{counterRemaining}Zählerziel minus aktueller Wert, mindestens 018
Variablennamen werden ohne Beachtung der Groß-/Kleinschreibung abgeglichen. {USERNAME}, {Username}, und {username} funktionieren alle auf dieselbe Weise.
Im Flow ergänzte Felder funktionieren ebenfalls. Wenn eine frühere Aktion einen Wert auf oberster Ebene zur Nachricht hinzufügt, können spätere Vorlagen ihn direkt lesen. Beispiel: Check Counter liefert {counterValue}, {counterTarget}, und {counterRemaining}.
Call-Webhook-JSON: Vorlagenvariablen funktionieren in JSON-Zeichenfolgewerten auf jeder verschachtelten Objekt- oder Array-Ebene. Objektschlüssel werden nicht ersetzt; ein eigener Body ohne Platzhalter wird unverändert gesendet.

Beispielvorlagen

  • Text anzeigen: {username} just cheered {hasDonation}!
  • OBS-Textquelle setzen: {username}: now {counterValue}, need {counterTarget}
  • Relay Chat: [{source}] {username}: {message}
  • TTS: {username} says {message}
  • Spendenbenachrichtigung: {username} donated {donation} - {subtitle}
  • Thermoetikett: {username}, eine neue Zeile, dann {donation}. Siehe die Thermodrucker-Anleitung für Druckereinrichtung, Etiketten fester Größe und einen vollständigen Flow.
  • Discord Call Webhook: {"content":"{message}","username":"{username}","avatar_url":"{chatimg}"}
Fehlende Variablen werden zu leeren Zeichenfolgen. Wenn ein Ereignis ein bestimmtes Feld nicht hat (z. B. {donation} bei einer normalen Chatnachricht), wird der Platzhalter durch eine leere Zeichenfolge ersetzt, statt den wörtlichen {donation} Text anzuzeigen.

7. Checkliste bewährter Vorgehensweisen

  • Benenne und färbe deine Knoten, damit du später noch weißt, welcher Zweig welcher ist.
  • Mit dem integrierten Simulator testen (Send Test Event), bevor du einen Flow live schaltest.
  • Logik nahe der Quelle gruppieren. Filtere möglichst früh, um nachgelagerte Verarbeitung zu vermeiden.
  • Wiederholungen in Zustandsknoten speichern. Verwende Zähler, Schalter und Zeitstempel, um doppelte Benachrichtigungen zu vermeiden.
  • Meta-Felder dokumentieren. Wenn du eigene meta Schlüssel hinzufügst, dokumentiere sie, damit Overlays und entfernte Clients konsistent bleiben.
Versionen speichern. Exportiere deinen Flow nach jedem Meilenstein. Ein Import ist die einfachste Rückkehr, wenn ein Experiment schiefgeht.

8. Weiterführende Möglichkeiten

Eigene Abläufe über Stream Deck oder API ausführen: benannte Auslöser, eine Startvorlage, Auffinden von Abläufen, Zusatzdaten, HTTP-/WebSocket-/P2P-Beispiele und Drehregler-Gesten.

Bereit für mehr Details?

  • Verwende Zustandsknoten (Zähler, Schalter, Timer), um Kontext zwischen Ereignissen zu verfolgen.
  • Kombiniere Variablen und Logik zum Erstellen von Warteschlangen, Verlosungen oder Wertungssystemen.
  • Verbinde dich mit dem System Punkte und Belohnungen , damit Zuschauer Flows bewusst auslösen können.
  • Nutzt du die SSApp-Desktop-App? Freischalten Eigene JavaScript-Knoten für beliebige Logik, die kein integrierter Knoten abdeckt.
  • Prüfe die Ereignisreferenz für ausführliche Nutzdatendokumentation aller Plattformen.

Diese Anleitung ist bewusst eigenständig — kopiere sie lokal, passe sie für dein Team an und experimentiere weiter im Editor.

9. Eigenes JavaScript Nur SSApp / Desktop

Zwei Knoten im Event-Flow-Editor erlauben beliebiges JavaScript innerhalb der Flow-Verarbeitung: Eigener Code (Auslöser) und Eigenen Code ausführen (Aktion). Sie sind der Ausweg für alles, was die integrierten Knoten nicht ausdrücken können.

Desktop-App erforderlich. Eigene JavaScript-Knoten sind in der Browser-Erweiterung deaktiviert, weil folgende Aufrufe von Chromes Manifest-V3-Content-Security-Policy blockiert werden: new Function() / eval(). Öffne den Editor über die SSApp-Desktop-App zum Aktivieren. Im Erweiterungsmodus erscheinen die Knoten ausgegraut mit der Beschriftung „Nur Desktop“.
Code bearbeiten: wähle einen Custom-Code-Knoten und klicke auf Codeeditor öffnen für ein großes Bearbeitungsfenster. Speichern und schließen prüft die JavaScript-Syntax und speichert den gesamten Flow; Ctrl+S oder Cmd+S macht dasselbe. Abbrechen lässt den Knoten unverändert.
Event-Flow-Editor — leerer Zustand
Der Event-Flow-Editor. Links stehen alle verfügbaren Knoten; auf der gepunkteten Arbeitsfläche erstellst du Flows; rechts stehen Eigenschaften des ausgewählten Knotens.

Custom Code — Auslöserknoten

Ziehe Eigener Code aus der Gruppe Erweitert im Bereich Auslöser auf die Arbeitsfläche. Er dient als Gate: Der Flow läuft nur bei folgendem Rückgabewert deines Codes weiter: true.

Auslöserbereich mit Custom-Code-Knoten in der Gruppe Advanced
Custom Code befindet sich in der Gruppe Erweitert im Auslöserbereich.
Eigenschaftsbereich des Custom-Code-Auslösers mit JavaScript-Editor
Eigenschaftsbereich nach dem Platzieren des Auslösers. Schreibe einen Ausdruck mit dem Rückgabewert true oder false.
Signatur: dein Code läuft als function(message) { ... }
Muss zurückgeben: einen booleschen Wert — true um den Flow fortzusetzen, false um ihn zu stoppen.
Verfügbar: das Objekt message (siehe Nachrichten-API unten) sowie convertCurrency(value, targetCurrency, source) und convertToUSD(value, source).

Execute Custom Code — Aktionsknoten

Ziehe Eigenen Code ausführen aus der Gruppe Integrationen im Bereich Aktionen . Er kann die Nachricht verändern, blockieren oder Metadaten für nachgelagerte Knoten anhängen.

Aktionsbereich mit Execute Custom Code in der Gruppe Integrations
Execute Custom Code in der Gruppe Integrationen im Aktionsbereich.
Eigenschaftsbereich der Execute-Custom-Code-Aktion mit Codeeditor
Aktionseigenschaften. Gib ein Objekt zurück, um Änderungen in das Flow-Ergebnis zu übernehmen.
Signatur: dein Code läuft als function(message, result) { ... }
Sollte zurückgeben: ein Objekt oder Promise zur Übernahme in result— siehe Ergebnis-API.
Verfügbar: message (die Ereignisnutzdaten), result (aktueller Flow-Ergebniszustand), printThermal(html, options), plus convertCurrency(value, targetCurrency, source) und convertToUSD(value, source).
Thermodruck in SSApp: wähle den Drucker und kalibriere Papierbreite und Sicherheitsränder unter Druckersteuerung, und liefere anschließend als Rückgabewert printThermal('<strong>' + message.chatname + '</strong>'). SSApp reiht den Auftrag ohne Dialog über die native Windows-Drucker-API ein und verwendet diese gespeicherten Einstellungen. Ein Flow kann sie mit Optionen überschreiben, etwa { width: '58mm', marginLeft: '3mm', marginRight: '3mm', marginTop: '2mm', marginBottom: '2mm', feed: '3mm', marginType: 'printableArea' }. Durch Rückgabe des Promise kann Event Flow auf die Übermittlung warten und Fehler melden.
Arbeitsfläche mit einem Custom-Code-Auslöser und einer Execute-Custom-Code-Aktion nebeneinander
Ein Custom-Code-Auslöser (blau) und eine Execute-Custom-Code-Aktion (grün) auf der Arbeitsfläche. Verbinde den Ausgang des Auslösers mit dem Eingang der Aktion.

Das Objekt message

Beide Knoten erhalten die vollständigen Ereignisnutzdaten als message. Die folgenden Felder sind immer verfügbar; plattformspezifische Ereignisse können zusätzliche enthalten.

FeldDatentypBeschreibungBeispiel
message.chatmessageZeichenfolgeDer Chatnachrichtentext (kann HTML enthalten)"Hello stream!"
message.chatnameZeichenfolgeAnzeigename des Absenders"CoolViewer"
message.useridZeichenfolgePlattform-Nutzer-ID"12345678"
message.typeZeichenfolgeQuellplattform (Kleinbuchstaben)"twitch", "youtube", "kick"
message.hasDonationZeichenfolgeFormatierte Spendenzeichenfolge, falls vorhanden"$5.00", "500 bits"
message.donoValueZahl / ZeichenfolgeSpendenwert in USD, wenn die Quelle ihn liefert; gültige Nullwerte werden berücksichtigt. Event Flow verwendet ersatzweise die currency.js Umrechnung normalisierter hasDonation Bezeichnungen für Schwellenvergleiche, einschließlich 100 unbekannter benannter Einheiten = 0,01 USD. Es wertet keine chatmessage Fließtexte für Spendenwerte aus.5
message.eventZeichenfolgeEreignistyp-Kennung"new_follower", "cheer", "raid"
message.membershipZeichenfolgeMitgliedschaftsstatus, falls zutreffend"MEMBERSHIP"
message.subtitleZeichenfolgeZusätzliche Kontextzeile"Member for 3 months"
message.modbooleschAbsender ist Moderatortrue
message.subscriberbooleschAbsender ist Abonnenttrue
message.vipbooleschAbsender hat VIP-Statustrue
message.chatimgZeichenfolgeNutzer-Avatar-URL"https://..."
message.metaObjektBeliebige strukturierte Daten am Ereignis{ viewers: 120 }
Währungsumrechnung: verwende convertCurrency(message.hasDonation, 'EUR', message.type) zum Umrechnen der formatierten Spendenbezeichnung in EUR. Sie gibt eine Zahl oder null zurück, wenn die gewünschte Zielwährung nicht unterstützt wird. Der Konverter verwendet die ungefähren internen Kurse von Social Stream Ninja; er kontaktiert keinen externen Wechselkursdienst.

Was die Aktion zurückgibt

Gib aus deinem Aktionscode ein einfaches Objekt zurück. Alle enthaltenen Felder werden in das result Objekt übernommen; ausgelassene Felder behalten ihre aktuellen Werte.

RückgabefeldDatentypWirkung
modifiedbooleschSetze true bei geänderten Feldern in message . Teilt nachgelagerten Knoten mit, dass die Nutzdaten bearbeitet wurden.
messageObjektGib die (möglicherweise veränderte) Nachricht zurück, damit nachgelagerte Knoten deine Änderungen erhalten.
blockedbooleschSetze true um die Anzeige oder Weiterleitung der Nachricht zu verhindern.
Minimale sichere Rückgabe: return { modified: false, message };
Auch wenn du nichts geändert hast, sorgt die Rückgabe von message dafür, dass die Nachricht zum nächsten Knoten weiterläuft.

Codebeispiele

Kopiere eines dieser Beispiele in das JavaScript-Code-Textfeld des passenden Knotentyps.

Auslöserbeispiele — liefere als Rückgabewert true um den Flow fortzusetzen

Schlüsselworttreffer (ohne Beachtung der Groß-/Kleinschreibung)
Setze den Flow nur fort, wenn die Nachricht ein bestimmtes Wort oder einen Ausdruck enthält.
// Matches "!hello" anywhere in the message return (message.chatmessage || '').toLowerCase().includes('!hello');
Befehlserkennung mit Regex
Erkenne Nachrichten, die mit einem Befehl aus einer festgelegten Liste beginnen (z. B. !queue, !raffle, !enter).
return /^!(queue|raffle|enter)\b/i.test(message.chatmessage || '');
Spende über einem Schwellenwert
Nur auslösen, wenn eine Spende einen Mindestbetrag erreicht oder überschreitet.
const amount = message.donoValue !== undefined && message.donoValue !== null && message.donoValue !== '' ? Number(message.donoValue) : (typeof convertToUSD === 'function' ? convertToUSD(message.hasDonation || '', message.type || '') : Number(String(message.hasDonation || '').replace(/[^0-9.]/g, '') || 0)); return amount >= 5;
YouTube Super Chat oder Super Sticker in einem EUR-Bereich
Rechne die normale YouTube-Spendenbezeichnung in EUR um, schließe Jewels/Gifts aus und wähle einen Sound- oder Darstellungsbereich.
var eventName = String(message.event || '').toLowerCase(); if (eventName !== 'superchat' && eventName !== 'supersticker') return false; var eurValue = convertCurrency(message.hasDonation || '', 'EUR', message.type || ''); if (typeof eurValue !== 'number' || !isFinite(eurValue)) return false; message.eurValue = eurValue; return eurValue >= 10 && eurValue < 25;
Plattformfilter
Nur Ereignisse bestimmter Plattformen verarbeiten.
return ['twitch', 'youtube'].includes(message.type);
Gate für Abonnenten / VIPs / Moderatoren
Lasse den Flow nur für berechtigte Nutzer fortfahren.
return !!(message.subscriber || message.vip || message.mod);
Mehrfachbedingung — VIP + Schlüsselwort
Kombiniere Rollenprüfung und Nachrichteninhalt in einem einzigen Ausdruck, den kein integrierter Auslöser abdeckt.
const isPrivileged = !!(message.subscriber || message.vip || message.mod); const isCommand = /^!feature\b/i.test(message.chatmessage || ''); return isPrivileged && isCommand;
Gate für Nachrichtenlänge
Nur Nachrichten mit ausreichend Inhalt verarbeiten (nützlich für TTS oder Relay gegen Spam aus einzelnen Emojis).
return (message.chatmessage || '').replace(/<[^>]+>/g, '').trim().length >= 20;

Aktionsbeispiele — liefere als Rückgabewert { modified, message }

Ein Abzeichen oder Tag an die Nachricht anhängen
Füge am Ende jeder Nachricht, die diese Aktion durchläuft, einen visuellen Hinweis hinzu.
message.chatmessage = (message.chatmessage || '').trimEnd() + ' ✅'; return { modified: true, message };
Nachricht bedingt blockieren
Prüfe den Inhalt und verwerfe die Nachricht still, wenn eine Regel zutrifft — nützlich für Spammuster, die der Schlüsselwortfilter nicht ausdrücken kann.
const text = (message.chatmessage || '').toLowerCase(); const spamPatterns = ['buy followers', 'free nitro', 'click here']; if (spamPatterns.some(p => text.includes(p))) { return { blocked: true, message }; } return { modified: false, message };
@Erwähnungen entfernen
Entferne vor der Weiterleitung an eine andere Plattform alle @username-Erwähnungen aus einer Nachricht.
message.chatmessage = (message.chatmessage || '').replace(/@\w+/g, '').trim(); return { modified: true, message };
Eine Spendenankündigung formatieren
Schreibe chatmessage bei einer Spende in eine einheitliche Ankündigungszeichenfolge um.
const amount = parseFloat(message.donoValue || 0); if (amount > 0) { const note = (message.chatmessage || '').trim(); message.chatmessage = `💰 ${message.chatname} donated $${amount.toFixed(2)}!` + (note ? ` "${note}"` : ''); return { modified: true, message }; } return { modified: false, message };
Weiterleitungsmetadaten für nachgelagerte Knoten anhängen
Markiere die Nachricht mit einem eigenen Feld, das eine spätere Chat weiterleiten (Relay Chat) oder Nachricht senden Aktion über eine Vorlagenvariable lesen kann ({meta}).
message.meta = message.meta || {}; // Assign a donation tier so the next node can use {meta} to decide overlay colour const amount = parseFloat(message.donoValue || 0); message.meta.donationTier = amount >= 20 ? 'gold' : amount >= 5 ? 'silver' : 'bronze'; return { modified: true, message };
Nachrichtenpräfix mit Plattformbezug
Stelle beim plattformübergreifenden Weiterleiten eine Plattformbezeichnung voran, damit Zuschauer die Quelle kennen.
const labels = { twitch: '[Twitch]', youtube: '[YouTube]', kick: '[Kick]', tiktok: '[TikTok]', }; const label = labels[message.type] || `[${message.type || 'Chat'}]`; message.chatmessage = `${label} ${message.chatname}: ${message.chatmessage || ''}`; return { modified: true, message };

Vollständiges Beispiel — Bot für VIP-Funktionswünsche

Dieser Flow wartet auf !feature <text> von Abonnenten, VIPs oder Moderatoren, formatiert sie als Funktionswunsch und leitet sie an ein zweites Ziel (z. B. Discord) weiter.

┌──────────────────────┐ ┌──────────────────────────┐ ┌──────────────────┐ │ Custom-Code-Auslöser │────▶│ Eigene Codeaktion ausführen│────▶│ Chat weiterleiten │ │ │ │ │ │ (an Discord) │ │ Gate: VIP/Abo/Mod │ │ Nachrichtentext umformatieren │ │ │ │ + beginnt mit │ │ → "📋 Funktionswunsch │ │ │ │ !feature │ │ von {name}: {text}" │ │ │ └──────────────────────┘ └──────────────────────────┘ └──────────────────┘

Schritt 1 — Custom-Code-Auslöser (in das Feld JavaScript Code des Auslösers einfügen):

// Only let VIPs, subscribers, and mods through, and only for !feature commands const isPrivileged = !!(message.subscriber || message.vip || message.mod); const isCommand = /^!feature\b/i.test((message.chatmessage || '').trim()); return isPrivileged && isCommand;

Schritt 2 — Execute-Custom-Code-Aktion (in das Feld JavaScript Code der Aktion einfügen):

// Strip the "!feature" command word and format a clean announcement const featureText = (message.chatmessage || '') .replace(/^!feature\s*/i, '') .trim(); if (!featureText) { // No text after the command: block rather than relay an empty request return { blocked: true, message }; } message.chatmessage = `📋 Feature request from ${message.chatname}: ${featureText}`; return { modified: true, message };

Schritt 3 — Relay-Chat-Aktion: Füge nach der Aktion einen normalen Relay-Chat-Knoten hinzu und konfiguriere ihn für dein Discord-Ziel (oder ein anderes). Hier ist kein eigener Code erforderlich — der umformatierte Wert von message.chatmessage läuft automatisch durch.

Den Flow testen. Klicke auf diese Schaltfläche: Flow testen (oben rechts im Editor), um eine künstliche Nachricht ohne Livestream durch die Verarbeitung zu senden. Setze chatname auf einen Abonnenten und ergänze eine Nachricht wie !feature dark mode support, und prüfe, ob das Relay-Chat-Ziel die umformatierte Zeichenfolge empfängt.
Der Test-Flow-Bereich zum Senden künstlicher Testereignisse
Der Test-Flow-Bereich. Fülle die Felder passend zu deinen Auslösebedingungen aus und klicke auf Test ausführen um die gesamte Verarbeitung zu prüfen.

Sicherheitsaspekte

Eigener Code läuft mit den Rechten des Renderer-Prozesses. In SSApp hat Code in Custom-JS-Knoten vollen Zugriff auf das window Objekt und alle vom Preload-Skript bereitgestellten APIs (z. B. window.ninjafy). Behandle importierte Flow-Dateien wie ausführbaren Code — importiere nur Flows aus vertrauenswürdigen Quellen.
  • Keine Netzwerk-Sandbox. Aktionscode unterstützt Aufrufe von fetch(). Wenn du geteilte Flows von anderen übernimmst, prüfe vor der Aktivierung das JavaScript.
  • Fehler werden abgefangen. Ein Laufzeitfehler in deinem Code gibt false (Auslöser) oder eine wirkungslose Aktion zurück und protokolliert in der DevTools-Konsole — der Flow stürzt nicht ab.
  • Auch Syntaxfehler. Ein Fehler vom Typ SyntaxError beim Kompilieren wird genauso abgefangen. Prüfe DevTools (F12), wenn ein Knoten scheinbar nichts tut.