Configuration
After adding the extension to your channel, you have to configure it to use it.
When opening the configuration screen, you should see a few components after the loading is finished.
Preview & Editor
Here you can set the different categories and events the extension should handle for you. Hovering over the component should show the controls for adjusting it. As long as you are connected to the internet and the server, changes are saved automatically. Keep in mind that updating the configuration resets all event limits and locks to their default.
Categories
You need at least one Category before adding any events. You can use categories to sort events by type, for example, one for sounds, one for visual effects, etc.
Each category name must be unique.
Controls for adding events, editing, moving and deleting the category are shown below the category name when hovering over it.
Events
Adding an event to a category gives a bunch of options.
- Event ID: The event ID is used later in the WebSocket client (for example, your streaming broadcasting software), to identify the events. It should be unique, and it should only contain the characters
a-z
,A-Z
,0-9
,_
and-
. - Display Name (Optional): This is showed to the users in the extension. You can use any character here, including emojis. Without it, the display name is the same as the event id.
- Description (Optional): A short description shown when opening the event.
- Duration: How long the event takes to execute in seconds. While executing, no other event can be sent (besides limitations). For example, if you want to play a sound when executing the event, you can set the duration to the duration of the sound.
- Bits Amount (Optional): How many bits for sending the event. This requires activated bits capabilities.
- Write in Chat: Whether a message should be written in chat by the extension when someone redeems an event, including the user name and bits amount (if any).
- Limit (Optional): How often the event can be sent before it is automatically locked (besides limitations).
-1
means the event can be sent unlimited times. - Locked: Whether the event is locked by default. This can be used, for example, to lock events from the start. You can then unlock them via your WebSocket client, if you wish so (for example, automatically as a result of executing other events.)
After adding an event, you can hover over it in the list to adjust it. Editing the event also allows you to change it to another category.
You can also send a test event to your streaming software, as long as it’s properly connected to the server. Sending test events work regardless of whether the event is locked, limited or sending is currently blocked by the streamer.
Colors
Here you can individualize the colors of the extension, to make it fit your channel. Remember to save after you are done. You can always reset the colors to their default.
Secret, Exports and Setups
The secret is required for sending commands from the WebSocket client to the server. You should keep it hidden at all costs. Should you accidentally leak it, you can request a new one. Keep in mind this requires updating the commands of the WebSocket client.
Backup
When done with the configuration, it is recommended to make a local backup of all the settings. For exporting, you can copy the “Data” string and save it to a file. To import an existing backup, paste the backup string into the text input.
Streamer.bot
This is for setting up with Streamer.bot. Streamer.bot acts as a middleman between the extension and whatever other software you use (like OBS). Thus it offers more flexibility than connecting to OBS or any other streaming software directly. Sadly, it doesn’t support imports from generated code yet, so it requires more manual setup time.
Setup
- First, make sure Streamer.bot is setup correctly. Refer to their docs for more information, for example, to setup with OBS.
Use the import or set up manually following the next steps. After importing, you still need to create the necessary event actions for each event defined in the config. For example, if you got an event with ID “test”, you need to create an action named “Event_test”, that is going to be executed when the event “test” is redeemed.
-
Connect Streamer.bot with the server. Go to the tab
Server/Clients -> WebSocket Clients
, right click and add a new Websocket client with the info given in the setup form of the configuration. You should enable auto connect and reconnect. -
Create two persisted global variables:
StreamerSocketActive
with valueFalse
(check “Auto Type”).StreamerSocketSecret
with the value being your secret.
-
Create an action for handling WebSocket messages. It requires a trigger “Core - Websocket - Client - Websocket Client Message” and a sub action that executes the following code (“Core - C# - Execute C# Code”). Furthermore, you need to press “Find refs” so it compiles without error:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class CPHInline
{
private static readonly Regex EventRegex = new Regex("\"event_id\":\"([^\"]+)\"", RegexOptions.Compiled);
public static bool IsType(string message, string type)
{
return message.Contains("type\":\"" + type);
}
public static string GetEventId(string message)
{
Match match = EventRegex.Match(message);
return match.Success ? match.Groups[1].Value : null;
}
public static string CreateMessage(string type, Dictionary<string, object>? data = null){
var message = "{\"type\":\""+type+"\"";
if(data != null){
message += ", \"data\": {";
var size = data.Count;
var index = 0;
foreach(var entry in data){
index++;
message += "\""+entry.Key+"\":\""+entry.Value.ToString()+"\"" + (index < size ? "," : "");
}
message += "}";
}
message += "}";
return message;
}
public bool Execute()
{
CPH.TryGetArg<string>("message", out string message);
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
var active = CPH.GetGlobalVar<bool>("StreamSocketActive") ? "true" : "false";
if (IsType(message, "request_connection_check"))
{
CPH.WebsocketSend(CreateMessage("response_connection_check", new() {
{"secret", secret},
{"active", active}
}));
} else if(IsType(message, "notification_event"))
{
var event_id = GetEventId(message);
var action_name = "Event_"+event_id;
CPH.LogInfo($"Got event '{event_id}'.");
if(CPH.ActionExists(action_name))
{
CPH.RunAction(action_name);
} else
{
CPH.LogWarn($"No action for event '{event_id}'.");
}
}
return true;
}
}
- Create a new action “Enable”. This is used to activate the extension - you can add a trigger to execute it when starting streaming, for example. It should execute the following C# code:
using System;
public class CPHInline
{
public bool Execute()
{
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
CPH.WebsocketSend("{\"type\":\"notification_status_change\",\"data\":{\"secret\":\""+secret+"\",\"active\":true}}");
CPH.SetGlobalVar("StreamSocketActive", true);
return true;
}
}
- Do the same as 5. but with “Disable” and slightly different code:
using System;
public class CPHInline
{
public bool Execute()
{
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
CPH.WebsocketSend("{\"type\":\"notification_status_change\",\"data\":{\"secret\":\""+secret+"\",\"active\":false}}");
CPH.SetGlobalVar("StreamSocketActive", false);
return true;
}
}
-
For each event defined in the config, add a new action “Event_id”, with “id” being the ID of the event. Those are called by the code defined in step 4.
-
(Optional) Add a new action “skip” (skip event with duration) with the following code:
using System;
public class CPHInline
{
public bool Execute()
{
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
CPH.WebsocketSend("{\"type\":\"notification_skip_queue\",\"data\":{\"secret\":\""+secret+"\"}}");
return true;
}
}
- (Optional) Add a new action “reset” (reset all event locks and limits to their defaults) with the following code:
using System;
public class CPHInline
{
public bool Execute()
{
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
CPH.WebsocketSend("{\"type\":\"notification_event_reset\",\"data\":{\"secret\":\""+secret+"\",\"all\":true}}");
return true;
}
}
or if you only want to reset some events (change the events
array):
using System;
public class CPHInline
{
public static string CreateArray(string[] events)
{
var result = "[";
for(int i = 0; i < events.Length; i++){
result += "\""+events[i]+"\"" + ((i < events.Length - 1) ? "," : "");
}
return result + "]";
}
public bool Execute()
{
var secret = CPH.GetGlobalVar<string>("StreamSocketSecret");
var events = CreateArray(["example_1", "example_2"]);
CPH.WebsocketSend("{\"type\":\"notification_event_reset\",\"data\":{\"secret\":\""+secret+"\",\"events\":"+events+"}}");
return true;
}
}
After adding all the required actions, make sure to test them thoroughly. You can use the “test event” buttons in the config to check whether they execute successfully when you are connected to the server with your streaming software.
OBS
This is for setting up OBS and requires the Advanced Scene Switcher plugin.
- Address: The (custom uri) address to the WebSocket server. Advanced Scene Switcher does not currently support TLS for WebSockets, so the non-TLS variant is required. The unsecure option will be removed as soon as TLS is available for Advanced Scene Switcher.
- Settings: All the settings required for making the configuration work. This is useful if you haven’t used Advanced Scene Switcher before. Keep in mind it overrides all existing settings.
- Macros: All the macros required. Those can be pasted directly into the “Macros” list of advanced scene switcher.
Setup
- Open Advanced Scene Switcher in OBS via
Tools -> Advanced Scene Switcher
For a fresh install (overrides all Advanced Scene Switcher settings):
- Load the settings, by copying the settings provided by the config into a file and importing it via
General -> Save / load settings
- Check macros and add new actions to them to your liking
For adding to existing settings:
- Add a new WebSocket connection with a custom uri to the address given provided by the config. Remember to check “connect on startup” and “reconnect automatically” and uncheck “Use the obs-WebSocket protocol”. You should be able to successfully connect via “Test connection”.
- Add Macros by right-clicking on the Macro list, Import and paste the provided macros from the config.
- Make sure all macros (in conditions and actions) have the correct WebSocket server selected.
Macros
There are multiple macros defined after importing. The following are required to make the client work correctly:
- CheckConnection: The server periodically sends a message to the client, to make sure it is still connected.
- SetActive: Sets the extension active so events can be sent.
- SetInactive: Sets the extension inactive so no events can be sent.
- Event_
{event_id}
: This macro is executed when the corresponding event with variable{event_id}
is redeemed. You can add further actions here (for example, to play media or switch scenes). Refer to the Advanced Scene Switcher Wiki.
Optional macros can be used to further customize behavior:
- ResetAllEvents: Executing this macro resets all limits and locks to their default value.
- SkipEvent: If there is an event running and it is blocking other events from being run (because of the duration set when configuring events), you can skip the current duration and make the extension available for the next event immediately.
Custom
If any of the options provided aren’t sufficient, you can always implement your own WebSocket client that connects to the API.
- Use a package like
ws
to create the client. Connect to the address provided in the API documentation with “custom” as theapp_source
. - Every message you send requires the secret given to you in the configuration as a parameter of the data object.
- After connection, you will receive a
request_connection_check
. Reply with a JSON object that follows theresponse_connection_check
schema. If you don’t reply in time, you will be disconnected. - To activate the extension for viewers, send a
notification_status_change
with the corresponding values. Notifications do not receive a response. Remember to also update a state variable with the current status for theresponse_connection_check
. - Events are received with the
notification_event
message. The message might also include additional information, like about the user who sent the event. - Any other message types found in the API are optional and can be used to further enhance event behavior, like unlocking or locking events under certain conditions.