1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.0 KiB

/*
A very simple xmpp client
*/
var sys = require('sys'),
xmpp = require('node-xmpp'),
util = require('util'),
colors = require('colors'),
events = require('events');
var BasicClient = function(params, callback) {
events.EventEmitter.call(this);
this.idle = (new Date().getTime());
this._iq = 0;
this._iqCallback = {};
this._iqHandler = {};
var jabber = this;
this.params = params;
var jid = new xmpp.JID(params.jid);
this.params.host = (params.host == null) ? jid.domain : params.host;
this.params.nickname = (params.resource == null) ? jid.user : params.resource;
this.xmpp = new xmpp.Client(params);
/*
this.xmpp.addListener('rawStanza', function(stanza) {
sys.debug("RAW: "[jabber.color] + stanza.toString().white);
});
*/
this.xmpp.addListener('authFail', function(e) {
jabber.emit('authFail', e);
});
this.xmpp.addListener('error', function(e) {
jabber.emit('error', e);
});
this.xmpp.addListener('stanza', function(stanza) {
switch(stanza.name) {
case 'iq':
switch(stanza.attrs.type) {
case 'error':
var q = stanza.getChild('query');
if(q !== undefined) {
if(q.attrs.xmlns != null && jabber._iqHandler[q.attrs.xmlns] != null) {
return jabber._iqHandler[q.attrs.xmlns].call(jabber, stanza);
}
}
if (typeof jabber._iqCallback[stanza.attrs.id] !== "undefined") {
jabber._iqCallback[stanza.attrs.id].error.apply(jabber, [stanza]);
}
break;
case 'result':
if (typeof jabber._iqCallback[stanza.attrs.id] === "undefined") {
var q = stanza.getChild('query');
if(q !== undefined) {
if(q.attrs.xmlns != null && jabber._iqHandler[q.attrs.xmlns] != null) {
return jabber._iqHandler[q.attrs.xmlns].call(jabber, stanza);
}
}
} else if (typeof jabber._iqCallback[stanza.attrs.id] !== "undefined") {
jabber._iqCallback[stanza.attrs.id].success.apply(jabber, [stanza]);
}
break;
default:
jabber.emit('iq', stanza);
var q = stanza.getChild('query');
if(q == undefined) {
var q = stanza.getChild('time');
if(q !== undefined) {
if(q.attrs.xmlns != null && jabber._iqHandler[q.attrs.xmlns] != null) {
jabber._iqHandler[q.attrs.xmlns].call(jabber, stanza);
} else {
jabber.emit('iq:unknow', stanza);
}
} else {
if (typeof jabber._iqCallback[stanza.attrs.id] !== "undefined") {
jabber._iqCallback[stanza.attrs.id].success.apply(jabber, [stanza]);
} else if(stanza.attrs.xmlns != null && jabber._iqHandler[stanza.attrs.xmlns] != null) {
jabber._iqHandler[stanza.attrs.xmlns].call(jabber, stanza);
} else {
jabber.emit('iq:unknow', stanza);
}
}
} else {
if (typeof jabber._iqCallback[stanza.attrs.id] !== "undefined") {
jabber._iqCallback[stanza.attrs.id].success.apply(jabber, [stanza]);
} else if(q.attrs.xmlns != null && jabber._iqHandler[q.attrs.xmlns] != null) {
jabber._iqHandler[q.attrs.xmlns].call(jabber, stanza);
} else {
jabber.emit('iq:unknow', stanza);
}
}
break;
}
break;
case 'presence':
var newPresence = false;
if(stanza.attrs.type == 'error') {
jabber.emit('presence:error', stanza);
} else {
// Skip self presence
if (jabber.jid.user + "@" + jabber.jid.domain + "/" + jabber.jid.resource === stanza.attrs.from) {
return false;
}
try {
// This is a presences for a conference
if (stanza.attrs.from.indexOf('conference') === -1 || stanza.attrs.from.indexOf('conference') < stanza.attrs.from.indexOf('@')) {
var user = stanza.attrs.from.toString();
if (stanza.attrs.type === "unavailable") {
if (typeof jabber.presences[user] !== "undefined") {
delete jabber.presences[user];
}
} else {
jabber.presences[user] = stanza;
}
}
jabber.emit('presence', stanza);
} catch (err) {
console.log("Something went wrong parsing presences: " + err.toString());
console.log(stanza.toString());
console.log(err.stack);
}
}
break;
case 'message':
jabber.emit('message', stanza);
break;
default:
console.log(stanza.toString());
break;
}
});
this.xmpp.addListener('online', function() {
jabber.jid = this.jid;
jabber.emit('online');
callback.apply(jabber);
});
};
sys.inherits(BasicClient, events.EventEmitter);
exports.BasicClient = BasicClient;
BasicClient.prototype.unidle = function() {
this.idle = (new Date().getTime());
};
BasicClient.prototype.message = function(to, message) {
this.xmpp.send(new xmpp.Element('message', {
to: to,
type: 'chat'})
.c('body').t(message));
this.unidle();
};
BasicClient.prototype.presence = function(status, message)
{
if (typeof status === "undefined")
{
var status = "";
}
if (typeof message === "undefined")
{
var message = "";
}
this.xmpp.send(new xmpp.Element('presence', { type: 'chat'}).
c('show').t(status).up().
c('status').t(message)
);
};
BasicClient.prototype.iq = function(to, query, callback, error, type) {
if(error == undefined) error = function(stanza) { sys.error((this.jid + " : " + stanza.toString()).red);};
var n = 'node' + this._iq++;
this._iqCallback[n] = {};
this._iqCallback[n].success = callback;
this._iqCallback[n].error = error;
if (typeof type === "undefined") {
var type = "get";
}
var attrs = {
type: type,
id: n
};
if(to != null) {
attrs.to = to;
};
this.xmpp.send(new xmpp.Element('iq', attrs).cnode(query).tree());
return n;
};
/*
Answer an iq query
*/
BasicClient.prototype.resultIq = function(iqGet, result) {
if (typeof iqGet === "undefined" || typeof result === "string") {
this.xmpp.send(result);
} else {
this.xmpp.send(new xmpp.Element('iq', {
type: 'result',
from: iqGet.attrs.to,
to: iqGet.attrs.from,
id: iqGet.attrs.id
}).cnode(result).tree());
}
};
BasicClient.prototype.registerIqHandler = function(xmlns, action) {
this._iqHandler[xmlns] = action;
};