WebSocket data - songify-rocks/Songify GitHub Wiki

πŸ“‘ WebSocket: Subscribe to real-time data

Songify provides a WebSocket endpoint that streams live data such as the current track, requester, queue, and user information.

Endpoint

/ws/data

How to connect

JavaScript (Browser / Node.js)

const ws = new WebSocket("ws://localhost:PORT/ws/data");

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log(data);
};

C# example

using System.Net.WebSockets;
using System.Text;

using var client = new ClientWebSocket();
await client.ConnectAsync(new Uri("ws://localhost:PORT/ws/data"), CancellationToken.None);

var buffer = new byte[8192];

while (client.State == WebSocketState.Open)
{
    var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    var message = Encoding.UTF8.GetString(buffer, 0, result.Count);

    Console.WriteLine(message);
}

Response structure

Each message contains the full current state:

{
   "UserInfo":{
      "TwitchUser":{
         "Id":"string",
         "Login":"string",
         "BroadcasterType":"string"
      },
      "SpotifyUser":{
         "Id":"string",
         "DisplayName":"string",
         "Product":"string"
      }
   },
   "SongifyInfo":{
      "Version":"string",
      "Beta":"boolean"
   },
   "Track":{
      "Data":{
         "Artists":"string",
         "Title":"string",
         "Albums":[
            {
               "Height":"integer",
               "Width":"integer",
               "Url":"string"
            }
         ],
         "SongId":"string",
         "DurationMs":"integer",
         "IsPlaying":"boolean",
         "Url":"string",
         "DurationPercentage":"number",
         "DurationTotal":"integer",
         "Progress":"integer",
         "Playlist":"string | null",
         "FullArtists":[
            {
               "ExternalUrls":{
                  "spotify":"string"
               },
               "Href":"string",
               "Id":"string",
               "Name":"string",
               "Type":"string",
               "Uri":"string"
            }
         ]
      },
      "CanvasUrl":"string",
      "IsInLikedPlaylist":"boolean",
      "Requester":{
         "Name":"string",
         "ProfilePicture":"string"
      }
   },
   "Queue":{
      "Count":"integer",
      "Requests":[
         {
            "queueid":"integer",
            "uuid":"string",
            "trackid":"string",
            "artist":"string",
            "title":"string",
            "length":"string",
            "requester":"string",
            "albumcover":"string",
            "playerType":"string | null",
            "IsLiked":"boolean",
            "FullRequester":{
               "Id":"string",
               "DisplayName":"string",
               "ProfileImageUrl":"string"
            }
         }
      ],
      "Tracks":[
         {
            "queueid":"integer",
            "uuid":"string",
            "trackid":"string",
            "artist":"string",
            "title":"string",
            "length":"string",
            "requester":"string",
            "albumcover":"string",
            "playerType":"string | null",
            "IsLiked":"boolean",
            "FullRequester":"object | null"
         }
      ],
      "songRequests":{
         "chat":"boolean",
         "reward":"boolean"
      }
   }

Behavior

  • The WebSocket pushes updates automatically whenever:

    • the current track changes
    • playback state updates
    • the queue changes
    • requester info updates
  • Each message contains the full state, not partial updates.

Notes

  • Replace PORT with your configured Songify WebServer port
  • Use ws:// for local connections
  • When Require WebSocket password is on, connect with ?password= (or the password header). Unauthenticated connections are rejected, including /ws/data.

WebSocket Command Reference

This document provides examples of all supported WebSocket commands used to control Songify via a WebSocket connection.

Each message must be sent as raw JSON with an "action" key and an optional "data" object depending on the action.


πŸ“ Notes

  • The track field in queue_add can be a full Spotify link or a text search query.
  • The requester field is optional and will default to "" if not specified.
  • All messages must be sent as raw JSON strings through your WebSocket client.

🎡 Add to Queue

Adds a song to the request queue by Spotify link or search term.

{
  "action": "queue_add",
  "data": {
    "track": "https://open.spotify.com/track/4PTG3Z6ehGkBFwjybzWkR8",
    "requester": "Viewer42"
  }
}

πŸ”Š Set Volume

Sets the Spotify volume to a specific value between 0 and 100.

{
  "action": "vol_set",
  "data": {
    "value": 80
  }
}

⏭️ Skip / Next Song

Skips the currently playing song.

{
  "action": "skip"
}

Alternative:

{
  "action": "next"
}

⏯️ Play / Pause

Toggles playback. Also supports explicit pause or play.

{
  "action": "play_pause"
}
{
  "action": "pause"
}
{
  "action": "play"
}

πŸ’¬ Send Current Song to Chat

Sends the currently playing song info to Twitch chat.

{
  "action": "send_to_chat"
}

🚫 Block Current Artist

Blocks the currently playing song’s artist from future requests.

{
  "action": "block_artist"
}

🚫 Block All Artists in Current Song

Blocks all artists listed on the currently playing song.

{
  "action": "block_all_artists"
}

🚫 Block Current Song

Blocks the currently playing song from being requested again.

{
  "action": "block_song"
}

🚫 Block Requesting User

Blocks the last user who requested a song.

{
  "action": "block_user"
}

πŸ›‘ Stop Song Request Reward

Pauses all Twitch channel point song request rewards. (Only works if the Reward was created using Songify)

{
  "action": "stop_sr_reward"
}

πŸ”‰ Increase Volume

Increases volume by 5%.

{
  "action": "vol_up"
}

πŸ”‰ Decrease Volume

Decreases volume by 5%.

{
  "action": "vol_down"
}

Enable / Disable Song Requests

Enable - sr_enable (same payloads work for alias sr_open)

{"action": "sr_enable"}
{"action": "sr_enable", "data": {}}
{"action": "sr_enable", "data": {"scope": "both"}}
{"action": "sr_enable", "data": {"scope": "reward"}}
{"action": "sr_enable", "data": {"scope": "command"}}

Alias examples (identical behavior to sr_enable):

{"action": "sr_open"}
{"action": "sr_open", "data": {}}
{"action": "sr_open", "data": {"scope": "both"}}
{"action": "sr_open", "data": {"scope": "reward"}}
{"action": "sr_open", "data": {"scope": "command"}}

Disable - sr_disable (same payloads work for alias sr_close)

{"action": "sr_disable"}
{"action": "sr_disable", "data": {}}
{"action": "sr_disable", "data": {"scope": "both"}}
{"action": "sr_disable", "data": {"scope": "reward"}}
{"action": "sr_disable", "data": {"scope": "command"}}

Alias examples (identical behavior to sr_disable):

{"action": "sr_close"}
{"action": "sr_close", "data": {}}
{"action": "sr_close", "data": {"scope": "both"}}
{"action": "sr_close", "data": {"scope": "reward"}}
{"action": "sr_close", "data": {"scope": "command"}}
Scope Meaning
chat Turns the Song Request command on/off
reward Turns the Song Request reward on/off
both Turns both on/off

Optional body defaults to both if omitted or if data is missing:

⚠️ **GitHub.com Fallback** ⚠️