Skip to content

Instantly share code, notes, and snippets.

@evantahler
Created January 4, 2015 20:27
Show Gist options
  • Save evantahler/2417bfed451886e9fb61 to your computer and use it in GitHub Desktop.
Save evantahler/2417bfed451886e9fb61 to your computer and use it in GitHub Desktop.
Actionhero + XMPP boilerplate
var XmppPrototype = require('node-xmpp');
var xmpp = function(api, options, next){
//////////
// INIT //
//////////
var type = 'xmpp'
var attributes = {
canChat: true,
logConnections: true,
logExits: true,
sendWelcomeMessage: true,
verbs: [
'quit',
'exit',
'documentation',
'roomAdd',
'roomLeave',
'roomView',
'detailsView',
'say'
]
}
var server = new api.genericServer(type, options, attributes);
//////////////////////
// REQUIRED METHODS //
//////////////////////
server._start = function(next){
server.server = new XmppPrototype.C2SServer(api.config.servers.xmpp);
server.server.on('connect', function(rawConnection){
rawConnection.on('disconnect', function() {
handleDisconnection(rawConnection);
});
rawConnection.on('authenticate', function(opts, cb){
console.log("AUTH")
// console.log('AUTH' + opts.jid + ' -> ' +opts.password)
// TODO: Handle Auth
// rawConnection.xmppAuthenticated = true;
return cb(null, opts); // AUTH PASS
// return cb(false); // AUTH FAIL
});
rawConnection.on('online', function(){
console.log("ONLINE")
// TODO: Handle the IQ request
handleConnection(rawConnection);
});
rawConnection.on('register', function(opts, cb){
console.log("REG");
return cb(true);
});
});
api.log('xmpp server active', 'debug');
server.active = true;
next();
}
server._stop = function(next){
server.server.shutdown();
next();
}
server.sendMessage = function(connection, message, messageCount){
if(!message.context){ message.context = 'response'; }
if(!messageCount){ messageCount = connection.messageCount; }
if(message.context === 'response' && !message.messageCount){ message.messageCount = messageCount; }
connection.rawConnection.send(
new XmppPrototype.Message({ type: 'chat' }).c('body').t( JSON.stringify(message) )
);
}
server.sendFile = function(connection, error, fileStream, mime, length){
//TODO
};
server.goodbye = function(connection, reason){
connection.rawConnection.end();
};
////////////
// EVENTS //
////////////
server.on('connection', function(connection){
connection.rawConnection.on('stanza', function(data){
console.log(data)
handleData(connection, data);
});
});
server.on('actionComplete', function(connection, toRender, messageCount){
if(toRender !== false){
connection.response.messageCount = messageCount;
server.sendMessage(connection, connection.response, messageCount)
}
});
/////////////
// HELPERS //
/////////////
var handleConnection = function(rawConnection){
server.buildConnection({
rawConnection : rawConnection,
remoteAddress : rawConnection.connection.socket.remoteAddress,
remotePort : rawConnection.connection.socket.remotePort,
});
}
var handleDisconnection = function(rawConnection){
for(var i in server.connections()){
if(server.connections()[i] && rawConnection.id === server.connections()[i].rawConnection.id){
server.connections()[i].destroy();
break;
}
}
}
var handleData = function(connection, data){
var verb = data.event;
delete data.event;
connection.messageCount++;
if(verb === 'action'){
for(var v in data.params){
connection.params[v] = data.params[v];
}
connection.error = null;
connection.response = {};
server.processAction(connection);
} else if(verb === 'file'){
connection.params = {
file: data.file
}
server.processFile(connection);
} else {
var words = [];
var message;
for(var i in data){ words.push(data[i]); }
connection.verbs(verb, words, function(error, data){
if(!error){
message = {status: 'OK', context: 'response', data: data};
server.sendMessage(connection, message);
} else {
message = {status: error, context: 'response', data: data}
server.sendMessage(connection, message);
}
});
}
}
next(server);
}
exports.xmpp = xmpp;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment