1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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);
}
}
}
|