Système Event Flow

Guide de l’éditeur Event Flow

Créez des automatisations fiables pour Social Stream Ninja. Ce guide présente les bases, les nœuds logiques, la circulation des signaux et les astuces pratiques les plus demandées, comme éviter les échos et savoir quand combiner AND/NOT.

Français

0. Repères rapides

Event Flow est un éditeur par nœuds. Chaque liaison transporte les données d’un message et un état booléen (true = continuer, false = arrêter). Utilisez sources pour injecter des événements, nœuds logiques pour les décisions de filtrage, et actions pour effectuer des actions : envoyer du chat, contrôler des incrustations, relayer des messages, etc.
Vous souhaitez mémoriser des participants, vérifier ensuite leur admissibilité, tirer un utilisateur unique au sort ou vider une liste nommée ? Ouvrez le Guide User Memory pour le modèle d’état partagé, les captures et un exemple importable.

Qu’est-ce que cet éditeur ?

L’éditeur Event Flow est l’outil d’automatisation avancée de Social Stream Ninja. Il complète les options simples du panneau et permet de définir votre propre logique de routage. Utilisez-le pour :

  • Relayez le chat entre services avec des filtres, par exemple de Twitch vers Discord en bloquant les commandes.
  • Créez des commandes de fidélité, jeux de mots-clés ou conditions de tombola avec la logique AND/OR/NOT.
  • Déclenchez des incrustations, sons, scènes OBS ou webhooks à partir de données enrichies dans le flux.
  • Combinez plusieurs plateformes dans une même automatisation : Kick, Twitch et YouTube acheminés dans un seul flux.

Le panneau propose des préréglages rapides ; Event Flow fournit les outils pour des flux personnalisés.

Démarrage et bases

  • Ouvrez l’éditeur Event Flow depuis le menu du tableau de bord principal, dans l’application ou l’extension.
  • Chaque projet est enregistré localement jusqu’à son exportation. Utilisez Export pour sauvegarder ou partager.
  • Travaillez dans des canevas appelés flux. Chaque flux peut s’abonner à plusieurs plateformes à la fois.

Aperçu des nœuds

  • Entrées (ports de gauche) attendent le contexte du message.
  • Sorties (ports de droite) émettent le même contexte avec les éventuelles modifications.
  • Les nœuds logiques peuvent émettre le canal true et un canal facultatif false .

Structure des données

Chaque message contient un objet JSON. Les clés obligatoires suivent docs/event-reference.html (platform, type, chatname, chatmessage, etc.). Placez les données personnalisées dans meta.

Chaque flux commence par un déclencheur

Les nœuds d’action verts ne s’exécutent jamais seuls : ils se déclenchent uniquement lorsqu’un nœud déclencheur bleu en amont renvoie true. Un flux composé uniquement d’actions enchaînées semble valide mais reste inactif, car rien ne démarre la chaîne. Les noms des nœuds décrivent ce qu’ils font, pas le moment où cela se produit : Mettre un message en avant (Feature Message) met un message en avant lorsque le flux l’atteint ; il ne se déclenche pas lorsque vous mettez un message en avant ailleurs.

Deux nœuds d’action enchaînés sans déclencheur
❌ Ne s’exécute jamais. Feature Message et Speak Text sont tous deux des actions; sans déclencheur en amont, rien ne démarre la chaîne.
Déclencheur Any Message relié aux actions Feature Message et Speak Text
✅ Fonctionne. Un déclencheur Tout message (Any Message) , ou Message Contains, une expression régulière, un événement de don, etc., démarre la chaîne ; les deux actions s’exécutent pour chaque message correspondant.

Incrustation Flow Actions, sortie des actions

Commencez par un modèle d’alerte :

Choisir Don : célébration et voix pour une animation et un extrait de remerciement synthétique prêts à l’emploi, ou le modèle avancé Don : animation, son et filtre OBS . Les nouveaux modèles d’alertes sont désactivés au départ pour permettre leur configuration et test. Pour le modèle OBS, choisissez une source et le même filtre normalement désactivé dans les deux actions de filtre.

Lire un extrait audio (Play Audio Clip) et Multi Alerts partagent désormais une bibliothèque de 17 sons : applaudissements, roulement de tambour, souffle, caisse enregistreuse et autres effets, quatre phrases anglaises synthétiques libellées et des sons simples. Écouter / Arrêter prévisualise localement avec un état de lecture visible. Vous pouvez toujours téléverser un enregistrement ou choisir un fichier local de l’application. Pour des noms ou messages variables, utilisez l’action existante Prononcer du texte (Speak Text) .

Event Flow joue les sons via la source Navigateur Flow Actions ; Multi Alerts utilise sa propre source Navigateur. Pour un même événement, activez le son dans une seule des deux pour éviter les doublons. Utilisez Tab pour atteindre un nœud, puis Entrée ou Espace pour modifier ses propriétés.

Les nœuds comme Lire un extrait audio (Play Audio Clip), Afficher une incrustation multimédia (Display Media Overlay), ainsi que les contrôles OBS, ont besoin d’une interface de rendu. Il s’agit de la page d’incrustation Flow Actions servie depuis actions.html. Gardez-la ouverte dans votre logiciel de diffusion, OBS, docks de navigateur Streamer.bot, etc., pour que les actions Event Flow puissent s’afficher.

Déclencheur Any Message relié à une action Play Audio Clip
Ce flux est complet et se déclenche à chaque message, mais le son est joué sur la page d’incrustation Flow Actions, pas dans l’éditeur. Le bouton Aperçu de l’éditeur lance la lecture localement ; la lecture en direct nécessite que l’incrustation soit ouverte. Si le navigateur bloque la lecture automatique, cliquez sur Activer le son sur la page Flow Actions pour réessayer le dernier extrait bloqué. Cliquer ailleurs sur la page active aussi la lecture. Une source Navigateur OBS autorise normalement la lecture automatique.
Pour l’ouvrir depuis le panneau/tableau de bord :
  1. Ouvrez le panneau principal Social Stream Ninja (la fenêtre chargée depuis popup.html ou via l’icône de l’extension).
  2. Faites défiler jusqu’à la carte « Flow Actions ». Utilisez le bouton [copier le lien] ou cliquez sur l’URL dans la carte.
  3. Le lien ressemble à https://socialstream.ninja/actions.html?session=YOURSESSION. Collez-le dans une source Navigateur OBS, idéalement 1920×1080, ou ouvrez-le dans un navigateur d’incrustation.
Utiliser des médias locaux dans l’application autonome :
  1. Dans une action Play Audio Clip ou Display Media Overlay, cliquez sur Choisir un fichier local (Choose Local File).
  2. Cliquez sur Copier l'URL locale Flow Actions pour OBS (Copy Local Flow Actions URL for OBS) et utilisez cette URL localhost générée à la place de l’URL Flow Actions hébergée.
  3. Gardez SSApp ouvert. Si un fichier sélectionné est déplacé, revenez à l’action et cliquez sur Réassocier (Relink).

L’extension Chrome ne peut pas servir seule les fichiers du disque. Utilisez Upload ou une URL hébergée sans application de bureau compagnon. Consultez le guide des fichiers médias pour Event Flow pour la configuration complète.

Une fois chargée, cette incrustation peut :

  • Afficher des médias GIPHY ou provenant d’URL directes, du texte et des confettis déclenchés par vos flux.
  • Lire localement des sons, synthèse vocale ou extraits, pour que les spectateurs les entendent.
  • Communiquer avec OBS via les paramètres WebSocket de la section Flow Actions du panneau : changement de scène, visibilité des sources, textes GDI+/FreeType, tampon de relecture, etc.
Modes de contrôle OBS :
  • API de source Navigateur : disponible uniquement lorsque actions.html s’exécute dans une source Navigateur OBS avec Niveau d’accès avancé (Advanced Access Level). Le changement de scène y fonctionne ; les actions d’enregistrement, de diffusion et de tampon de relecture peuvent l’utiliser en repli.
  • OBS WebSocket : recommandé pour un contrôle cohérent. Flow Actions utilise l’API OBS WebSocket v5 d’OBS 28+ et attend les requêtes modernes sur le port 4455.
  • Mot de passe : facultatif. Ajoutez uniquement &obspw=... à l’URL Flow Actions si votre serveur OBS exige une authentification.
  • Diagnostics de l’incrustation : ajouter &obsdebug=1 à l’URL de actions.html si vous souhaitez un petit badge de connexion OBS sur l’incrustation pendant le dépannage.
  • Set Text Source : met directement à jour les entrées Texte (GDI+) et Texte (FreeType 2) d’OBS et accepte les variables de modèle Event Flow telles que {counterValue} et {counterTarget}.
  • Anciennes installations 4.x : si vous utilisez encore obs-websocket 4.x / le port 4444, les actions de source, filtre, son muet et texte ne fonctionneront pas avant la mise à jour d’OBS / obs-websocket.

Consultez le guide dédié Guide de contrôle OBS pour tous les déclencheurs, actions, étapes de configuration et recettes testées.

Parcours de diagnostic recommandé :
  1. Ouvrir obs-websocket-test.html.
  2. Vérifiez que GetVersion, GetCurrentProgramScene, et GetSceneList réussissent.
  3. Effectuez-y la vérification de l’action correspondante avant de tester toute l’automatisation Event Flow.
Gardez l’incrustation ouverte. Fermer la page Flow Actions suspend toutes les actions d’incrustation, audio et OBS d’Event Flow. Masquez-la ou placez-la sur un autre écran au lieu de la fermer.

1. Que traverse un nœud ?

L’environnement Event Flow transmet deux éléments dans chaque liaison :

  1. Données – l’objet de données de l’événement ou du message.
  2. Signal de porte – un bit true/false indiquant au nœud suivant s’il doit s’exécuter.
Si un nœud renvoie false : les nœuds suivants cessent de s’exécuter sauf s’ils reçoivent une entrée d’une autre branche (par exemple la sortie false d’un nœud Condition). Cela permet de créer facilement une logique de repli sans dupliquer tout le flux.

Entrées attendues

  • Sources d’événements (Twitch Message, Timers, Manual Trigger, etc.) ignorent l’entrée en amont : ils génèrent leurs propres données et émettent toujours true sauf erreur dans le nœud lui-même.
  • Nœuds de transformation et de logique lisent les données et peuvent réécrire des champs, définir un état ou modifier le signal de porte en false.
  • Nœuds d’action ne se déclenchent que si la porte reste true. Ils peuvent aussi produire des données modifiées si vous souhaitez enchaîner d’autres actions.

Modèles de sortie

Sortie unique

La plupart des nœuds possèdent une seule sortie. Ce qui entre, données et signal de porte, ressort inchangé sauf modification par le nœud.

Sorties true/false

Les nœuds Condition, Compare, Regex et Logic possèdent deux sorties. Vrai continue par le port vert ; false est disponible sur le port gris/rouge.

Transmission ou remplacement

Certains nœuds, Set Variable, Math ou Text Replace, modifient les données tout en transmettant l’état true/false de leur entrée. D’autres, NOT, AND et OR, recalculent eux-mêmes le booléen.

2. Aide-mémoire des nœuds logiques

Ces blocs répondent aux questions courantes sur la signification de true/false.

NOT

  • Entrées : 1 booléen, true/false, dérivé du nœud précédent.
  • Sorties : booléen inversé et données inchangées.
  • Comportement par défaut : Si rien n’est relié à l’entrée de NOT, il évalue false, la sortie est donc true.
Exemple : Placez NOT après « Contains Keyword » pour déclencher une alerte lorsqu’un spectateur n’utilise pas le mot-clé.

AND

  • Entrées : au moins deux signaux booléens, A, B, etc. Vous pouvez laisser les ports supplémentaires vides.
  • Sorties : true uniquement si toutes les entrées connectées valent true.
  • Utilisez AND si plusieurs conditions doivent être remplies simultanément (« est abonné » et « le message de chat contient !raffle »).

OR

  • Renvoie true si n’importe quelle entrée connectée est true.
  • Utile pour les déclencheurs multiplateformes : reliez Twitch et YouTube à un même OR, puis utilisez une action commune en aval.
Ai-je toujours besoin d’un nœud AND ?
Non. De nombreux nœuds proposent déjà des filtres combinés, par exemple « Filter User Level » et « Contains Text ». Utilisez AND uniquement si les options intégrées ne couvrent pas votre combinaison, ou pour créer une jonction logique réutilisable par d’autres branches.
NOT et entrées vides : Un nœud NOT non relié produit tout de même true. Gardez-le relié à un élément pertinent ou désactivez-le pour qu’il ne débloque pas accidentellement un flux.

3. Exemples de petits flux

A. Répondre automatiquement sauf aux commandes

Message Twitch ──▶ Regex Match "^!" ─┐ │ ├─false──▶ Réponse automatique (« Merci de participer ! ») │ └─true──▶ Ne rien faire

Ici, le nœud Regex émet true lorsque le message est une commande. Nous relions la sortie false à la réponse ; les participants ordinaires reçoivent donc un accusé, tandis que les commandes passent simplement.

B. Exiger plusieurs vérifications avec AND

Message YouTube ──▶ Contient "!queue" ─▶ AND ─▶ Relayer vers Discord Adhésion offerte ─▶ Rôle utilisateur = Membre ──▲

Le nœud AND assure que seuls les membres utilisant le bon mot-clé sont relayés vers Discord. Les deux branches envoient leur booléen à AND ; les données de la première branche sont transmises en aval.

C. Utiliser NOT pour bloquer les alertes répétées

Données d’événement ─▶ Vérification d’état (isAlertMuted) └─false─▶ NOT ─▶ Lancer la célébration

State Check renvoie la valeur true lorsque l’alerte est muette. En inversant le résultat, NOT garantit que la célébration n’est jouée que lorsque l’indicateur est false.

D. Lire au hasard l’un de deux sons

Flux utilisant des portes RANDOM, NOT et AND pour lire aléatoirement l’un de deux extraits audio
Un tirage à 50/50 entre deux extraits audio. La porte RANDOM effectue un tirage par message correspondant : en cas de réussite, le son A est lu ; sinon, NOT inverse le résultat et AND laisse jouer le son B.
Déclencheur ──▶ RANDOM (50 %) ──▶ Lire le son A │ └──▶ NOT ──▶ AND ──▶ Lire le son B Déclencheur ──────────────────▲

La porte AND est indispensable. Un NOT isolé produirait true chaque fois que RANDOM est inactif ; le son B serait donc joué pour tout message qui ne correspond pas au déclencheur. Relier aussi le déclencheur à AND comme seconde entrée limite le son B aux messages correspondants. Ce schéma convient à toute paire d’actions alternatives, pas seulement au son.

4. Éviter les échos, boucles et retours de relais

Le relais entre interfaces est puissant, mais peut créer un écho infini si vous écoutez votre propre sortie. Suivez ces précautions :

Note sur la destination YouTube Shorts :
Les déclencheurs entrants et les destinations sortantes de Relay Chat font tous deux la distinction entre youtube et youtubeshorts. Utilisez deux actions de relais si un message doit atteindre les deux variantes. Consultez YouTube Shorts et Event Flow.
Relay Chat ignore automatiquement les reflets reconnus.
Un reflet est un message sortant capturé à nouveau depuis un chat de destination. Les actions Relay Chat actuelles ignorent les reflets reconnus ; il n’existe pas de case No Reflections distincte. Pour masquer ou limiter leur affichage dans le dock et les incrustations, utilisez un Filtre d’échos (Reflection Filter) avec Tout bloquer (Block All), Autoriser le premier (Allow First), ou Tout autoriser (Allow All). Cela contrôle l’affichage lors de la réception à nouveau, pas l’envoi. Suivez le Guide du relais Twitch et YouTube pour une configuration complète.
  • Évitez les systèmes de relais en double. Désactivez Relay all global lorsque vous utilisez des routes Event Flow équivalentes et recherchez d’autres services reliant les mêmes chats. Les métadonnées personnalisées ne sont pas garanties après un passage par un chat de plateforme.
  • Utilisez des nœuds Debounce ou Cooldown pour les alertes devant se déclencher au plus une fois toutes les X secondes.
  • Rompez les boucles volontairement. Si deux branches s’alimentent mutuellement, ajoutez un nœud logique vérifiant une variable d’état « currentlyRelaying » pour arrêter tôt le flux lorsque cet indicateur est actif.

5. Entrées, sorties et questions pratiques

Qu’est-ce qui entre dans un nœud ?

  • Données complètes du message.
  • Le booléen de porte (true/false).
  • Contexte facultatif, variables d’état ou minuteurs, explicitement demandé par le nœud.

Qu’est-ce qui sort d’un nœud ?

  • Les mêmes données, sauf modification par le nœud.
  • Un booléen recalculé par les nœuds logiques ou transmis par les actions.
  • La plupart des effets, comme l’envoi de messages, ne modifient pas les données, mais les actions de points peuvent ajouter des champs d’état comme pointsTotal ou pointsSpendError pour la logique en aval.

Quand créer une branche ?

Chaque fois que vous souhaitez réagir différemment à true et false. Reliez la sortie colorée souhaitée au nœud suivant : vert = true, gris/rouge = false.

Rappel : Si vous n’utilisez pas une sortie false , le flux s’arrête simplement là. C’est idéal pour les filtres qui bloquent tout échec, mais pensez à relier le chemin false si vous avez besoin de solutions de repli.

Questions fréquentes

  • Dois-je utiliser AND pour chaque paire de filtres ? Non. De nombreux nœuds intègrent plusieurs vérifications ; le filtre de message de base combine par exemple mot-clé et rôle. Utilisez AND pour des combinaisons avancées ou pour réunir des signaux de nœuds différents.
  • Comment les valeurs true/false arrivent-elles au nœud NOT ? Tout nœud avec une sortie verte émet true par défaut. Si une condition échoue, il émet false. Reliez ce fil à NOT pour inverser le résultat.
  • Un nœud peut-il émettre des données tout en renvoyant false ? Oui. Les données passent toujours par la sortie false ; vous décidez de la destination de cette branche.
  • Comment reconnaître les membres d’équipe TikTok ? Choisir Membre d’équipe TikTok (TikTok Team Member) dans le nœud User Role. Il reconnaît les niveaux et badges TikTok Fan Club/équipe du message entrant, indépendamment des réglages de Main Chat Overlay.
  • Chaque nœud Speak Text peut-il utiliser une voix différente ? Oui. Saisissez un nom ou identifiant de voix pris en charge par le fournisseur dans Remplacement de voix (Voice Override), ou laissez vide pour utiliser la voix par défaut de Flow Actions.

6. Référence des variables de modèle

Plusieurs nœuds d’action, Show Text, Set Text Source, Send Message, Relay Chat, TTS Speak, Call Webhook et Print Thermal Label, acceptent des variables de modèle remplacées par les données de l’événement à l’exécution. Entourez les noms de variables d’accolades, comme {username}.

Variables principales, rétrocompatibles

VariableAliasDescriptionExemple
{username}{chatname}Nom d’affichage de l’utilisateurCoolViewer123
{message}{chatmessage}Texte du message de chatBonjour tout le monde !
{source}-Nom de plateforme avec majusculeTwitch, YouTube
{type}-Nom brut de plateformetwitch, youtube
{donation}{hasDonation}Libellé d’affichage du don/pourboire$5.00, 500 bits

Variables étendues

VariableDescriptionExemple
{displayname}Nom d’affichage, champ alternatifCoolViewer123
{donoValue}Équivalent du don en USD, fourni ou estimé ; Event Flow déduit les seuils des données normalisées hasDonation sous forme de valeur, $valeur avec unité ou unité/valeur compacte. Les unités virtuelles nommées inconnues utilisent 100 unités = $0.01 USD ; les cadeaux TikTok sans prix utilisent une pièce par cadeau, soit $0.01 chacun. {donationAmount} est un ancien alias5.00
{event}Identifiant du type d’événementcheer, raid, new_follower
{membership}Statut d’adhésionMEMBERSHIP, new_sponsor
{subtitle}Contexte supplémentaireMembre depuis 3 mois
{userid}Identifiant de l’utilisateur sur la plateforme12345678
{chatimg}URL de l’avatar utilisateurhttps://...
{contentimg}URL de l’image jointehttps://...
{rewardTitle}Nom de la récompense lorsque la source expose un champ de titre de récompense au premier niveauMettre mon message en avant
{meta}Données structurées de l’événement, JSON{"viewers":100}
{counterValue}Valeur actuelle du compteur après une étape Counter ou Check Counter12
{counterTarget}Valeur cible du compteur30
{counterRemaining}Cible du compteur moins sa valeur actuelle, avec un minimum de 018
La reconnaissance des variables est insensible à la casse. {USERNAME}, {Username}, et {username} fonctionnent tous de la même façon.
Les champs ajoutés par le flux fonctionnent aussi. Si une action précédente ajoute une valeur de premier niveau au message, les modèles suivants peuvent la lire directement. C’est ainsi que Check Counter expose {counterValue}, {counterTarget}, et {counterRemaining}.
JSON de Call Webhook : Les variables de modèle fonctionnent dans les valeurs de chaîne JSON, à toute profondeur d’objet ou de tableau. Les clés d’objet ne sont pas interprétées et un corps personnalisé sans variables est envoyé inchangé.

Modèles d’exemple

  • Show Text : {username} just cheered {hasDonation}!
  • Set OBS Text Source : {username}: now {counterValue}, need {counterTarget}
  • Relay Chat : [{source}] {username}: {message}
  • Synthèse vocale : {username} says {message}
  • Alerte de don : {username} donated {donation} - {subtitle}
  • Étiquette thermique : {username}, une nouvelle ligne, puis {donation}. Consultez le Guide des imprimantes thermiques pour la configuration de l’imprimante, les étiquettes de taille fixe et un flux complet.
  • Call Webhook Discord : {"content":"{message}","username":"{username}","avatar_url":"{chatimg}"}
Les variables absentes deviennent des chaînes vides. Si un événement ne possède pas un champ donné (par exemple {donation} sur un message ordinaire), la variable est remplacée par une chaîne vide au lieu d’afficher littéralement {donation} .

7. Liste de bonnes pratiques

  • Nommez et colorez vos nœuds pour reconnaître chaque branche plus tard.
  • Testez avec le simulateur intégré (Send Test Event) avant d’activer un flux en direct.
  • Regroupez la logique près de la source. Filtrez le plus tôt possible pour éviter des traitements inutiles en aval.
  • Conservez les répétitions dans des nœuds d’état. Utilisez des compteurs, interrupteurs et horodatages pour éviter les doubles alertes.
  • Documentez les champs meta. Lorsque vous ajoutez des clés meta personnalisées, documentez-les pour garder les incrustations et clients distants cohérents.
Enregistrez des versions. Exportez le flux à chaque étape importante. Réimporter est le moyen le plus simple de retrouver une configuration fonctionnelle après un essai infructueux.

8. Pour aller plus loin

Exécuter des flux personnalisés depuis Stream Deck ou l’API: déclencheurs nommés, modèle de départ, découverte des flux, données supplémentaires, exemples HTTP/WebSocket/P2P et gestes de molette.

Vous souhaitez approfondir ?

  • Utilisez Nœuds d’état (compteurs, interrupteurs, minuteurs) pour conserver le contexte entre les événements.
  • Combinez Variables et logique pour créer des files d’attente, tombolas ou systèmes de scores.
  • Connectez-vous au système Points et récompenses pour que les spectateurs puissent déclencher volontairement des flux.
  • Vous utilisez l’application de bureau SSApp ? Débloquez Nœuds JavaScript personnalisés pour une logique arbitraire non couverte par les nœuds intégrés.
  • Consultez la Référence des événements pour la documentation détaillée des données de toutes les plateformes.

Ce guide est volontairement autonome : copiez-le localement, adaptez-le à votre équipe et poursuivez vos essais dans l’éditeur.

9. JavaScript personnalisé SSApp / Application de bureau uniquement

Deux nœuds de l’éditeur Event Flow permettent d’écrire du JavaScript arbitraire exécuté dans le traitement du flux : Code personnalisé (Custom Code) (déclencheur) et Exécuter du code personnalisé (Execute Custom Code) (action). Ils permettent d’exprimer ce que les nœuds intégrés ne couvrent pas.

Application de bureau requise. Les nœuds JavaScript personnalisés sont désactivés dans l’extension de navigateur car la politique de sécurité du contenu Manifest V3 de Chrome bloque new Function() / eval(). Ouvrez l’éditeur via cette application : application de bureau SSApp pour les activer. Dans l’extension, les nœuds sont grisés avec le libellé « Application de bureau uniquement ».
Modifier le code : sélectionnez un nœud Custom Code et cliquez sur Ouvrir l’éditeur de code (Open Code Editor) pour une grande fenêtre d’édition. Enregistrer et fermer (Save & Close) vérifie la syntaxe JavaScript et enregistre tout le flux ; Ctrl+S ou Cmd+S fait de même. Annuler laisse le nœud inchangé.
Éditeur Event Flow — état vide
Éditeur Event Flow. Le panneau gauche répertorie les nœuds disponibles ; le canevas pointillé sert à créer les flux ; le panneau droit affiche les propriétés du nœud sélectionné.

Custom Code — nœud déclencheur

Faites glisser Code personnalisé (Custom Code) depuis le groupe Avancé du panneau Déclencheurs vers le canevas. Il agit comme une porte : le flux continue uniquement si votre code renvoie true.

Panneau Déclencheurs affichant Custom Code dans le groupe Advanced
Custom Code se trouve dans le groupe Avancé du panneau Triggers.
Propriétés du déclencheur Custom Code affichant l’éditeur JavaScript
Panneau de propriétés après ajout du déclencheur. Écrivez une expression renvoyant true ou false.
Signature : votre code s’exécute sous forme de function(message) { ... }
Doit renvoyer : un booléen — true pour laisser continuer le flux, false pour l’arrêter.
Disponible : l’objet message (voir API des messages ci-dessous), ainsi que convertCurrency(value, targetCurrency, source) et convertToUSD(value, source).

Execute Custom Code — nœud d’action

Faites glisser Exécuter du code personnalisé (Execute Custom Code) depuis le groupe Intégrations du panneau Actions . Il peut modifier le message, le bloquer ou ajouter des métadonnées lisibles par les nœuds suivants.

Panneau Actions affichant Execute Custom Code dans le groupe Integrations
Execute Custom Code dans le groupe Intégrations du panneau Actions.
Propriétés de l’action Execute Custom Code affichant l’éditeur de code
Propriétés de l’action. Renvoyez un objet pour fusionner les modifications dans le résultat du flux.
Signature : votre code s’exécute sous forme de function(message, result) { ... }
Devrait renvoyer : un objet ou une Promise fusionnés dans result— consultez API du résultat.
Disponible : message (les données de l’événement), result (état du résultat actuel du flux), printThermal(html, options), ainsi que convertCurrency(value, targetCurrency, source) et convertToUSD(value, source).
Impression thermique dans SSApp : choisissez l’imprimante et calibrez la largeur du papier et les marges de sécurité dans Contrôle de l’imprimante (Printer Control), puis renvoyez printThermal('<strong>' + message.chatname + '</strong>'). SSApp met silencieusement la tâche en attente via l’API native d’impression Windows et utilise ces paramètres enregistrés. Un flux peut les remplacer avec des options telles que { width: '58mm', marginLeft: '3mm', marginRight: '3mm', marginTop: '2mm', marginBottom: '2mm', feed: '3mm', marginType: 'printableArea' }. Renvoyer la Promise permet à Event Flow d’attendre la soumission et de signaler les erreurs.
Canevas affichant côte à côte un déclencheur Custom Code et une action Execute Custom Code
Déclencheur Custom Code bleu et action Execute Custom Code verte placés sur le canevas. Reliez la sortie du déclencheur à l’entrée de l’action pour les connecter.

L’objet message

Les deux nœuds reçoivent les données complètes de l’événement sous message. Les champs ci-dessous sont toujours disponibles ; les événements propres à une plateforme peuvent en inclure d’autres.

ChampType de donnéesDescriptionExemple
message.chatmessagechaîneTexte du message de chat, pouvant contenir du HTML"Hello stream!"
message.chatnamechaîneNom d’affichage de l’expéditeur"CoolViewer"
message.useridchaîneIdentifiant utilisateur de plateforme"12345678"
message.typechaînePlateforme source, en minuscules"twitch", "youtube", "kick"
message.hasDonationchaîneChaîne de don formatée, si présente"$5.00", "500 bits"
message.donoValuenombre / chaîneÉquivalent du don en USD lorsque la source le fournit ; les zéros valides sont respectés. Event Flow utilise en repli currency.js pour convertir les libellés normalisés de hasDonation pour comparer les seuils, y compris 100 unités nommées inconnues = $0.01 USD. Il n’analyse pas le texte libre de chatmessage pour déterminer les montants de dons.5
message.eventchaîneIdentifiant du type d’événement"new_follower", "cheer", "raid"
message.membershipchaîneStatut d’adhésion le cas échéant"MEMBERSHIP"
message.subtitlechaîneLigne de contexte secondaire"Member for 3 months"
message.modbooléenL’expéditeur est modérateurtrue
message.subscriberbooléenL’expéditeur est abonnétrue
message.vipbooléenL’expéditeur est VIPtrue
message.chatimgchaîneURL de l’avatar utilisateur"https://..."
message.metaobjetDonnées structurées arbitraires jointes à l’événement{ viewers: 120 }
Conversion monétaire : utilisez convertCurrency(message.hasDonation, 'EUR', message.type) pour convertir le libellé de don formaté en EUR. Renvoie un nombre, ou null lorsque la devise cible demandée n’est pas prise en charge. Le convertisseur utilise les taux internes approximatifs de Social Stream Ninja ; il ne contacte aucun service de change externe.

Ce que renvoie l’action

Renvoyez un objet simple depuis le code d’action. Tous ses champs sont fusionnés dans l’objet result ; les champs omis conservent leurs valeurs actuelles.

Champ renvoyéType de donnéesEffet
modifiedbooléenDéfinissez true si vous avez modifié des champs de message . Indique aux nœuds suivants que les données ont été modifiées.
messageobjetRenvoyez le message, éventuellement modifié, pour transmettre les changements aux nœuds suivants.
blockedbooléenDéfinissez true pour empêcher l’affichage ou le relais du message.
Valeur de retour sûre minimale : return { modified: false, message };
Même sans modification, renvoyer message permet sa transmission au nœud suivant.

Exemples de code

Copiez l’un de ces exemples dans le champ JavaScript Code du type de nœud correspondant.

Extraits de déclencheur — renvoyer true pour continuer le flux

Correspondance de mot-clé, sans distinction de casse
Continuez le flux uniquement si le message contient un mot ou une expression précis.
// Matches "!hello" anywhere in the message return (message.chatmessage || '').toLowerCase().includes('!hello');
Détection de commande par expression régulière
Reconnaissez les messages commençant par une commande d’une liste définie (par exemple !queue, !raffle, !enter).
return /^!(queue|raffle|enter)\b/i.test(message.chatmessage || '');
Don dépassant un seuil
Déclenchez uniquement lorsqu’un don atteint ou dépasse un montant minimum.
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;
Super Chat ou Super Sticker YouTube dans une plage en EUR
Convertissez le libellé de don YouTube standard en EUR, excluez les joyaux/cadeaux et sélectionnez une plage sonore ou visuelle.
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;
Filtre de plateforme
Traiter uniquement les événements de plateformes précises.
return ['twitch', 'youtube'].includes(message.type);
Condition abonné / VIP / modérateur
Ne poursuivez le flux que pour les utilisateurs autorisés.
return !!(message.subscriber || message.vip || message.mod);
Condition multiple — VIP et mot-clé
Combinez une vérification de rôle et du contenu du message dans une expression qu’aucun déclencheur intégré ne couvre.
const isPrivileged = !!(message.subscriber || message.vip || message.mod); const isCommand = /^!feature\b/i.test(message.chatmessage || ''); return isPrivileged && isCommand;
Condition de longueur du message
Traiter uniquement les messages suffisamment longs ; utile pour éviter le spam d’un seul emoji en synthèse vocale ou relais.
return (message.chatmessage || '').replace(/<[^>]+>/g, '').trim().length >= 20;

Extraits d’action — renvoyer { modified, message }

Ajouter un badge ou une étiquette au message
Ajoutez un indicateur visuel à la fin de chaque message traversant cette action.
message.chatmessage = (message.chatmessage || '').trimEnd() + ' ✅'; return { modified: true, message };
Bloquer un message selon une condition
Examinez le contenu et ignorez silencieusement le message si une règle correspond ; utile pour les motifs de spam impossibles à exprimer avec un filtre de mots-clés.
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 };
Retirer les @mentions
Retirez toutes les mentions @username d’un message avant de le relayer vers une autre plateforme.
message.chatmessage = (message.chatmessage || '').replace(/@\w+/g, '').trim(); return { modified: true, message };
Formater une annonce de don
Réécrivez chatmessage sous forme d’annonce cohérente lorsqu’un don est présent.
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 };
Ajouter des métadonnées de routage pour les nœuds suivants
Ajoutez au message un champ personnalisé qu’un nœud suivant Relayer le chat (Relay Chat) ou Envoyer un message (Send Message) peut lire depuis une variable de modèle ({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 };
Préfixe de message selon la plateforme
Ajoutez un libellé de plateforme au début des messages relayés pour que les spectateurs connaissent leur origine.
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 };

Exemple complet — bot de demandes de fonctionnalités pour VIP

Ce flux écoute !feature <text> provenant d’abonnés, VIP ou modérateurs, le reformate comme demande de fonctionnalité et le relaie à une autre destination, par exemple Discord.

┌──────────────────────┐ ┌──────────────────────────┐ ┌──────────────────┐ │ Déclencheur Custom Code │────▶│ Action Execute Custom Code│────▶│ Relay Chat │ │ │ │ │ │ (vers Discord) │ │ Porte : VIP/abonné/mod │ │ Reformater le message │ │ │ │ + commence par │ │ → "📋 Demande de fonctionnalité │ │ │ │ !feature │ │ de {name} : {text}" │ │ │ └──────────────────────┘ └──────────────────────────┘ └──────────────────┘

Étape 1 — Déclencheur Custom Code (à coller dans le champ JavaScript Code du déclencheur) :

// 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;

Étape 2 — Action Execute Custom Code (à coller dans le champ JavaScript Code de l’action) :

// 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 };

Étape 3 — Action Relay Chat: ajoutez un nœud Relay Chat standard après l’action et configurez sa destination Discord ou autre. Aucun code personnalisé nécessaire ici : le texte reformatté message.chatmessage est transmis automatiquement.

Tester le flux. Cliquez sur ce bouton : Tester le flux (Test Flow) (en haut à droite de l’éditeur) pour envoyer un message synthétique dans le flux sans direct. Définissez chatname sur un abonné et ajoutez un message tel que !feature dark mode support, et vérifiez que la destination Relay Chat reçoit la chaîne reformattée.
Panneau Test Flow pour envoyer des événements de test synthétiques
Panneau Test Flow. Remplissez les champs correspondant aux conditions du déclencheur et cliquez sur Lancer le test (Run Test) pour valider toute la chaîne.

Considérations de sécurité

Le code personnalisé s’exécute avec les privilèges du processus de rendu. Dans SSApp, le code des nœuds Custom JS dispose d’un accès complet à l’objet window et à toutes les API exposées par le script de préchargement (par exemple window.ninjafy). Traitez les fichiers de flux importés comme du code exécutable : importez uniquement ceux de sources fiables.
  • Aucune isolation réseau. Le code d’action peut appeler fetch(). Si vous importez des flux partagés, examinez le JavaScript avant de les activer.
  • Les erreurs sont interceptées. Une erreur d’exécution de votre code renvoie false (déclencheur) ou ne fait rien (action), et écrit dans la console DevTools ; le flux ne plante pas.
  • Les erreurs de syntaxe aussi. Une erreur de type SyntaxError à la compilation est interceptée de la même manière. Consultez DevTools, F12, si un nœud semble ne rien faire.