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.

263 lines
7.5 KiB

15 years ago
var sys = require('sys'),
xmpp = require('xmpp'),
colors = require('colors'),
15 years ago
events = require('events');
var Client = function(params, callback) {
15 years ago
events.EventEmitter.call(this);
this.color = (params.color != null) ? params.color : 'blue';
15 years ago
this.debug = true;
15 years ago
var jabber = this;
this.jid = new xmpp.JID(params.jid);
this.host = (params.host == null) ? this.jid.domain : params.host;
15 years ago
this.rooms = {};
this._iq = 0;
15 years ago
this._iqHandler = {};
15 years ago
this._iqCallback = {};
this.presences = {};
15 years ago
this.roster = {};
this.xmpp = new xmpp.Client(params);
15 years ago
this.xmpp.addListener('rawStanza', function(stanza) {
15 years ago
//sys.debug("RAW: "[jabber.color] + stanza.toString().white);
15 years ago
});
this.xmpp.addListener('authFail', function() {
sys.error("[Error] Jabber : Authentication failure");
process.exit(1);
});
this.xmpp.addListener('error', function(e) {
sys.error(e);
process.exit(1);
});
this.xmpp.addListener('stanza', function(stanza) {
15 years ago
sys.debug('STANZA: '[jabber.color] + ('<' + stanza.name + '> ').bold[jabber.color] + stanza);
15 years ago
if(stanza.name == 'iq') {
if(stanza.attrs.type == 'result') {
15 years ago
jabber._debug('IQ result: ' + stanza);
15 years ago
jabber.emit('iqResult', stanza.attrs.id, stanza);
} else {
15 years ago
jabber._debug(('IQ: ' + stanza)[jabber.color]);
15 years ago
jabber.emit('iq', stanza);
15 years ago
var q = stanza.getChild('query');
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);
}
15 years ago
}
}
if(stanza.name == 'presence') {
var jfrom = new xmpp.JID(stanza.attrs.from);
var roomName = jfrom.user + '@' + jfrom.domain;
if(stanza.attrs.type == 'error') {
sys.error(stanza.toString().inverse);
if(jabber.rooms[roomName] != null) {
jabber.rooms[roomName].emit('presence:error', stanza.getChild('error'), stanza);
} else {
jabber.emit('presence:error', stanza.getChild('error'), stanza);
}
15 years ago
} else {
if(jabber.rooms[roomName] != null) {
jabber.rooms[roomName].emit('presence', stanza.attrs.from, stanza);
} else {
jabber.emit('presence', stanza.attrs.from, stanza);
}
15 years ago
}
}
if(stanza.name == 'message') {
var from = stanza.attrs.from;
if(stanza.attrs.type == 'groupchat') {
jabber.emit('groupchat', from, stanza);
} else {
15 years ago
jabber._debug('MESSAGE: ' + stanza);
jabber.emit('message', from, stanza.getChild('body').getText(), stanza);
15 years ago
}
}
});
this.xmpp.addListener('online', function() {
jabber._debug("[Info] xmpp connection");
jabber.presence();
jabber.emit('online');
jabber.askForRoster(function(roster) {
jabber._debug("ROSTER : "[jabber.color] + JSON.stringify(roster));
15 years ago
if(callback != null) {
callback.call(jabber);
}
});
15 years ago
});
this.addListener('groupchat', function(from, stanza) {
fromName = from.split('@')[0];
jabber.rooms[fromName].emit('message', stanza);
});
this.addListener('iqResult', function(id, stanza){
jabber._iqCallback[id].call(jabber, stanza);
});
this.addListener('presence', function(from, stanza) {
if(stanza.attrs.type == 'error') {
var jfrom = new JID(stanza.attrs.from);
var roomName = jfrom.user + '@' + jfrom.domain;
if(this.rooms[roomName] != null) {
}
} else {
jabber.presences[from] = stanza.attrs.type;
}
});
15 years ago
this.registerIqHandler('http://jabber.org/protocol/disco#info', function(stanza) {
sys.debug((stanza.attrs.from + " wont to disco!")[jabber.color]);
jabber.resultIq(stanza, new xmpp.Element('query', {xmlns: 'http://jabber.org/protocol/disco#info'})
.c('feature', {'var': 'http://jabber.org/protocol/disco#info'}).up()
.c('feature', {'var': 'http://jabber.org/protocol/disco#items'}).up()
.c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
.c('identity', {
category: 'conference',
type: 'text',
name: 'Play-Specific Chatrooms'
}).up()
.tree()
);
});
this.registerIqHandler('jabber:iq:last', function(stanza) {
sys.debug((stanza.attrs.from + ' wonts last')[jabber.color]);
//[FIXME] giving a good last time
jabber.resultIq(stanza, new xmpp.Element('query', {
xmlns: 'jabber:iq:last', seconds:'1'})
.tree()
);
});
this.registerIqHandler('jabber:iq:version', function(stanza) {
jabber.resultIq(stanza, new xmpp.Element('query', {xmlns:'jabber:iq:version'})
.c('name').t('node-xmpp-client').up()
.c('version').t('0.0.1').up()
.c('os').t('mac').up()
.tree()
);
});
15 years ago
this.addListener('iq', function(stanza) {
15 years ago
sys.debug(stanza.getChild('query').toString().yellow);
15 years ago
});
15 years ago
};
sys.inherits(Client, events.EventEmitter);
15 years ago
exports.Client = Client;
Client.prototype._debug = function(txt) {
if(this.debug) {
sys.debug(txt);
}
};
15 years ago
Client.prototype.registerIqHandler = function(xmlns, action) {
this._iqHandler[xmlns] = action;
};
15 years ago
Client.prototype.message = function(to, message) {
this.xmpp.send(new xmpp.Element('message', {
to: to,
type: 'chat'}).
c('body').
t(message));
};
Client.prototype.askForRoster = function(callback) {
15 years ago
var jabber = this;
this.iq(new xmpp.Element('query', {xmlns: 'jabber:iq:roster'}), function(iq) {
iq.getChild('query', 'jabber:iq:roster').children.forEach(function(child) {
jabber.roster[child.attrs.jid] = {
name: child.attrs.name,
subscription: child.attrs.subscription};
});
if(callback != null) {
callback.call(jabber, jabber.roster);
}
jabber.emit('roster', jabber.roster);
15 years ago
});
};
15 years ago
Client.prototype.iq = function(iq, callback) {
var n = this._iq++;
this._iqCallback[n] = callback;
this.xmpp.send(new xmpp.Element('iq', {type:"get", id: n}).cnode(iq).tree());
};
15 years ago
Client.prototype.resultIq = function(iqGet, result) {
this.xmpp.send(new xmpp.Element('iq', {
type: 'result',
from: iqGet.attrs.to,
to: iqGet.attrs.from,
id: iqGet.attrs.id
}).cnode(result).tree());
};
15 years ago
Client.prototype.presence = function(type) {
this.xmpp.send(new xmpp.Element('presence', (type != null) ? {type: type} : {}).tree());
15 years ago
};
Client.prototype.canonicalRoomName = function(room) {
if(room.indexOf('@') > 0) {
return room;
} else {
return room + '@conference.' + this.client.jid.domain;
}
};
15 years ago
Client.prototype.room = function(name, callback) {
var room = this.canonicalRoomName(name);
if(this.rooms[room] == null) {
15 years ago
this.rooms[room] = new Room(this, room, callback);
15 years ago
}
return this.rooms[room];
15 years ago
};
15 years ago
Client.prototype.disconnect = function() {
this.xmpp.send(new xmpp.Element('presence', {type: 'unavailable'})
.c('status')
.t('Logged out')
.tree());
var jabber = this;
/* Object.keys(this.rooms).forEach(function(room) {
jabber.rooms[room].leave();
});*/
this.xmpp.end();
sys.debug("disconnect from XMPP");
};
15 years ago
15 years ago
var Room = function(client, name, callback) {
15 years ago
events.EventEmitter.call(this);
this.client = client;
15 years ago
this.room = name;
var room = this;
this.addListener('presence', function(from, stanza) {
var jfrom = new xmpp.JID(from);
if(name == jfrom.user + '@' + jfrom.domain) {
var x = stanza.getChild('x', 'http://jabber.org/protocol/muc#user');
if(x != null) {
var item = x.getChild('item');
if(item != null) {
room.affiliation = item.attrs.affiliation;
room.role = item.attrs.role;
}
var status = x.getChild('status');
callback.call(room, (status != null) ? status.attrs.code : '200');
}
}
});
15 years ago
this.presence();
};
sys.inherits(Room, events.EventEmitter);
exports.Room = Room;
Room.prototype.presence = function() {
this.client.xmpp.send(new xmpp.Element('presence', {
to: this.room + '/' + this.client.jid.user
15 years ago
})
.c('priority').t("5").up()
.c('x', {xmlns:"http://jabber.org/protocol/muc"})
.tree()
);
};
Room.prototype.message = function(msg) {
};