Delete js directory

This commit is contained in:
Rodrigo Emanuel
2025-04-20 09:11:19 -03:00
committed by GitHub
parent c01d3eaa1d
commit 6ffd0e15bf
11 changed files with 0 additions and 2155 deletions

View File

@@ -1,335 +0,0 @@
/* ----------------------- */
/* MOCKUP SYSTEM */
/* ----------------------- */
let mockupInterval = null;
let isMockupActive = false;
const mockupDelay = 2500; // 2 seconds between events
let mockupConnectionState = false; // Track mock connection state
// Sample data for mockup events
const mockData = {
users: [
{ id: 'user1', name: 'ViewerPro', avatar: 'https://static-cdn.jtvnw.net/user-default-pictures-uv/75305d54-c7cc-40d1-bb9c-91fbe85943c7-profile_image-70x70.png' },
{ id: 'user2', name: 'StreamFan42', avatar: 'https://static-cdn.jtvnw.net/user-default-pictures-uv/41780b5a-def8-11e9-94d9-784f43822e80-profile_image-70x70.png' },
{ id: 'user3', name: 'ProGamerVIP', avatar: 'https://static-cdn.jtvnw.net/user-default-pictures-uv/dbdc9198-def8-11e9-8681-784f43822e80-profile_image-70x70.png' },
{ id: 'user4', name: 'GameQueen', avatar: 'https://static-cdn.jtvnw.net/user-default-pictures-uv/de130ab0-def7-11e9-b668-784f43822e80-profile_image-70x70.png' },
],
messages: [
'Hey everyone! How\'s the stream going?',
'This game looks awesome!',
'LOL that was hilarious',
'GG WP!',
'When are you playing Minecraft next?',
'Love the new overlay!',
'First time watching, this is great!',
'Can you explain that strategy again?',
'Greetings from Germany!',
'What\'s your favorite game?'
],
emotes: [
'<img src="https://static-cdn.jtvnw.net/emoticons/v2/425618/default/dark/1.0" class="emote">',
'<img src="https://static-cdn.jtvnw.net/emoticons/v2/425671/default/dark/1.0" class="emote">',
'<img src="https://static-cdn.jtvnw.net/emoticons/v2/301428702/default/dark/1.0" class="emote">'
],
rewards: [
'Highlight My Message',
'Play Sound Effect',
'Choose Next Game',
'Song Request',
'Dad Joke',
'Hydration Check'
],
announcements: [
'Welcome to the stream everyone!',
'Don\'t forget to follow for stream notifications!',
'We\'re going to raid someone awesome after this game!',
'Thanks for all the subs today!',
'New emotes coming next week!'
]
};
// Function to generate a random mockup event
function generateMockEvent() {
const eventTypes = [
'chat', 'chat', 'chat', 'chat', 'chat', 'chat', 'chat', 'chat', // More weight to regular chat messages
'follow', 'sub', 'bits', 'raid', 'superchat', 'gift',
'announcement', 'reward', 'resub', 'giftsub'
];
// Select random event type and user
const eventType = eventTypes[Math.floor(Math.random() * eventTypes.length)];
const user = mockData.users[Math.floor(Math.random() * mockData.users.length)];
const messageId = createRandomString(40);
switch(eventType) {
case 'chat':
// Generate a regular chat message
const message = mockData.messages[Math.floor(Math.random() * mockData.messages.length)];
// Randomly add an emote
const includeEmote = Math.random() > 0.7;
const fullMessage = includeEmote ?
message + ' ' + mockData.emotes[Math.floor(Math.random() * mockData.emotes.length)] :
message;
const platform = Math.random() > 0.5 ? 'twitch' : (Math.random() > 0.5 ? 'youtube' : 'tiktok');
const messageData = {
classes: Math.random() > 0.8 ? 'sub' : '',
avatar: user.avatar,
badges: Math.random() > 0.8 ? '<i class="fa-solid fa-star"></i>' : '',
userName: user.name,
color: `hsl(${Math.random() * 360}, 100%, 75%)`,
message: fullMessage,
reply: '',
shared: ''
};
addMessageToChat(user.id, messageId, platform, messageData);
break;
case 'follow':
const followData = {
classes: 'follow',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.follow(),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', followData);
break;
case 'sub':
const subData = {
classes: 'sub',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.sub({
months: Math.floor(Math.random() * 24) + 1,
isPrime: Math.random() > 0.5,
tier: Math.floor(1000 * randomIntFromInterval(1,3))
}),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', subData);
break;
case 'resub':
const resubData = {
classes: 'sub',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.resub({
months: Math.floor(Math.random() * 24) + 1,
isPrime: Math.random() > 0.5,
tier: Math.floor(1000 * randomIntFromInterval(1,3))
}),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', resubData);
break;
case 'bits':
const bitsAmount = Math.floor(Math.random() * 5000) + 100;
const bitsData = {
classes: 'bits',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.bits({ bits: bitsAmount }),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', bitsData);
break;
case 'raid':
const viewerCount = Math.floor(Math.random() * 500) + 10;
const raidData = {
classes: 'raid',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.raid({ viewers: viewerCount }),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', raidData);
break;
case 'superchat':
const amount = (Math.random() * 100 + 5).toFixed(2);
const currencies = ['USD', 'EUR', 'CAD', 'GBP', 'AUD'];
const currency = currencies[Math.floor(Math.random() * currencies.length)];
const superChatData = {
classes: 'superchat',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.youtube.superchat({
money: formatCurrency(amount, currency),
message: mockData.messages[Math.floor(Math.random() * mockData.messages.length)]
}),
reply: '',
};
addEventToChat(user.id, messageId, 'youtube', superChatData);
break;
case 'gift':
const giftData = {
classes: 'gift',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.tiktok.gift({
gift: 'Rose',
count: Math.floor(Math.random() * 50) + 1,
coins: Math.floor(Math.random() * 1000) + 100
}),
reply: '',
};
addEventToChat(user.id, messageId, 'tiktok', giftData);
break;
case 'announcement':
const announcementText = mockData.announcements[Math.floor(Math.random() * mockData.announcements.length)];
const announcementData = {
classes: 'announcement',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: ` ${announcementText}`,
reply: currentLang.twitch.announcement(),
};
addEventToChat(user.id, messageId, 'twitch', announcementData);
break;
case 'reward':
const rewardTitle = mockData.rewards[Math.floor(Math.random() * mockData.rewards.length)];
const userInput = Math.random() > 0.5 ? mockData.messages[Math.floor(Math.random() * mockData.messages.length)] : '';
const rewardData = {
classes: 'rewards-redemption',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: ` ${userInput}`,
reply: currentLang.twitch.channelpoints({ title : rewardTitle }),
};
addEventToChat(user.id, messageId, 'twitch', rewardData);
break;
case 'giftsub':
const recipientUser = mockData.users[Math.floor(Math.random() * mockData.users.length)];
const giftsubData = {
classes: 'sub',
avatar: user.avatar,
badges: '',
userName: user.name,
color: '#FFF',
message: currentLang.twitch.gifted({
gifted: recipientUser.name,
months: Math.floor(Math.random() * 12) + 1,
tier: Math.floor(1000 * randomIntFromInterval(1,3)),
total: Math.floor(Math.random() * 50) + 1
}),
reply: '',
};
addEventToChat(user.id, messageId, 'twitch', giftsubData);
break;
}
}
// Function to start the mockup system
function startMockupSystem() {
if (!isMockupActive) {
console.debug('Starting mockup system...');
isMockupActive = true;
mockupConnectionState = false;
// Add a notification about mockup mode
notifyInfo({
title: currentLang.streamerbotdisconnected || "Streamer.Bot Disconnected",
text: "Running in mockup mode. Showing sample events."
});
// Start with a few initial events
for (let i = 0; i < 3; i++) {
setTimeout(() => generateMockEvent(), i * 500);
}
// Set interval for regular events
mockupInterval = setInterval(generateMockEvent, mockupDelay);
// Update statistics for demo
updateMockStatistics();
}
}
// Function to stop the mockup system
function stopMockupSystem() {
if (isMockupActive) {
console.debug('Stopping mockup system...');
isMockupActive = false;
mockupConnectionState = true;
clearInterval(mockupInterval);
mockupInterval = null;
// Clear chat to start fresh with real events
chatContainer.innerHTML = '';
document.querySelector('#statistics #twitch .viewers span').textContent = '0';
document.querySelector('#statistics #youtube .viewers span').textContent = '0';
document.querySelector('#statistics #youtube .likes span').textContent = '0';
document.querySelector('#statistics #tiktok .viewers span').textContent = '0';
document.querySelector('#statistics #tiktok .likes span').textContent = '0';
}
}
// Function to update mock statistics
function updateMockStatistics() {
if (showPlatformStatistics) {
if (showTwitchViewers) {
document.querySelector('#statistics #twitch .viewers span').textContent = formatNumber(Math.floor(Math.random() * 500) + 50);
}
if (showYouTubeStatistics) {
document.querySelector('#statistics #youtube .viewers span').textContent = formatNumber(Math.floor(Math.random() * 300) + 20);
document.querySelector('#statistics #youtube .likes span').textContent = formatNumber(Math.floor(Math.random() * 1000) + 100);
}
if (showTikTokStatistics) {
document.querySelector('#statistics #tiktok .viewers span').textContent = formatNumber(Math.floor(Math.random() * 800) + 200);
document.querySelector('#statistics #tiktok .likes span').textContent = formatNumber(Math.floor(Math.random() * 5000) + 500);
}
}
}
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}

287
js/app.js
View File

@@ -1,287 +0,0 @@
/* ----------------------- */
/* OPTIONS */
/* ----------------------- */
const streamerBotServerAddress = getURLParam("streamerBotServerAddress", "127.0.0.1");
const streamerBotServerPort = getURLParam("streamerBotServerPort", "8080");
const chatThreshhold = 50;
const chatContainer = document.querySelector('#chat');
const currentLang = lang[getURLParam("language", 'ptbr')];
const chatHorizontal = getURLParam("chatHorizontal", false);
const showPlatform = getURLParam("showPlatform", false);
const showAvatar = getURLParam("showAvatar", false);
const showTimestamps = getURLParam("showTimestamps", false);
const ampmTimeStamps = getURLParam("ampmTimeStamps", false);
const showBadges = getURLParam("showBadges", true);
const showPlatformStatistics = getURLParam("showPlatformStatistics", false);
const hideAfter = getURLParam("hideAfter", 0);
const ignoreChatters = getURLParam("ignoreChatters", "");
const excludeCommands = getURLParam("excludeCommands", true);
const avatars = new Map();
const userColors = new Map();
const ignoreUserList = ignoreChatters.split(',').map(item => item.trim().toLowerCase()) || [];
/* ----------------------- */
/* START */
/* ----------------------- */
if (showPlatformStatistics == false) { document.querySelector('#statistics').style.display = 'none'; }
if (chatHorizontal == true) { chatContainer.classList.add('horizontal'); }
/* ----------------------- */
/* STREAMER.BOT CONNECTION */
/* ----------------------- */
const streamerBotClient = new StreamerbotClient({
host: streamerBotServerAddress,
port: streamerBotServerPort,
onConnect: (data) => {
console.debug( currentLang.streamerbotconnected );
console.debug(data);
notifySuccess({
title: currentLang.streamerbotconnected,
text: ``
});
stopMockupSystem();
},
onDisconnect: () => {
console.error(currentLang.streamerbotdisconnected);
startMockupSystem();
}
});
streamerBotClient.on('WebsocketClient.Message', (response) => {
console.debug('Event Received:', response);
});
/* ----------------------- */
/* UTILITIES */
/* ----------------------- */
async function addMessageToChat(userID, messageID, platform, data) {
const html = DOMPurify.sanitize(`
<div id="${messageID}" data-user="${userID}" class="${platform} ${data.classes} message" style="">
<div class="animate__animated ${chatHorizontal == true ? 'animate__fadeInRight' : 'animate__fadeInUp'} animate__faster">
${!data.shared ? '' : data.shared}
${showTimestamps == true ? '<span class="time">'+whatTimeIsIt()+'</span>' : ''}
${showPlatform == true ? '<i class="platform fa-brands fa-'+platform+'"></i>' : '' }
${showAvatar == true ? '<span class="avatar"><img src="'+data.avatar+'"></span>' : ''}
${showBadges == true ? '<span class="badges">'+data.badges+'</span>' : ''}
<span style="color: ${data.color}" class="user">${data.userName}:</span>
${!data.reply ? '' : data.reply}
<span class="text">${data.message}</span>
</div>
</div>
`);
chatContainer.insertAdjacentHTML('beforeend', html);
const messageElement = document.getElementById(messageID);
if (hideAfter > 0) {
setTimeout(function () {
messageElement.style.opacity = 0;
setTimeout(function () {
messageElement.remove();
}, 1000);
}, Math.floor(hideAfter * 1000));
}
removeExtraChatMessages();
}
async function addEventToChat(userID, messageID, platform, data) {
const html = DOMPurify.sanitize(`
<div id="${messageID}" data-user="${userID}" class="${platform} ${data.classes} message event" style="">
<div class="animate__animated ${chatHorizontal == true ? 'animate__fadeInRight' : 'animate__fadeInUp'} animate__faster">
${!data.reply ? '' : data.reply}
${showPlatform == true ? '<i class="platform '+(platform == 'money' ? 'fa-solid' : 'fa-brands')+' fa-'+platform+'"></i>' : '&nbsp;&nbsp;' }
<span class="info">
<!--<span class="avatar"><img src="${data.avatar}"></span>-->
<span style="color: ${data.color}" class="user">${data.userName}</span>
<span class="text">${data.message}</span>
</span>
</div>
</div>
`);
chatContainer.insertAdjacentHTML('beforeend', html);
const messageElement = document.getElementById(messageID);
if (hideAfter > 0) {
setTimeout(function () {
messageElement.style.opacity = 0;
setTimeout(function () {
messageElement.remove();
}, 1000);
}, Math.floor(hideAfter * 1000));
}
removeExtraChatMessages();
}
const whatTimeIsIt = () => {
const now = new Date();
const hours24 = now.getHours();
const minutes = now.getMinutes().toString().padStart(2, '0');
const ampm = hours24 >= 12 ? 'PM' : 'AM';
const hours12 = (hours24 % 12) || 12;
if (ampmTimeStamps == true) { return `${hours12}:${minutes} ${ampm}`; }
else { return `${hours24}:${minutes}`; }
};
function removeExtraChatMessages() {
const chatMessages = chatContainer.querySelectorAll('div.message').length;
if (chatMessages >= chatThreshhold) {
for (let i = 0; i < Math.floor(chatThreshhold/2); i++) {
chatContainer.removeChild(chatContainer.firstElementChild);
}
}
}
// Function to format large numbers (e.g., 1000 => '1K')
function formatNumber(num) {
if (num >= 1000000) {
let numStr = (num / 1000000).toFixed(1);
if (numStr.endsWith('.0')) {
numStr = numStr.slice(0, -2);
}
return numStr + 'M';
}
else if (num >= 1000) {
let numStr = (num / 1000).toFixed(1);
if (numStr.endsWith('.0')) {
numStr = numStr.slice(0, -2);
}
return numStr + 'K';
}
return num.toString();
}
function formatCurrency(amount, currencyCode) {
return new Intl.NumberFormat(undefined, {
style: 'currency',
currency: currencyCode,
minimumFractionDigits: 0,
maximumFractionDigits: 2
}).format(amount);
}
function createRandomColor(platform, username) {
if (userColors.get(platform).has(username)) {
return userColors.get(platform).get(username);
}
else {
const randomColor = "hsl(" + Math.random() * 360 + ", 100%, 75%)";
userColors.get(platform).set(username, randomColor);
return randomColor;
}
}
function createRandomString(length) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
function getURLParam(param, defaultValue) {
const chatQueryString = window.location.search;
const urlParams = new URLSearchParams(chatQueryString);
const paramVar = urlParams.get(param);
switch (paramVar) {
case 'true':
return true;
case 'false':
return false;
case null:
case undefined:
return defaultValue;
default:
return paramVar;
}
}
const pushNotify = (data) => {
const SimpleNotify = {
effect: 'fade',
speed: 500,
customClass: 'toasty',
customIcon: '',
showIcon: true,
showCloseButton: true,
autoclose: true,
autotimeout: 5000,
notificationsGap: null,
notificationsPadding: null,
type: 'outline',
position: 'x-center bottom',
customWrapper: '',
};
const mergedData = {
...SimpleNotify,
...data
}
new Notify (mergedData);
}
const notifyError = (err) => {
err.status = 'error';
pushNotify(err);
}
const notifyInfo = (info) => {
info.status = 'info';
pushNotify(info);
}
const notifyWarning = (warn) => {
warn.status = 'warning';
pushNotify(warn);
}
const notifySuccess = (success) => {
success.status = 'success';
pushNotify(success);
}

View File

@@ -1,72 +0,0 @@
const en = {
streamerbotconnected: 'Streamer.bot Online!',
streamerbotdisconnected: 'Streamer.bot Disconnected!',
twitch : {
follow : () => ` followed the channel.`,
announcement : () => ` <div class="reply">📢 <strong>Announcement</strong></div>`,
channelpoints : ({ title }) => ` <div class="reply"><i class="fa-solid fa-wand-magic-sparkles"></i> <strong>Channel Points - ${title}</strong></div>`,
bits : ({ bits, message }) => ` cheered <i class="fa-regular fa-gem fall-and-bounce"></i> <strong>${bits} bits</strong>${message ? ' - '+message : ''}`,
sub : ({ months, isPrime, tier }) => ` subscribed for
${isPrime == true ? '<i class="fa-solid fa-crown"></i>' : '<i class="fa-solid fa-star"></i>'}
<strong>${months || 1 } ${months == 1 ? 'month' : 'months'}
(${isPrime == true ? 'Prime' : 'Tier '+tier.toString().charAt(0)})</strong>`,
resub : ({ months, isPrime, tier }) => ` subscribed for
${isPrime == true ? '<i class="fa-solid fa-crown"></i>' : '<i class="fa-solid fa-star"></i>'}
<strong>${months || 1 } ${months == 1 ? 'month' : 'months'}
(${isPrime == true ? 'Prime' : 'Tier '+tier.toString().charAt(0)})</strong>`,
gifted : ({ gifted, months, tier, total }) => ` gifted
<strong>${months || 1 } ${months == 1 ? 'month' : 'months'}
of Tier ${tier.toString().charAt(0)} sub</strong>
to <i class="fa-solid fa-gift"></i> <strong>${gifted}</strong>`,
giftedbomb : ({ count, total, tier }) => ` gifted <i class="fa-solid fa-gift"></i> <strong>${count} Tier ${tier.toString().charAt(0)} subs</strong> to the Community, <strong>${total || 1} ${total == 1 ? 'gift' : 'gifts'} in total.</strong>`,
raid : ({ viewers }) => ` raided the channel with <i class="fa-solid fa-users"></i> <strong>${viewers} viewers</strong>`
},
youtube : {
superchat : ({ money, message }) => ` superchatted <i class="fa-solid fa-comments-dollar"></i> <strong>${money}</strong>
${message ? ' - '+message : ''}
`,
supersticker : ({ money, message }) => ` sent a supersticker of <i class="fa-solid fa-comments-dollar"></i> <strong>${money}</strong>
${message ? ' - '+message : ''}
`,
member : ({ months, tier }) => ` became a member for
<i class="fa-solid fa-star"></i>
<strong>${months || 1 } ${months == 1 ? 'month' : 'months'}
(Tier ${tier})</strong>`,
giftedmembers : ({ total, tier }) => ` gifted <i class="fa-solid fa-gift"></i> <strong>${total} Tier ${tier} memberships</strong>`,
giftedtrainmembers : ({ gifted, tier }) => ` gifted a membership
<strong>(${tier})</strong>
to <i class="fa-solid fa-gift"></i> <strong>${gifted}</strong>`,
},
streamlabs : {
tip : ({ money, message }) => ` donated 🪙 <strong>${money}</strong><!-- ${message} -->`,
},
streamelements : {
tip : ({ money, message }) => ` donated 🪙 <strong>${money}</strong><!-- ${message} -->`,
},
tiktok : {
follow : () => ` followed the channel.`,
sub : ({ months }) => ` subscribed for <i class="fa-solid fa-star"></i> <strong>${months || 1 } ${months == 1 ? 'month' : 'months'}.</strong>`,
gift : ({ gift, count, coins }) => ` gifted <strong>${gift} x${count}</strong> (🪙 <strong>${coins} ${coins == 1 ? 'coin' : 'coins'}).</strong>`,
}
}

View File

@@ -1,4 +0,0 @@
const lang = {
ptbr : ptbr,
en : en
}

View File

@@ -1,72 +0,0 @@
const ptbr = {
streamerbotconnected: 'Streamer.bot Conectado!',
streamerbotdisconnected: 'Streamer.bot Desconectado!',
twitch : {
follow : () => ` seguiu o canal.`,
announcement : () => ` <div class="reply">📢 <strong>Anúncio</strong></div>`,
channelpoints : ({ title }) => ` <div class="reply"><i class="fa-solid fa-wand-magic-sparkles"></i> <strong>Pontos do Canal - ${title}</strong></div>`,
bits : ({ bits, message }) => ` doou <i class="fa-regular fa-gem fall-and-bounce"></i> <strong>${bits} bits</strong>${message ? ' - '+message : ''}`,
sub : ({ months, isPrime, tier }) => ` se inscreveu por
${isPrime == true ? '<i class="fa-solid fa-crown"></i>' : '<i class="fa-solid fa-star"></i>'}
<strong>${months || 1 } ${months == 1 ? 'mês' : 'meses'}
(${isPrime == true ? 'Prime' : 'Tier '+tier.toString().charAt(0)})</strong>`,
resub : ({ months, isPrime, tier }) => ` se inscreveu por
${isPrime == true ? '<i class="fa-solid fa-crown"></i>' : '<i class="fa-solid fa-star"></i>'}
<strong>${months || 1 } ${months == 1 ? 'mês' : 'meses'}
(${isPrime == true ? 'Prime' : 'Tier '+tier.toString().charAt(0)})</strong>`,
gifted : ({ gifted, months, tier }) => ` doou
<strong>${months || 1 } ${months == 1 ? 'mês' : 'meses'}
de Tier ${tier.toString().charAt(0)}</strong>
para <i class="fa-solid fa-gift"></i> <strong>${gifted}</strong>`,
giftedbomb : ({ count, total, tier }) => ` doou <i class="fa-solid fa-gift"></i> <strong>${count} inscrições Tier ${tier.toString().charAt(0)}</strong> para a Comunidade, totalizando <strong>${total || 1} ${total == 1 ? 'doação' : 'doações'}.</strong>`,
raid : ({ viewers }) => ` raidou o canal com <i class="fa-solid fa-users"></i> <strong>${viewers} pessoas</strong>`
},
youtube : {
superchat : ({ money, message }) => ` fez um superchat de <i class="fa-solid fa-comments-dollar"></i> <strong>${money}</strong>
${message ? ' - '+message : ''}
`,
supersticker : ({ money, message }) => ` enviou um superchat de <i class="fa-solid fa-comments-dollar"></i> <strong>${money}</strong>
${message ? ' - '+message : ''}
`,
member : ({ months, tier }) => ` se inscreveu por
<i class="fa-solid fa-star"></i>
<strong>${months || 1 } ${months == 1 ? 'mês' : 'meses'}
(Tier ${tier})</strong>`,
giftedmembers : ({ total, tier }) => ` doou <i class="fa-solid fa-gift"></i> <strong>${total} inscrições (Tier ${tier})</strong>`,
giftedtrainmembers : ({ gifted, tier }) => ` doou uma assinatura
<strong>(${tier})</strong>
para <i class="fa-solid fa-gift"></i> <strong>${gifted}</strong>`,
},
streamlabs : {
tip : ({ money, message }) => ` doou 🪙 <strong>${money}</strong><!-- ${message} -->`,
},
streamelements : {
tip : ({ money, message }) => ` doou 🪙 <strong>${money}</strong><!-- ${message} -->`,
},
tiktok : {
follow : () => ` seguiu o canal.`,
sub : ({ months }) => ` se inscreveu por <i class="fa-solid fa-star"></i> <strong>${months || 1 } ${months == 1 ? 'mês' : 'meses'}.</strong>`,
gift : ({ gift, count, coins }) => ` doou <strong>${gift} x${count}</strong> (🪙 <strong>${coins} ${coins == 1 ? 'moeda' : 'moedas'}).</strong>`,
}
}

View File

@@ -1,138 +0,0 @@
function saveSettingsToLocalStorage() {
const checkboxes = document.querySelectorAll("input[type=checkbox]");
const textfields = document.querySelectorAll("input[type=text]");
const numberfields = document.querySelectorAll("input[type=number]");
const selects = document.querySelectorAll("select");
const settings = {};
checkboxes.forEach((checkbox) => {
settings[checkbox.name] = checkbox.checked;
});
textfields.forEach((textfield) => {
settings[textfield.name] = textfield.value;
});
numberfields.forEach((numberfield) => {
settings[numberfield.name] = numberfield.value;
});
selects.forEach((select) => {
settings[select.name] = select.value;
});
localStorage.setItem("chatWidgetSettings", JSON.stringify(settings));
}
function loadSettingsFromLocalStorage() {
const saved = localStorage.getItem("chatWidgetSettings");
if (!saved) return;
const settings = JSON.parse(saved);
Object.keys(settings).forEach((key) => {
const input = document.querySelector(`[name="${key}"]`);
if (input) {
if (input.type === "checkbox") {
input.checked = settings[key];
} else {
input.value = settings[key];
}
}
});
}
function pushChangeEvents() {
const checkboxes = document.querySelectorAll("input[type=checkbox]");
const textfields = document.querySelectorAll("input[type=text]");
const numberfields = document.querySelectorAll("input[type=number]");
const selects = document.querySelectorAll("select");
checkboxes.forEach((checkbox) => {
checkbox.addEventListener('change', () => {
generateUrl();
saveSettingsToLocalStorage();
});
});
textfields.forEach((textfield) => {
textfield.addEventListener('input', () => {
generateUrl();
saveSettingsToLocalStorage();
});
});
numberfields.forEach((numberfield) => {
numberfield.addEventListener('input', () => {
generateUrl();
saveSettingsToLocalStorage();
});
});
selects.forEach((select) => {
select.addEventListener('change', () => {
generateUrl();
saveSettingsToLocalStorage();
});
});
}
function generateUrl() {
document.getElementById("outputUrl").value = '';
var runThisLocally = document.querySelector("input[type=checkbox][name=runThisLocally]").checked;
var baseUrl = '';
if (runThisLocally == false) {
baseUrl = 'https://vortisrd.github.io/chatrd/chat.html'
}
const checkboxes = document.querySelectorAll("input[type=checkbox]");
const textfields = document.querySelectorAll("input[type=text]");
const numberfields = document.querySelectorAll("input[type=number]");
const selects = document.querySelectorAll("select");
const params = new URLSearchParams();
selects.forEach((select) => {
params.set(select.name, select.value);
});
checkboxes.forEach((checkbox) => {
params.set(checkbox.name, checkbox.checked);
});
textfields.forEach((textfield) => {
params.set(textfield.name, textfield.value);
});
numberfields.forEach((numberfield) => {
params.set(numberfield.name, numberfield.value);
});
document.getElementById("outputUrl").value = baseUrl + '?' + params.toString();
document.querySelector('#chat-preview iframe').src = 'chat.html?'+params.toString();
}
function copyUrl() {
const output = document.getElementById("outputUrl");
output.select();
document.execCommand("copy");
const button = document.querySelector('.url-bar button');
const buttonDefaulText = 'Copy URL';
button.textContent = 'ChatRD URL Copied!';
button.style.backgroundColor = "#00dd63";
setTimeout(() => {
button.textContent = buttonDefaulText;
button.removeAttribute('style');
}, 3000);
}
window.addEventListener('load', () => {
loadSettingsFromLocalStorage();
generateUrl();
pushChangeEvents();
});

View File

@@ -1,44 +0,0 @@
const showStreamElementsTips = getURLParam("showStreamElementsTips", true);
const streamElementsHandlers = {
'StreamElements.Tip': (response) => {
console.debug(response.data);
if (showStreamElementsTips == false)
return;
streamElementsEventMessage(response.data);
},
};
for (const [event, handler] of Object.entries(streamElementsHandlers)) {
streamerBotClient.on(event, handler);
}
async function streamElementsEventMessage(data) {
const {
username: userName,
amount: moneyFromUser,
currency: currencyFromUser,
message: messageFromUser,
} = data;
const userID = createRandomString(40);
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
'',
currentLang.streamlabs.tip({
money : formatCurrency(moneyFromUser,currencyFromUser),
message : messageFromUser
})
]);
const classes = 'streamelements';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'dollar-sign', messageData);
}

View File

@@ -1,42 +0,0 @@
const showStreamlabsDonations = getURLParam("showStreamlabsDonations", true);
const streamLabsHandlers = {
'Streamlabs.Donation': (response) => {
console.debug(response.data);
if (showStreamlabsDonations == false)
return;
streamLabsEventMessage(response.data);
},
};
for (const [event, handler] of Object.entries(streamLabsHandlers)) {
streamerBotClient.on(event, handler);
}
async function streamLabsEventMessage(data) {
const {
from: userName,
formattedAmount: moneyFromUser,
currency: currencyFromUser,
message: messageFromUser,
} = data;
const userID = createRandomString(40);
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
'',
currentLang.streamlabs.tip({
money : formatCurrency(moneyFromUser,currencyFromUser),
message : messageFromUser
})
]);
const classes = 'streamlabs';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'dollar-sign', messageData);
}

View File

@@ -1,222 +0,0 @@
/* ----------------------------------------------------------------------------------------- */
/* TikFinity >< Streamer.Bot */
/* ----------------------------------------------------------------------------------------- */
/* In Streamer.bot, go into Servers/Clients, then Websocket clients, */
/* and add the server info for TikFinity Desktop App. */
/* ----------------------------------------------------------------------------------------- */
/* If it's also running on the same computer, the address will be: ws://127.0.0.1:21213/ */
/* ----------------------------------------------------------------------------------------- */
const showTikTokMessages = getURLParam("showTikTokMessages", true);
const showTikTokFollows = getURLParam("showTikTokFollows", true);
const showTikTokGifts = getURLParam("showTikTokGifts", true);
const showTikTokSubs = getURLParam("showTikTokSubs", true);
const showTikTokStatistics = getURLParam("showTikTokStatistics", true);
userColors.set('tiktok', new Map());
if (showTikTokStatistics == false) { document.querySelector('#statistics #tiktok').style.display = 'none'; }
streamerBotClient.on('General.Custom', (response) => {
if (response.data.platform === 'TikTok') {
let json = response.data;
let jsonData = json.data.data;
switch (json.data.event) {
case 'roomUser' :
if (showPlatformStatistics == false || showTikTokStatistics == false) return;
tiktokUpdateStatistics(jsonData, 'viewers');
break;
case 'like' :
if (showPlatformStatistics == false || showTikTokStatistics == false) return;
tiktokUpdateStatistics(jsonData, 'likes');
break;
case 'chat' :
console.debug(json);
if (showTikTokMessages == false) return;
if (ignoreUserList.includes(jsonData.nickname.toLowerCase())) return;
tiktokChatMessage(jsonData);
break;
case 'follow' :
if (showTikTokFollows == false) return;
tiktokFollowMessage(jsonData);
break;
case 'subscribe' :
if (showTikTokSubs == false) return;
tiktokSubMessage(jsonData);
break;
case 'gift' :
if (showTikTokGifts == false) return;
if (jsonData.giftType === 1 && !jsonData.repeatEnd) {}
else {
tiktokGiftMessage(jsonData);
}
break;
default:
//console.debug(json);
}
}
});
async function tiktokChatMessage(data) {
if (data.comment.startsWith("!") && excludeCommands == true)
return;
const {
userId: userID,
msgId: messageID,
profilePictureUrl: avatar,
comment: message,
emotes,
nickname: userName,
isSubscriber,
isModerator,
} = data;
const badgesHTML = [
isSubscriber && '<i class="fa-solid fa-star"></i>',
isModerator && '<i class="fa-solid fa-user-gear"></i>',
].filter(Boolean).join('');
const classes = [
isSubscriber && 'sub',
isModerator && 'mod',
].filter(Boolean);
var fullmessage = message;
emotes.forEach(emote => {
var emotetoadd = ` <img src="${emote.emoteImageUrl}" class="emote" data-emote-id="${emote.emoteId}"> `;
var position = emote.placeInComment;
fullmessage = [fullmessage.slice(0, position), emotetoadd, fullmessage.slice(position)].join('');
});
const messageData = {
classes: classes.join(' '),
avatar,
badges: badgesHTML,
userName,
color: await createRandomColor('tiktok', userID),
message: fullmessage,
reply: '',
};
addMessageToChat(userID, messageID, 'tiktok', messageData);
}
async function tiktokFollowMessage(data) {
const {
userId: userID,
msgId: messageID,
profilePictureUrl: avatar,
nickname: userName,
} = data;
const message = currentLang.tiktok.follow();
const classes = 'follow'
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'tiktok', messageData);
}
async function tiktokSubMessage(data) {
const {
userId: userID,
msgId: messageID,
profilePictureUrl: avatar,
nickname: userName,
} = data;
const message = currentLang.tiktok.sub({
months : data.subMonth
});
const classes = 'sub'
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'tiktok', messageData);
}
async function tiktokGiftMessage(data) {
const {
userId: userID,
msgId: messageID,
profilePictureUrl: avatar,
nickname: userName,
} = data;
var coins = Math.floor(data.repeatCount*data.diamondCount);
const message = currentLang.tiktok.gift({
gift : data.giftName,
count : data.repeatCount,
coins : coins
});
const classes = 'gift'
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'tiktok', messageData);
}
async function tiktokUpdateStatistics(data, type) {
if (type == 'viewers') {
const viewers = DOMPurify.sanitize(data.viewerCount);
document.querySelector('#statistics #tiktok .viewers span').textContent = formatNumber(viewers);
}
if (type == 'likes') {
const likes = DOMPurify.sanitize(data.totalLikeCount);
document.querySelector('#statistics #tiktok .likes span').textContent = formatNumber(likes);
}
}

View File

@@ -1,588 +0,0 @@
const showTwitchMessages = getURLParam("showTwitchMessages", true);
const showTwitchFollows = getURLParam("showTwitchFollows", true);
const showTwitchBits = getURLParam("showTwitchBits", true);
const showTwitchAnnouncements = getURLParam("showTwitchAnnouncements", true);
const showTwitchSubs = getURLParam("showTwitchSubs", true);
const showTwitchGiftedSubs = getURLParam("showTwitchGiftedSubs", true);
const showTwitchGiftedSubsUserTrain = getURLParam("showTwitchGiftedSubsUserTrain", true);
const showTwitchMassGiftedSubs = getURLParam("showTwitchMassGiftedSubs", true);
const showTwitchRewardRedemptions = getURLParam("showTwitchRewardRedemptions", true);
const showTwitchRaids = getURLParam("showTwitchRaids", true);
const showTwitchSharedChat = getURLParam("showTwitchSharedChat", true);
const showTwitchViewers = getURLParam("showTwitchViewers", true);
if (showTwitchViewers == false) { document.querySelector('#statistics #twitch').style.display = 'none'; }
const twitchMessageHandlers = {
'Twitch.ChatMessage': (response) => {
console.debug('Twitch Chat', response.data);
if (showTwitchMessages == false)
return;
if (ignoreUserList.includes(response.data.message.username.toLowerCase()))
return;
twitchChatMessage(response.data);
},
'Twitch.Follow': (response) => {
console.debug('Twitch Follow', response.data);
if (showTwitchFollows == false)
return;
twitchFollowMessage(response.data);
},
'Twitch.Announcement': (response) => {
console.debug('Twitch Announcements', response.data);
if (showTwitchAnnouncements == false) return;
twitchAnnouncementMessage(response.data);
},
'Twitch.Cheer': (response) => {
console.debug('Twitch Cheer/Bits', response.data);
if (showTwitchBits == false) return;
twitchBitsMessage(response.data);
},
'Twitch.AutomaticRewardRedemption': (response) => {
console.debug('Twitch Auto Reward Redemption', response.data);
if (showTwitchMessages == false) return;
twitchChatMessageGiantEmote(response.data);
},
'Twitch.RewardRedemption': (response) => {
console.debug('Twitch Reward Redemption', response.data);
if (showTwitchRewardRedemptions == false) return;
twitchRewardRedemption(response.data);
},
'Twitch.Sub': (response) => {
console.debug('Twitch Sub', response.data);
if (showTwitchSubs == false) return;
twitchSubMessage(response.data);
},
'Twitch.ReSub': (response) => {
console.debug('Twitch Resub', response.data);
if (showTwitchSubs == false) return;
twitchReSubMessage(response.data);
},
'Twitch.GiftSub': (response) => {
console.debug('Twitch Gift Sub', response.data);
if (response.data.fromCommunitySubGift === false) {
if (showTwitchSubs == false || showTwitchGiftedSubs == false) return;
twitchGiftMessage(response.data);
}
else {
if (showTwitchSubs == false || showTwitchGiftedSubsUserTrain == false) return;
twitchGiftMessage(response.data);
}
},
'Twitch.GiftBomb': (response) => {
console.debug('Twitch Gift Bomb', response.data);
if (showTwitchSubs == false || showTwitchMassGiftedSubs == false) return;
twitchGiftSubsMessage(response.data);
},
'Twitch.Raid': (response) => {
console.debug('Twitch Raid', response.data);
if (showTwitchRaids == false) return;
twitchRaidMessage(response.data);
},
'Twitch.ChatMessageDeleted': (response) => {
console.debug(response.data);
twitchChatMessageDeleted(response.data);
},
'Twitch.UserBanned': (response) => {
console.debug(response.data);
twitchUserBanned(response.data);
},
'Twitch.UserTimedOut': (response) => {
console.debug(response.data);
twitchUserBanned(response.data);
},
'Twitch.ViewerCountUpdate': (response) => {
console.debug(response.data);
if (showPlatformStatistics == false || showTwitchViewers == false) return;
twitchUpdateStatistics(response.data);
},
'Twitch.ChatCleared': (response) => {
console.debug(response.data);
twitchChatClearMessages();
}
};
for (const [event, handler] of Object.entries(twitchMessageHandlers)) {
streamerBotClient.on(event, handler);
}
async function twitchChatMessage(data) {
if (data.message.message.startsWith("!") && excludeCommands == true)
return;
const {
message: {
username: userID,
color,
displayName: userName,
message: text,
firstMessage,
isReply,
isSharedChat,
reply: replyData,
},
messageId,
} = data;
const [avatar, message, badges] = await Promise.all([
getTwitchAvatar(userID),
getTwitchEmotes(data),
getTwitchBadges(data),
]);
const classes = firstMessage ? ['first-message'] : [];
const replyHTML = isReply ?
`<div class="reply"><i class="fa-solid fa-arrow-turn-up"></i> <strong>${replyData.userName}:</strong> ${replyData.msgBody}</div>` :
'';
var sharedChat = '';
if (isSharedChat) {
if (showTwitchSharedChat == true) {
if (!data.sharedChat.primarySource)
{
var sharedChat = `<div class="shared"><span><i class="fa-solid fa-comments"></i> <strong>${data.sharedChat.sourceRoom.name}</strong></span> <i class="fa-solid fa-arrow-turn-down"></i></div>`;
}
}
else if (!data.sharedChat.primarySource && showTwitchSharedChat == false) {
return;
}
}
const messageData = {
classes: classes.join(' '),
avatar,
badges,
userName,
color,
message,
shared: sharedChat,
reply: replyHTML,
};
addMessageToChat(userID, messageId, 'twitch', messageData);
}
async function twitchChatMessageGiantEmote(data) {
const { user_login: userID, gigantified_emote: { id: emoteGigantify } } = data;
const userMessages = chatContainer.querySelectorAll(`.twitch.message[data-user="${userID}"]`);
if (userMessages.length === 0) return;
const firstMessage = userMessages[0];
const emoteImages = firstMessage.querySelectorAll(`img[data-emote-id="${emoteGigantify}"]`);
if (emoteImages.length === 0) return;
emoteImages.forEach(img => {
img.classList.add("gigantify");
if (img.src.endsWith("2.0")) {
img.src = img.src.replace("2.0", "3.0");
}
});
}
async function twitchFollowMessage(data) {
const {
user_id : userID,
user_name : userName
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.follow(),
]);
const classes = 'follow';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchBitsMessage(data) {
const {
messageId : messageID,
user : {
id : userID,
name : userName
}
} = data;
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.bits({
bits: data.message.bits,
message : data.message.message.replace(/\bCheer\d+\b/g, '').replace(/\s+/g, ' ').trim()
}),
]);
const classes = 'bits';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchAnnouncementMessage(data) {
const {
messageId : messageID,
user : {
id : userID,
name : userName
}
} = data;
data.message = {
message: await getTwitchAnnouncementEmotes(data)
};
const replyHTML = currentLang.twitch.announcement();
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
` ${data.message.message}`
]);
const classes = 'announcement';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: replyHTML,
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchRewardRedemption(data) {
const {
user_id : userID,
user_name : userName,
} = data;
const messageID = createRandomString(40);
const replyHTML = currentLang.twitch.channelpoints({ title : data.reward.title });
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
` ${data.user_input}`
]);
const classes = 'rewards-redemption';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: replyHTML,
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchSubMessage(data) {
const {
user : {
id : userID,
name : userName
}
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.sub({
months : data.duration_months,
isPrime : data.isPrime,
tier : data.sub_tier
})
]);
const classes = 'sub';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchReSubMessage(data) {
const {
user : {
id : userID,
name : userName
}
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.resub({
months : data.cumulativeMonths,
isPrime : data.isPrime,
tier : data.subTier
})
]);
const classes = 'sub';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchGiftMessage(data) {
const {
user : {
id : userID,
name : userName
}
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.gifted({
gifted : data.recipient.name,
months : data.durationMonths,
tier : data.subTier,
total : data.cumlativeTotal
})
]);
const classes = 'sub';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchGiftSubsMessage(data) {
const {
user : {
id : userID,
name : userName
}
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.giftedbomb({ count : data.total, tier : data.sub_tier, total : data.cumulative_total })
]);
const classes = 'sub';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchRaidMessage(data) {
const {
from_broadcaster_user_login: userID,
from_broadcaster_user_name: userName
} = data;
const messageID = createRandomString(40);
const [avatar, message] = await Promise.all([
getTwitchAvatar(userID),
currentLang.twitch.raid({ viewers : data.viewers })
]);
const classes = 'raid';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
};
addEventToChat(userID, messageID, 'twitch', messageData);
}
async function twitchChatMessageDeleted(data) {
document.getElementById(data.messageId)?.remove();
}
async function twitchUserBanned(data) {
chatContainer.querySelectorAll(`[data-user="${data.user_login}"]`).forEach(element => {
element.remove();
});
}
async function twitchChatClearMessages() {
chatContainer.innerHTML = '';
}
async function twitchUpdateStatistics(data) {
const viewers = DOMPurify.sanitize(data.viewers);
document.querySelector('#statistics #twitch .viewers span').textContent = formatNumber(viewers);
}
async function getTwitchEmotes(data) {
const message = data.message.message;
const emotes = data.emotes;
const words = message.split(" ");
emotes.sort((a, b) => b.startIndex - a.startIndex);
for (let i = 0; i < words.length; i++) {
emotes.forEach(emote => {
if (words[i] === emote.name) {
words[i] = `<img src="${emote.imageUrl}" data-emote-id="${emote.id}" alt="${emote.name}" class="emote">`;
}
});
}
return words.join(" ");
}
async function getTwitchAnnouncementEmotes(data) {
const message = data.text;
const emotes = data.parts;
const words = message.split(" ");
emotes.sort((a, b) => b.startIndex - a.startIndex);
for (let i = 0; i < words.length; i++) {
emotes.forEach(emote => {
if (words[i] === emote.text) {
words[i] = `<img src="${emote.imageUrl}" alt="${emote.text}" class="emote">`;
}
});
}
return words.join(" ");
}
async function getTwitchBadges(data) {
const badges = data.message.badges;
var htmlBadges = '';
badges.forEach((badge) => {
htmlBadges += `<img src="${badge.imageUrl}" class="badge">`;
});
return htmlBadges;
}
async function getTwitchAvatar(user) {
if (showAvatar == true) {
if (avatars.has(user)) {
console.debug(`Avatar found for ${user}!`);
return avatars.get(user);
}
else {
console.debug(`Avatar not found for ${user}! Getting it from DECAPI!`);
var decapi = await fetch('https://decapi.me/twitch/avatar/' + user);
var newavatar = await decapi.text()
avatars.set(user, newavatar);
return newavatar;
}
}
}

View File

@@ -1,351 +0,0 @@
const showYouTubeMessages = getURLParam("showYouTubeMessages", true);
const showYouTubeSuperChats = getURLParam("showYouTubeSuperChats", true);
const showYouTubeSuperStickers = getURLParam("showYouTubeSuperStickers", false);
const showYouTubeMemberships = getURLParam("showYouTubeMemberships", true);
const showYouTubeGiftMemberships = getURLParam("showYouTubeGiftMemberships", true);
const showYouTubeMembershipsTrain = getURLParam("showYouTubeMembershipsTrain", true);
const showYouTubeStatistics = getURLParam("showYouTubeStatistics", true);
userColors.set('youtube', new Map());
if (showYouTubeStatistics == false) { document.querySelector('#statistics #youtube').style.display = 'none'; }
const youtubeMessageHandlers = {
'YouTube.Message': (response) => {
console.debug('YouTube Chat', response.data);
if (showYouTubeMessages == false)
return;
if (ignoreUserList.includes(response.data.user.name.toLowerCase()))
return;
youTubeChatMessage(response.data);
},
/*'YouTube.SuperChat': (response) => {
console.debug('YouTube SuperChat', response.data);
if (showYouTubeSuperChats == false) return;
youTubeSuperChatMessage(response.data);
},
'YouTube.SuperSticker': (response) => {
console.debug('YouTube SuperSticker', response.data);
if (showYouTubeSuperStickers == false) return;
youTubeSuperStickerMessage(response.data);
},
'YouTube.NewSponsor': (response) => {
console.debug('YouTube New Member', response.data);
if (showYouTubeMemberships == false) return;
youTubeNewSponsorMessage(response.data);
},
'YouTube.MemberMileStone': (response) => {
console.debug('YouTube Member Milestone', response.data);
if (showYouTubeMemberships == false) return;
youTubeNewSponsorMessage(response.data);
},
'YouTube.MembershipGift': (response) => {
console.debug('YouTube Gifted Membership', response.data);
if (showYouTubeGiftMemberships == false) return;
youTubeGiftedMembersMessage(response.data);
},
'YouTube.GiftMembershipReceived': (response) => {
console.debug('YouTube Gifted Membership Bomb', response.data);
if (showYouTubeMembershipsTrain == false) return;
youTubeGiftedMembersMessage(response.data);
},*/
'YouTube.StatisticsUpdated': (response) => {
console.debug(response.data);
if (showYouTubeStatistics == false) return;
youTubeUpdateStatistics(response.data);
}
};
for (const [event, handler] of Object.entries(youtubeMessageHandlers)) {
streamerBotClient.on(event, handler);
}
streamerBotClient.on('General.Custom', (response) => {
if (response.data.platform === 'YouTube') {
let json = response.data;
let ytdata = response.data.data;
switch (json.data.eventname) {
case 'Super Chat' :
console.debug('YouTube Super Chat', ytdata);
if (showYouTubeSuperChats == false) return;
youTubeSuperChatMessage(ytdata);
break;
case 'Super Sticker' :
console.debug('YouTube Super Sticker', ytdata);
if (showYouTubeSuperStickers == false) return;
youTubeSuperStickerMessage(ytdata);
break;
case 'New Sponsor' :
console.debug('YouTube New Member', ytdata);
if (showYouTubeMemberships == false) return;
youTubeNewSponsorMessage(ytdata);
break;
case 'Member Milestone' :
console.debug('YouTube Member Milestone', ytdata);
if (showYouTubeMemberships == false) return;
youTubeNewSponsorMessage(ytdata);
break;
case 'Membership Gift' :
console.debug('YouTube Membership Gift', ytdata);
if (showYouTubeGiftMemberships == false) return;
youTubeGiftedMembersMessage(ytdata);
break;
case 'Gift Membership Received' :
console.debug('YouTube Gift Bomb Membership', ytdata);
if (showYouTubeMembershipsTrain == false) return;
YouTubeGiftReceivedMessage(ytdata);
break;
default:
console.debug('General YouTube Data', ytdata);
}
}
});
async function youTubeChatMessage(data) {
if (data.message.startsWith("!") && excludeCommands == true)
return;
const {
user: {
id: userID,
profileImageUrl: avatar,
name: userName,
isVerified,
isSponsor,
isModerator,
isOwner,
},
eventId: messageID,
message,
} = data;
var messageHTML = message;
const badgesHTML = [
isVerified && '<i class="fa-solid fa-check"></i>',
isSponsor && '<i class="fa-solid fa-star"></i>',
isModerator && '<i class="fa-solid fa-wrench"></i>',
isOwner && '<i class="fa-solid fa-video"></i>',
].filter(Boolean).join('');
const classes = [
isSponsor && 'sub',
isModerator && 'mod',
isOwner && 'owner',
].filter(Boolean);
for (i in data.emotes) {
const emoteElement = `<img src="${data.emotes[i].imageUrl}" class="emote"/>`;
messageHTML = messageHTML.replace(data.emotes[i].name, emoteElement);
}
const messageData = {
classes: classes.join(' '),
avatar,
badges: badgesHTML,
userName,
color: await createRandomColor('youtube', userID),
message : messageHTML,
reply: '',
};
addMessageToChat(userID, messageID, 'youtube', messageData);
}
async function youTubeSuperChatMessage(data) {
const {
user: {
id: userID,
name: userName,
},
eventId: messageID,
currencyCode: currency,
amount,
message : textmessage
} = data;
/*var moneycurrency = currency || 'USD';
var money = formatCurrency(amount, moneycurrency);*/
var money = amount;
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.superchat({
money : money,
message : textmessage
})
]);
const classes = 'superchat';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
}
addEventToChat(userID, messageID, 'youtube', messageData);
}
async function youTubeSuperStickerMessage(data) {
const {
user: {
id: userID,
name: userName,
},
eventId: messageID,
currency,
amount,
message : textmessage
} = data;
/*var moneycurrency = currency || 'USD';
var money = formatCurrency(amount, moneycurrency);*/
var money = amount;
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.superchat({
money : money,
message : textmessage
})
]);
const classes = 'supersticker';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
}
addEventToChat(userID, messageID, 'youtube', messageData);
}
async function youTubeNewSponsorMessage(data) {
const {
user: {
id: userID,
name: userName,
},
eventId: messageID,
levelName,
months,
tier,
} = data;
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.member({
months : months,
tier : levelName,
})
]);
const classes = 'member';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
}
addEventToChat(userID, messageID, 'youtube', messageData);
}
async function youTubeGiftedMembersMessage(data) {
const {
user: {
id: userID,
name: userName,
},
eventId: messageID,
tier,
count
} = data;
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.giftedmembers({
total : count,
tier : tier
})
]);
const classes = 'giftedmembers';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
}
addEventToChat(userID, messageID, 'youtube', messageData);
}
async function YouTubeGiftReceivedMessage(data) {
const {
user: {
id: userID,
name: userName,
},
gifter: {
id : gifterUserId,
name: gifterUserName
},
eventId: messageID,
tier
} = data;
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.giftedmembers({
gifted : gifterUserName,
tier : tier
})
]);
const classes = 'giftedtrainmembers';
const messageData = {
classes: classes,
avatar,
badges: '',
userName,
color: '#FFF',
message,
reply: '',
}
addEventToChat(userID, messageID, 'youtube', messageData);
}
async function youTubeUpdateStatistics(data) {
const viewers = DOMPurify.sanitize(data.concurrentViewers);
const likes = DOMPurify.sanitize(data.likeCount);
document.querySelector('#statistics #youtube .viewers span').textContent = formatNumber(viewers);
document.querySelector('#statistics #youtube .likes span').textContent = formatNumber(likes);
}