Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added away(msg, optional callback) + ignored rpl_luserunknown + emit 'unhandled' #80

Closed
wants to merge 4 commits into from

3 participants

@alessioalex

1) Added (with doc & examples) away functionality:

bot.away('Leave a message', function(serverResponse) {
console.log('Server responds with..');
});

bot.away(); // remove away

2) Added rpl_luserunknown to ignored

3) Emit 'unhandled' event, just in case there's something missing (special) so you can handle it without changing the source code for node-irc.

@alessioalex

4) On free node for example, when quitting you get this unhandled message:

Unhandled message: { command: 'ERROR',
rawCommand: 'ERROR',
commandType: 'normal',
args: [ 'Closing Link: 188.26.233.46 (Client Quit)' ] }

I've added code so this gets ignored.

@tjfontaine

There should be a better way to handle this case, the match and the command state checking just feel icky

Dear god freenode is a blight to the rest of the irc world

I've only seen this on freenode so far, so it's icky indeed, but I'm not sure what the best way to deal with this would be. The QUIT command is sent, so the server just shouldn't send that weird error message back anyway.

I reported the issue to freenode, and the response goes as such

it's because the eventloop handles stuff lazily
we flush the linebufs on disconnect
sometimes you get it, sometimes you don't
it depends on how well the eventloop has done it's job

They use a ratbox derivative, but I'm not aware of any other ratbox based network exhibiting this type behavior. But the situation convinces me more that this is something that the server should just handle properly in the first place.

Absolutely, I just thought this should be present so others won't feel node-irc is buggy or to loose time investigating this issue. Devs are mostly aware of freenode, so that may be the first choice when they decide to play around with the library (as I did).

@martynsmith
Owner

Personally I'm okay with the creative hack to make the library play a little nicer with FreeNode. Sure, in a perfect world FreeNode wouldn't suck, but there's not much we can do about that.

Would it be possible to add the two nowaway and unaway events to the documentation too? (since people could subscribe to those independently of away's callback parameter?

@martynsmith
Owner

Closing this due to lack of response ... If anyone feels strongly about it, feel free to re-open :-)

@martynsmith martynsmith closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 18, 2012
  1. Added rpl_luserunknown to ignored stuff

    Alexandru Vladutu authored
Commits on Mar 19, 2012
  1. Added AWAY command, with doc & example

    Alexandru Vladutu authored
  2. Emit unhandled, so others can extend functionality where needed

    Alexandru Vladutu authored
  3. Ignore weird error message on quit for some servers

    Alexandru Vladutu authored
This page is out of date. Refresh to see the latest.
Showing with 59 additions and 3 deletions.
  1. +9 −0 docs/API.rst
  2. +10 −0 example/bot.js
  3. +10 −0 example/secure.js
  4. +30 −3 lib/irc.js
View
9 docs/API.rst
@@ -102,6 +102,15 @@ Client
generating the whois information and is passed exactly the same
information as a `whois` event described above.
+.. js:function:: Client.away(awayMessage, callback)
+
+ Set away status to `awayMessage` or reset it.
+
+ :param string awayMessage: message to be set
+ :param function callback: Optional callback to fire when the server responds
+ to the away call with a message such as 'You have been marked as beeing
+ away.' or 'You are no longer marked as beeing away'.
+
.. js:function:: Client.list([arg1, arg2, ...])
Request a channel listing from the server. The arguments for this method are
View
10 example/bot.js
@@ -26,6 +26,16 @@ bot.addListener('message', function (from, to, message) {
if ( message.match(/hello/i) ) {
bot.say(to, 'Hello there ' + from);
}
+ // set away on request
+ if (message.match(/away/i)) {
+ bot.away('I am not here, leave a msg!', function(serverResponse) {
+ console.log(serverResponse);
+ });
+ }
+ // back
+ if (message.match(/back/i)) {
+ bot.away();
+ }
if ( message.match(/dance/) ) {
setTimeout(function () { bot.say(to, "\u0001ACTION dances: :D\\-<\u0001") }, 1000);
setTimeout(function () { bot.say(to, "\u0001ACTION dances: :D|-<\u0001") }, 2000);
View
10 example/secure.js
@@ -40,6 +40,16 @@ bot.addListener('message', function (from, to, message) {
if ( message.match(/hello/i) ) {
bot.say(to, 'Hello there ' + from);
}
+ // set away on request
+ if (message.match(/away/i)) {
+ bot.away('I am not here, leave a msg!', function(serverResponse) {
+ console.log(serverResponse);
+ });
+ }
+ // back
+ if (message.match(/back/i)) {
+ bot.away();
+ }
if ( message.match(/dance/) ) {
setTimeout(function () { bot.say(to, "\u0001ACTION dances: :D\\-<\u0001") }, 1000);
setTimeout(function () { bot.say(to, "\u0001ACTION dances: :D|-<\u0001") }, 2000);
View
33 lib/irc.js
@@ -96,6 +96,7 @@ function Client(server, nick, opt) {
break;
case "rpl_luserclient":
case "rpl_luserop":
+ case "rpl_luserunknown":
case "rpl_luserchannels":
case "rpl_luserme":
case "rpl_localusers":
@@ -103,6 +104,12 @@ function Client(server, nick, opt) {
case "rpl_statsconn":
// Random welcome crap, ignoring
break;
+ case "rpl_nowaway":
+ self.emit('nowaway', message.args[1]);
+ break;
+ case "rpl_unaway":
+ self.emit('unaway', message.args[1]);
+ break;
case "err_nicknameinuse":
if ( typeof(self.opt.nickMod) == 'undefined' )
self.opt.nickMod = 0;
@@ -424,6 +431,10 @@ function Client(server, nick, opt) {
util.log("\033[01;31mERROR: " + util.inspect(message) + "\033[0m");
}
else {
+ // ignore quit error message (happens with some servers, ex: freenode)
+ if (self._lastCommand === 'QUIT' && command === 'ERROR'
+ && message.args[0] && message.args[0].match(/Closing link/i)) { break; }
+ self.emit('unhandled', message);
if ( self.opt.debug )
util.log("\033[01;31mUnhandled message: " + util.inspect(message) + "\033[0m");
}
@@ -505,7 +516,7 @@ Client.prototype.connect = function ( retryCount, callback ) { // {{{
util.log(self.conn.authorizationError);
}
});
- }else {
+ } else {
self.conn = net.createConnection(self.opt.port, self.opt.server);
}
self.conn.requestedDisconnect = false;
@@ -588,8 +599,8 @@ Client.prototype.send = function(command) { // {{{
args.push(arguments[k]);
args[args.length-1] = ":" + args[args.length-1];
- // Remove the command
- args.shift();
+ // Remove the command from args and remember it
+ this._lastCommand = args.shift();
if ( this.opt.debug )
util.log('SEND: ' + command + " " + args.join(" "));
@@ -694,6 +705,22 @@ Client.prototype.list = function() { // {{{
args.unshift('LIST');
this.send.apply(this, args);
} // }}}
+Client.prototype.away = function(msg, callback) { // {{{
+ if ( typeof callback === 'function' ) {
+ var callbackWrapper = function(msg) {
+ this.removeListener('nowaway', callbackWrapper);
+ this.removeListener('unaway', callbackWrapper);
+ return callback.apply(this, arguments);
+ };
+ this.addListener('nowaway', callbackWrapper);
+ this.addListener('unaway', callbackWrapper);
+ }
+ if (msg) {
+ this.send('AWAY', msg);
+ } else {
+ this.send('AWAY');
+ }
+} // {{{
Client.prototype._addWhoisData = function(nick, key, value, onlyIfExists) { // {{{
if ( onlyIfExists && !this._whoisData[nick] ) return;
this._whoisData[nick] = this._whoisData[nick] || {nick: nick};
Something went wrong with that request. Please try again.