martynsmith / node-irc

NodeJS IRC client library
GNU General Public License v3.0
1.33k stars 424 forks source link

Twitch Sending CAP REQ Stops All Channel Message Events #533

Open DigitalData opened 6 years ago

DigitalData commented 6 years ago

I am not sure of the issue, but when I go through the irc client creation process and add the cap req: ircClient.send('CAP REQ', 'twitch.tv/tags');

Then connect to the channel: ircClient.join((userChannel), function () { console.log('Connected to ' + userChannel); chatTalk('/color hotpink'); chatAction('Hello Everybody! I\'m here to help. Type !help for commands.'); });

The following code, doesn't execute:

ircClient.addListener(('message' + userChannel), function (from, text, messageObject) { console.log('got a message!'); console.log(from + ' => ' + userChannel + ': '); console.log(text); });

What I think is happening is that for some reason, the twitch cap req somehow stops the message event from being called, because RAW events still occur with the messages. I know I could probably just parse the raw event with the information I'd like, but I'd rather avoid doing that if possible, and there may be some real underlying issue here.

I'm sorry if this issue report is inadequate, I'm not entirely sure of GitHub convention.

Thank you,

DigitalData commented 6 years ago

Until this is fixed, I will just avoid adding the Cap Req.

BarryCarlyon commented 5 years ago

When you add CAP's it changes the raw lines as it adds IRCv3 stuff to the message/line.

The parser in this library doesn't handle it.

You need to add stuff to lib/parse_message.js

I cherry picked some code from https://github.com/sigkell/irc-message/ into my Fork of node-irc to deal with it.

I inserted on https://github.com/martynsmith/node-irc/blob/master/lib/parse_message.js#L20

Something along the lines of the following:

    // The first thing we check for is IRCv3.2 message tags.
    // http://ircv3.atheme.org/specification/message-tags-3.2
    // cherry picked from https://github.com/sigkell/irc-message/
    if (line.charCodeAt(0) === 64) {
        var nextspace = line.indexOf(' ')

        if (nextspace === -1) {
            // Malformed IRC message.
            return null
        }

        // Tags are split by a semi colon.
        var rawTags = line.slice(1, nextspace).split(';')
        message.tags = {};

        for (var i = 0; i < rawTags.length; i++) {
            // Tags delimited by an equals sign are key=value tags.
            // If there's no equals, we assign the tag a value of true.
            var tag = rawTags[i]
            var pair = tag.split('=')

            // this is a patch for tag name containing a -
            // makes parsing them later much easier…
            message.tags[pair[0].replace(/-/g, '_')] = pair[1] || true
        }

        position = nextspace + 1

        // strip the message back to non IRCv3
        // to easy pass to the base parser
        line = line.substr(position);
    }

that should at least get your going somewhat with IRCv3 support and thus Twitch IRC Capabilities.

Edit: This will at least make ircClient.addListener(('message' work again, if you want to access tags/etc in your code/bot/program, you'll need to tweak irc.js to add stuff like

            case 'PRIVMSG':
                from = message.nick;
                to = message.args[0];
                text = message.args[1] || '';
                if (text[0] === '\u0001' && text.lastIndexOf('\u0001') > 0) {
                    self._handleCTCP(from, to, text, 'privmsg', message);
                    break;
                }

                tags = message.tags || {};

                // Twitch
                if (from == 'twitchnotify') {
                    self.emit('twitchnotify', from, to, text, tags, message);
                } else {
                    // Twitch

                    self.emit('message', from, to, text, tags, message);
                    if (self.supported.channel.types.indexOf(to.charAt(0)) !== -1) {
                        self.emit('message#', from, to, text, tags, message);
                        self.emit('message' + to, from, text, tags, message);
                        if (to != to.toLowerCase()) {
                            self.emit('message' + to.toLowerCase(), from, text, tags, message);
                        }
                    }
                    if (to.toUpperCase() === self.nick.toUpperCase()) self.emit('pm', from, text, tags, message);
                }

                if (self.opt.debug && to == self.nick)
                    util.log('GOT MESSAGE from ' + from + ': ' + text);
                break;

Which'll pass tags over as needed/etc. Or fudge however you want