Actions aus C# auslösen: RunAction & RunActionById
Sobald du mehrere C#-Actions baust, willst du Logik nicht überall kopieren. Streamer.bot lässt dich aus dem Code heraus andere Actions aufrufen: einmal eine Helfer-Action bauen, von überall starten. Dafür gibt es CPH.RunAction und CPH.RunActionById.
Doku: docs.streamer.bot · RunAction und RunActionById
RunAction über den Namen
Abschnitt betitelt „RunAction über den Namen“Die einfache Variante ruft eine Action über ihren Namen auf:
public class CPHInline { public bool Execute() { CPH.RunAction("Streamer.bot Docs Action"); return true; }}Die Signatur ist:
public bool RunAction(string actionName, bool runImmediately = true)Der Rückgabewert ist true, wenn die Action gefunden und gestartet wurde, sonst false. Prüf ihn, wenn der Aufruf optional ist:
if (!CPH.RunAction("Streamer.bot Docs Action")) { CPH.LogWarn("Action nicht gefunden oder deaktiviert.");}RunActionById über die GUID
Abschnitt betitelt „RunActionById über die GUID“Action-Namen kannst du im Editor umbenennen, die GUID bleibt stabil. Für robuste Aufrufe in produktiven Setups ist CPH.RunActionById deshalb die sicherere Wahl:
public class CPHInline { public bool Execute() { string actionId = "4fcc2d13-9bcf-4c18-9d91-821a15f4b6e5"; CPH.RunActionById(actionId); return true; }}Die GUID kopierst du im Streamer.bot-UI per Rechtsklick auf die Action (Copy Action Id). Die Signatur entspricht RunAction:
public bool RunActionById(string actionId, bool runImmediately = true)runImmediately: inline gegen eigene Queue
Abschnitt betitelt „runImmediately: inline gegen eigene Queue“Der zweite Parameter runImmediately entscheidet, wie die Ziel-Action läuft. Default ist true.
true(inline): Die Ziel-Action läuft als Teil der aktuellen Action, wie eine Sub-Action. Sie wird sofort im selben Thread ausgeführt, dein Code wartet, bis sie fertig ist, dann geht es weiter.false(eigene Queue): Die Ziel-Action wird in ihre eigene Queue eingereiht. Dein Code läuft sofort weiter, ohne auf das Ende der Ziel-Action zu warten.
public class CPHInline { public bool Execute() { // Sofort, im selben Thread, dann geht es hier weiter CPH.RunAction("[Helper] Post Stats", true);
// In eigene Queue, läuft nebenher, evtl. später CPH.RunAction("[Helper] Post Stats", false); return true; }}Wann was? runImmediately: true (Default) ist richtig, wenn du auf das Ergebnis oder die Reihenfolge angewiesen bist, also etwa wenn die Ziel-Action ein Argument zurückschreibt, das du danach liest. runImmediately: false ist sinnvoll, wenn die Ziel-Action lange dauert (z. B. ein Sleep oder ein Netzwerk-Call) und du den auslösenden Thread nicht blockieren willst. Details zu Queues und Blockieren stehen unter Threading & Performance.
Argumente an die Ziel-Action übergeben
Abschnitt betitelt „Argumente an die Ziel-Action übergeben“Eine aufgerufene Action sieht deine lokalen Variablen nicht. Du musst Werte vorher als Argumente setzen, dann kann die Ziel-Action sie als %arg% oder per CPH.TryGetArg lesen. Das machst du mit CPH.SetArgument vor dem Aufruf:
public class CPHInline { public bool Execute() { // Werte zusammenbauen int viewers = CPH.Between(50, 200); CPH.TryGetArg("user", out string user);
// Argumente für die Ziel-Action setzen CPH.SetArgument("statsUser", user); CPH.SetArgument("statsViewers", viewers);
// Helfer-Action inline starten, sie liest %statsUser% und %statsViewers% CPH.RunAction("[Helper] Post Stats", true); return true; }}Die Helfer-Action [Helper] Post Stats greift dann auf die gesetzten Argumente zu:
public class CPHInline { public bool Execute() { CPH.TryGetArg("statsUser", out string user); CPH.TryGetArg("statsViewers", out int viewers);
CPH.SendMessage($"📊 {user} hat aktuell {viewers} Zuschauer im Blick."); return true; }}So baust du eine Logik (Stats posten) genau einmal und rufst sie aus jeder beliebigen Action auf. Das ist der Kern des modularen Aufbaus: kleine, benannte Helfer-Actions wiederverwenden statt Code zu duplizieren. Mehr zum Rückgabeweg in Argumente zurückgeben.
Wichtig bei runImmediately: false
Abschnitt betitelt „Wichtig bei runImmediately: false“Bei false läuft die Ziel-Action eventuell erst später, dein Code aber sofort weiter. Wenn du danach dieselben Argumente erneut setzt oder mehrere Aufrufe nebeneinander schickst, kann ein Race entstehen: Die Ziel-Action liest das Argument womöglich erst, nachdem dein Code es schon wieder verändert hat.
public class CPHInline { public bool Execute() { // Riskant: beide Aufrufe sind nicht inline und teilen sich denselben Argument-Namen CPH.SetArgument("statsViewers", 100); CPH.RunAction("[Helper] Post Stats", false);
CPH.SetArgument("statsViewers", 200); // überschreibt evtl. bevor der erste Call liest CPH.RunAction("[Helper] Post Stats", false); return true; }}Wenn die Reihenfolge oder die exakten Argument-Werte zählen, nutze runImmediately: true. Inline-Aufrufe lesen ihre Argumente garantiert in dem Zustand, in dem du sie gesetzt hast.
Häufige Fallen
Abschnitt betitelt „Häufige Fallen“- Action-Name exakt schreiben (Groß-/Kleinschreibung):
RunActionmatcht den Namen genau."[Helper] Post Stats"ist nicht dasselbe wie"[helper] post stats". Bei Tippfehlern oder umbenannten Actions gibt der Aufruffalsezurück und es passiert stillschweigend nichts. Für stabile Aufrufe lieberRunActionByIdmit der GUID nehmen. - Endlosrekursion: Ruft sich eine Action direkt oder über eine Kette wieder selbst auf, hängst du dich in einer Endlosschleife auf. Besonders tückisch mit
runImmediately: true, weil das inline im selben Thread passiert. Baue einen Abbruch (z. B. ein Argument oder eine Globale als Tiefenzähler) ein, bevor du rekursiv aufrufst. - Race auf Argumente bei
false:runImmediately: falseheißt, die Ziel-Action läuft evtl. später. Setzt du dazwischen dasselbe Argument neu, liest die Ziel-Action womöglich den falschen Wert. Für reihenfolgekritische Übergabentrueverwenden. - Rückgabewert ignoriert:
RunActionundRunActionByIdgebenboolzurück. Wenn der Aufruf scheitert (Action fehlt, deaktiviert, falscher Name), merkst du das nur, wenn du den Rückgabewert prüfst und perCPH.LogWarnprotokollierst.