diff --git a/.common/utils/helpers.js b/.common/utils/helpers.js
index a6925f5..effe42d 100644
--- a/.common/utils/helpers.js
+++ b/.common/utils/helpers.js
@@ -4,6 +4,9 @@
const avatarMap = new Map();
const pronounMap = new Map();
+// const kickPusherKey = '32cbd69e4b950bf97679'; // Updated Pusher key for Kick
+const kickPusherKey = '34bf7a0ff419a2a775b9'; // Updated Pusher key for Kick
+const kickPusherWsUrl = `wss://ws-us2.pusher.com/app/${kickPusherKey}?protocol=7&client=js&version=8.4.0&flash=false`;
@@ -325,7 +328,7 @@ function RandomHex(str) {
}
// Used to construct a message from "parts" variable commonly found in Streamer.bot chat messages
-function ConstructMessageFromParts(parts) {
+function ConstructMessageFromParts(parts, isHorizontalChat = false, twitchGIFsEnabled = false) {
return parts.map(part => {
if (part.emoji)
return `
`;
@@ -358,7 +361,15 @@ function ConstructMessageFromParts(parts) {
case "mention":
return part.text;
case "gif":
- return `
`;
+ if (twitchGIFsEnabled)
+ {
+ if (!isHorizontalChat)
+ return `
`;
+ else
+ return `
`;
+ }
+ else
+ return `${EscapeHTML(part.text)}`;
default:
return `
`;
}
diff --git a/horizontal-chat/script.js b/horizontal-chat/script.js
index 34967d1..ed558fc 100644
--- a/horizontal-chat/script.js
+++ b/horizontal-chat/script.js
@@ -16,7 +16,6 @@ let alertQueue = [];
// GLOBAL VARS //
/////////////////
-const kickPusherWsUrl = 'wss://ws-us2.pusher.com/app/32cbd69e4b950bf97679?protocol=7&client=js&version=7.6.0&flash=false';
let kickSubBadges = [];
/////////////
@@ -51,6 +50,7 @@ const showTwitchPowerUpRedemptions = GetBooleanParam("showTwitchPowerUpRedemptio
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true);
const showTwitchSharedChat = GetBooleanParam("showTwitchSharedChat", true);
+const showTwitchGIFs = GetBooleanParam("showTwitchGIFs", false);
const showKickMessages = GetBooleanParam("showKickMessages", true);
const showKickFollows = GetBooleanParam("showKickFollows", false);
@@ -62,6 +62,8 @@ const showKickGifts = GetBooleanParam("showKickGifts", true);
const showYouTubeMessages = GetBooleanParam("showYouTubeMessages", true);
const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true);
const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true);
+const showYouTubeJewelsGifted = GetBooleanParam("showYouTubeJewelsGifted", true);
+const showYouTubeSubscribers = GetBooleanParam("showYouTubeSubscribers", false);
const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true);
const enableTikTokSupport = GetBooleanParam("enableTikTokSupport", false);
@@ -235,6 +237,16 @@ client.on('YouTube.SuperSticker', (response) => {
YouTubeSuperSticker(response.data);
})
+client.on('YouTube.JewelsGifted', (response) => {
+ console.debug(response.data);
+ YouTubeJewelsGifted(response.data);
+})
+
+client.on('YouTube.NewSubscriber', (response) => {
+ console.debug(response.data);
+ YouTubeNewSubscriber(response.data);
+})
+
client.on('YouTube.NewSponsor', (response) => {
console.debug(response.data);
YouTubeNewSponsor(response.data);
@@ -576,7 +588,7 @@ async function TwitchChatMessage(data) {
}
// Set the message data
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, true, showTwitchGIFs);
const messageColor = data.user.color;
const role = data.user.role;
@@ -681,7 +693,7 @@ async function TwitchAnnouncement(data) {
break;
}
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, true, showTwitchGIFs);
ShowAlert(message, background);
}
@@ -834,7 +846,7 @@ async function TwitchWatchStreak(data) {
// TODO: Streamer.bot v1.0.5-alpha3 changed the data sent with this event, so for backwards compatibility we need to check for both the old and new properties
const displayName = data.displayName ?? data.user.name;
- const watchStreak = data.watchStreak ?? data.streak_count;
+ const watchStreak = data.watchStreak ?? data.streak_count ?? data.streakCount;
let message = `${displayName} is currently on a ${watchStreak} stream streak!`;
@@ -937,7 +949,7 @@ function YouTubeMessage(data) {
// Set the message data
//let message = RenderMessageWithEmotesHTML(data.message, data.emotes);
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, true, showTwitchGIFs);
// Set furry mode
if (furryMode)
@@ -1043,6 +1055,27 @@ function YouTubeSuperSticker(data) {
ShowAlert(message, 'youtube');
}
+function YouTubeJewelsGifted(data) {
+ if (!showYouTubeJewelsGifted)
+ return;
+
+ let message = `${data.user.name} gifted ${data.jewelsAmount} Jewels`;
+
+ ShowAlert(message, 'youtube');
+}
+
+function YouTubeNewSubscriber(data) {
+ if (!showYouTubeSubscribers)
+ return;
+
+ // Set the text
+ let username = data.user.name;
+
+ const message = `${username} subscribed`;
+
+ ShowAlert(message, 'youtube');
+}
+
function YouTubeNewSponsor(data) {
if (!showYouTubeMemberships)
return;
@@ -1361,7 +1394,7 @@ async function KickChatMessage(data) {
}
// Set the message data
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, true, showTwitchGIFs);
// Set furry mode
if (furryMode)
diff --git a/horizontal-chat/settings/settings.json b/horizontal-chat/settings/settings.json
index eac218e..25a9c93 100644
--- a/horizontal-chat/settings/settings.json
+++ b/horizontal-chat/settings/settings.json
@@ -226,6 +226,14 @@
"defaultValue": true,
"group": "Which Twitch messages do you want to see?"
},
+ {
+ "id": "showTwitchGIFs",
+ "label": "GIFs",
+ "description": "Tier 2/3 subs only",
+ "type": "checkbox",
+ "defaultValue": false,
+ "group": "Which Twitch messages do you want to see?"
+ },
{
"id": "showYouTubeMessages",
"label": "Chat Messages",
@@ -250,6 +258,22 @@
"defaultValue": true,
"group": "Which YouTube messages do you want to see?"
},
+ {
+ "id": "showYouTubeJewelsGifted",
+ "label": "Jewels Gifted",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": true,
+ "group": "Which YouTube messages do you want to see?"
+ },
+ {
+ "id": "showYouTubeSubscribers",
+ "label": "New Subscribers",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": false,
+ "group": "Which YouTube messages do you want to see?"
+ },
{
"id": "showYouTubeMemberships",
"label": "Memberships",
diff --git a/multichat-overlay/index.html b/multichat-overlay/index.html
index b8aa6a5..a5134d4 100644
--- a/multichat-overlay/index.html
+++ b/multichat-overlay/index.html
@@ -9,7 +9,7 @@
- Connecting...
+
@@ -98,8 +98,6 @@
13
-
-
diff --git a/multichat-overlay/script.js b/multichat-overlay/script.js
index 5c989db..e3f50a2 100644
--- a/multichat-overlay/script.js
+++ b/multichat-overlay/script.js
@@ -13,7 +13,6 @@ const sbServerPort = urlParams.get("port") || "8080";
/////////////////
const youtubeRegex = /^(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})(?:[&?#].*)?$/;
-const kickPusherWsUrl = 'wss://ws-us2.pusher.com/app/32cbd69e4b950bf97679?protocol=7&client=js&version=7.6.0&flash=false';
let kickSubBadges = [];
/////////////
@@ -57,6 +56,7 @@ const showTwitchPowerUpRedemptions = GetBooleanParam("showTwitchPowerUpRedemptio
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true);
const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2);
+const showTwitchGIFs = GetBooleanParam("showTwitchGIFs", true);
const showKickMessages = GetBooleanParam("showKickMessages", true);
const showKickFollows = GetBooleanParam("showKickFollows", false);
@@ -68,6 +68,8 @@ const showKickGifts = GetBooleanParam("showKickGifts", true);
const showYouTubeMessages = GetBooleanParam("showYouTubeMessages", true);
const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true);
const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true);
+const showYouTubeJewelsGifted = GetBooleanParam("showYouTubeJewelsGifted", true);
+const showYouTubeSubscribers = GetBooleanParam("showYouTubeSubscribers", false);
const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true);
const enableTikTokSupport = GetBooleanParam("enableTikTokSupport", false);
@@ -271,6 +273,16 @@ client.on('YouTube.SuperSticker', (response) => {
YouTubeSuperSticker(response.data);
})
+client.on('YouTube.JewelsGifted', (response) => {
+ console.debug(response.data);
+ YouTubeJewelsGifted(response.data);
+})
+
+client.on('YouTube.NewSubscriber', (response) => {
+ console.debug(response.data);
+ YouTubeNewSubscriber(response.data);
+})
+
client.on('YouTube.NewSponsor', (response) => {
console.debug(response.data);
YouTubeNewSponsor(response.data);
@@ -675,7 +687,7 @@ async function TwitchChatMessage(data) {
}
// Set the message data
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, false, showTwitchGIFs);
const messageColor = data.user.color;
const role = data.user.role;
@@ -927,7 +939,7 @@ async function TwitchAnnouncement(data) {
else
content.querySelector("#username").innerText = `${data.user.name} (${data.user.login})`;
content.querySelector("#username").style.color = data.user.color;
- content.querySelector("#message").innerHTML = ConstructMessageFromParts(data.parts);
+ content.querySelector("#message").innerHTML = ConstructMessageFromParts(data.parts, false, showTwitchGIFs);
// Remove the line break
content.querySelector("#colon-separator").style.display = `inline`;
@@ -1307,10 +1319,10 @@ async function TwitchWatchStreak(data) {
// TODO: Streamer.bot v1.0.5-alpha3 changed the data sent with this event, so for backwards compatibility we need to check for both the old and new properties
const displayName = data.displayName ?? data.user.name;
- const watchStreak = data.watchStreak ?? data.streak_count;
+ const watchStreak = data.watchStreak ?? data.streak_count ?? data.streakCount;
titleDiv.innerText = `${displayName} is currently on a ${watchStreak} stream streak! `;
- contentDiv.innerHTML = ConstructMessageFromParts(data.parts);
+ contentDiv.innerHTML = ConstructMessageFromParts(data.parts, false, showTwitchGIFs);
AddMessageItem(instance, data.messageId);
}
@@ -1427,7 +1439,7 @@ async function YouTubeMessage(data) {
// Set the message data
//let message = RenderMessageWithEmotesHTML(data.message, data.emotes);
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, false, showTwitchGIFs);
// Highlight mentions
const mentionRgx = new RegExp(`(^|\\s)@${youtubeUsername}(\\s|$)`, 'i');
@@ -1662,6 +1674,70 @@ function YouTubeSuperSticker(data) {
AddMessageItem(instance);
}
+function YouTubeJewelsGifted(data) {
+ if (!showYouTubeJewelsGifted)
+ 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('youtube');
+
+ avatarDiv.style.width = 'auto';
+
+ // Set the text
+ const user = data.user.name;
+ const amount = data.jewelsAmount;
+ const jewelURL = data.url;
+ const jewelImage = `
`;
+
+ avatarDiv.innerHTML = jewelImage;
+ titleDiv.innerHTML = `${user} gifted ${amount} Jewels`;
+
+ AddMessageItem(instance);
+}
+
+function YouTubeNewSubscriber(data) {
+ if (!showYouTubeSubscribers)
+ 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('youtube');
+
+ // Set the text
+ let username = data.user.name;
+
+ titleDiv.innerText = `${username} subscribed`;
+
+ AddMessageItem(instance);
+}
+
function YouTubeNewSponsor(data) {
if (!showYouTubeMemberships)
return;
@@ -2408,7 +2484,7 @@ async function KickChatMessage(data) {
}
// Set the message data
- let message = ConstructMessageFromParts(data.parts);
+ let message = ConstructMessageFromParts(data.parts, false, showTwitchGIFs);
// Highlight mentions
const mentionRgx = new RegExp(`(^|\\s)@${kickUsername}(\\s|$)`, 'i');
@@ -2795,7 +2871,6 @@ async function KickKicksGifted(data) {
const giftNameSpan = instance.querySelector('#kick-gift-name');
const stickerImg = instance.querySelector('.kick-gift-sticker');
const amountDiv = instance.querySelector('#kick-gift-amount');
- const messageDiv = instance.querySelector('#kick-gift-message');
avatarImg.src = await GetAvatar(data.sender.username, 'kick'); // Set the card header
usernameSpan.innerText = data.sender.username; // Set the username
@@ -2803,7 +2878,6 @@ async function KickKicksGifted(data) {
giftNameSpan.innerText = data.gift.name; // Set the gift name
stickerImg.src = `https://files.kick.com/kicks/gifts/${data.gift.gift_id.replace('_', '-')}.webp`; // Set the sticker image URL
amountDiv.innerText = data.gift.amount; // Set the number of gifts sent
- messageDiv.innerText = data.message // Set the message
AddMessageItem(instance, null, 'kick', data.senderId);
}
diff --git a/multichat-overlay/settings/settings.json b/multichat-overlay/settings/settings.json
index 8445c9d..1ff85d3 100644
--- a/multichat-overlay/settings/settings.json
+++ b/multichat-overlay/settings/settings.json
@@ -355,6 +355,14 @@
"defaultValue": 2,
"group": "Which Twitch messages do you want to see?"
},
+ {
+ "id": "showTwitchGIFs",
+ "label": "GIFs",
+ "description": "Tier 2/3 subs only",
+ "type": "checkbox",
+ "defaultValue": true,
+ "group": "Which Twitch messages do you want to see?"
+ },
{
"id": "showYouTubeMessages",
"label": "Chat Messages",
@@ -379,6 +387,22 @@
"defaultValue": true,
"group": "Which YouTube messages do you want to see?"
},
+ {
+ "id": "showYouTubeJewelsGifted",
+ "label": "Jewels Gifted",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": true,
+ "group": "Which YouTube messages do you want to see?"
+ },
+ {
+ "id": "showYouTubeSubscribers",
+ "label": "New Subscribers",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": false,
+ "group": "Which YouTube messages do you want to see?"
+ },
{
"id": "showYouTubeMemberships",
"label": "Memberships",
diff --git a/multichat-overlay/style.css b/multichat-overlay/style.css
index 7b3ed0c..1e013c7 100644
--- a/multichat-overlay/style.css
+++ b/multichat-overlay/style.css
@@ -282,7 +282,7 @@ li {
}
.kick-gift-sticker {
- height: 5em;
+ height: 2.5em;
}
#tiktok-gift-repeat-count {
diff --git a/multistream-alerts/script.js b/multistream-alerts/script.js
index b25d9f0..6d3afe7 100644
--- a/multistream-alerts/script.js
+++ b/multistream-alerts/script.js
@@ -27,7 +27,6 @@ let alertQueue = [];
// GLOBAL VARS //
/////////////////
-const kickPusherWsUrl = 'wss://ws-us2.pusher.com/app/32cbd69e4b950bf97679?protocol=7&client=js&version=7.6.0&flash=false';
let kickSubBadges = [];
@@ -89,6 +88,10 @@ const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true);
const youtubeSuperChatAction = urlParams.get("youtubeSuperChatAction") || "";
const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true);
const youtubeSuperStickerAction = urlParams.get("youtubeSuperStickerAction") || "";
+const showYouTubeJewelsGifted = GetBooleanParam("showYouTubeJewelsGifted", true);
+const youtubeJewelsGiftedAction = urlParams.get("youtubeJewelsGiftedAction") || "";
+const showYouTubeSubscribers = GetBooleanParam("showYouTubeSubscribers", false);
+const youtubeSubscriberAction = urlParams.get("youtubeSubscriberAction") || "";
const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true);
const youtubeMembershipAction = urlParams.get("youtubeMembershipAction") || "";
@@ -247,6 +250,16 @@ client.on('YouTube.SuperSticker', (response) => {
YouTubeSuperSticker(response.data);
})
+client.on('YouTube.JewelsGifted', (response) => {
+ console.debug(response.data);
+ YouTubeJewelsGifted(response.data);
+})
+
+client.on('YouTube.NewSubscriber', (response) => {
+ console.debug(response.data);
+ YouTubeNewSubscriber(response.data);
+})
+
client.on('YouTube.NewSponsor', (response) => {
console.debug(response.data);
YouTubeNewSponsor(response.data);
@@ -772,7 +785,7 @@ async function TwitchWatchStreak(data) {
// Set the text
// TODO: Streamer.bot v1.0.5-alpha3 changed the data sent with this event, so for backwards compatibility we need to check for both the old and new properties
const displayName = data.displayName ?? data.user.name;
- const watchStreak = data.watchStreak ?? data.streak_count;
+ const watchStreak = data.watchStreak ?? data.streak_count ?? data.streakCount;
UpdateAlertBox(
'twitch',
@@ -827,6 +840,46 @@ function YouTubeSuperSticker(data) {
);
}
+function YouTubeJewelsGifted(data) {
+ if (!showYouTubeJewelsGifted)
+ return;
+
+ UpdateAlertBox(
+ 'youtube',
+ data.url,
+ `${data.user.name}`,
+ `gifted ${data.jewelsAmount} Jewels`,
+ '',
+ data.user.name,
+ '',
+ youtubeJewelsGiftedAction,
+ data
+ );
+}
+
+function YouTubeNewSubscriber(data) {
+ if (!showYouTubeSubscribers)
+ return;
+
+ // Set the text
+ const username = data.user.name;
+
+ // Render avatars
+ const avatarURL = data.user.profileImageUrl;
+
+ UpdateAlertBox(
+ 'youtube',
+ avatarURL,
+ `${username}`,
+ `subscribed`,
+ ``,
+ username,
+ ``,
+ youtubeSubscriberAction,
+ data
+ );
+}
+
function YouTubeNewSponsor(data) {
if (!showYouTubeMemberships)
return;
diff --git a/multistream-alerts/settings/settings.json b/multistream-alerts/settings/settings.json
index ec19143..a4cff71 100644
--- a/multistream-alerts/settings/settings.json
+++ b/multistream-alerts/settings/settings.json
@@ -380,6 +380,40 @@
"showIf": "showYouTubeSuperStickers",
"group": "Which YouTube alerts do you want to see?"
},
+ {
+ "id": "showYouTubeJewelsGifted",
+ "label": "Jewels Gifted",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": true,
+ "group": "Which YouTube alerts do you want to see?"
+ },
+ {
+ "id": "youtubeJewelsGiftedAction",
+ "label": "",
+ "description": "Also run this Streamer.bot Action",
+ "type": "sb-actions",
+ "defaultValue": "",
+ "showIf": "showYouTubeJewelsGifted",
+ "group": "Which YouTube alerts do you want to see?"
+ },
+ {
+ "id": "showYouTubeSubscribers",
+ "label": "New Subscribers",
+ "description": "",
+ "type": "checkbox",
+ "defaultValue": false,
+ "group": "Which YouTube alerts do you want to see?"
+ },
+ {
+ "id": "youtubeSubscriberAction",
+ "label": "",
+ "description": "Also run this Streamer.bot Action",
+ "type": "sb-actions",
+ "defaultValue": "",
+ "showIf": "showYouTubeSubscribers",
+ "group": "Which YouTube alerts do you want to see?"
+ },
{
"id": "showYouTubeMemberships",
"label": "Memberships",
diff --git a/now-playing/themes/classic/style.css b/now-playing/themes/classic/style.css
index 8880684..ff8f10a 100644
--- a/now-playing/themes/classic/style.css
+++ b/now-playing/themes/classic/style.css
@@ -9,6 +9,8 @@
align-items: stretch;
gap: 0.5em;
opacity: 0;
+ filter: drop-shadow(15px 15px 7px rgba(0, 0, 0, 1));
+
}
#album-art-container {