Skip to content

Sigmanuts API

max edited this page Feb 21, 2023 · 6 revisions

This page will go over some technical parts of the app.

How does it work?

Sigmanuts is a .NET Core 3.1 WPF app, and uses WebView2 for the user interface. We will call the frontend simply Sigmanuts, and the backend Sigmanuts API. Let's talk about the frontend first.

Sigmanuts

In the frontend, the app is running two WebView2 instances - YouTube chat in the background, and the user interface of the app in the foreground. Switching to either Chat or Login tabs will bring up the background WebView2 instance, and switching away from those tabs bring the app user interface back. Both of these WebView2 instances are running together at all times.

The background instance hosts YouTube chat. It is required that it is always running as the YouTube chat stops scrolling when unfocused which breaks the mechanism by which this app works. When app is launched, the Sigmanuts API injects a script into the chat which listens for any DOM mutations, packs all the information into JSON objects and sends them out through a websocket to all the widgets that are connected to the websocket.

Sigmanuts API

Sigmanuts API has 2 main components: the websocket, and the local server. The local server is hosted on port 6969 as long as the app is running, and the websocket port is 6970. All widgets are hosted on the local server, and so can be accessed like so

http://localhost:6969/widgets/${WIDGETNAME}/widget.html

When writing widgets for Sigmanuts, you don't need to create the websocket connection yourself, the app takes care of that for you. We tried to make the coding process as similar to Streamelements as possible, as it is the most popular coding environment for custom widgets. In the next section, you will find information about which events you can listen for, and what information is available to you.

API Reference

To start, when writing the widget, you can listen for the following window events: onWidgetLoad and onEventReceived. In the onWidgetLoad scope you can access all the fields of your widget like so

window.addEventListener('onWidgetLoad', function (obj) {
    const fieldData = obj.detail.fieldData;
});

Similarly, listener and detail fields of an event can be accessed in the onEventReceived scope like so

window.addEventListener('onEventReceived', function (obj) {
    const listener = obj.detail.listeners;
    const event = obj.detail.event;
});

Continue reading to find all listeners and their corresponding event information.

Chat Message

The listener for chat messages is message. The full JSON schema for the event is

{
    "listener": "message",
    "event": {
        "service": "youtube",
        "data": {
            "time": 1676958488,
            "tags": {
                "badge-info": "",
                "badges": "member/1,moderator/1",
                "client-nonce": "",
                "color": "#FFFFFF",
                "display-name": "sigmacw",
                "emotes": "",
                "first-msg": "0",
                "flags": "",
                "id": "",
                "mod": true,
                "returning-chatter": "0",
                "room-id": 1234,
                "subscriber": true,
                "member": true,
                "tmi-sent-ts": "",
                "turbo": "",
                "user-id": 12345678,
                "user-type": "moderator"
            },
            "nick": "sigmacw",
            "userId": 12345678,
            "displayName": "sigmacw",
            "displayColor": "#FFFFFF",
            "profileImage": "https://img.url",
            "badges": [],
            "channel": "",
            "text": "Hello",
            "isAction": false,
            "emotes": [],
            "msgId": 12345678
        },
        "renderedText": "Hello"
    }
}

Membership Event

The listener for membership notifications is member-latest. The full JSON schema for the event is

{
    "listener": "member-latest",
    "event": {
        "type": "member",
        "name": "sigmacw",
        "amount": 1,
        "count": 1,
        "items": [],
        "tier": "1000",
        "month": 1,
        "message": "Hello",
        "sessionTop": false,
        "originalEventName": "member-latest",
        "profileImage": "https://img.url",
        "badge": "https://badge.url"
    }
}

Membership Gift

The listener for membership gifts is gift-latest. The full JSON schema for the event is

{
    "listener": "gift-latest",
    "event": {
        "type": "gift",
        "name": "sigmacw",
        "items": [],
        "tier": "1000",
        "month": "",
        "message": "Hello",
        "sessionTop": false,
        "originalEventName": "gift-latest",
        "profileImage": "https://img.url",
        "amount": 1,
        "badge": "https://badge.url"
    }
}

Membership Redemption

The listener for membership redemption is gift-redemption. The full JSON schema for the event is

{
    "listener": "gift-redemption",
    "event": {
        "type": "gift-redemption",
        "name": "sigmacw",
        "items": [],
        "tier": "1000",
        "month": "",
        "message": "Hello",
        "sessionTop": false,
        "originalEventName": "gift-redemption",
        "profileImage": "https://img.url",
        "sender": "chroneco"
    }
}

Superchat Event

The listener for superchat messages is superchat-latest. Superchats have a lot of interesting information in them, specifically colors and tier. Tiers go from 1000 to 7000 based on the superchat color, and colors just list primary and secondary colors used in superchat messages.

The full JSON schema for the event is

{
    "listener": "superchat-latest",
    "event": {
        "type": "superchat",
        "name": "sigmacw",
        "amount": 50,
        "count": 1,
        "items": [],
        "tier": "1000",
        "colors": {
            "primaryColor": "rgba(30,136,229,1)",
            "secondaryColor": "rgba(21,101,192,1)"
        },
        "month": "",
        "message": "Hello",
        "sessionTop": false,
        "originalEventName": "superchat-latest",
        "profileImage": "https://img.url",
        "badge": "https://badge.url"
    }
}

Sticker Event

The listener for sticker messages is sticker-latest. Stickers, just like superchats, have a lot of interesting information in them, specifically colors and tier. Tiers go from 1000 to 7000 based on the sticker color, and colors just list primary and secondary colors used in sticker messages.

The full JSON schema for the event is

{
    "listener": "sticker-latest",
    "event": {
        "type": "sticker",
        "name": "sigmacw",
        "amount": 50,
        "count": 1,
        "items": [],
        "tier": "1000",
        "colors": {
            "primaryColor": "rgba(30,136,229,1)",
            "secondaryColor": "rgba(21,101,192,1)"
        },
        "month": "",
        "stickerUrl": "https://sticker.url",
        "message": "",
        "sessionTop": false,
        "originalEventName": "sticker-latest",
        "profileImage": "https://img.url",
    }
}

Youtube Basic

This one is a bit special. It doesn't have any special purpose, it just sends the raw HTML of the DOM Mutation. You can listen for it using youtube-basic as a listener, but it's only really useful for the default YouTube chat preset in the app. The JSON schema for this event is as follows

{
    "listener": "youtube-basic",
    "event": {
        "type": "message",
        "html": "<yt-message-renderer-..> ..."
    }
}