ircanywhere / irc-factory

A rebuilt irc-factory from simple-irc-socket and irc-message. Get support at #ircanywhere on freenode
https://ircanywhere.com
MIT License
60 stars 14 forks source link

How to get a list of users in a channel #4

Closed Jazcash closed 10 years ago

Jazcash commented 10 years ago

I'm very new to node and JS programming in general, so forgive my newbishness.

How can I get a list of users in a channel? I know how to catch an event for 'list' but how do I get the bot to send "LIST" to the server in first place?

I thought it'd be something like:

client.irc.raw('LIST #ectest2'); OR client.raw('LIST #ectest2');

But the first does nothing and the second causes an error because client.raw doesn't exist.

Jazcash commented 10 years ago

Nevermind. Got it: ` client.irc.raw('LIST', '#ectest2');

api.hookEvent('*', 'list', function(message) { console.log(message); }); `

Jazcash commented 10 years ago

I want to reopen this issue with a new question. How can I do this synchronously?

For example, I can get the number of users in a channel like this:

client.irc.raw('LIST', loc);
                    api.hookEvent('*', 'list', function(info) {
                        var numOfUsersInChannel = info["list"][0]["users"];
                        client.irc.privmsg(loc, "There are "+numOfUsersInChannel+" users in this channel");
                    });

But I have to fire the event myself and then the hook has to wait until it catches it, even though I know exactly when the event is fired. This means the bot is waiting for a second or two before it can respond with the answer when it should be almost instantaneous.

How can I achieve this?

rickihastings commented 10 years ago

At the moment you can't. I toyed with the idea of adding callbacks when sending commands to handle their responses but never got round to it.

I'll have a look into doing it this week.

On 26 Feb 2014, at 09:57, Jazcash notifications@github.com wrote:

I want to reopen this issue with a new question. How can I do this synchronously?

For example, I can get the number of users in a channel like this:

client.irc.raw('LIST', loc); api.hookEvent('*', 'list', function(info) { var numOfUsersInChannel = info["list"][0]["users"]; client.irc.privmsg(loc, "There are "+numOfUsersInChannel+" users in this channel"); }); But I have to fire the event myself and then the hook has to wait until it catches it, even though I know exactly when the event is fired. This means the bot is waiting for a second or two before it can respond with the answer when it should be almost instantaneous.

How can I achieve this?

— Reply to this email directly or view it on GitHub.

rickihastings commented 10 years ago

Ok, I'm at a computer now so I can try and shed some more light on the situation here. What is happening when you call client.irc.raw('LIST', loc); is that it's sending the command to the IRC server, the information you get back is going to be in the format of;

:leguin.freenode.net 322 testbot #puppet 1058 :Puppet Enterprise 3.1.0: http://bit.ly/PE_31 | Puppet 3.3.2: http://bit.ly/QUjTW0 |  Help: http://{ask,docs}.puppetlabs.com | Bugs & Feature Requests: http://bit.ly/aoNNEP
:leguin.freenode.net 322 testbot ##linux 1368 : Welcome to ##Linux! Freenode's general Linux support/discussion channel. | Channel website and rules: http://www.linuxassist.net | Our pastebin http://paste.linuxassist.net | Spammers or trolls? use !ops <troll's nick> <reason>\". | For op assistance, join ##linux-ops. Feel at home and enjoy your stay.
:leguin.freenode.net 322 testbot #git 1082 :Welcome to #git, the place for git-related help and tomato soup | Current stable version: 1.8.5.1 | Start here: http://jk.gs/git | Seeing \"Cannot send to channel\" or unable to change nick? /msg gitinfo .voice | git-hg: Don\'t you know that\'s poison?
:leguin.freenode.net 323 testbot :End of /LIST

We only emit the list event when we've got to the end of the list, numeric 323. That means if you run this on a network like freenode with no parameters you're going to get a large list, some 10-15k channels. Which is going to take a second or two to come in, then it has to be parsed from it's raw IRC format, which comes out like this:

{ list:
   [ { channel: "#puppet",
       users: "1058",
       topic: "Puppet Enterprise 3.1.0: http://bit.ly/PE_31 | Puppet 3.3.2: http://bit.ly/QUjTW0 |  Help: http://{ask,docs}.puppetlabs.com | Bugs & Feature Requests: http://bit.ly/aoNNEP" },
     { channel: "##linux",
       users: "1368",
       topic: " Welcome to ##Linux! Freenode's general Linux support/discussion channel. | Channel website and rules: http://www.linuxassist.net | Our pastebin http://paste.linuxassist.net | Spammers or trolls? use !ops <troll's nick> <reason>. | For op assistance, join ##linux-ops. Feel at home and enjoy your stay." },
     { channel: "#git",
       users: "1082",
       topic: "Welcome to #git, the place for git-related help and tomato soup | Current stable version: 1.8.5.1 | Start here: http://jk.gs/git | Seeing \"Cannot send to channel\" or unable to change nick? /msg gitinfo .voice | git-hg: Don't you know that's poison?" } ],
  raw:
   [ ":leguin.freenode.net 322 testbot #puppet 1058 :Puppet Enterprise 3.1.0: http://bit.ly/PE_31 | Puppet 3.3.2: http://bit.ly/QUjTW0 |  Help: http://{ask,docs}.puppetlabs.com | Bugs & Feature Requests: http://bit.ly/aoNNEP",
     ":leguin.freenode.net 322 testbot ##linux 1368 : Welcome to ##Linux! Freenode's general Linux support/discussion channel. | Channel website and rules: http://www.linuxassist.net | Our pastebin http://paste.linuxassist.net | Spammers or trolls? use !ops <troll's nick> <reason>. | For op assistance, join ##linux-ops. Feel at home and enjoy your stay.",
     ":leguin.freenode.net 322 testbot #git 1082 :Welcome to #git, the place for git-related help and tomato soup | Current stable version: 1.8.5.1 | Start here: http://jk.gs/git | Seeing \"Cannot send to channel\" or unable to change nick? /msg gitinfo .voice | git-hg: Don't you know that's poison?" ],
  time: Sat Dec 21 2013 12:29:57 GMT+0000 (UTC) }

Which is going to again add processing time. Now I see you're running it with a parameter, which should be fired instantly as it's only returning one item. If you run the test suite you can see that the tests for lists should return results instant.

I'm unsure whats causing the hang of a couple of seconds. As for introducing a synchronised version of the command. What are your ideas for it? Either something like;

client.irc.raw('LIST', loc, function(data)) {
    console.log(data);
}
// which isn't technically synchronised

Or;

var data = client.irc.raw('LIST', loc);

The only way I can think of achieving the latter is by using a generator, a promise, or a fiber. But that would require that the first solution is implemented, and if you're familiar with node-irc. They provide callbacks for their own proxy methods, ie join part mode and so on. Doing so for raw would be more difficult, as you don't know what the response is going to be unless you know exactly what the command is going to be. So it would mean parsing the command and hooking an event then executing the callback when we know what event is going to be returned from that command.

Jazcash commented 10 years ago

I'm just a newbie student, new to JS, so I can't help with the implementation much at all, sorry. The latter is very syntactically nice though. As for the lag I mentioned, it turns out that it is pretty quick according to the timestamps (1 second) but it feels more like 2-3 seconds. Whether that's to do with server lag or lag on my end or what I don't know but it shouldn't be problematic for you.

I was using node-irc initially but switched to irc-factory because of the lack of activity from the owner of node-irc.

Thanks for the quick response though!

rickihastings commented 10 years ago

You're very right, syntactically it does look nice, and in theory is possible, but it means implementing callbacks to receive responses, but for the sake of keeping things as simple as possible (this has been a goal from the beginning irc-factory). I'd only be willing to implement them for these commands: https://github.com/ircanywhere/irc-factory/blob/master/lib/irc.js#L966-L1041

I wouldn't be opposed to adding a client.irc.list() command though and any others that need added. But adding a callback to raw is going to prove more difficult.

As for the 1 second lag it's likely it's due to the network, I developed this on a localhost IRC server and everything was instantaneous. It could vary whats causing the lag but it's likely it's caused by something else and not irc-factory.

Jazcash commented 10 years ago

That's fine, I was just using raw for testing some other things. Implementing the callbacks for those specific ones would still be very very nice ^_^

rickihastings commented 10 years ago

I'll look into adding that functionality in the near future when I have some free time.