Comparing version 0.2.2 to 0.3.0
@@ -19,2 +19,7 @@ module.exports = function(ferd) { | ||
ferd.listen(/ferd poo/i, function(response) { | ||
var sender = response.getMessageSender(); | ||
response.sendDirectMessage('No, ' + sender.name + '. Poo be upon you!'); | ||
}); | ||
}; | ||
@@ -21,0 +26,0 @@ |
{ | ||
"name": "ferd", | ||
"version": "0.2.2", | ||
"description": "A modular slackbot", | ||
"version": "0.3.0", | ||
"description": "A modular Slackbot", | ||
"main": "index.js", | ||
"author": "Timothy Quach", | ||
"license": "ISC", | ||
"contributors": [{ | ||
"name": "Nick Salloum", | ||
"email": "nick@callmenick.com" | ||
}], | ||
"license": "MIT", | ||
"dependencies": { | ||
"rx": "^3.1.2", | ||
"slack-client": "^1.4.1" | ||
}, | ||
"devDependencies": { | ||
"grunt": "^0.4.5", | ||
"grunt-jsdoc": "^0.6.8" | ||
} | ||
} |
# A modular slackbot | ||
## A refactor | ||
# Slack types | ||
https://api.slack.com/types | ||
A modular Slacbot. More info coming soon. | ||
## Slack types | ||
https://api.slack.com/types |
144
src/bot.js
@@ -5,13 +5,14 @@ var Slack = require('slack-client'); | ||
/** | ||
* TODO: FIGURE OUT HOW TO DESTROY OBSERVABLES | ||
* BUG: OBSERVABLES MUST BE EXPLICITLY DESTROYED. MEMORY LEAK! | ||
*/ | ||
// TODO: FIGURE OUT HOW TO DESTROY OBSERVABLES | ||
// BUG: OBSERVABLES MUST BE EXPLICITLY DESTROYED. MEMORY LEAK! | ||
/** | ||
* Creates a new bot | ||
* @param {String} apiKey Slack API Key | ||
* Ferd | ||
* | ||
* @constructor | ||
* @description A modular Slack Bot. Returns nothing. | ||
* @param {String} apiToken Slack's Bot Integration API Token | ||
*/ | ||
var Bot = function(apiKey) { | ||
this.slack = new Slack(apiKey, true, true); | ||
var Ferd = function(apiToken) { | ||
this.slack = new Slack(apiToken, true, true); | ||
this.messages = null; | ||
@@ -23,18 +24,22 @@ this.name = null; | ||
/** | ||
* Opens WebSocket with slack using API key | ||
* @return {[type]} [description] | ||
* Ferd.prototype.login | ||
* | ||
* @description Opens WebSocket with Slack's Real-time Messaging API. Returns | ||
* nothing. | ||
*/ | ||
Bot.prototype.login = function() { | ||
Ferd.prototype.login = function() { | ||
var self = this; | ||
this.slack.on('open', () => self.setUp() ); | ||
this.slack.on('open', () => self._setUp() ); | ||
this.slack.on('error', (reason, code) => console.log('socket error: reason ' + reason + ', code ' + code) ); | ||
this.slack.login(); | ||
this.messages = this.createMessageStream(); | ||
this.messages = this._createMessageStream(); | ||
}; | ||
/** | ||
* Closes WebSocket and cleans up Observables | ||
* @return {[type]} [description] | ||
* Ferd.prototype.logout | ||
* | ||
* @description Closes WebSocket with Slack's Real-time Messaging API. Returns | ||
* nothing. | ||
*/ | ||
Bot.prototype.logout = function() { | ||
Ferd.prototype.logout = function() { | ||
this.slack.disconnect(); | ||
@@ -45,19 +50,36 @@ // destroy all observables created from this.messages | ||
/** | ||
* Sets up an Observable message stream | ||
* @return {[type]} [description] | ||
* Ferd.prototype.addModule | ||
* | ||
* @description Injects a module into Ferd. Returns nothing. | ||
* @param {module} ferdModule A module to inject into Ferd. Example: | ||
* `ferd.addModule(require('./ferd_modules/yo.js'))` | ||
*/ | ||
Bot.prototype.createMessageStream = function() { | ||
var messages = rx.Observable.fromEvent(this.slack, 'message') | ||
.where(e => e.type === 'message') | ||
// .map(e => new Message(e)); | ||
return messages; | ||
Ferd.prototype.addModule = function(ferdModule) { | ||
ferdModule(this); | ||
}; | ||
/** | ||
* Sets up an Observer to the message stream | ||
* @param {Regex} capture [description] | ||
* @param {Function} callback [description] | ||
* @return {Observable} [description] | ||
* Ferd.prototype.addModules | ||
* | ||
* @description Injects modules into Ferd. Returns nothing. | ||
* @param {module[]} ferdModules An array of modules to inject into Ferd. | ||
* Example: `ferd.addModules([require('ferd-bart'), require('./ferd_modules/yo.js'), ...])` | ||
*/ | ||
Bot.prototype.listen = function(capture, callback) { | ||
Ferd.prototype.addModules = function(ferdModules) { | ||
var self = this; | ||
ferdModules.forEach(function(module) { | ||
module(self); | ||
}); | ||
}; | ||
/** | ||
* Ferd.prototype.listen | ||
* | ||
* @description Listen to message stream for `capture` to trigger, then calls | ||
* a `callback` function. | ||
* @param {String} capture A regular expression to trigger the callback on | ||
* @param {Function} callback A callback with a response object passed in | ||
* @return {observable} - WHAT IS AN OBSERVABLE? | ||
*/ | ||
Ferd.prototype.listen = function(capture, callback) { | ||
return this.hear(function(message) { | ||
@@ -69,6 +91,11 @@ return true; | ||
/** | ||
* Listens to message stream for bot name and capture | ||
* @return {[type]} [description] | ||
* Ferd.prototype.respond | ||
* | ||
* @description Listens to message stream for ferd's name and `capture` to | ||
* trigger, then calls `callback` | ||
* @param {String} capture A regular expression to trigger the callback on | ||
* @param {Function} callback A callback with a response object passed in | ||
* @return {observable} - PUPPIES? | ||
*/ | ||
Bot.prototype.respond = function(capture, callback) { | ||
Ferd.prototype.respond = function(capture, callback) { | ||
var self = this; | ||
@@ -82,17 +109,19 @@ return this.hear(function(message) { | ||
/** | ||
* Helper for listen, respond | ||
* @param {Function} filter [description] | ||
* @param {Regex} capture [description] | ||
* @param {Function} callback [description] | ||
* @return {Disposable} [description] | ||
* Ferd.prototype.hear | ||
* | ||
* @description Listens to message stream for `filter` to return true and | ||
* `capture` to trigger, then calls `callback` | ||
* @param {Function} filter A function that returns true or false. Takes in message. | ||
* @param {String} capture A regular expression to trigger the callback on | ||
* @param {Function} callback A callback with a response object passed in | ||
* @return {disposable} More reactive shenanigans. | ||
*/ | ||
Bot.prototype.hear = function(filter, capture, callback) { | ||
Ferd.prototype.hear = function(filter, capture, callback) { | ||
var self = this; | ||
var slack = this.slack; | ||
var messages = this.messages | ||
.filter(m => filter(m) && m.text.match(capture)) | ||
.filter(m => filter(m) && m.text.match(capture)); | ||
var disposable = messages | ||
.subscribe(function(message) { | ||
// console.log(message.text); | ||
var response = Response(capture, message, slack) | ||
@@ -106,28 +135,25 @@ callback(response); | ||
/** | ||
* Bootstraps Bot identity | ||
* Ferd.prototype._createMessageStream | ||
* | ||
* @private | ||
* @description Sets up a message stream. | ||
* @return {observable} Message Stream | ||
*/ | ||
Bot.prototype.setUp = function() { | ||
this.name = this.slack.self.name; | ||
this.id = this.slack.self.id; | ||
Ferd.prototype._createMessageStream = function() { | ||
var messages = rx.Observable.fromEvent(this.slack, 'message') | ||
.where(e => e.type === 'message'); | ||
return messages; | ||
}; | ||
/** | ||
* Inject ferd into module | ||
* @param {Module} ferdModules [description] | ||
* Ferd.prototype._setUp | ||
* | ||
* @private | ||
* @description Bootstraps Ferd identity. Returns nothing. | ||
*/ | ||
Bot.prototype.addModule = function(ferdModule) { | ||
ferdModule(this); | ||
Ferd.prototype._setUp = function() { | ||
this.name = this.slack.self.name; | ||
this.id = this.slack.self.id; | ||
}; | ||
/** | ||
* Inject ferd into modules | ||
* @param {Array[Module]} ferdModules [description] | ||
*/ | ||
Bot.prototype.addModules = function(ferdModules) { | ||
var self = this; | ||
ferdModules.forEach(function(module) { | ||
module(self); | ||
}); | ||
}; | ||
module.exports = Bot; | ||
module.exports = Ferd; |
@@ -1,31 +0,70 @@ | ||
var ResponseFactory = function(trigger, message, slack) { | ||
var match = message.text.match(trigger); | ||
if (match) return new Response(trigger, message, slack, match); | ||
else return null; | ||
/** | ||
* ResponseFactory | ||
* | ||
* @description The factory that builds the response | ||
* @param {[type]} | ||
* @param {[type]} | ||
* @param {[type]} | ||
* @return {[type]} [description] | ||
*/ | ||
var ResponseFactory = function(trigger, incomingMessage, slack) { | ||
var match = incomingMessage.text.match(trigger); | ||
if (match) { | ||
return new Response(trigger, incomingMessage, slack, match); | ||
} else { | ||
return null; | ||
} | ||
}; | ||
var Response = function(trigger, message, slack, match) { | ||
this.message = message; | ||
/** | ||
* Response | ||
* | ||
* @constructor | ||
* @description The Response class. Returns nothing. | ||
* @param {regex} trigger [description] | ||
* @param {message} message [description] | ||
* @param {slack} slack [description] | ||
* @param {match} match [description] | ||
*/ | ||
var Response = function(trigger, incomingMessage, slack, match) { | ||
this.incomingMessage = incomingMessage; | ||
this.trigger = trigger; | ||
this.slack = slack; | ||
this.match = match | ||
this.match = match; | ||
}; | ||
/** | ||
* Sends response to same channel | ||
* @param {String} response A response | ||
* Response.prototype.send | ||
* | ||
* @description Sends a message to same channel. Returns nothing. | ||
* @param {Object} outgoingMessage The message to send back. | ||
*/ | ||
Response.prototype.send = function(response) { | ||
var channelId = this.message.channel; | ||
Response.prototype.send = function(outgoingMessage) { | ||
var channelId = this.incomingMessage.channel; | ||
var channel = this.getChannelGroupOrDMByID(channelId); | ||
channel.send(response); | ||
channel.send(outgoingMessage); | ||
}; | ||
/** | ||
* Returns Slack User object | ||
* https://api.slack.com/types/user | ||
* Response.prototype.sendDirectMessage | ||
* | ||
* @description Sends a direct message to a user. Returns nothing. | ||
* @param {Object} outgoingMessage The message to send back. | ||
*/ | ||
Response.prototype.sendDirectMessage = function(outgoingMessage) { | ||
var username = this.getMessageSender().name; | ||
var dmChannel = this.getDMByName(username); | ||
dmChannel.send(outgoingMessage); | ||
}; | ||
/** | ||
* Response.prototype.getMessageSender | ||
* | ||
* @description Returns Slack user object of sender. Visit the Slack API to see | ||
* more about user types - https://api.slack.com/types/user | ||
* @return {Object} A slack user object | ||
*/ | ||
Response.prototype.getMessageSender = function() { | ||
var userId = this.message.user; | ||
var userId = this.incomingMessage.user; | ||
var user = this.getUser(userId); | ||
@@ -36,5 +75,8 @@ return user; | ||
/** | ||
* Returns User slack object | ||
* @param {String} id [description] | ||
* @return {Object} [description] | ||
* Response.prototype.getUser | ||
* | ||
* @description Returns Slack user object. Visit the Slack API to see more about | ||
* user types - https://api.slack.com/types/user | ||
* @param {String} id The ID of the user | ||
* @return {Object} Slack user object | ||
*/ | ||
@@ -46,8 +88,23 @@ Response.prototype.getUser = function(id) { | ||
/** | ||
* Returns Channel, Group, or IM slack object | ||
* Use to send appropriate message to right channel | ||
* https://api.slack.com/types | ||
* @param {String} id [description] | ||
* @return {Object} [description] | ||
* Response.prototype.getDMByName | ||
* | ||
* @description Gets a direct message channel by username, and is used to send | ||
* IM message types to the right direct message channel. Visit the Slack API | ||
* to see more about message types - https://api.slack.com/types | ||
* @param {String} name The name (username) of the DM's owner | ||
* @return {Object} Slack message object | ||
*/ | ||
Response.prototype.getDMByName = function(name) { | ||
return this.slack.getDMByName(name); | ||
}; | ||
/** | ||
* Response.prototype.getChannelGroupOrDMByID | ||
* | ||
* @description Returns Channel, Group, or IM slack object. Use to send | ||
* appropriate message to right channel. Visit the Slack API to see more about | ||
* message types - https://api.slack.com/types | ||
* @param {String} id An ID of a message type | ||
* @return {Object} Slack message object | ||
*/ | ||
Response.prototype.getChannelGroupOrDMByID = function(id) { | ||
@@ -57,3 +114,3 @@ return this.slack.getChannelGroupOrDMByID(id); | ||
/** | ||
/*** | ||
* BUG: UNTESTED | ||
@@ -60,0 +117,0 @@ * @param {[type]} id [description] |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
9
7
10701
2
297
2