Skip to content

Latest commit

 

History

History
1355 lines (1028 loc) · 53.8 KB

File metadata and controls

1355 lines (1028 loc) · 53.8 KB

Social Stream Ninja API Documentation

The API allows real-time, bidirectional communication between your application and the Social Stream Ninja extension/app, the dock page, and the overlay pages.

There is an easy to use sandbox to play with some of the common API commands and options over here.

Capability-driven control clients should use the versioned Social Stream Remote-Control Protocol. The legacy commands documented below remain supported.

Table of Contents

WebSocket API

The WebSocket API allows real-time, bidirectional communication between your application and the Social Stream Ninja server.

If you prefer to keep traffic peer-to-peer without enabling the WebSocket relay, you can instead integrate the Social Stream Ninja WebRTC SDK. It offers a Node- and browser-friendly interface that plugs into the same transport layer used by the extension. A Social Stream Ninja listener example is available at ninjasdk/demos/socialstreamninja-listener.js.

Choose Your Use Case

There are two main reasons to use the WebSocket API:

Use Case What You Want Required Toggle(s) Channel
Remote Control Send commands to SSN (clear, feature, next in queue, send chat) from StreamDeck, Bitfocus Companion, or custom apps ✅ Enable remote API control Channel 1 (default)
Chat Listener Receive chat messages from Twitch/YouTube/etc. in your Python/Node app ✅ Enable remote API control + ✅ Send chat messages to API server (3rd toggle) Channel 4

Toggle Reference (Global settings > Mechanics):

Toggle Purpose
1. Enable remote API control of extension Required for ALL API usage. Allows sending commands to the extension.
2. Enable Dock to use and publish via API server Needed to send commands directly to the Dock page (clear, nextInQueue, etc.)
3. Send chat messages to API server Required to RECEIVE chat messages! Routes Twitch/YouTube/etc. chat through the server on channel 4.
4. Dock sends its commands to Extension via server Optional. Allows Dock to send commands back to extension via server instead of P2P.

Quick Start: Remote Control (StreamDeck / Bitfocus Companion)

For controlling SSN from StreamDeck, Bitfocus Companion, or similar tools, you only need the first toggle enabled.

Simple HTTP GET request:

https://io.socialstream.ninja/SESSION_ID/nextInQueue
https://io.socialstream.ninja/SESSION_ID/clearOverlay
https://io.socialstream.ninja/SESSION_ID/clearBotOverlay
https://io.socialstream.ninja/SESSION_ID/sendEncodedChat/null/Hello%20World
https://io.socialstream.ninja/SESSION_ID/drawmode/null/toggle

WebSocket commands:

ws = new WebSocket("wss://io.socialstream.ninja/join/SESSION_ID");
ws.onopen = () => {
    // Send a command
    ws.send(JSON.stringify({ action: "nextInQueue" }));
    ws.send(JSON.stringify({ action: "clearOverlay" }));
    ws.send(JSON.stringify({ action: "clearBotOverlay" }));
    ws.send(JSON.stringify({ action: "sendChat", value: "Hello from API!" }));
};

See the StreamDeck Integration Guide and Bitfocus Companion sections below for detailed setup.


Quick Start: Receiving Chat Messages (Python / Node.js)

To receive chat messages from Twitch, YouTube, and other platforms in your own application:

Required toggles (Global settings > Mechanics):

  1. Enable remote API control of extension
  2. Send chat messages to API server (the 3rd toggle) - This is the key one!

Connect to Channel 4 - This is where chat messages are broadcast:

Python Example:

import asyncio
import websockets
import json

SESSION_ID = "YOUR_SESSION_ID_HERE"  # From your dock.html URL

async def listen_to_chat():
    uri = f"wss://io.socialstream.ninja/join/{SESSION_ID}/4"  # Channel 4 receives chat

    async with websockets.connect(uri) as ws:
        print(f"Connected! Listening for chat messages...")

        while True:
            message = await ws.recv()
            data = json.loads(message)

            # Chat messages have 'chatname' and 'chatmessage' fields
            if "chatname" in data:
                print(f"[{data.get('type', 'unknown')}] {data['chatname']}: {data.get('chatmessage', '')}")

                # Check for donations
                if data.get('hasDonation'):
                    print(f"  💰 Donation: {data['hasDonation']}")

asyncio.run(listen_to_chat())

Node.js Example:

const WebSocket = require('ws');

const SESSION_ID = 'YOUR_SESSION_ID_HERE';  // From your dock.html URL

const ws = new WebSocket(`wss://io.socialstream.ninja/join/${SESSION_ID}/4`);

ws.on('open', () => {
    console.log('Connected! Listening for chat messages...');
});

ws.on('message', (message) => {
    const data = JSON.parse(message);

    // Chat messages have 'chatname' and 'chatmessage' fields
    if (data.chatname) {
        console.log(`[${data.type || 'unknown'}] ${data.chatname}: ${data.chatmessage || ''}`);

        // Check for donations
        if (data.hasDonation) {
            console.log(`  💰 Donation: ${data.hasDonation}`);
        }
    }
});

ws.on('error', console.error);

Channel Reference for Listeners:

  • Channel 4 (/join/SESSION/4) - Receives chat messages from the extension (when "Send chat messages to API server" is enabled)
  • Channel 2 (/join/SESSION/2) - Receives messages from the Dock (when "Enable Dock to use and publish via API server" is enabled)

Connecting to the API Server

Connect to the WebSocket server at wss://io.socialstream.ninja.

There are two methods to connect and join a session:

  1. Direct connection with parameters:
ws = new WebSocket("wss://io.socialstream.ninja/join/SESSION_ID/IN_CHANNEL/OUT_CHANNEL");
  1. Connect first, then send a join message:
ws = new WebSocket("wss://io.socialstream.ninja");
ws.onopen = function() {   
    ws.send(JSON.stringify({ join: "SESSION_ID", in: IN_CHANNEL, out: OUT_CHANNEL }));
};

Parameters:

  • SESSION_ID: Your unique session identifier (same as used in dock.html or featured.html URL)
  • IN_CHANNEL: Channel number to receive messages (optional)
  • OUT_CHANNEL: Channel number to send messages (optional)

The default channel value is used if not specified

Channel System Explained

The channel system allows for more granular control over message routing:

  • Channel 1: Main communication channel (default)
  • Channel 2: Typically used for dock.html communication
  • Channel 3: Often used for extension communication
  • Channel 4: Commonly used for featured.html communication
  • Channel 5: Used for waitlist.html communication
  • Channel 6: Reserved for future use
  • Channel 7: Reserved for future use
  • Channel 8: Reserved for future use
  • Channel 9: Reserved for future use

When specifying channels, you're defining which channels to receive messages from (IN_CHANNEL) and which to send messages to (OUT_CHANNEL). This allows different components of your setup to communicate on separate channels, reducing noise and improving organization.

When a message is sent, it goes to the specified output channel. Those who have that channel set as their input channel will receive the message.

Available Commands

  1. Send Chat Message

    • Action: sendChat
    • Example: {"action": "sendChat", "value": "Hello, world!"}
  2. Send Encoded Chat Message

    • Action: sendEncodedChat
    • Example: {"action": "sendEncodedChat", "value": "Hello%2C%20world%21"}
  3. Block User

    • Action: blockUser
    • Example: {"action": "blockUser", "value": {"chatname": "username", "type": "twitch"}}
  4. Send External Content

    • Action: extContent
    • Example: {"action": "extContent", "value": "{\"chatname\":\"User\",\"chatmessage\":\"Hello\"}"}
  5. Waitlist Operations

    • Remove the first active entry: {"action": "removefromwaitlist", "value": 1}
    • Highlight an active entry: {"action": "highlightwaitlist", "value": 2}
    • Reset: {"action": "resetwaitlist"}
    • Stop accepting new entries: {"action": "stopentries"}
    • Start accepting new entries again: {"action": "startentries"}
    • Set the waitlist/draw title message: {"action": "waitlistmessage", "value": "Type !join to enter!"}
    • Download: {"action": "downloadwaitlist"}
    • Select winners: {"action": "selectwinner", "value": 1}
  6. Leaderboard Operations

    • Reset open leaderboard overlays: {"action": "resetleaderboard"}
  7. Clear Messages

    • Dock: {"action": "clearDock"} (clear and clearAll remain supported aliases)
    • A dock with &sync also clears its synced docks. Without &sync, only the targeted dock clears.
    • Target a labeled dock with {"action": "clearDock", "target": "producer"} and &label=producer on that dock URL.
    • Permanently delete saved history: {"action": "clearHistory", "value": {"confirm": true}}
    • Overlay: {"action": "clearOverlay"}
  8. Queue Operations

    • Next: {"action": "nextInQueue"}
    • Get Size: {"action": "getQueueSize"}
  9. Auto-show Toggle

    • {"action": "autoShow", "value": "toggle"}
  10. Feature Next Message

  • {"action": "feature"}
  1. Get Chat Sources
  • {"action": "getChatSources"}
  1. VIP User Operations
  • Toggle: {"action": "toggleVIPUser", "value": {"chatname": "username", "type": "twitch"}}
  1. Get User History
  • {"action": "getUserHistory", "value": {"chatname": "username", "type": "twitch"}}
  1. Draw Mode
  • {"action": "drawmode", "value": true}
  • {"action": "drawmode", "value": "toggle"}
  1. Emote-only Filter
  • Toggle or set the global emote-only mode that keeps only emotes/emoji from chat messages. Messages that become empty (and have no donation/content image) after filtering are dropped.
  • Examples:
    • {"action": "emoteonly", "value": "toggle"}
    • {"action": "emoteonly", "value": true}
    • {"action": "emoteonly", "value": false}
  1. Poll Operations
    • Reset: {"action": "resetpoll"}
    • Close: {"action": "closepoll"}
    • Load Preset: {"action": "loadpoll", "value": {"pollId": "poll-123456"}}
    • Set Settings: {"action": "setpollsettings", "value": {"pollQuestion": "What's your favorite color?", "pollType": "multiple", "multipleChoiceOptions": "Red\nBlue\nGreen"}}
    • Get Presets: {"action": "getpollpresets"}
    • Create New: {"action": "createpoll", "value": {"settings": {"pollQuestion": "New Poll", "pollType": "freeform"}}}

Channel-Specific Messaging

You can send messages to specific channels using the content action with a channel number:

  • Channel 1: {"action": "content", ...}
  • Channel 2: {"action": "content2", ...}
  • Channel 3: {"action": "content3", ...}
  • Channel 4: {"action": "content4", ...}
  • Channel 5: {"action": "content5", ...}
  • Channel 6: {"action": "content6", ...}
  • Channel 7: {"action": "content7", ...}

HTTP API

The server also supports HTTP GET, POST, and PUT requests for the same actions. Replace SESSION_ID with your actual session ID.

  • GET: https://io.socialstream.ninja/SESSION_ID/ACTION/TARGET/VALUE
  • POST/PUT: https://io.socialstream.ninja/SESSION_ID (with JSON body)
  • POST/PUT: https://io.socialstream.ninja/SESSION_ID/ACTION (with JSON body)

If your action needs a value but no target, use null as the target placeholder:

https://io.socialstream.ninja/SESSION_ID/drawmode/null/true
https://io.socialstream.ninja/SESSION_ID/drawmode/null/toggle

Channel Parameter

You can specify the output channel for HTTP requests using the channel query parameter:

https://io.socialstream.ninja/SESSION_ID/ACTION/TARGET/VALUE?channel=2

This will send the message to channel 2. If not specified, it defaults to channel 1.

Server-Sent Events (SSE)

Connect to the SSE endpoint to receive real-time updates:

const eventSource = new EventSource(`https://io.socialstream.ninja/sse/SESSION_ID`);

There is a demo overlay that uses SSE here: https://socialstream.ninja/tests/sse.html

Receiving Responses

Include a get parameter in your request for actions that require a response:

{
  "action": "yourAction",
  "value": "yourValue",
  "get": "uniqueIdentifier"
}

The server will respond with:

{
  "callback": {
    "get": "uniqueIdentifier",
    "result": true
  }
}

Note: Not all commands support or require this callback mechanism.

Response Types

  • Success: The server will typically respond with the result of the action.
  • Failed: If the action couldn't be performed (e.g., no clients connected to the specified room), the server responds with "failed".
  • Timeout: If the server doesn't receive a response from the clients within 5 seconds, it responds with "timeout".
  • Special: For non-default channels (2-7), if no clients are connected, the server responds with "special" instead of "failed".

Special Pages and Features

  1. Emotes Page (emotes.html)

    • Displays emojis/emotes/icons dancing on the screen
    • Can receive content via WebRTC or the WebSocket API
    • To send content via API: Use the content action on channel 1
  2. Waitlist Page (waitlist.html)

    • Manages draws and waitlists for giveaways
    • Communicates on channel 5
    • Supports actions like selecting winners and managing the waitlist
  3. Custom Actions

    • Create custom auto-responding triggers or actions using a custom.js file
    • Example: auto1 trigger responds "1" to any message that is "1"
  4. Queuing and Pinning Messages

    • Queue: Hold CTRL (cmd on Mac) and click messages in the dock
    • Pin: Hold ALT and click messages to pin them at the top
    • API pin existing row: {"action":"pin","value":"MESSAGE_MID"}
    • API pin by full message object: {"action":"pin","value":{"id":"external-1","chatname":"User","chatmessage":"Pinned note","type":"api"}}
    • API unpin row: {"action":"unpin","value":"MESSAGE_MID"}
    • API feature the first pinned row: {"action":"nextPinned"}
    • Existing dock sync payloads are still supported: {"pin":["MESSAGE_MID"]} and {"unpin":["MESSAGE_MID"]}

    Pinning is handled by dock.html, so a dock must be open on the same session. If you have multiple docks, use a dock label and target it:

    {"action":"pin","target":"moderator-dock","value":"MESSAGE_MID"}
    {"action":"unpin","target":"moderator-dock","value":"MESSAGE_MID"}
    {"action":"nextPinned","target":"moderator-dock"}

    HTTP GET examples:

    https://io.socialstream.ninja/SESSION_ID/pin/null/MESSAGE_MID
    https://io.socialstream.ninja/SESSION_ID/unpin/null/MESSAGE_MID
    https://io.socialstream.ninja/SESSION_ID/nextPinned
    https://io.socialstream.ninja/SESSION_ID/pin/moderator-dock/MESSAGE_MID
    
  5. MIDI Hotkey Support

    • Toggle in the extension menu
    • Allows predefined chat messages to be sent to all social destinations
    • MIDI actions available on Control Change channel 1

Message Targeting System

Social Stream Ninja implements a targeting system that allows messages to be directed to specific instances of the dock or featured pages if multiple of either are open.

How it works

  1. URL Parameter: Each instance (featured/dock) can be given a unique label using the label URL parameter.

    Example: featured.html?label=stream1 or dock.html?label=controlpanel1

  2. Message Structure: When sending a message through the API, include a target field with the label of the intended recipient.

    Example:

    {
      "action": "someAction",
      "target": "stream1",
      "value": "someValue"
    }
  3. Message Processing: The application checks each incoming message for a target. If the message has a target that doesn't match the instance's label, the message is ignored.

Use Cases

  • Running multiple streams with different configurations
  • Sending commands to specific control panels
  • Updating particular displays without affecting others

This targeting system allows for more flexible and powerful setups, especially in complex streaming environments.

Best Practices

  1. Always handle potential errors and timeouts in your application.
  2. Use appropriate channels for different types of messages to keep your communication organized.
  3. Leverage the targeting system when working with multiple instances to ensure messages reach the intended recipients.
  4. Regularly check for updates to the API as new features may be added over time.

Inbound Donation Webhooks

Social Stream Ninja can receive donation events from external platforms via webhooks. These donations appear in your dock and overlays alongside regular chat messages.

Prerequisites

  1. Note Your Session ID: Find it in the extension popup or in your URL after ?session=.
  2. Keep Social Stream Ninja enabled.
  3. Under Global settings and toolsMechanics, enable remote API control of extension. This lets background.js receive and normalize inbound webhooks before sending them through the normal message path.
  4. Use your normal generated dock and overlay links. Do not manually add &server, &server2, or &server3 for donation webhooks.
  5. If the dock was already open when you enabled the setting, reload it once.

This is the only API toggle required for inbound donation webhooks. The other API transport toggles serve different workflows and can remain off.

With this route, each donation is normalized once in the extension and then delivered like a regular Social Stream message to chat, alerts, Event Flow, and the Tip Jar/Goal Meter.

Enable the remote API control of extension toggle

Supported Platforms

Platform Webhook URL Event Type
Stripe https://io.socialstream.ninja/{sessionID}/stripe checkout.session.completed
Ko-Fi https://io.socialstream.ninja/{sessionID}/kofi Donations (public only)
Buy Me A Coffee https://io.socialstream.ninja/{sessionID}/bmac donation.created, membership.started
Fourthwall https://io.socialstream.ninja/{sessionID}/fourthwall ORDER_PLACED

Stripe Setup

  1. Create a Stripe Payment Link
  2. Important: Add custom fields to your payment link:
    • Display Name or Username (required) - donations without this field are rejected
    • Message (optional) - allows donors to leave a message
  3. Go to Stripe Webhooks and create a new endpoint
  4. Set the URL to: https://io.socialstream.ninja/YOUR_SESSION_ID/stripe
  5. Select event: checkout.session.completed
  6. No signature verification is needed (keep your session ID private instead)

Testing: Use Stripe's Test Mode with card number 4242 4242 4242 4242, any future expiry date, and any CVC.

Ko-Fi Setup

  1. Sign in to Ko-Fi Webhook Settings
  2. Paste https://io.socialstream.ninja/YOUR_SESSION_ID/kofi into Webhook URL, then click Update
  3. Enable remote API control of extension as shown above
  4. Reload an already-open dock, then click Send single tip test in Ko-Fi
  5. Confirm exactly one alert appears; only public donations are supported

Buy Me A Coffee Setup

  1. Sign in to Buy Me A Coffee and navigate to Settings → Webhooks
  2. Add webhook URL: https://io.socialstream.ninja/YOUR_SESSION_ID/bmac
  3. Both one-time donations (donation.created) and new memberships (membership.started) are supported

Fourthwall Setup

  1. Go to your Fourthwall admin: Settings → For Developers → Webhooks
  2. Create a webhook with URL: https://io.socialstream.ninja/YOUR_SESSION_ID/fourthwall
  3. Subscribe to ORDER_PLACED events

Security Note

Keep your session ID private. Anyone with your session ID can send fake donation events to your overlay. The webhook URLs do not use signature verification, so security relies on the secrecy of your session ID.

Donation Message Format

When a donation webhook is received, it is normalized into a standard SSN message format:

{
  "chatname": "Donor Name",
  "chatmessage": "Optional message from donor",
  "hasDonation": "$50.00 USD",
  "type": "stripe",
  "id": "unique_id",
  "meta": {
    "webhookId": "provider_delivery_id"
  },
  "chatbadges": "",
  "chatimg": "",
  "membership": ""
}

The hasDonation field contains the formatted amount and currency. meta.webhookId preserves the provider's stable event identifier for retry and mixed-transport deduplication. This allows donations to be filtered, featured, and displayed using the same mechanisms as platform-native donations (Super Chats, Bits, etc.).

Featured Page (featured.html)

The featured.html page is designed to display featured content, typically used for showcasing selected messages or donations in a stream overlay. It communicates primarily on channel 3 for output and channels 1 and 2 for input, depending on the configuration.

Connection Options

The featured.html page can be configured to connect to the WebSocket server in three different ways:

  1. Default (server): Connects to wss://io.socialstream.ninja, joins the room, and sets output to channel 3 and input to channel 2.
  2. Server2: Sets output to channel 3 and input to channel 4.
  3. Server3: Sets output to channel 3 and input to channel 1.

In all cases, channel 3 is reserved for output from the featured.html page.

These can be set using URL parameters:

  • ?server: Default connection
  • ?server2: Server2 connection
  • ?server3: Server3 connection

Content Filtering Options

The featured page offers several filtering options that can be controlled via the API:

  1. onlyshowdonos: Only show messages with donations
  2. hideDonations: Hide donation information
  3. hideevents: Hide all event payloads that include an event type
  4. filterevents: Hide specific events by exact event name or matching event text
  5. hideTwitch: Hide messages from Twitch
  6. onlyTwitch: Only show messages from Twitch
  7. onlyFrom: Only show messages from a specific source
  8. hideFrom: Hide messages from specific sources
  9. filterfeaturedusers: Only show messages from approved listed users

API Actions

The featured page responds to the following API actions:

  1. content: Display new content
    • Example: {"action": "content", "value": {...contentObject...}}
  2. clear: Clear the currently displayed content
    • Example: {"action": "clear"}
  3. toggleTTS or tts: Toggle or set Text-to-Speech
    • Example: {"action": "toggleTTS", "value": "toggle"} or {"action": "tts", "value": "on"}

Content Object Structure

When sending content to be displayed, the content object should have the following structure:

{
  "chatname": "Username",
  "chatmessage": "Message content",
  "chatimg": "URL to user avatar",
  "contentimg": "URL to content image",
  "subtitle": "Subtitle text",
  "membership": "Membership information",
  "hasDonation": "Donation information",
  "type": "Source type (e.g., twitch, youtube)",
  "id": "Unique message ID"
}

chatname, chatmessage, and type tend to be the most important.

A full breakdown of different keys though used in SSN are the following:

key name value type description
chatname string Display name that will be rendered in overlays.
chatmessage string (HTML permitted) Message body; can contain sanitized HTML/emote markup when textonly is false.
chatimg string (URL or data URI <= 55 KB) Author avatar. Absolute URLs preferred; legacy data URIs remain supported.
type string (lowercase identifier) Primary source identifier such as twitch, youtube, kick. Also used to resolve the default icon https://socialstream.ninja/sources/images/{type}.png.
sourceImg string (URL or ./sources/images/...) Optional alternate icon representing a sub-source (ex: channel avatar, Restream origin). Should generally differ from the type icon. Legacy relative paths are normalised to ./sources/images/{file} for consistency but remain locally resolved.
sourceName string Channel title, profile name, or host identifier associated with the source feed.
textonly boolean Applies only to chatmessage; indicates whether chatmessage should be treated as plain text (true) or may contain markup (false). Other normal fields are expected to be plain text, except media fields such as chatimg and contentimg.
hasDonation string Donation amount with units, e.g., "3 roses" or "$50 USD".
chatbadges Array<string | BadgeDescriptor> Badge icons shown beside the author. Strings are image URLs; BadgeDescriptor objects can include { type, text, src } for richer badges.
contentimg string (URL) Optional media attachment for the message (image/gif/mp4/webm).
membership string Short description of a membership/subscription state or label (e.g., "Member" or "Tier 3 Upgrade").
title string Display title for donations or other highlighted events (defaults like "CHEERS" or "DONATION" are common).
subtitle string Additional detail for memberships or donations (e.g., "12 months" or "Gifted by Alex").
moderator boolean Marks the author as a moderator for the source platform.
event string | boolean Identifies structured events ("follow", "raid", etc.) or false/omitted when the message is standard chat.
admin boolean Flags elevated/privileged accounts.
bot boolean Flags automated or host-generated messages.
question boolean Indicates the message has been classified as a question.
userid string Stable user identifier from the source platform (helpful for API lookups, blocking, etc.).
karma number (0.0–1.0) Sentiment score; 1.0 positive, 0.0 negative. Provided by AI heuristics when available.
id integer Internal message identifier assigned by SSN for de-duplication/routing.
private boolean Marks direct/private messages that should not be surfaced publicly by default.
nameColor string (CSS color) Overrides the rendered display-name color.
textColor string (CSS color) Overrides the rendered message text color.
backgroundColor string (CSS color) Overrides the background color for highlighted message cards.
meta object Extra structured data that doesn't fit elsewhere (viewer counts, membership details, eventTypeMapping, etc.).

Additional Features

  1. Queue System: If queuetime is set, messages are added to a queue and displayed sequentially.
  2. Image Preloading: The page attempts to preload user avatars and source type images for smoother display.
  3. IFrame Support: The page can adjust its height when embedded in an IFrame.
  4. Transition Effects: Content transitions can be customized using CSS classes.

Best Practices and Improvements

  1. Error Handling: Implement more robust error handling for WebSocket connections and message parsing.
  2. Configuration Options: Consider adding more configuration options via URL parameters or API calls to control filtering and display behavior.
  3. Performance Optimization: For high-traffic streams, implement rate limiting or batching of messages to prevent overwhelming the display.
  4. Accessibility: Add options for controlling text size, contrast, and display duration to improve readability for viewers.
  5. Analytics: Implement tracking for displayed messages and user interactions to gather insights on engagement.

Example API Usage

To display a new featured message:

socketserver.send(JSON.stringify({
  action: "content",
  value: {
    chatname: "ExampleUser",
    chatmessage: "Hello, featured chat!",
    type: "twitch",
    hasDonation: "$5.00"
  }
}));

To clear the current featured message:

socketserver.send(JSON.stringify({ action: "clear" }));

To toggle Text-to-Speech:

socketserver.send(JSON.stringify({ action: "toggleTTS", value: "toggle" }));

Dock Page (dock.html)

The dock.html page serves as a control center for managing chat messages and interactions. It connects to multiple WebSocket servers and processes incoming messages.

Connection Options

The dock page can be configured to connect to different WebSocket servers:

  1. Main Server (default):

    • URL: wss://io.socialstream.ninja/api
    • Configurable via the server URL parameter
    • Joins room with out: 2, in: 1
  2. Extension Server:

    • URL: wss://io.socialstream.ninja/extension
    • Configurable via the server2 or server3 URL parameters
    • Joins room with out: 3, in: 4

URL Parameters

  • server: Sets the main server URL
  • server2: Enables connection to the extension server and sets its URL
  • server3: Enables connection to both main and extension servers

WebSocket Message Processing

The dock page processes incoming WebSocket messages using the processInput function. This function handles various types of messages and actions, including:

  1. Message management (pin, unpin, queue)
  2. User actions (block, delete messages)
  3. Content display and filtering
  4. Chat source management
  5. User history retrieval
  6. Payment processing (Stripe, Ko-fi, Buy Me a Coffee)
  7. OBS commands
  8. TTS (Text-to-Speech) control

Key Features

  1. Message Queue: Manages a queue of messages for display
  2. Pinned Messages: Allows pinning and unpinning of messages
  3. User Blocking: Supports blocking users across different platforms
  4. Content Filtering: Provides options to filter content based on various criteria
  5. Payment Integration: Processes donations from Stripe, Ko-fi, and Buy Me a Coffee
  6. OBS Integration: Allows control of OBS scenes
  7. TTS Control: Enables toggling and control of Text-to-Speech functionality

API Actions

The dock page responds to various API actions, including:

  1. clearDock (clear and clearAll are aliases): Clears dock messages except pinned ones; &sync propagates the clear.
  2. clearHistory: Permanently deletes the local message database when value.confirm is true or value is "confirm".
  3. clearOverlay: Clears the overlay without affecting the dock
  4. clearBotOverlay: Clears the Primary Chat Bot's bot.html overlay without stopping active TTS
  5. nextInQueue: Moves to the next message in the queue
  6. getQueueSize: Returns the current queue size
  7. autoShow: Controls automatic message display
  8. content: Processes and displays new content
  9. feature: Features the next unfeatured message
  10. pin: Pins an existing dock message by mid, or pins a full message object.
  11. unpin: Unpins an existing dock message by mid.
  12. nextPinned: Features the first pinned message.
  13. toggleTTS or tts: Controls Text-to-Speech functionality

Example API Usage

To clear all messages:

socketserver.send(JSON.stringify({ action: "clear" }));

To feature the next message:

socketserver.send(JSON.stringify({ action: "feature" }));

To toggle Text-to-Speech:

socketserver.send(JSON.stringify({ action: "toggleTTS", value: "toggle" }));

Best Practices and Improvements

  1. Error Handling: Implement more robust error handling for WebSocket connections and message parsing.
  2. Modularization: Consider splitting the processInput function into smaller, more manageable functions for easier maintenance.
  3. Configuration Options: Add more configuration options via URL parameters to control filtering and display behavior.
  4. Security: Implement authentication and encryption for sensitive operations, especially those involving payment processing.
  5. Performance Optimization: For high-traffic scenarios, implement batching of messages and more efficient DOM manipulation.
  6. Accessibility: Add keyboard shortcuts and screen reader support for better accessibility.
  7. Documentation: Maintain detailed inline documentation for complex functions and processes.

Social Stream Ninja API Documentation

Extension

The extension is a critical component of the Social Stream Ninja system, acting as the primary source of messages and managing communication between different parts of the system.

WebSocket Connections

The extension maintains two WebSocket connections:

  1. Dock Connection:

    • URL: wss://io.socialstream.ninja/dock
    • Joins room with out: 4, in: 3
    • Controlled by settings.server2 or settings.server3
  2. API Connection:

    • URL: wss://io.socialstream.ninja/api
    • Joins room with out: 2, in: 1
    • Controlled by settings.socketserver

Message Flow

  1. The extension receives messages from various sources (e.g., chat platforms).
  2. Messages are processed and can be modified by applyBotActions().
  3. Processed messages are sent to the dock or featured pages using sendToDestinations().
  4. Responses or user actions from the dock/featured pages are received by the extension.
  5. The extension can then send responses back to the original platforms using processResponse().

API Actions

The extension processes various API actions, including:

  1. sendChat: Sends a chat message to the specified destination.
  2. sendEncodedChat: Sends an encoded chat message to the specified destination.
  3. blockUser: Blocks a user from a specific source or all sources.
  4. extContent: Processes external content, applying bot actions before sending.
  5. removefromwaitlist: Removes an entry from the waitlist.
  6. highlightwaitlist: Highlights an entry in the waitlist.
  7. resetwaitlist: Resets the entire waitlist.
  8. resetleaderboard: Resets open leaderboard overlays and clears their saved leaderboard state.
  9. stopentries: Stops accepting new entries.
  10. startentries, openentries, or resumeentries: Starts accepting new entries again.
  11. waitlistmessage or setwaitlistmessage: Sets the waitlist/draw title message.
  12. downloadwaitlist: Initiates a download of the waitlist.
  13. selectwinner: Selects one or more random winners from the waitlist.
  14. drawmode: Toggles draw mode for giveaways/waitlists.

.. and most actions that target the dock can be sent via the extension API or other overlays.

The logic in the app lets you target non-Dock overlays via the extension API using the target value, where target is the label name of the connected P2P IFRAME.

if (data.target && (data.target.toLowerCase!=="null")){
	sendTargetP2P(data, data.target);
} else {
	sendDataP2P(data);
}

Example API Usage

To send a chat message:

socketserver.send(JSON.stringify({
  action: "sendChat",
  value: "Hello, world!",
  target: "twitch" // optional, specifies the destination platform
}));

To block a user:

socketserver.send(JSON.stringify({
  action: "blockUser",
  value: "username",
  target: "youtube" // optional, "*" for all platforms
}));

To process external content:

socketserver.send(JSON.stringify({
  action: "extContent",
  value: JSON.stringify({
    chatname: "User",
    chatmessage: "Hello from an external source!",
    type: "external"
  })
}));

Best Practices and Improvements

  1. Error Handling: Implement more robust error handling for WebSocket connections and message parsing.
  2. Rate Limiting: Implement rate limiting to prevent flooding of messages to destinations.
  3. Modularization: Consider splitting the message processing logic into smaller, more manageable functions.
  4. Logging: Implement comprehensive logging for easier debugging and monitoring.
  5. Security: Implement authentication and encryption for sensitive operations.
  6. Configurability: Allow more fine-grained control over which actions are enabled or disabled.
  7. Documentation: Maintain detailed inline documentation for complex functions and processes.
  8. Testing: Implement unit and integration tests to ensure reliability of the extension.

Integration with Other Components

The extension plays a central role in the Social Stream Ninja system:

  1. It receives messages from external chat platforms.
  2. Processes and optionally modifies these messages.
  3. Sends the processed messages to the dock.html or featured.html pages for display.
  4. Receives user actions or responses from the dock/featured pages.
  5. Can send responses back to the original chat platforms.

This central position allows the extension to act as a powerful intermediary, enabling features like chat moderation, custom bot actions, and cross-platform interactions.

Waitlist Page (waitlist.html)

The waitlist.html page is designed to manage and display waitlists or giveaways within the Social Stream Ninja system. It connects to a WebSocket server and processes incoming messages to update the waitlist display.

WebSocket Connection

  • URL: wss://io.socialstream.ninja/extension
  • Joins room with out: 5, in: 6

Key Functions

  1. setupSocket(): Establishes and manages the WebSocket connection.
  2. processInput(data): Processes incoming WebSocket messages and updates the waitlist display.

Waitlist Display Modes

  1. Draw Mode: Displays entries in a draw or giveaway.
  2. Regular Mode: Displays a standard waitlist.

Message Types and Actions

The waitlist page processes various types of messages:

  1. waitlistmessage: Updates the waitlist title.
  2. drawmode: Toggles draw mode and displays winners.
  3. drawPoolSize: Updates the number of entries in the draw.
  4. waitlist: Updates the entire waitlist display.

Key Features

  1. Winner Selection: Displays selected winners with confetti animation.
  2. Entry Count: Shows the number of entries in the draw.
  3. Customizable Messages: Allows setting custom messages for the waitlist title.
  4. Source Display: Option to show the source (e.g., Twitch, YouTube) of each entry.
  5. Randomization: Option to randomize the order of entries in the display.

CSS Classes for Styling

  • .winner: Applied to winning entries.
  • .loser: Applied to non-winning entries in draw mode.
  • .selected: Applied to highlighted entries.
  • .guestListHolder: Container for each waitlist entry.

API Actions

The normal remote API command path controls waitlist state in the extension/app. The waitlist page then receives display payloads from that state.

Remote API actions:

{ "action": "removefromwaitlist", "value": 1 }
{ "action": "highlightwaitlist", "value": 1 }
{ "action": "resetwaitlist" }
{ "action": "stopentries" }
{ "action": "startentries" }
{ "action": "waitlistmessage", "value": "Type !join to enter!" }
{ "action": "selectwinner", "value": 1 }
{ "action": "drawmode", "value": "toggle" }

Display payloads handled by waitlist.html include:

  1. waitlistmessage: Sets a custom message for the waitlist.

    {
      "waitlistmessage": "Welcome to the giveaway!"
    }
  2. drawmode: Toggles draw mode and can display winners.

    {
      "drawmode": true,
      "winlist": [
        {"chatname": "Winner1", "type": "twitch", "chatimg": "URL"},
        {"chatname": "Winner2", "type": "youtube", "chatimg": "URL"}
      ]
    }
  3. drawPoolSize: Updates the number of entries in the draw.

    {
      "drawPoolSize": 100
    }
  4. waitlist: Updates the entire waitlist.

    {
      "waitlist": [
        {"chatname": "User1", "type": "twitch", "chatimg": "URL", "waitStatus": 0},
        {"chatname": "User2", "type": "youtube", "chatimg": "URL", "waitStatus": 2}
      ]
    }

Best Practices and Improvements

  1. Error Handling: Implement more robust error handling for WebSocket connections and message parsing.
  2. Performance Optimization: For large waitlists, implement virtualization or pagination to improve performance.
  3. Accessibility: Ensure the waitlist is accessible, including keyboard navigation and screen reader support.
  4. Customization Options: Allow more customization of the waitlist appearance through API calls or configuration options.
  5. Animation Options: Provide options to customize or disable animations for different use cases.
  6. Localization: Add support for multiple languages in the waitlist display.
  7. Persistence: Implement a way to save and restore waitlist state in case of page reload or disconnection.

Integration with Other Components

The waitlist page integrates with the Social Stream Ninja system by:

  1. Receiving waitlist updates from the extension or other components.
  2. Displaying real-time updates of entries, winners, and draw status.
  3. Providing a visual interface for giveaways or queue management.

This integration allows streamers or moderators to manage waitlists or giveaways efficiently while providing an engaging visual display for viewers.

Battle royale, Polls, etc

These pages may lack API support directly, however in some cases they can be controlled via the extension's API.

For example the waitlist has some functions that can be controlled via the extension:

removefromwaitlist
highlightwaitlist
resetwaitlist
stopentries
startentries
waitlistmessage
downloadwaitlist
selectwinner
drawmode

Poll Control via API

The poll system can now be controlled through the API with the following actions:

Basic Poll Controls

  • Reset Poll: {"action": "resetpoll"} - Resets the current poll, clearing all votes
  • Close Poll: {"action": "closepoll"} - Closes the current poll, preventing new votes

Advanced Poll Controls

  • Load Poll Preset: {"action": "loadpoll", "value": {"pollId": "poll-123456"}} - Loads a previously saved poll preset by its ID
  • Get Poll Presets: {"action": "getpollpresets"} - Returns a list of all saved poll presets with their IDs and names
  • Set Poll Settings: {"action": "setpollsettings", "value": {...}} - Updates the current poll settings
    • Available settings: pollType, pollQuestion, multipleChoiceOptions, pollMatchMode, pollStyle, pollTimer, pollTimerState, pollTally, pollSpam
  • Create New Poll: {"action": "createpoll", "value": {"settings": {...}}} - Creates a new poll with specified settings

Example Usage

// Create a multiple choice poll
ws.send(JSON.stringify({
    action: "createpoll",
    value: {
        settings: {
            pollType: "multiple",
            pollQuestion: "What's your favorite streaming platform?",
            multipleChoiceOptions: "Twitch\nYouTube\nFacebook\nOther",
            pollTimer: "120",
            pollTimerState: true
        }
    }
}));

// Load a saved poll preset
ws.send(JSON.stringify({
    action: "loadpoll",
    value: { pollId: "poll-1234567890" }
}));

Timer Control via API

The timer page can be controlled through the API with the following actions:

Basic Timer Controls

  • Start Timer: {"action": "starttimer"}
  • Pause Timer: {"action": "pausetimer"}
  • Toggle Timer: {"action": "toggletimer"}
  • Reset Timer: {"action": "resettimer"}
  • Add Time: {"action": "timeradd", "value": 30} adds 30 seconds
  • Subtract Time: {"action": "timersubtract", "value": 30} subtracts 30 seconds

Setting Timer State

  • Set Timer: {"action": "settimer", "value": {...}}
    • Common fields: seconds, label, mode, style, warnSeconds, dangerSeconds, soundUrl
  • Get Timer State: {"action": "gettimerstate", "get": "timer-123"} returns the current timer state via callback

Example Usage

// Set a 5-minute countdown named "Interview"
ws.send(JSON.stringify({
    action: "settimer",
    value: {
        seconds: 300,
        label: "Interview",
        mode: "countdown",
        style: "stage",
        warnSeconds: 60,
        dangerSeconds: 15
    }
}));

// Request current timer state
ws.send(JSON.stringify({
    action: "gettimerstate",
    get: "timer-state-1"
}));

Just to touch on the Battle Royale game though,

Battle Page (battle.html)

The battle.html page is an interactive game-like feature. Currently it doesn't use a WebSocket connection but instead communicates directly with the extension via WebRTC.

Communication Method

  • Uses WebRTC (peer-to-peer) for direct communication with the extension
  • No WebSocket server connection at the moment -- but I'll update this when it does.

Game Features

  1. Player Join: Users can join the game using the !join command
  2. Weapon Selection: Players can choose a weapon type when joining
  3. In-game Chat: Players can send messages using the !say command

Message Types

  1. startgame: Initiates the game
  2. Content messages: Processed for game actions (join, chat)

API Actions

While the battle page doesn't directly connect to the API server, it can receive actions through the extension:

  1. startgame: Starts the game

    sendDataP2P({startgame: true});
  2. Player join:

    processData({
      chatname: "PlayerName",
      chatmessage: "!join sword",
      chatimg: "URL",
      type: "twitch",
      nameColor: "#FFFFFF"
    });
  3. In-game chat:

    processData({
      chatname: "PlayerName",
      chatmessage: "!say Hello, everyone!"
    });

Integration with Extension

The battle page relies on the extension for receiving data:

  1. The extension uses sendDataP2P() to send data to the battle page
  2. Data can be sent via WebRTC or fallback to WebSocket if available
  3. The extension can trigger game actions like starting the game

StreamDeck Integration Guide for Social Stream Ninja

Quick Setup Method

  1. Open StreamDeck software
  2. Add a new "Website" action to your StreamDeck
  3. Check GET request in background
  4. Configure the URL using this format:
https://io.socialstream.ninja/YOUR_SESSION_ID/sendEncodedChat/null/YOUR_URL_ENCODED_MESSAGE_HERE

Replace:

  • YOUR_SESSION_ID with your Social Stream Ninja session ID
  • YOUR_MESSAGE with your URL-encoded message

For example, to send "Hello Stream!":

https://io.socialstream.ninja/abc123/sendEncodedChat/null/Hello%20Stream!

You can use this page to test and generate the correct URL here, if having problems doing it manually: https://socialstream.ninja/sampleapi.html. Note that we want to generate a GET request with this method.

image

Advanced Setup with Multi Actions

For more flexibility, you can use Multi Actions to send different messages:

  1. Create a new "Multi Action" on your StreamDeck
  2. Add "Website" actions for each command
  3. Use these URL patterns:

WebSocket (WSS)

https://io.socialstream.ninja/YOUR_SESSION_ID/sendChat/null/YOUR_MESSAGE

HTTPS POST

https://io.socialstream.ninja/YOUR_SESSION_ID

With body:

{
    "action": "sendChat",
    "value": "YOUR_MESSAGE",
    "apiid": "YOUR_SESSION_ID"
}

Tips for StreamDeck Setup

  • Use URL encoding for special characters in messages
  • You can create multiple buttons for different preset messages
  • Chain commands using Multi Actions for complex sequences
  • Add a delay between actions if needed using StreamDeck's delay feature

Testing Your Setup

  1. Find your session ID from the Social Stream API Sandbox
  2. Create a test button with a simple message
  3. Press the button to verify the message appears in your social platforms
  4. Check the Social Stream API Sandbox's incoming messages panel to confirm delivery

Channel-Specific Messages

To send to specific channels, add the channel parameter:

https://io.socialstream.ninja/YOUR_SESSION_ID/sendChat/null/YOUR_MESSAGE?channel=2

Channels:

  • 1: General communication
  • 2: Dock
  • 3: Featured content
  • 4-7: Custom channels

Using Bitfocus Companion with Social Stream Ninja

Bitfocus Companion enables the reasonably priced Elgato Streamdeck to be a professional shotbox surface for a huge amount of different presentation switchers, video playback software and broadcast equipment. It supports Social Stream Ninja and VDO.Ninja!

https://bitfocus.io/companion https://bitfocus.io/connections/socialstream-ninja

Initial Setup

  1. Enable API Control:

    • Open Social Stream Ninja
    • Go to Global settings and tools > Mechanics
    • Enable Enable remote API control of extension
  2. Get Your Session ID:

    • Navigate to Global settings and tools > Session Options
    • Copy your Session ID
    • Alternatively, find it in your URL after ?session=
  3. Configure Companion:

    • Install the Social Stream Ninja module in Companion
    • Paste your Session ID into the module settings

Available Actions

The following commands are confirmed available in Companion:

  • Clear featured message
  • Clear all messages
  • Next in queue
  • Toggle auto-show
  • Feature next un-featured
  • Reset Poll
  • Close Poll
  • Waitlist Controls
  • Text to Speech (TTS) Controls
  • Send Chat Message

Variables

Companion can access:

  • queue_size: Shows the current queue size

Comparison with StreamDeck

Advantages of using Companion:

  • Native integration with Social Stream Ninja
  • No need for URL encoding or complex HTTP requests
  • Direct access to all core functionality
  • Real-time queue size monitoring through variables
  • Can be used alongside StreamDeck for more complex setups

This makes Companion a simpler alternative to the StreamDeck HTTP method described above, especially for basic Social Stream Ninja control.