SocialStream.Ninja Integration with Streamer.bot

This guide explains how to integrate SocialStream.Ninja with Streamer.bot using WebSockets. This allows Streamer.bot to receive chat messages captured by SocialStream.Ninja and trigger custom actions based on them.

Table of Contents

Integration Features

Prerequisites

Setting Up Streamer.bot WebSocket Server

  1. In Streamer.bot, go to Servers/ClientsWebSocket Server
  2. Enable the server by checking Enabled
  3. Check Auto Start to start the server automatically when Streamer.bot launches
  4. Note the Port (default is 8080)
  5. Optionally enable Authentication and set a password if required. If you set a password here, you *must* enter it in SocialStream.Ninja settings.
  6. Click Start if the server isn't running. The status should show "Listening".
  7. Click Apply or Save (depending on SB version)

Setting Up the Streamer.bot Action (Required)

To process messages from SocialStream.Ninja, you must create an Action in Streamer.bot. SocialStream.Ninja will trigger this action for each incoming message.

  1. In Streamer.bot, navigate to the Actions tab
  2. Right-click in the actions pane and select Add
  3. Name your action clearly (e.g., "Process SocialStream Message")
  4. Very Important: After creating the action, right-click on it and select Copy Action ID. You will paste this ID into the SocialStream.Ninja settings.
  5. Add sub-actions to handle the message data. A common first step is to extract the data using C#. Right-click the action → Add Sub-ActionCoreC#Execute C# Code
  6. Paste the following C# code. This code extracts the chat data sent by SocialStream.Ninja from the `chatData` argument:
using System;
using Newtonsoft.Json.Linq; // Make sure Newtonsoft.Json is referenced
public class CPHInline
{
    public bool Execute()
    {
        // --- Get the main chatData object sent from SocialStream.Ninja ---
        JObject chatData = null;
        if (args.ContainsKey("chatData") && args["chatData"] is JObject)
        {
            chatData = (JObject)args["chatData"];
        }
        else
        {
             CPH.LogWarn("[SocialStream] Action triggered but 'chatData' argument was missing or not a JSON object.");
             // Try converting if it's a string representation of JSON (less ideal)
             if (args.ContainsKey("chatData") && args["chatData"] is string) {
                try {
                    chatData = JObject.Parse((string)args["chatData"]);
                } catch (Exception ex) {
                    CPH.LogError($"[SocialStream] Failed to parse chatData string: {ex.Message}");
                    return false;
                }
             } else {
                 return false; // Exit if we definitely don't have chatData
             }
        }
        // --- Extract specific fields from the chatData object ---
        string message = GetStringValue(chatData, "chatmessage", ""); 
        string username = GetStringValue(chatData, "chatname", "Unknown User");
        string userId = GetStringValue(chatData, "userid", "");
        string avatar = GetStringValue(chatData, "chatimg", "");
        bool isBot = GetBoolValue(chatData, "isBot", false);
        string originalPlatform = GetStringValue(chatData, "originalPlatform", "unknown");
        string source = GetStringValue(chatData, "source", "unknown");
        
        // Log the received message to Streamer.bot's Action Queue logs for debugging
        CPH.LogInfo($"[SocialStream][{originalPlatform}] {username}: {message}");
        
        // --- Set arguments for subsequent sub-actions ---
        CPH.SetArgument("ss_message", message);
        CPH.SetArgument("ss_username", username);
        CPH.SetArgument("ss_userId", userId);
        CPH.SetArgument("ss_avatar", avatar);
        CPH.SetArgument("ss_isBot", isBot);
        CPH.SetArgument("ss_platform", originalPlatform);
        CPH.SetArgument("ss_source", source);
        
        return true;
    }
    
    // Helper methods to safely get values from JObject with specific types
    private string GetStringValue(JObject obj, string key, string defaultValue)
    {
        try
        {
            if (obj != null && obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken token))
            {
                return token.ToString();
            }
        }
        catch (Exception ex) {
             CPH.LogWarn($"[SocialStream] Error getting value for key '{key}': {ex.Message}");
        }
        return defaultValue;
    }
    
    private bool GetBoolValue(JObject obj, string key, bool defaultValue)
    {
        try
        {
            if (obj != null && obj.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken token))
            {
                return token.ToObject<bool>();
            }
        }
        catch (Exception ex) {
             CPH.LogWarn($"[SocialStream] Error getting value for key '{key}': {ex.Message}");
        }
        return defaultValue;
    }
}
  1. Click Compile. If it shows "Compiled successfully!", click OK.
  2. Add more sub-actions *after* the C# code sub-action to use the data (e.g., send messages, play sounds). Use the arguments set in the C# code (like `%ss_message%`, `%ss_username%`, `%ss_platform%`). For example:
    • Right-click → Add Sub-Action → Twitch → Chat → Send Message
    • Set Message to: `[%ss_platform%] %ss_username%: %ss_message%`
    • Check "Use Arguments" (or ensure variables are enabled)
  3. Click Save to save the entire action.

Configuring SocialStream.Ninja

  1. In SocialStream.Ninja's menu, go to Global settings and toolsMechanics (or similar path).
  2. Find the Streamer.bot integration section.
  3. Toggle the integration **ON**.
  4. Set the **WebSocket URL** to match Streamer.bot (e.g., `ws://127.0.0.1:8080`). Use `127.0.0.1` if SSN is on the same PC as Streamer.bot.
  5. If you set a password in Streamer.bot's WebSocket Server settings, enter it in the **Password** field here.
  6. **Action ID (Required):** Paste the Action ID you copied from Streamer.bot into this field. This is required for the integration to function.
  7. Save your settings in SocialStream.Ninja.

SocialStream.Ninja Data Structure Reference

When SocialStream.Ninja sends data to Streamer.bot, it passes a detailed JSON object with the following fields that you can access in your Streamer.bot actions. The example C# code above extracts these fields and makes them available as arguments.

Primary Data Fields

These are the main fields available in the chatData object:

Field Name Type Description Argument Name Example Usage
chatmessage String The actual chat message content. May contain HTML tags if textonly is false. ss_message %ss_message%
chatname String The display name of the user who sent the message. ss_username %ss_username%
userid String The unique ID of the user from the original platform. ss_userId %ss_userId%
chatimg String URL to the user's avatar/profile image. ss_avatar %ss_avatar%
isBot Boolean Flag indicating if the message was from a bot. ss_isBot %ss_isBot%
originalPlatform String The platform the message originated from (e.g., "youtube", "twitch", "kick", etc.). ss_platform %ss_platform%
source String Identifies the source as "SocialStream.Ninja". ss_source %ss_source%

Additional Available Fields

These additional fields may be present depending on the message type and platform:

Field Name Type Description Access in C#
contentimg String URL to content image, if present in the message. GetValue<string>(chatData, "contentimg", "")
subtitle String Additional text like user status or other metadata. GetValue<string>(chatData, "subtitle", "")
membership String Membership information, if applicable. GetValue<string>(chatData, "membership", "")
hasDonation String/Boolean Donation information, if present. GetValue<string>(chatData, "hasDonation", "")
type String Source type (e.g., "twitch", "youtube", "kick"). GetValue<string>(chatData, "type", "")
id String Unique message ID from the source platform. GetValue<string>(chatData, "id", "")
nameColor String HEX color code for the username (e.g., "#FF0000"). GetValue<string>(chatData, "nameColor", "#FFFFFF")
chatbadges String/Array Chat badges from the source platform. GetValue<string>(chatData, "chatbadges", "")
textonly Boolean If true, indicates that HTML has been stripped from the message. GetValue<bool>(chatData, "textonly", false)
tid String Transaction ID used for duplicate detection. GetValue<string>(chatData, "tid", "")

Accessing Additional Fields in C#

To access fields not already extracted in the example C# code, add lines like:

// Extract additional fields as needed
string contentImage = GetValue<string>(chatData, "contentimg", "");
string subtitle = GetValue<string>(chatData, "subtitle", "");
string nameColor = GetValue<string>(chatData, "nameColor", "#FFFFFF");

// Make them available as arguments
CPH.SetArgument("ss_contentImage", contentImage);
CPH.SetArgument("ss_subtitle", subtitle);
CPH.SetArgument("ss_nameColor", nameColor);

Example: Working with Platform-Specific Messages

You can add conditional logic based on the platform or other message properties:

// Example: Process messages differently based on platform
if (originalPlatform.Equals("youtube", StringComparison.OrdinalIgnoreCase))
{
    // YouTube-specific processing
    CPH.PlaySound("sounds/youtube_alert.mp3");
    
    // Check for YouTube memberships
    string membership = GetValue<string>(chatData, "membership", "");
    if (!string.IsNullOrEmpty(membership))
    {
        CPH.SetArgument("ss_hasMembership", true);
        CPH.SetArgument("ss_membershipInfo", membership);
        CPH.LogInfo($"[YouTube Membership] {username}: {membership}");
    }
}
else if (originalPlatform.Equals("twitch", StringComparison.OrdinalIgnoreCase))
{
    // Twitch-specific processing
    string badges = GetValue<string>(chatData, "chatbadges", "");
    bool isSubscriber = badges.Contains("subscriber");
    CPH.SetArgument("ss_isSubscriber", isSubscriber);
}

Example: Creating Custom Text Formats

You can format messages for display in various ways:

// Standard format with platform
string formattedMessage = $"[{originalPlatform.ToUpper()}] {username}: {message}";
CPH.SetArgument("ss_formattedMessage", formattedMessage);

// HTML format for web display
string htmlFormat = $"<span style='color:{GetValue<string>(chatData, "nameColor", "#FFFFFF")}'>{username}</span>: {message}";
CPH.SetArgument("ss_htmlMessage", htmlFormat);

// Format for OBS Text Source
string obsText = $"{originalPlatform} | {username} says: {message}";
CPH.SetArgument("ss_obsText", obsText);

Troubleshooting

Important Note on Direct Chat Display

Limitation: Sending messages from an external application (like SocialStream.Ninja) via WebSocket to directly appear within Streamer.bot's own "Chat" tab or integrated overlays (using the `ChatMessage` request type) is currently **not a reliably supported feature** of the Streamer.bot WebSocket server.

While the WebSocket specification includes a `ChatMessage` request, its behaviour for *injecting* messages *into* Streamer.bot's display seems inconsistent or non-functional for this purpose. Its primary role is typically to report messages *from* Streamer.bot *to* connected clients.

Therefore, **you MUST use the Action ID method** described above to send message data to Streamer.bot. You can then use sub-actions within Streamer.bot (like sending a message to your Twitch/YouTube channel) if you want the message content to appear in chat overlays that monitor those platforms.

Please do not report issues related to messages not appearing directly in Streamer.bot's chat tab when *not* using an Action ID, as this relies on functionality that may need to be specifically added or modified by the Streamer.bot developers.

For help on using Streamer.bot, please contact the Streamer.bot's support, as I do have on experience with using it. Also, Streamer.bot's code does not appear to be open-sourced, so if you wish to have additional Social Stream Ninja supported within Streamer.bot, you'll need to make requests to them.

-steve