Twitch chat message to little image guy
I stream over on Twitch quite often, and I like making little widgets and stuff for my streams. A little guy I made a ways back would listen for certain words in chat and swap a displayed image if it sees any of those messages. Pretty nice for having a recently posted emote show up in the corner of the stream!
It’s super primitive and I made it in about 20 minutes, but I figured someone else might want to use or tweak it a bit, so here ya go!
To use it like I did make a folder named ‘images’ and copy your emote images in there. Add the emote word (like ‘aezaliRoll’) and its path (like ‘images/aezaliRoll.gif’) to the config dictionary. Change the defaults of the “main image” html element and the current to whatever you want it to start as, and set your channel name.
Have fun!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Twitch Chat Image Changer</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100vh;
display: flex;
justify-content: flex-end;
align-items: flex-end;
}
#image-container {
position: fixed;
bottom: -4px;
right: -3px;
max-width: 150px;
height: auto;
transition: transform 0.15s ease-in-out;
/*max-width: 100%;
height: 150px;*/
}
#image-container.slide-out {
transform: translateX(100%)
}
@keyframes wobble {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-3deg);
}
50% {
transform: rotate(3deg);
}
75% {
transform: rotate(-3deg);
}
100% {
transform: rotate(0deg);
}
}
.wobble-image {
display: inline-block;
animation: wobble 3s infinite ease-in-out;
}
#main-image {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<div id="image-container">
<img id="main-image" src="images/image.png" alt="Default Image">
</div>
<script src="https://github.com/tmijs/tmi.js/releases/download/v1.8.5/tmi.min.js"></script>
<script>
// Configuration data embedded directly in the HTML
const config = {
"messageToImage": {
"messageWord": "images/image.png",
"otherMessageWord": "images/second.gif"
},
"timeWindow": 2000,
"messageThreshold": 1
};
var current = "whateverTheDefaultWordIs"
const imageContainer = document.getElementById('image-container');
const mainImage = document.getElementById('main-image');
const messageCount = {};
// Initialize Twitch client and message handling
const client = new tmi.Client({
channels: ['your_channel_name_here'] // Replace with your Twitch channel
});
client.connect();
client.on('disconnected', (reason) => {
console.error("Disconnected from Twitch:", reason);
// Attempt to reconnect
client.connect();
});
client.on('message', (channel, tags, message, self) => {
if (self) return;
const words = message.split(' ');
let matchedKeyword = null;
for (let word of words) {
console.log(`trying ${word}`)
if (config.messageToImage.hasOwnProperty(word)) {
matchedKeyword = word;
break; // Exit the loop once a match is found
}
}
if(matchedKeyword){
console.log(`found ${matchedKeyword}`)
if (config.messageToImage[matchedKeyword]) { // now it needs to update the image
if (!messageCount[matchedKeyword]) {
messageCount[matchedKeyword] = 0;
}
messageCount[matchedKeyword]++;
setTimeout(() => {
messageCount[matchedKeyword]--;
if (messageCount[matchedKeyword] === 0) {
delete messageCount[matchedKeyword];
}
}, config.timeWindow);
if (messageCount[matchedKeyword] >= config.messageThreshold) {
if(matchedKeyword == current){
messageCount[matchedKeyword] = 0; // Reset count after change
return;
}
imageContainer.classList.add('slide-out');
setTimeout(() => {
//mainImage.src == config.messageToImage[matchedKeyword];
var path = config.messageToImage[matchedKeyword]
document.getElementById('main-image').src = path//config.messageToImage[matchedKeyword];
/*if(path.endsWith(".png") && !imageContainer.classList.contains('wobble-image')){
imageContainer.classList.add('wobble-image');
}else if(imageContainer.classList.contains('wobble-image')){
imageContainer.classList.remove('wobble-image');
}*/
imageContainer.classList.remove('slide-out')
}, 150)
//document.getElementById('main-image').src = config.messageToImage[matchedKeyword];
messageCount[matchedKeyword] = 0; // Reset count after change
current = matchedKeyword;
}
}
}
});
</script>
</body>
</html>