Add files via upload
This commit is contained in:
36
README.md
36
README.md
@@ -18,9 +18,9 @@ ChatRD is a chat overlay widget for OBS that unifies messages and events from **
|
|||||||
|
|
||||||
## 🛠️ Usage
|
## 🛠️ Usage
|
||||||
|
|
||||||
1. Make sure your **Twitch** and **YouTube** accounts are connected on **Streamer.bot** and you have **TikFinity Desktop App** installed and set up to your account on **TikTok**. **BOTH APPS NEED TO RUN ON THE SAME PC**.
|
1. Make sure your **Twitch** and **YouTube** accounts are connected on **Streamer.Bot** and you have **TikFinity Desktop App** installed and set up to your account on **TikTok**. **BOTH APPS NEED TO RUN ON THE SAME PC**.
|
||||||
2. In **Streamer.bot**, go to **Server/Clients → WebSocket Server** and make sure it is running
|
2. In **Streamer.Bot**, go to **Server/Clients → WebSocket Server** and make sure it is running
|
||||||
3. Import the string inside the file [streamerbot-import.vortisrd](https://github.com/vortisrd/chatrd/blob/main/streamerbot-import.vortisrd) to your **Streamer.bot** using the **Import** button at the top.
|
3. Import the string inside the file [streamerbot-import.vortisrd](https://github.com/vortisrd/chatrd/blob/main/streamerbot-import.vortisrd) to your **Streamer.Bot** using the **Import** button at the top.
|
||||||
4. Open the [Settings Page](https://vortisrd.github.io/chatrd) in your browser
|
4. Open the [Settings Page](https://vortisrd.github.io/chatrd) in your browser
|
||||||
5. Choose your desired options
|
5. Choose your desired options
|
||||||
6. Click **"Copy URL"**
|
6. Click **"Copy URL"**
|
||||||
@@ -30,21 +30,34 @@ ChatRD is a chat overlay widget for OBS that unifies messages and events from **
|
|||||||
|
|
||||||
## 🛠️ How to Use it in a Local Network
|
## 🛠️ How to Use it in a Local Network
|
||||||
|
|
||||||
1. On **Streamer.bot**, go to **Server/Clients → WebSocket Server** and make sure the Address is set to the Local Network IP from the PC, for example **192.168.0.10** ... or, if you prefer, use 0.0.0.0.
|
1. On **Streamer.Bot**, go to **Server/Clients → WebSocket Server** and make sure the Address is set to the Local Network IP from the PC, for example **192.168.0.10** ... or, if you prefer, use 0.0.0.0.
|
||||||
2. On the [Settings Page](https://vortisrd.github.io/chatrd), make sure you set that IP on **Streamer.bot WebSocket Server**.
|
2. On the [Settings Page](https://vortisrd.github.io/chatrd), make sure you set that IP on **Streamer.Bot WebSocket Server**.
|
||||||
3. Turn the **"Run Locally"** switch on.
|
3. Turn the **"Run Locally"** switch on.
|
||||||
4. Click **"Copy URL"**
|
4. Click **"Copy URL"**
|
||||||
5. [Download ChatRD](https://github.com/vortisrd/chatrd/archive/refs/heads/main.zip) on the machine you want to see the chat on or want to set up OBS in, unzipping the file.
|
5. [Download ChatRD](https://github.com/vortisrd/chatrd/archive/refs/heads/main.zip) on the machine you want to see the chat on or want to set up OBS in, unzipping the file.
|
||||||
6. Open it on your browser or add it in OBS as Browser Source (don't tick **Local File**)following the file trail, for example: **file:///C:/PATH_TO_THE_FILE/chat.html**.
|
6. Open it on your browser or add it in OBS as Browser Source (don't tick **Local File**)following the file trail, for example: **file:///C:/PATH_TO_THE_FILE/chat.html**.
|
||||||
7. After **chat.html**, paste the URL copied from the configurator. The full link should be like this: **file:///C:/PATH_TO_THE_FILE/chat.html?language=ptbr&showPlatform=true&showAvatar=true&showTimestamps=false&showBadges=true&showPlatformStatistics=false&excludeCommands=true&showTwitchMessages=true&showTwitchFollows=true&showTwitchBits=true&showTwitchAnnouncements=true&showTwitchSubs=true&showTwitchGiftedSubs=true&showTwitchMassGiftedSubs=true&showTwitchGiftedSubsUserTrain=true&showTwitchRewardRedemptions=true&showTwitchRaids=true&showTwitchSharedChat=true&showTwitchViewers=true&showYouTubeMessages=true&showYouTubeSuperChats=true&showYouTubeSuperStickers=false&showYouTubeMemberships=true&showYouTubeGiftMemberships=true&showYouTubeMembershipsTrain=true&showYouTubeStatistics=true&showTikTokMessages=true&showTikTokFollows=true&showTikTokGifts=true&showTikTokSubs=true&showTikTokStatistics=true&showStreamlabsDonations=true&showStreamElementsTips=true&ignoreChatters=&streamerBotServerAddress=127.0.0.1&streamerBotServerPort=8080&=&hideAfter=0**
|
7. After **chat.html**, paste the URL copied from the configurator. The full link should be like this: **file:///C:/PATH_TO_THE_FILE/chat.html?language=ptbr&showPlatform=true&showAvatar=true&showTimestamps=false&showBadges=true&showPlatformStatistics=false&excludeCommands=true&showTwitchMessages=true&showTwitchFollows=true&showTwitchBits=true&showTwitchAnnouncements=true&showTwitchSubs=true&showTwitchGiftedSubs=true&showTwitchMassGiftedSubs=true&showTwitchGiftedSubsUserTrain=true&showTwitchRewardRedemptions=true&showTwitchRaids=true&showTwitchSharedChat=true&showTwitchViewers=true&showYouTubeMessages=true&showYouTubeSuperChats=true&showYouTubeSuperStickers=false&showYouTubeMemberships=true&showYouTubeGiftMemberships=true&showYouTubeMembershipsTrain=true&showYouTubeStatistics=true&showTikTokMessages=true&showTikTokFollows=true&showTikTokGifts=true&showTikTokSubs=true&showTikTokStatistics=true&showStreamlabsDonations=true&showStreamElementsTips=true&ignoreChatters=&streamerBotServerAddress=127.0.0.1&streamerBotServerPort=8080&=&hideAfter=0**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔊 How to set TTS with Speaker.Bot
|
||||||
|
|
||||||
|
### Speaker.Bot Setup
|
||||||
|
1. Go to **Settings → WebSocket Server**, click on *Start Server*. Make sure to also tick the *Auto-Start* checkbox.
|
||||||
|
2. Go to **Settings → Speech Engine** and add the TTS Service of your preference. (Sapi5 is the Windows default).
|
||||||
|
3. Go to **Settings → Voice Aliases**, name the voice *SpeakerBot* and click **Add** right next to it.
|
||||||
|
4. In the Left Column, click on the **SpeakerBot** you just added and on the **Speak!** section, select the voice you want to use and click **Add**. (If you're using Sapi5, I recommend using *Microsoft Zira Desktop* as a voice).
|
||||||
|
|
||||||
|
### Streamer.Bot Setup
|
||||||
|
1. Import the [streamerbot-import.vortisrd](https://github.com/vortisrd/chatrd/blob/main/streamerbot-import.vortisrd) file to your **Streamer.Bot**. There's a new action that will handle the **Speaker.Bot** integration.
|
||||||
|
2. Go to **Integrations → Speaker.Bot**, click on *Connect*. Make sure to also tick the *Auto-Start* and *Auto-Connect* checkboxes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧩 Integrations
|
## 🧩 Integrations
|
||||||
|
|
||||||
- 🟣 **Twitch** (via Streamer.bot)
|
- 🟣 **Twitch** (via Streamer.Bot)
|
||||||
- 🔴 **YouTube** (via Streamer.bot)
|
- 🔴 **YouTube** (via Streamer.Bot)
|
||||||
- ⚫ **TikTok** (via TikFinity Desktop App)
|
- ⚫ **TikTok** (via TikFinity Desktop App)
|
||||||
- 💸 **Streamlabs / StreamElements**
|
- 💸 **Streamlabs / StreamElements**
|
||||||
|
|
||||||
@@ -52,8 +65,9 @@ ChatRD is a chat overlay widget for OBS that unifies messages and events from **
|
|||||||
|
|
||||||
## 📦 Dependencies
|
## 📦 Dependencies
|
||||||
|
|
||||||
- [Streamer.bot](https://streamer.bot)
|
- [Streamer.Bot](https://streamer.bot)
|
||||||
- [Streamer.bot Client JS](https://streamerbot.github.io/client/)
|
- [Speaker.Bot](http://speaker.bot/)
|
||||||
|
- [Streamer.Bot Client JS](https://streamerbot.github.io/client/)
|
||||||
- [TikFinity Desktop App](https://tikfinity.zerody.one/)
|
- [TikFinity Desktop App](https://tikfinity.zerody.one/)
|
||||||
- [Font Awesome](https://fontawesome.com/)
|
- [Font Awesome](https://fontawesome.com/)
|
||||||
- [Animate.css](https://animate.style/)
|
- [Animate.css](https://animate.style/)
|
||||||
@@ -78,9 +92,9 @@ ChatRD is a chat overlay widget for OBS that unifies messages and events from **
|
|||||||
## **⚠️ DISCLAIMERS ⚠️**
|
## **⚠️ DISCLAIMERS ⚠️**
|
||||||
|
|
||||||
### About YouTube Membership Emojis
|
### About YouTube Membership Emojis
|
||||||
I tried to add member emotes but **that is currently impossible due to YouTube's API not exposing Members Emotes and with that, Streamer.bot won't be able to show them.**. So I've added a way for the users to add them manually at the overlay, with the data saved as a Streamer.Bot Global Variable.
|
I tried to add member emotes but **that is currently impossible due to YouTube's API not exposing Members Emotes and with that, Streamer.Bot won't be able to show them.**. So I've added a way for the users to add them manually at the overlay, with the data saved as a Streamer.Bot Global Variable.
|
||||||
|
|
||||||
What Casterlabs Caffeinated, Social Stream Ninja and Onecomme do to scrape the emotes won't work with the current way Streamer.bot and my code works, so I had to choose between **making the user add them manually** or build a **server-sided executable (using NodeJS, Python or whatever) to read the chat as it's going or scrape the HTML code**. I don't want to add another executable on top of the user's flow, so it would be easier to use what it's currently available. **And no, I won't do any research based on what other tools do.** Tried to do that and wasted 1 week of my life doing it.
|
What Casterlabs Caffeinated, Social Stream Ninja and Onecomme do to scrape the emotes won't work with the current way Streamer.Bot and my code works, so I had to choose between **making the user add them manually** or build a **server-sided executable (using NodeJS, Python or whatever) to read the chat as it's going or scrape the HTML code**. I don't want to add another executable on top of the user's flow, so it would be easier to use what it's currently available. **And no, I won't do any research based on what other tools do.** Tried to do that and wasted 1 week of my life doing it.
|
||||||
|
|
||||||
When YouTube decide to expose their Partner Emotes on their API, I'll come back to this.
|
When YouTube decide to expose their Partner Emotes on their API, I'll come back to this.
|
||||||
|
|
||||||
|
@@ -45,13 +45,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.1.5/dist/purify.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.1.5/dist/purify.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/simple-notify@1.0.4/dist/simple-notify.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/simple-notify@1.0.4/dist/simple-notify.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@streamerbot/client@1.9.5/dist/streamerbot-client.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@streamerbot/client@1.9.5/dist/streamerbot-client.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script src="js/lang/ptbr.js"></script>
|
<script src="js/lang/ptbr.js"></script>
|
||||||
<script src="js/lang/en.js"></script>
|
<script src="js/lang/en.js"></script>
|
||||||
<script src="js/lang/es.js"></script>
|
<script src="js/lang/es.js"></script>
|
||||||
@@ -69,4 +66,4 @@
|
|||||||
<script src="js/streamelements/module.js"></script>
|
<script src="js/streamelements/module.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -422,3 +422,13 @@ footer a {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#memberemotesbstatus.online i {
|
||||||
|
color: #00dd63;
|
||||||
|
text-shadow: 0 0 5px #00dd63;
|
||||||
|
}
|
||||||
|
#memberemotesbstatus.offline i {
|
||||||
|
color: #ff0000;
|
||||||
|
text-shadow: 0 0 5px #ff0000;
|
||||||
|
}
|
28
index.html
28
index.html
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" c\ontent="width=device-width, initial-scale=1.0">
|
||||||
<title>ChatRD - Config</title>
|
<title>ChatRD - Config</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900">
|
||||||
@@ -22,9 +22,23 @@
|
|||||||
|
|
||||||
<div class="tab-content" id="config">
|
<div class="tab-content" id="config">
|
||||||
<h2><i class="fa-solid fa-screwdriver-wrench"></i> Config</h2>
|
<h2><i class="fa-solid fa-screwdriver-wrench"></i> Config</h2>
|
||||||
|
|
||||||
|
<div class="setting">
|
||||||
|
<small id="memberemotesbstatus" class="offline" style="display: inline-block; padding: 10px 20px 10px 10px; background-color: #232323; color: #FFF; border-radius: 10px;">
|
||||||
|
<i class="fa-solid fa-power-off"></i>
|
||||||
|
<span>Streamer.Bot is Offline!</span>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="setting field"><label>Streamer.bot WebSocket Server</label><input type="text" name="streamerBotServerAddress" value="127.0.0.1"></div>
|
<div class="setting field"><label>Streamer.bot WebSocket Server</label><input type="text" name="streamerBotServerAddress" value="127.0.0.1"></div>
|
||||||
<div class="setting field"><label>Streamer.bot WebSocket Port</label><input type="text" name="streamerBotServerPort" value="8080"></div>
|
<div class="setting field"><label>Streamer.bot WebSocket Port</label><input type="text" name="streamerBotServerPort" value="8080"></div>
|
||||||
<div class="setting"><label>Run Locally<br><small>In case you want to download ChatRD to run locally or over the network.<br><a target="_blank" href="https://github.com/vortisrd/chatrd?tab=readme-ov-file#%EF%B8%8F-how-to-use-in-a-local-network--como-usar-em-rede-local">Follow the tutorial.</a></small></label><label class="switch"><input type="checkbox" name="runThisLocally"><span class="slider"></span></label></div>
|
<div class="setting"><label>Text-to-Speech Chat<br><small>Enables TTS for Chat.</small></label><label class="switch"><input type="checkbox" name="ttsSpeakerBotChat"><span class="slider"></span></label></div>
|
||||||
|
|
||||||
|
<div class="setting"><label>Text-to-Speech Events<br><small>Enables TTS for Events.</small></label><label class="switch"><input type="checkbox" name="ttsSpeakerBotEvents"><span class="slider"></span></label></div>
|
||||||
|
|
||||||
|
<div class="setting"><small style="display: inline-block; padding: 10px 20px 10px 10px; background-color: #232323; color: #FFF; border-radius: 10px;"><i class="fa-solid fa-volume-high"></i> Speaker.Bot is required for Text-to-Speech! <strong><a target="_blank" href="https://github.com/vortisrd/chatrd?tab=readme-ov-file#%EF%B8%8F-how-to-use-in-a-local-network--como-usar-em-rede-local">Follow the tutorial</a>.</strong></small></label></div>
|
||||||
|
|
||||||
|
<div class="setting"><label>Run Locally<br><small>In case you want to download ChatRD to run locally or over the network.<br><strong><a target="_blank" href="https://github.com/vortisrd/chatrd?tab=readme-ov-file#%EF%B8%8F-how-to-use-in-a-local-network--como-usar-em-rede-local">Follow the tutorial</a></strong>.</small></label><label class="switch"><input type="checkbox" name="runThisLocally"><span class="slider"></span></label></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-content" id="geral">
|
<div class="tab-content" id="geral">
|
||||||
@@ -89,8 +103,16 @@
|
|||||||
<div class="setting"><label><i class="fa-solid fa-arrow-turn-up"></i> Gifted Membership<br><small>Shows the person gifting members.</small></label><label class="switch"><input type="checkbox" name="showYouTubeGiftMemberships" checked><span class="slider"></span></label></div>
|
<div class="setting"><label><i class="fa-solid fa-arrow-turn-up"></i> Gifted Membership<br><small>Shows the person gifting members.</small></label><label class="switch"><input type="checkbox" name="showYouTubeGiftMemberships" checked><span class="slider"></span></label></div>
|
||||||
<div class="setting"><label><i class="fa-solid fa-arrow-turn-up"></i> Gifted Membership Train<br><small>Shows all users that were gifted a membership on a massive gifting membership.</small></label><label class="switch"><input type="checkbox" name="showYouTubeMembershipsTrain" checked><span class="slider"></span></label></div>
|
<div class="setting"><label><i class="fa-solid fa-arrow-turn-up"></i> Gifted Membership Train<br><small>Shows all users that were gifted a membership on a massive gifting membership.</small></label><label class="switch"><input type="checkbox" name="showYouTubeMembershipsTrain" checked><span class="slider"></span></label></div>
|
||||||
<div class="setting"><label>Statistics<br><small>Shows viewers and likes.</small></label><label class="switch"><input type="checkbox" name="showYouTubeStatistics" checked><span class="slider"></span></label></div>
|
<div class="setting"><label>Statistics<br><small>Shows viewers and likes.</small></label><label class="switch"><input type="checkbox" name="showYouTubeStatistics" checked><span class="slider"></span></label></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="setting column">
|
<div class="setting column">
|
||||||
<label>Members Only Emotes<br><small>Because YouTube's API doesn't expose Partner Custom Emotes. <em>Really YouTube!?</em> 🤨<br><em id="memberemotesbstatus" style="font-style: normal; font-weight: bold; color: #ff0000;">Streamer.Bot Needs to be Online!</em></small></label>
|
<label>
|
||||||
|
Members Only Emotes
|
||||||
|
<br>
|
||||||
|
<small>Because YouTube's API doesn't expose Partner Custom Emotes. <em>Really YouTube!?</em> 🤨
|
||||||
|
</small>
|
||||||
|
</label>
|
||||||
<div class="emote-list">
|
<div class="emote-list">
|
||||||
|
|
||||||
<span class="emote-item">
|
<span class="emote-item">
|
||||||
|
47
js/app.js
47
js/app.js
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
const streamerBotServerAddress = getURLParam("streamerBotServerAddress", "127.0.0.1");
|
const streamerBotServerAddress = getURLParam("streamerBotServerAddress", "127.0.0.1");
|
||||||
const streamerBotServerPort = getURLParam("streamerBotServerPort", "8080");
|
const streamerBotServerPort = getURLParam("streamerBotServerPort", "8080");
|
||||||
|
|
||||||
|
const ttsSpeakerBotChat = getURLParam("ttsSpeakerBotChat", false);
|
||||||
|
const ttsSpeakerBotEvents = getURLParam("ttsSpeakerBotEvents", false);
|
||||||
|
|
||||||
let streamerBotConnected = false;
|
let streamerBotConnected = false;
|
||||||
const chatThreshhold = 50;
|
const chatThreshhold = 50;
|
||||||
|
|
||||||
@@ -75,6 +79,8 @@ const streamerBotClient = new StreamerbotClient({
|
|||||||
|
|
||||||
|
|
||||||
async function addMessageToChat(userID, messageID, platform, data) {
|
async function addMessageToChat(userID, messageID, platform, data) {
|
||||||
|
|
||||||
|
if (ttsSpeakerBotChat == true) { ttsSpeakerBotSays(data.userName, currentLang.ttschat, data.message); }
|
||||||
|
|
||||||
const html = DOMPurify.sanitize(`
|
const html = DOMPurify.sanitize(`
|
||||||
<div id="${messageID}" data-user="${userID}" class="${platform} ${data.classes} message" style="">
|
<div id="${messageID}" data-user="${userID}" class="${platform} ${data.classes} message" style="">
|
||||||
@@ -121,6 +127,8 @@ async function addMessageToChat(userID, messageID, platform, data) {
|
|||||||
|
|
||||||
async function addEventToChat(userID, messageID, platform, data) {
|
async function addEventToChat(userID, messageID, platform, data) {
|
||||||
|
|
||||||
|
if (ttsSpeakerBotEvents == true) { ttsSpeakerBotSays(data.userName, '', data.message); }
|
||||||
|
|
||||||
const html = DOMPurify.sanitize(`
|
const html = DOMPurify.sanitize(`
|
||||||
<div id="${messageID}" data-user="${userID}" class="${platform} ${data.classes} message event" style="">
|
<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">
|
<div class="animate__animated ${chatHorizontal == true ? 'animate__fadeInRight' : 'animate__fadeInUp'} animate__faster">
|
||||||
@@ -149,7 +157,7 @@ async function addEventToChat(userID, messageID, platform, data) {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}, Math.floor(hideAfter * 1000));
|
}, Math.floor(hideAfter * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
removeExtraChatMessages();
|
removeExtraChatMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +306,42 @@ const notifySuccess = (success) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function escapeRegex(string) {
|
function escapeRegex(string) {
|
||||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function ttsSpeakerBotSays(user, action, message) {
|
||||||
|
|
||||||
|
if (streamerBotConnected == false) return;
|
||||||
|
|
||||||
|
const ttstext = await cleanStringOfHTMLButEmotes(message);
|
||||||
|
const ttsmessage = user+' '+action+' '+ttstext;
|
||||||
|
|
||||||
|
streamerBotClient.doAction(
|
||||||
|
{ name : "TTS Event" },
|
||||||
|
{
|
||||||
|
"ttsmessage": ttsmessage,
|
||||||
|
}
|
||||||
|
).then( (ttsstuff) => {
|
||||||
|
console.debug('Sending TTS to Streamer.Bot', ttsstuff);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function cleanStringOfHTMLButEmotes(string) {
|
||||||
|
// Cria um elemento DOM temporário
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.innerHTML = string;
|
||||||
|
|
||||||
|
// Substitui <img class="emote" alt="..."> por texto do alt
|
||||||
|
const emotes = container.querySelectorAll('img.emote[alt]');
|
||||||
|
emotes.forEach(img => {
|
||||||
|
const altText = img.getAttribute('alt');
|
||||||
|
const textNode = document.createTextNode(altText);
|
||||||
|
img.replaceWith(textNode);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove todo o restante do HTML
|
||||||
|
return container.textContent || "";
|
||||||
}
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
const en = {
|
const en = {
|
||||||
streamerbotconnected: 'Streamer.bot Online!',
|
streamerbotconnected: 'Streamer.bot Online!',
|
||||||
streamerbotdisconnected: 'Streamer.bot Disconnected!',
|
streamerbotdisconnected: 'Streamer.bot Disconnected!',
|
||||||
|
ttschat: 'said',
|
||||||
|
|
||||||
twitch : {
|
twitch : {
|
||||||
firstMessage : () => `First chatter`,
|
firstMessage : () => `First chatter`,
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
const es = {
|
const es = {
|
||||||
streamerbotconnected: '¡Streamer.bot en línea!',
|
streamerbotconnected: '¡Streamer.bot en línea!',
|
||||||
streamerbotdisconnected: '¡Streamer.bot desconectado!',
|
streamerbotdisconnected: '¡Streamer.bot desconectado!',
|
||||||
|
ttschat: 'dijo',
|
||||||
|
|
||||||
twitch : {
|
twitch : {
|
||||||
firstMessage : () => `Primeira mensaje`,
|
firstMessage : () => `Primeira mensaje`,
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
const ptbr = {
|
const ptbr = {
|
||||||
streamerbotconnected: 'Streamer.bot Conectado!',
|
streamerbotconnected: 'Streamer.bot Conectado!',
|
||||||
streamerbotdisconnected: 'Streamer.bot Desconectado!',
|
streamerbotdisconnected: 'Streamer.bot Desconectado!',
|
||||||
|
ttschat: 'disse',
|
||||||
|
|
||||||
twitch : {
|
twitch : {
|
||||||
firstMessage : () => `Primeira mensagem`,
|
firstMessage : () => `Primeira mensagem`,
|
||||||
|
@@ -77,10 +77,9 @@ async function loadSettingsFromLocalStorage() {
|
|||||||
onConnect: (data) => {
|
onConnect: (data) => {
|
||||||
streamerBotConnected = true;
|
streamerBotConnected = true;
|
||||||
|
|
||||||
var sbstatus = document.getElementById('memberemotesbstatus');
|
document.querySelector('#memberemotesbstatus').classList.remove('offline');
|
||||||
|
document.querySelector('#memberemotesbstatus').classList.add('online');
|
||||||
sbstatus.style.color = '#00dd63';
|
document.querySelector('#memberemotesbstatus span').textContent = 'Streamer.Bot is Online!';
|
||||||
sbstatus.textContent = 'Streamer.Bot is Online!';
|
|
||||||
|
|
||||||
streamerBotClient.getGlobals().then( (getglobals) => {
|
streamerBotClient.getGlobals().then( (getglobals) => {
|
||||||
const settings = JSON.parse(getglobals.variables.chatrdytcustomemotes.value);
|
const settings = JSON.parse(getglobals.variables.chatrdytcustomemotes.value);
|
||||||
@@ -96,10 +95,10 @@ async function loadSettingsFromLocalStorage() {
|
|||||||
console.error('Streamer.bot Disconnected!');
|
console.error('Streamer.bot Disconnected!');
|
||||||
|
|
||||||
streamerBotConnected = false;
|
streamerBotConnected = false;
|
||||||
|
|
||||||
var sbstatus = document.getElementById('memberemotesbstatus');
|
document.querySelector('#memberemotesbstatus').classList.remove('online');
|
||||||
sbstatus.style.color = '#ff0000';
|
document.querySelector('#memberemotesbstatus').classList.add('offline');
|
||||||
sbstatus.textContent = 'Streamer.Bot Needs to be Online!';
|
document.querySelector('#memberemotesbstatus span').textContent = 'Streamer.Bot is Offline!';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -515,7 +515,6 @@ async function twitchChatClearMessages() {
|
|||||||
|
|
||||||
|
|
||||||
async function twitchUpdateStatistics(data) {
|
async function twitchUpdateStatistics(data) {
|
||||||
|
|
||||||
if (showPlatformStatistics == false || showTwitchViewers == false) return;
|
if (showPlatformStatistics == false || showTwitchViewers == false) return;
|
||||||
|
|
||||||
const viewers = DOMPurify.sanitize(data.viewerCount);
|
const viewers = DOMPurify.sanitize(data.viewerCount);
|
||||||
|
@@ -353,7 +353,7 @@ async function getYouTubeEmotes(data) {
|
|||||||
const emoteRegex = new RegExp(`(?<!\\S)${escapedCode}(?!\\S)`, 'g');
|
const emoteRegex = new RegExp(`(?<!\\S)${escapedCode}(?!\\S)`, 'g');
|
||||||
|
|
||||||
const imageUrl = `https://cdn.betterttv.net/emote/${emote.id}/1x`;
|
const imageUrl = `https://cdn.betterttv.net/emote/${emote.id}/1x`;
|
||||||
const emoteElement = `<img src="${imageUrl}" class="emote">`;
|
const emoteElement = `<img src="${imageUrl}" class="emote" alt="${escapedCode}">`;
|
||||||
|
|
||||||
message = message.replace(emoteRegex, emoteElement);
|
message = message.replace(emoteRegex, emoteElement);
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,7 @@ async function getYouTubeEmotes(data) {
|
|||||||
if (data.emotes) {
|
if (data.emotes) {
|
||||||
for (const emote of data.emotes) {
|
for (const emote of data.emotes) {
|
||||||
const emoteRegex = new RegExp(escapeRegex(emote.name), 'g');
|
const emoteRegex = new RegExp(escapeRegex(emote.name), 'g');
|
||||||
const emoteElement = `<img src="${emote.imageUrl}" class="emote">`;
|
const emoteElement = `<img src="${emote.imageUrl}" class="emote" alt="${emote.name}">`;
|
||||||
message = message.replace(emoteRegex, emoteElement);
|
message = message.replace(emoteRegex, emoteElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ async function getYouTubeEmotes(data) {
|
|||||||
if (data.user.isSponsor == true || data.user.isOwner == true) {
|
if (data.user.isSponsor == true || data.user.isOwner == true) {
|
||||||
message = message.replace(/:([a-zA-Z0-9_]+):/g, (match, emoteName) => {
|
message = message.replace(/:([a-zA-Z0-9_]+):/g, (match, emoteName) => {
|
||||||
if (youTubeCustomEmotes[emoteName]) {
|
if (youTubeCustomEmotes[emoteName]) {
|
||||||
return `<img src="${youTubeCustomEmotes[emoteName]}" class="emote">`;
|
return `<img src="${youTubeCustomEmotes[emoteName]}" class="emote" alt="${emoteName}">`;
|
||||||
}
|
}
|
||||||
return match;
|
return match;
|
||||||
});
|
});
|
||||||
|
@@ -1 +1 @@
|
|||||||
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
|
Reference in New Issue
Block a user