summaryrefslogtreecommitdiff
path: root/scripts/chat.js
blob: b78f946bbb05b66dbfd7c23eba90546615a8d1f6 (plain)
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);
        }
    }
}