initial commit

This commit is contained in:
Kegan Myers 2014-08-08 20:13:24 -05:00
commit b08773f233
4 changed files with 127 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules

6
README.md Normal file
View file

@ -0,0 +1,6 @@
slack-command-router
====================
This is a simple library that exposes both a way to add event handlers for slack commands, and connect middleware to
facilitate the simple addition of a slack command handler to any project.
This project is written as a standalone library, but primarily designed for use in `slack-command-server`

99
index.js Normal file
View file

@ -0,0 +1,99 @@
var _ = require('lodash'),
Formidable = require('formidable'),
EventEmitter = require('events').EventEmitter;
function Slacker() {
}
_.assign(Slacker.prototype, EventEmitter.prototype);
function SlashCommand(body, res) {
//Things from the server
this.token = body.token;
this.teamId = body.team_id;
this.channelId = body.channel_id;
this.channelName = body.channel_name;
this.userId = body.user_id;
this.userName = body.user_name;
this.command = body.command;
this.text = body.text;
this.res = res;
//State variables
this._hasReplied = false;
}
_.assign(SlashCommand.prototype, {
_generalReply: function() {
if (this.hasReplied) {
throw {
message: "Only one handler can respond to a command"
}
}
this.hasReplied = true;
},
replyUser: function (message) {
this._generalReply();
this.res.end(message);
},
replyChannel: function () {
this._generalReply();
this.res.end();
},
error: function (message) {
this._generalReply();
this.res.writeHead(400);
this.res.end(message);
}
});
function SlackIncoming(commands) {
this.router = new Slacker();
if (typeof commands === "object") {
for (var handlerName in commands) {
if (commands.hasOwnProperty(handlerName)) {
this.registerHandler(commands[handlerName]);
}
}
}
}
(function () {
var checkedFields = ["token", "team_id", "channel_id", "channel_name", "user_id", "user_name", "command", "text"];
function checkCommand(fields) {
return _.xor(_.keys(fields), checkedFields).length === 0;
}
_.assign(SlackIncoming.prototype, {
registerHandler: function (handler) {
handler(this.router);
},
getMiddleware: function () {
var self = this;
return function (req, res, next) {
var form = new Formidable.IncomingForm();
form.encoding = 'utf-8';
form.type = 'urlencoded';
form.maxFieldsSize = 8192;
form.maxFields = 15;
form.parse(req, function (err, fields, files) {
if (err || !checkCommand(fields)
//Actually run the handlers
|| !self.router.emit(fields.command.slice(1), new SlashCommand(fields, res))) {
//This will only happen if there were no handlers for our event
next();
}
});
form.on('error', function(){
next();
});
form.on('aborted', function(){
next();
});
}
}
});
})();
module.exports = SlackIncoming;

21
package.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "slack-command-router",
"version": "0.0.0",
"description": "A slack slash command handler routing framework",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"slack",
"slash",
"command",
"webhooks"
],
"author": "Kegan Myers <kegan@keganmyers.com>",
"license": "BSD-2-Clause",
"dependencies": {
"formidable": "~1.0.15",
"lodash": "~2.4.1"
}
}