【问题标题】:Chat Bot twitch IRC integration, Cannot get a response from NAMES 421 Unknown Command聊天机器人抽搐 IRC 集成,无法从 NAMES 421 未知命令获得响应
【发布时间】:2018-10-27 05:31:34
【问题描述】:

我已使用 IRC 启动器 javascript program 成功连接到 twitch 聊天。

运行程序时,我可以看到我连接的频道的消息,但是每当我通过socket.send('NAMES') 发送NAMES 信号时,twitch 都会返回一个421 unknown command 代码。

我真正想知道的是,如何获取频道中当前存在的用户列表?

我对提供的聊天机器人稍作修改的版本如下:

var chatClient = function chatClient(options){
    this.username = options.username;
    this.password = options.password;
    this.channel = options.channel;

    this.server = 'irc-ws.chat.twitch.tv';
    this.port = 443;
}

chatClient.prototype.open = function open(){
    this.webSocket = new WebSocket('wss://' + this.server + ':' + this.port + '/', 'irc');

    this.webSocket.onmessage = this.onMessage.bind(this);
    this.webSocket.onerror = this.onError.bind(this);
    this.webSocket.onclose = this.onClose.bind(this);
    this.webSocket.onopen = this.onOpen.bind(this);
};

chatClient.prototype.onError = function onError(message){
    console.log('Error: ' + message);
};

/* This is an example of a leaderboard scoring system. When someone sends a message to chat, we store 
   that value in local storage. It will show up when you click Populate Leaderboard in the UI. 
*/
chatClient.prototype.onMessage = function onMessage(message){
    if(message !== null){
        var parsed = this.parseMessage(message.data);
        if(parsed !== null){
            console.log(parsed)
            if(parsed.command === "PRIVMSG") {
                userPoints = localStorage.getItem(parsed.username);

                if(userPoints === null){
                    localStorage.setItem(parsed.username, 10);
                }
                else {
                    localStorage.setItem(parsed.username, parseFloat(userPoints) + 0.25);
                }
            } else if(parsed.command === "PING") {
                this.webSocket.send("PONG :" + parsed.message);
            }
        }
    }
};

chatClient.prototype.message = function message(){
    var socket = this.webSocket;

    console.log($(".message-text").val())

    if (socket !== null && socket.readyState === 1) {
        console.log("socket not null")
        socket.send("PRIVMSG " + this.channel + " :" + $(".message-text").val() + "\r\n")
        console.log("PRIVMSG " + this.channel + " :" + $(".message-text").val())
    }
}

chatClient.prototype.names = function names(){
    var socket = this.webSocket;

    if (socket !== null && socket.readyState === 1) {
        socket.send('NAMES')
    }
}    

chatClient.prototype.onOpen = function onOpen(){
    var socket = this.webSocket;

    if (socket !== null && socket.readyState === 1) {
        console.log('Initializing connection and authenticating...');
        console.log('username: ' + this.username);
        console.log('password: ' + this.password);
        console.log('channel: ' + this.channel);

        socket.send('PASS ' + this.password);
        socket.send('NICK ' + this.username);
        socket.send('JOIN ' + this.channel);
        socket.send('CAP REQ :twitch.tv/tags');
        socket.send('CAP REQ :twitch.tv/commands');
        socket.send('CAP REQ :twitch.tv/membership');
    }
};

chatClient.prototype.onClose = function onClose(){
    console.log('Disconnected from the chat server.');
};

chatClient.prototype.close = function close(){
    if(this.webSocket){
        this.webSocket.close();
    }
};

/* This is an example of an IRC message with tags. I split it across 
multiple lines for readability. The spaces at the beginning of each line are 
intentional to show where each set of information is parsed. */

//@badges=global_mod/1,turbo/1;color=#0D4200;display-name=TWITCH_UserNaME;emotes=25:0-4,12-16/1902:6-10;mod=0;room-id=1337;subscriber=0;turbo=1;user-id=1337;user-type=global_mod
// :twitch_username!twitch_username@twitch_username.tmi.twitch.tv 
// PRIVMSG 
// #channel
// :Kappa Keepo Kappa

chatClient.prototype.parseMessage = function parseMessage(rawMessage) {
    var parsedMessage = {
        message: null,
        tags: null,
        command: null,
        original: rawMessage,
        channel: null,
        username: null
    };

    if(rawMessage[0] === '@'){
        var tagIndex = rawMessage.indexOf(' '),
        userIndex = rawMessage.indexOf(' ', tagIndex + 1),
        commandIndex = rawMessage.indexOf(' ', userIndex + 1),
        channelIndex = rawMessage.indexOf(' ', commandIndex + 1),
        messageIndex = rawMessage.indexOf(':', channelIndex + 1);

        parsedMessage.tags = rawMessage.slice(0, tagIndex);
        parsedMessage.username = rawMessage.slice(tagIndex + 2, rawMessage.indexOf('!'));
        parsedMessage.command = rawMessage.slice(userIndex + 1, commandIndex);
        parsedMessage.channel = rawMessage.slice(commandIndex + 1, channelIndex);
        parsedMessage.message = rawMessage.slice(messageIndex + 1);
    } else if(rawMessage.startsWith("PING")) {
        parsedMessage.command = "PING";
        parsedMessage.message = rawMessage.split(":")[1];
    }

    return parsedMessage;
}

/* Builds out the top 10 leaderboard in the UI using a jQuery template. */
function buildLeaderboard(){
    var chatKeys = Object.keys(localStorage),
        outputTemplate = $('#entry-template').html(),
        leaderboard = $('.leaderboard-output'),
        sortedData = chatKeys.sort(function(a,b){
            return localStorage[b]-localStorage[a]
        });

    leaderboard.empty();

    for(var i = 0; i < 10; i++){
        var viewerName = sortedData[i],
            template = $(outputTemplate);

        template.find('.rank').text(i + 1);
        template.find('.user-name').text(viewerName);
        template.find('.user-points').text(localStorage[viewerName]);

        leaderboard.append(template);
    }
}

【问题讨论】:

    标签: javascript chatbot irc twitch


    【解决方案1】:

    显然 Twitch IRCd 不支持请求 NAMES 命令。 但它确实支持在加入频道时使用 NAMES 进行响应。

    你几乎做对了所有事情。

    为了获得频道名称列表并真正加入,您应该首先提交您的CAP请求,然后加入频道。当服务器响应时,他也会给你频道名称列表。

    实际订单

    socket.send('CAP REQ :twitch.tv/tags');
    socket.send('CAP REQ :twitch.tv/commands');
    socket.send('CAP REQ :twitch.tv/membership');
    socket.send('JOIN ' + this.channel);
    

    【讨论】:

    • 非常感谢您抽出宝贵的时间回复,我会暂时投赞成票,然后今晚回家后跟进。如果我能够按照此流程整理好所有内容,将标记为已接受。
    • 正如您所描述的,通过添加一些基于号码353 在最后发送的加入响应中的尴尬名称消息的解析,能够使此工作正常进行。非常感谢您的帮助,非常感谢。
    猜你喜欢
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2020-02-09
    相关资源
    最近更新 更多