From aed413b1bed8dc2883a94262e4c6fa64e7e986de Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Fri, 31 Oct 2025 17:14:06 +0500 Subject: feat: connect to twitch chat --- index.html | 14 ++++++++- scripts/chat.js | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 scripts/chat.js diff --git a/index.html b/index.html index c484ff9..de2f7a0 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,18 @@ webberino -

xd

+
+
+ +
+
+ + \ No newline at end of file diff --git a/scripts/chat.js b/scripts/chat.js new file mode 100644 index 0000000..b78f946 --- /dev/null +++ b/scripts/chat.js @@ -0,0 +1,98 @@ +function displayMessage(data) { + const messages = document.getElementById("window-messages"); + + const message = document.createElement("p"); + message.classList.add("message"); + + if ("nick" in data && data.nick.length > 0) { + const nickElement = document.createElement("span"); + nickElement.classList.add("nick"); + nickElement.textContent = `${data.nick}: `; + + if ("color" in data.tags) { + nickElement.style.color = data.tags["color"]; + } + + message.append(nickElement); + } + + const messageContent = document.createElement("span"); + messageContent.classList.add("content"); + messageContent.textContent = data.params[1]; + message.append(messageContent); + + messages.append(message); +} + +function displaySystemMessage(channelName, message, nick = "System") { + displayMessage({ + "nick": nick, + "prefix": nick, + "command": "PRIVMSG", + "params": [channelName, message], + "tags": {} + }); +} + +class TwitchIRCClient { + constructor (host, nick, pass) { + this.joinedChannels = []; + this.socket = null; + this.host = host; + this.nick = nick; + this.pass = pass; + } + + connect() { + this.socket = new WebSocket(this.host); + + this.socket.addEventListener("open", () => { + this.socket.send(`NICK ${this.nick}`); + this.socket.send(`PASS ${this.pass}`); + this.socket.send(`CAP REQ :twitch.tv/tags twitch.tv/membership`); + }); + + this.socket.addEventListener("message", (e) => { + const lines = e.data.split("\r\n"); + for (const line of lines) { + if (line.trim().length == 0) { + continue; + } + if (line.includes("001")) { + for (const c of this.joinedChannels) { + this.join(c); + } + displaySystemMessage("*", "Connected!"); + } + displaySystemMessage("forsen", line, "Message"); + } + }); + + this.socket.addEventListener("error", (e) => { + console.error(e); + }); + + this.socket.addEventListener("close", (e) => { + for (const c of this.joinedChannels) { + displaySystemMessage(c, `Disconnected! Reason: ${e.reason}`); + displaySystemMessage(c, "Reconnecting in 10 seconds..."); + } + + setTimeout(() => this.connect(), 10000); + }); + } + + say(channelName, message) { + this.socket.send(`PRIVMSG #${channelName} :${message}`); + } + + join(channelName) { + if (this.socket != null && this.socket.readyState == this.socket.OPEN) { + this.socket.send(`JOIN #${channelName}`); + } + + if (!this.joinedChannels.includes(channelName)) { + this.joinedChannels.push(channelName); + } + } +} \ No newline at end of file -- cgit v1.2.3