From 38cd241122a12a1b08136c68602073ec0a25c6d8 Mon Sep 17 00:00:00 2001 From: nuttylmao Date: Sat, 8 Nov 2025 05:43:49 +1100 Subject: [PATCH] Added support for Twitch Watch Streaks --- horizontal-chat/script.js | 18 +++++++++ horizontal-chat/settings/settings.json | 8 ++++ multichat-overlay/script.js | 47 +++++++++++++++++++++++ multichat-overlay/settings/settings.json | 8 ++++ multistream-alerts/script.js | 31 +++++++++++++++ multistream-alerts/settings/settings.json | 17 ++++++++ 6 files changed, 129 insertions(+) diff --git a/horizontal-chat/script.js b/horizontal-chat/script.js index 43358f7..f5cd335 100644 --- a/horizontal-chat/script.js +++ b/horizontal-chat/script.js @@ -46,6 +46,7 @@ const showTwitchFollows = GetBooleanParam("showTwitchFollows", false); const showTwitchSubs = GetBooleanParam("showTwitchSubs", true); const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true); const showTwitchRaids = GetBooleanParam("showTwitchRaids", true); +const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true); const showTwitchSharedChat = GetBooleanParam("showTwitchSharedChat", true); const kickUsername = urlParams.get("kickUsername") || ""; @@ -181,6 +182,11 @@ client.on('Twitch.Raid', (response) => { TwitchRaid(response.data); }) +client.on('Twitch.WatchStreak', (response) => { + console.debug(response.data); + TwitchWatchStreak(response.data); +}) + client.on('Twitch.ChatMessageDeleted', (response) => { console.debug(response.data); TwitchChatMessageDeleted(response.data); @@ -789,6 +795,18 @@ async function TwitchRaid(data) { ShowAlert(message, 'twitch'); } +async function TwitchWatchStreak(data) { + if (!showTwitchWatchStreaks) + return; + + const displayName = data.displayName; + const watchStreak = data.watchStreak; + + let message = `${displayName} is currently on a ${watchStreak}-stream streak!`; + + ShowAlert(message, 'twitch'); +} + function TwitchChatMessageDeleted(data) { const messageList = document.getElementById("messageList"); diff --git a/horizontal-chat/settings/settings.json b/horizontal-chat/settings/settings.json index 0222140..b1eed16 100644 --- a/horizontal-chat/settings/settings.json +++ b/horizontal-chat/settings/settings.json @@ -175,6 +175,14 @@ "defaultValue": true, "group": "Which Twitch messages do you want to see?" }, + { + "id": "showTwitchWatchStreaks", + "label": "Watch Streaks", + "description": "", + "type": "checkbox", + "defaultValue": true, + "group": "Which Twitch messages do you want to see?" + }, { "id": "showTwitchSharedChat", "label": "Shared Chat Messages", diff --git a/multichat-overlay/script.js b/multichat-overlay/script.js index abe2055..4448375 100644 --- a/multichat-overlay/script.js +++ b/multichat-overlay/script.js @@ -51,6 +51,7 @@ const showTwitchFollows = GetBooleanParam("showTwitchFollows", false); const showTwitchSubs = GetBooleanParam("showTwitchSubs", true); const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true); const showTwitchRaids = GetBooleanParam("showTwitchRaids", true); +const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true); const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2); const kickUsername = urlParams.get("kickUsername") || ""; @@ -200,6 +201,11 @@ client.on('Twitch.Raid', (response) => { TwitchRaid(response.data); }) +client.on('Twitch.WatchStreak', (response) => { + console.debug(response.data); + TwitchWatchStreak(response.data); +}) + client.on('Twitch.ChatMessageDeleted', (response) => { console.debug(response.data); TwitchChatMessageDeleted(response.data); @@ -1160,6 +1166,47 @@ async function TwitchRaid(data) { AddMessageItem(instance, data.messageId); } +async function TwitchWatchStreak(data) { + if (!showTwitchWatchStreaks) + return; + + // Get a reference to the template + const template = document.getElementById('cardTemplate'); + + // Create a new instance of the template + const instance = template.content.cloneNode(true); + + // Get divs + const cardDiv = instance.querySelector("#card"); + const headerDiv = instance.querySelector("#header"); + const avatarDiv = instance.querySelector("#avatar"); + const iconDiv = instance.querySelector("#icon"); + const titleDiv = instance.querySelector("#title"); + const contentDiv = instance.querySelector("#content"); + + // Set the card background colors + cardDiv.classList.add('twitch'); + + if (showAvatar) { + // Render avatars + const username = data.userName; + const avatarURL = await GetAvatar(username, 'twitch'); + const avatar = new Image(); + avatar.src = avatarURL; + avatar.classList.add("avatar"); + avatarDiv.appendChild(avatar); + } + + const displayName = data.displayName; + const watchStreak = data.watchStreak; + const message = data.message; + + titleDiv.innerText = `${displayName} is currently on a ${watchStreak}-stream streak! `; + contentDiv.innerText = `${message}`; + + AddMessageItem(instance, data.messageId); +} + function TwitchChatMessageDeleted(data) { const messageList = document.getElementById("messageList"); diff --git a/multichat-overlay/settings/settings.json b/multichat-overlay/settings/settings.json index dbf67a4..65ecd5a 100644 --- a/multichat-overlay/settings/settings.json +++ b/multichat-overlay/settings/settings.json @@ -282,6 +282,14 @@ "defaultValue": true, "group": "Which Twitch messages do you want to see?" }, + { + "id": "showTwitchWatchStreaks", + "label": "Watch Streaks", + "description": "", + "type": "checkbox", + "defaultValue": true, + "group": "Which Twitch messages do you want to see?" + }, { "id": "showTwitchSharedChat", "label": "Shared Chat Messages", diff --git a/multistream-alerts/script.js b/multistream-alerts/script.js index 3abfb05..a2a6ec9 100644 --- a/multistream-alerts/script.js +++ b/multistream-alerts/script.js @@ -67,6 +67,8 @@ const showTwitchCheers = GetBooleanParam("showTwitchCheers", true); const twitchCheerAction = urlParams.get("twitchCheerAction") || ""; const showTwitchRaids = GetBooleanParam("showTwitchRaids", true); const twitchRaidAction = urlParams.get("twitchRaidAction") || ""; +const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true); +const twitchWatchStreaksAction = urlParams.get("twitchWatchStreaksAction") || ""; // Which Kick alerts do you want to see? const kickUsername = urlParams.get("kickUsername") || ""; @@ -211,6 +213,11 @@ client.on('Twitch.Raid', (response) => { TwitchRaid(response.data); }) +client.on('Twitch.WatchStreak', (response) => { + console.debug(response.data); + TwitchWatchStreak(response.data); +}) + client.on('YouTube.SuperChat', (response) => { console.debug(response.data); YouTubeSuperChat(response.data); @@ -721,6 +728,30 @@ async function TwitchRaid(data) { ); } +async function TwitchWatchStreak(data) { + if (!showTwitchWatchStreaks) + return; + + // Render avatars + const avatarURL = await GetAvatar(data.userName, 'twitch'); + + // Set the text + const username = data.displayName; + const watchStreak = data.watchStreak; + + UpdateAlertBox( + 'twitch', + avatarURL, + `${username}`, + `is currently on a ${watchStreak}-stream streak!`, + '', + username, + '', + twitchWatchStreaksAction, + data + ); +} + function YouTubeSuperChat(data) { if (!showYouTubeSuperChats) return; diff --git a/multistream-alerts/settings/settings.json b/multistream-alerts/settings/settings.json index 89768e0..b59bc74 100644 --- a/multistream-alerts/settings/settings.json +++ b/multistream-alerts/settings/settings.json @@ -312,6 +312,23 @@ "showIf": "showTwitchRaids", "group": "Which Twitch alerts do you want to see?" }, + { + "id": "showTwitchWatchStreaks", + "label": "Watch Streaks", + "description": "", + "type": "checkbox", + "defaultValue": true, + "group": "Which Twitch alerts do you want to see?" + }, + { + "id": "twitchWatchStreaksAction", + "label": "", + "description": "Also run this Streamer.bot Action", + "type": "sb-actions", + "defaultValue": "", + "showIf": "showTwitchWatchStreaks", + "group": "Which Twitch alerts do you want to see?" + }, { "id": "showYouTubeSuperChats", "label": "Super Chats",