From 9c0746ea891b733b659a74bf010267efa7f2b146 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sat, 27 Aug 2016 17:45:47 -0300 Subject: [PATCH 01/26] Add microbadger badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 747d5dc..789e830 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # hubot.js -[![Build Status](https://travis-ci.org/hubot-js/hubot.js.svg?branch=master)](https://travis-ci.org/hubot-js/hubot.js) [![Coverage Status](https://coveralls.io/repos/github/hubot-js/hubot.js/badge.svg?branch=master)](https://coveralls.io/github/hubot-js/hubot.js?branch=master) [![Code Climate](https://img.shields.io/codeclimate/github/hubot-js/hubot.js.svg)](https://codeclimate.com/github/hubot-js/hubot.js) [![dependencies-badge](https://david-dm.org/hubot-js/hubot.js.svg)](https://david-dm.org/hubot-js/hubot.js) [![devDependencies Status](https://david-dm.org/hubot-js/hubot.js/dev-status.svg)](https://david-dm.org/hubot-js/hubot.js?type=dev) [![Docker Stars](https://img.shields.io/docker/stars/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![Docker Pulls](https://img.shields.io/docker/pulls/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) +[![Build Status](https://travis-ci.org/hubot-js/hubot.js.svg?branch=master)](https://travis-ci.org/hubot-js/hubot.js) [![Coverage Status](https://coveralls.io/repos/github/hubot-js/hubot.js/badge.svg?branch=master)](https://coveralls.io/github/hubot-js/hubot.js?branch=master) [![Code Climate](https://img.shields.io/codeclimate/github/hubot-js/hubot.js.svg)](https://codeclimate.com/github/hubot-js/hubot.js) [![dependencies-badge](https://david-dm.org/hubot-js/hubot.js.svg)](https://david-dm.org/hubot-js/hubot.js) [![devDependencies Status](https://david-dm.org/hubot-js/hubot.js/dev-status.svg)](https://david-dm.org/hubot-js/hubot.js?type=dev) [![Docker Stars](https://img.shields.io/docker/stars/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![Docker Pulls](https://img.shields.io/docker/pulls/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![image-size](https://images.microbadger.com/badges/image/robsonbittencourt/hubot.js.svg)](http://microbadger.com/images/robsonbittencourt/hubot.js) > A small robot written in Javascript (He doesn't like coffeescript) From 99a9596dd0c66e15bc8d23373a1bae1532cb50c2 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sat, 1 Oct 2016 20:31:52 -0300 Subject: [PATCH 02/26] Encapsulate the postMessage function --- package.json | 1 + src/lib/hubot.js | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/package.json b/package.json index a13803f..e63b9a4 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "slackbots": "^0.5.2", "string": "^3.3.1", "winston": "^2.2.0", + "q": "^1.4.1", "gear-help": "^1.0.1", "gear-jenkins": "^1.0.1" }, diff --git a/src/lib/hubot.js b/src/lib/hubot.js index 003cd84..c59e744 100644 --- a/src/lib/hubot.js +++ b/src/lib/hubot.js @@ -6,6 +6,7 @@ var log = require(__base + 'src/lib/log'); var Assembler = require(__base + 'src/lib/assembler'); var messageHandler = require(__base + 'src/lib/message-handler'); var speech = require(__base + 'src/lib/speech'); +let Q = require('q'); process.on('uncaughtException', function (exception) { log.error(exception); @@ -78,3 +79,26 @@ Hubot.prototype.getRecipient = function (message) { return message.channel; } } + +Hubot.prototype.talkTo = function (recipient, text, message, delay = 1000) { + let deferred = Q.defer(); + let channel = message ? message.channel : recipient; + + this.ws.send(JSON.stringify({ type: 'typing', channel: channel })); + + setTimeout(() => { + + this.postMessage(recipient, text, {as_user: true}).then(function() { + deferred.resolve(); + }, function() { + deferred.reject(); + }); + + }, delay); + + return deferred.promise; +} + +Hubot.prototype.talk = function (message, text, delay) { + return this.talkTo(this.getRecipient(message), text, message, delay); +} From b6bc2be6445842e67845d2a9e414b5e428cddd8b Mon Sep 17 00:00:00 2001 From: Robson Date: Mon, 10 Oct 2016 15:11:25 -0300 Subject: [PATCH 03/26] Fix #15 Allow configurations made by Slack --- .gitignore | 6 + data/.gitkeep | 0 package.json | 1 + src/lib/assembler.js | 80 +++++-- src/lib/conversation.js | 178 +++++++++++++++ src/lib/db.js | 78 +++++++ src/lib/hubot.js | 129 ++++++++++- src/lib/message-handler.js | 19 -- .../handlers/conversation-handler.js | 14 ++ .../handlers/first-run-handler.js | 11 + .../handlers/gear-activate-handler.js | 49 ++++ .../handlers/gear-configure-handler.js | 37 +++ .../handlers/gear-deactivate-handler.js | 50 +++++ .../message-handler/handlers/tasks-handler.js | 35 +++ src/lib/message-handler/message-handler.js | 28 +++ test/lib/assembler.js | 138 +++++++----- test/lib/trigger.js | 212 +++++++++--------- .../config/categories.json | 0 .../{test => gear-test}/config/tasks.json | 0 .../handlers/test-handler.js | 0 20 files changed, 853 insertions(+), 212 deletions(-) create mode 100644 data/.gitkeep create mode 100644 src/lib/conversation.js create mode 100644 src/lib/db.js delete mode 100644 src/lib/message-handler.js create mode 100644 src/lib/message-handler/handlers/conversation-handler.js create mode 100644 src/lib/message-handler/handlers/first-run-handler.js create mode 100644 src/lib/message-handler/handlers/gear-activate-handler.js create mode 100644 src/lib/message-handler/handlers/gear-configure-handler.js create mode 100644 src/lib/message-handler/handlers/gear-deactivate-handler.js create mode 100644 src/lib/message-handler/handlers/tasks-handler.js create mode 100644 src/lib/message-handler/message-handler.js rename test/resource/gears/{test => gear-test}/config/categories.json (100%) rename test/resource/gears/{test => gear-test}/config/tasks.json (100%) rename test/resource/gears/{test => gear-test}/handlers/test-handler.js (100%) diff --git a/.gitignore b/.gitignore index a1a08ae..519be63 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ npm-debug.log* hubot.log +hubot.db + # Runtime data pids *.pid @@ -35,3 +37,7 @@ jspm_packages # Optional REPL history .node_repl_history + +hubot.db + +.vscode diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index e63b9a4..3f1e290 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "string": "^3.3.1", "winston": "^2.2.0", "q": "^1.4.1", + "sqlite3": "^3.1.4", "gear-help": "^1.0.1", "gear-jenkins": "^1.0.1" }, diff --git a/src/lib/assembler.js b/src/lib/assembler.js index 8df32bd..ab03f5b 100644 --- a/src/lib/assembler.js +++ b/src/lib/assembler.js @@ -3,39 +3,45 @@ var fs = require('fs'); var log = require(__base + 'src/lib/log'); var speech = require(__base + 'src/lib/speech'); +var db = new (require(__base + 'src/lib/db')); const gearNamePrefix = 'gear-'; module.exports = class Assembler { constructor() { - this.core = { - tasks: [], - categories: [], - handlers: [] - }; + this.gears = []; } build() { this.loadGears(this); - return this.core; + return this.gears; } loadGears(self) { fs.readdir(__nodeModules, function (error, list) { - var gears = list.filter(function (e) { + var gearsNames = list.filter(function (e) { return e.startsWith(gearNamePrefix); }); - gears.forEach((gear, index) => self.loadGear(gears, gear, index)); + gearsNames.forEach(function(gearName) { + var gearDescription = gearName.replace("gear-", ""); + + self.gears.push( { name: gearName, description: gearDescription } ); + }); + + self.gears.forEach((gear, index) => self.loadGear(self.gears, gear, index)); }); - }; + } loadGear(gears, gear, index) { logAddingGear(gears, gear, index); + this.tryToLoad('gearStatus', gear, this.loadGearStatus); + this.tryToLoad('configs', gear, this.loadConfigs); this.tryToLoad('tasks', gear, this.loadTasks); this.tryToLoad('categories', gear, this.loadCategories); this.tryToLoad('handlers', gear, this.loadHandlers); + this.tryToLoad('configHandler', gear, this.loadConfigHandler); } tryToLoad(type, gear, assemble) { @@ -47,38 +53,66 @@ module.exports = class Assembler { } } + loadGearStatus(gear, self) { + db.get('SELECT * FROM gears WHERE name = ?', gear.name).then(function(record) { + if (!record) { + gear.active = false; + db.run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', [gear.name, gear.description, 'NO']); + } else { + gear.active = (record.active === 'YES') ? true : false; + } + }); + } + + loadConfigs(gear, self) { + gear.configs = []; + gear.configs = gear.configs.concat(require(self.configsPath(gear))); + } + loadTasks(gear, self) { - self.core.tasks = self.core.tasks.concat(require(self.tasksPath(gear))); + gear.tasks = []; + gear.tasks = gear.tasks.concat(require(self.tasksPath(gear))); } loadCategories(gear, self) { - self.core.categories = self.core.categories.concat(require(self.categoriesPath(gear))); + gear.categories = []; + gear.categories = gear.categories.concat(require(self.categoriesPath(gear))); } loadHandlers(gear, self) { - self.core.tasks.forEach(function(task) { - if (!self.containsHandler(task.handler)) { - var handler = require(self.handlersPath(gear, task.handler)); - self.core.handlers.push({ key: task.handler, handle: handler.handle}); - } + gear.handlers = []; + + gear.tasks.forEach(function(task) { + var handler = require(self.handlersPath(gear, task.handler)); + + gear.handlers.push({ key: task.handler, handle: handler.handle}); }); } - containsHandler(handler) { - return this.core.handlers.find(h => h.key === handler) != null; + loadConfigHandler(gear, self) { + gear.configHandler = require(self.configsHandlersPath(gear)); + } + + configsPath(gear) { + return __nodeModules + gear.name + '/config/config.json'; } - + tasksPath(gear) { - return __nodeModules + gear + '/config/tasks.json'; + return __nodeModules + gear.name + '/config/tasks.json'; } categoriesPath(gear) { - return __nodeModules + gear + '/config/categories.json'; + return __nodeModules + gear.name + '/config/categories.json'; } handlersPath(gear, handler) { - return __nodeModules + gear + '/src/handlers/' + handler; + return __nodeModules + gear.name + '/src/handlers/' + handler; + } + + configsHandlersPath(gear) { + return __nodeModules + gear.name + '/src/configHandler/configHandler'; } + } function logStartAssembling() { @@ -88,7 +122,7 @@ function logStartAssembling() { function logAddingGear(gears, gear, index) { if (!gears) return log.error('Could not load gears.'); if (!gear) return log.error('Could not load gear at index ' + index); - log.info(speech.start('Adding ').refer(gear).progress(index + 1, gears.length).end()); + log.info(speech.start('Adding ').refer(gear.name).progress(index + 1, gears.length).end()); } function logInfoLoadingGear(gear) { diff --git a/src/lib/conversation.js b/src/lib/conversation.js new file mode 100644 index 0000000..bc866da --- /dev/null +++ b/src/lib/conversation.js @@ -0,0 +1,178 @@ +'use strict'; + +exports.startConversation = startConversation; +exports.hasActiveConversation = hasActiveConversation; +exports.notify = notify; + +let Q = require('q'); + +const EventEmitter = require('events'); + +class MyEmitter extends EventEmitter {} + +const myEmitter = new MyEmitter(); + +var activeConversations = []; + +function startConversation(hubot, conversation, message) { + activeConversations.push(conversation); + + conversation.nextInteration = 0; + + start(hubot, conversation, message); +} + +function start(hubot, conversation, message) { + var interactions = conversation.interactions; + + if (conversation.nextInteration < interactions.length) { + speak(hubot, message, conversation, function(conversation) { + start(hubot, conversation, message); + }); + } + + if (conversation.nextInteration == interactions.length) { + if (conversation.previousConversation) { + start(hubot, conversation.previousConversation, message); + } else { + endConversations(conversation); + } + } +} + +function speak(hubot, message, conversation, callback) { + var interaction = conversation.interactions[conversation.nextInteration]; + + hubot.talk(message, interaction.speak).then(function() { + if(justSpeak(conversation, interaction, callback)) return; + + myEmitter.once(message.user, function(response) { + if (withoutExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; + + if (withExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; + + Q(handleResponse(conversation, interaction, response)).then(function(text) { + conversation.nextInteration++; + + if(text) { + hubot.talk(message, text).then(function() { + if(hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; + callback(conversation); + }); + } else { + if(hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; + callback(conversation); + } + }, function(text) { + speakReturnedText(hubot, message, conversation, text, callback); + }); + }); + }); +} + +function justSpeak(conversation, interaction, callback) { + if (!interaction.expectedResponses && !interaction.handler) { + conversation.nextInteration++; + callback(conversation); + return true; + } + + return false; +} + +function withoutExpectedResponse(conversation, interaction, response, hubot, message, callback) { + if (!interaction.expectedResponses) { + Q(handleResponse(conversation, interaction, response)).then(function(text) { + conversation.nextInteration++; + speakReturnedText(hubot, message, conversation, text, callback); + }, function(text) { + speakReturnedText(hubot, message, conversation, text, callback); + }); + return true; + } + + return false; +} + +function speakReturnedText(hubot, message, conversation, text, callback) { + if(text) { + hubot.talk(message, text).then(function() { + callback(conversation); + }); + } else { + callback(conversation); + } +} + +function withExpectedResponse(conversation, interaction, response, hubot, message, callback) { + if (!getExpectedResponse(interaction.expectedResponses, response)) { + hubot.talk(message, invalidResponseMessage(hubot, getExpectedResponses(interaction))).then(function() { + callback(conversation); + }); + return true; + } + + return false; +} + +function hasAnotherInteraction(conversation, interaction, response, hubot, message) { + var expectedResponse = getExpectedResponse(interaction.expectedResponses, response); + + if (expectedResponse.iteration) { + var newConversation = { + user: message.user, + interactions: [expectedResponse.iteration], + gear: conversation.gear, + nextInteration: 0, + previousConversation: conversation + }; + + start(hubot, newConversation, message); + return true; + } + + return false; +} + +function handleResponse(conversation, interaction, response) { + if (interaction.handler) { + var handler = require(__nodeModules + 'gear-' + conversation.gear + '/' + interaction.handler); + return handler.handle(response.text); + } +} + +function getExpectedResponse(expectedResponses, response) { + if (expectedResponses) { + return expectedResponses.find(r => r.response === response.text); + } + + return null; +} + +function getExpectedResponses(interaction) { + let expectedResponses = []; + + interaction.expectedResponses.forEach(e => expectedResponses.push(e.response)); + + return expectedResponses; +} + +function invalidResponseMessage(hubot, expectedResponses) { + return hubot.speech().append("Sorry, I didn't understand.").append("(Expected responses: ").bold(expectedResponses.join(", ")).append(").").end(); +} + +function hasActiveConversation(message) { + return getActiveConversation(message) != null; +} + +function notify(message) { + myEmitter.emit(message.user, message); +} + +function getActiveConversation(message) { + return activeConversations.find(c => c.user === message.user); +} + +function endConversations(conversation) { + activeConversations = activeConversations.filter(c => c.user !== conversation.user); +} diff --git a/src/lib/db.js b/src/lib/db.js new file mode 100644 index 0000000..86f9587 --- /dev/null +++ b/src/lib/db.js @@ -0,0 +1,78 @@ +'use strict'; + +let Q = require('q'); +let fs = require('fs'); +let log = require(__base + 'src/lib/log'); +let path = require('path'); +let sqlite3 = require('sqlite3'); + +module.exports = class DataBase { + + constructor() { + this.outputFile = path.resolve(process.cwd(), 'data', 'hubot.db'); + + if (!fs.existsSync(this.outputFile)) { + return createDb(this); + } + + return updateDb(this); + } + + run(sql, params) { + let deferred = Q.defer(); + + this.db.run(sql, params, function(err) { + resultHandler(deferred, err); + }); + + return deferred.promise; + } + + get(sql, params) { + let deferred = Q.defer(); + + this.db.get(sql, params, function(err, row) { + resultHandler(deferred, err, row); + }); + + return deferred.promise; + } + + all(sql, params) { + let deferred = Q.defer(); + + this.db.all(sql, params, function(err, rows) { + resultHandler(deferred, err, rows); + }); + + return deferred.promise; + } + +} + +function createDb(dataBase) { + dataBase.db = new sqlite3.Database(dataBase.outputFile); + + dataBase.db.serialize(); + + dataBase.db.run('CREATE TABLE IF NOT EXISTS admins (admin TEXT NOT NULL)'); + dataBase.db.run('CREATE TABLE IF NOT EXISTS first_use (first_use TEXT NOT NULL)'); + dataBase.db.run('CREATE TABLE IF NOT EXISTS gears (name TEXT NOT NULL, description TEXT NOT NULL, active TEXT NOT NULL)'); + + return dataBase; +} + +function updateDb(dataBase) { + dataBase.db = new sqlite3.Database(dataBase.outputFile); + + return dataBase; +} + +function resultHandler(deferred, err, result) { + if (err) { + log.error(err); + deferred.reject(err); + } else { + deferred.resolve(result); + } +} diff --git a/src/lib/hubot.js b/src/lib/hubot.js index c59e744..26c5c86 100644 --- a/src/lib/hubot.js +++ b/src/lib/hubot.js @@ -1,12 +1,13 @@ -'use strict'; + 'use strict'; var util = require('util'); var Bot = require('slackbots'); var log = require(__base + 'src/lib/log'); var Assembler = require(__base + 'src/lib/assembler'); -var messageHandler = require(__base + 'src/lib/message-handler'); +var messageHandler = require(__base + 'src/lib/message-handler/message-handler'); var speech = require(__base + 'src/lib/speech'); let Q = require('q'); +var db = new (require(__base + 'src/lib/db')); process.on('uncaughtException', function (exception) { log.error(exception); @@ -16,6 +17,7 @@ var Hubot = function Constructor(settings) { this.settings = settings; this.name = this.settings.name; this.user = null; + this.isFirstRun = false; }; util.inherits(Hubot, Bot); @@ -31,15 +33,60 @@ Hubot.prototype.run = function () { Hubot.prototype._onStart = function () { this._loadBotUser(); - this.core = new Assembler().build(); + this.gears = new Assembler().build(); + this._firstRunChecker(); +}; + +Hubot.prototype._firstRunChecker = function () { + let self = this; + + db.get('SELECT * FROM first_use').then(function(record) { + if (!record || !record.first_use) { + self.isFirstRun = true; + } + }); }; Hubot.prototype._onMessage = function (message) { - if (this._isChatMessage(message) && !this._isFromHubot(message)) { - messageHandler.callTasks(message, this); + if (this._isChatMessage(message) && !this._isFromHubot(message)) { + if (isFirstInteraction(this, message)) { + this._firstRun(message); + } else { + messageHandler.callTasks(message, this); + } } }; +Hubot.prototype._firstRun = function(message) { + db.run("INSERT INTO first_use(first_use) VALUES('NO')"); + db.run("INSERT INTO admins(admin) VALUES(?)", message.user); + + let self = this; + + self.isFirstRun = false; + let messageDelay = 3000; + + self.talk(message, message1(self, message), messageDelay) + .then(function() { + return self.talk(message, message2(self), messageDelay); + }) + .then(function() { + return self.talk(message, message3(self), messageDelay); + }) + .then(function() { + return self.talk(message, message4(self), messageDelay); + }) + .then(function() { + return self.talk(message, message5(self), messageDelay); + }) + .then(function() { + return self.talk(message, message6(self), messageDelay); + }) + .then(function() { + self.talk(message, postGearsNames(self), messageDelay); + }); +} + Hubot.prototype._loadBotUser = function () { this.user = this._getUserByName(this.name); }; @@ -102,3 +149,75 @@ Hubot.prototype.talkTo = function (recipient, text, message, delay = 1000) { Hubot.prototype.talk = function (message, text, delay) { return this.talkTo(this.getRecipient(message), text, message, delay); } + +Hubot.prototype._isAdminUser = function (user) { + return db.get('SELECT * FROM admins WHERE admin = ?', user); +}; + +Hubot.prototype._activateGear = function (gear) { + findGear(this, gear).active = true; + + return db.run('UPDATE gears SET active = "YES" WHERE description = ?', gear); +} + +Hubot.prototype._deactivateGear = function (gear) { + findGear(this, gear).active = false; + + return db.run('UPDATE gears SET active = "NO" WHERE description = ?', gear); +} + +Hubot.prototype._getGear = function (gear) { + return db.get('SELECT * FROM gears WHERE description = ?', gear); +} + +Hubot.prototype.info = function (info) { + log.info(info); +} + +Hubot.prototype.error = function (error) { + log.error(error); +} + +Hubot.prototype.detailedError = function (error, metadata) { + log.detailedError(error, metadata); +} + +function isFirstInteraction(hubot, message) { + return hubot.isFirstRun && hubot._isPrivateConversation(message) && message.text === hubot.name; +} + +function message1(hubot, message) { + return hubot.speech().hello(hubot._getUserById(message.user)).append("My name is ").append(hubot.name).append(" and from now on I will help you with some tasks using the Slack.").end(); +} + +function message2(hubot) { + return hubot.speech().append("Before I need you to do some settings. How was you who started me I will define it as my system administrator. So you can access the settings in the future.").end(); +} + +function message3(hubot) { + return hubot.speech().append("Initially I do not know perform tasks. But there are gears that when coupled to me add me skills.").end(); +} + +function message4(hubot) { + return hubot.speech().append("At this time all the gears are inactive. You can activate them using the command ").bold("activate gear-name").period().end(); +} + +function message5(hubot) { + return hubot.speech().append("Some gears have settings. To let them use the command ").bold("configure gear-name").period().end(); +} + +function message6(hubot) { + return hubot.speech().append("Below is a list of gears available:").end(); +} + +function postGearsNames(hubot) { + var speech = hubot.speech(); + + hubot.gears.forEach(g => speech.item(g.description).line()); + + return speech.end(); +} + +function findGear(hubot, gear) { + return hubot.gears.find(g => g.description === gear); +} diff --git a/src/lib/message-handler.js b/src/lib/message-handler.js deleted file mode 100644 index f1eda5e..0000000 --- a/src/lib/message-handler.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -exports.callTasks = callTasks; - -var trigger = require(__base + 'src/lib/trigger'); - -function callTasks(message, hubot) { - hubot.core.tasks.forEach(function(task) { - var acceptance = trigger.check(message.text, task.trigger); - if (acceptance.ok) { - var handler = getHandler(hubot, task); - handler.handle(hubot, message, task, acceptance.params); - } - }); -} - -function getHandler(hubot, task) { - return hubot.core.handlers.find(h => h.key === task.handler); -} diff --git a/src/lib/message-handler/handlers/conversation-handler.js b/src/lib/message-handler/handlers/conversation-handler.js new file mode 100644 index 0000000..f32f999 --- /dev/null +++ b/src/lib/message-handler/handlers/conversation-handler.js @@ -0,0 +1,14 @@ +'use strict'; + +exports.handle = handle; + +const conversation = require(__base + 'src/lib/conversation'); + +function handle(hubot, message) { + if (conversation.hasActiveConversation(message)) { + conversation.notify(message); + return true; + } + + return false; +} diff --git a/src/lib/message-handler/handlers/first-run-handler.js b/src/lib/message-handler/handlers/first-run-handler.js new file mode 100644 index 0000000..077ab3a --- /dev/null +++ b/src/lib/message-handler/handlers/first-run-handler.js @@ -0,0 +1,11 @@ +'use strict'; + +exports.handle = handle; + +function handle(hubot, message) { + if (hubot.isFirstRun) { + return true; + } + + return false; +} diff --git a/src/lib/message-handler/handlers/gear-activate-handler.js b/src/lib/message-handler/handlers/gear-activate-handler.js new file mode 100644 index 0000000..e6351a0 --- /dev/null +++ b/src/lib/message-handler/handlers/gear-activate-handler.js @@ -0,0 +1,49 @@ +'use strict'; + +exports.handle = handle; + +const speech = require(__base + 'src/lib/speech'); + +function handle(hubot, message) { + if (isGearActivateMessage(hubot, message)) { + hubot._isAdminUser(message.user) + .then(getGear) + .then(activateGear); + + function getGear(isAdmin) { + if (isAdmin) { + var gearDescription = message.text.replace("activate ", ""); + + return hubot._getGear(gearDescription); + } + } + + function activateGear(gear) { + if (gear && 'YES' == gear.active) { + hubot.talk(message, 'This gear is already active.'); + } else { + hubot._activateGear(gear.description).then(function() { + hubot.talk(message, sucessMessage(gear.description)); + }, function() { + hubot.talk(message, errorMessage(gear.description)); + }); + } + } + } +} + +function isGearActivateMessage(hubot, message) { + return hubot.gears.find(function(gear) { + var configureMessage = 'activate ' + gear.description; + + return message.text === configureMessage; + }) != null; +} + +function sucessMessage(gearDescription) { + return speech.start('Successfully activated ').bold('gear ' + gearDescription).end(); +} + +function errorMessage(gearDescription) { + return speech.start('Could not activate ').bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() +} diff --git a/src/lib/message-handler/handlers/gear-configure-handler.js b/src/lib/message-handler/handlers/gear-configure-handler.js new file mode 100644 index 0000000..fb63104 --- /dev/null +++ b/src/lib/message-handler/handlers/gear-configure-handler.js @@ -0,0 +1,37 @@ +'use strict'; + +exports.handle = handle; + +const conversation = require(__base + 'src/lib/conversation'); + +function handle(hubot, message) { + if (isGearConfigureMessage(hubot, message)) { + var param = { + user: message.user, + gear: gearDescription(message), + interactions: discoverConfig(hubot, message) + } + + conversation.startConversation(hubot, param, message); + } +} + +function isGearConfigureMessage(hubot, message) { + return hubot.gears.find(function(gear) { + var configureMessage = 'configure ' + gear.description; + + return message.text === configureMessage; + }) != null; +} + +function discoverConfig(hubot, message) { + return hubot.gears.find(g => g.description === gearDescription(message)).configs; +} + +function getConfigHandler(hubot, message) { + return hubot.gears.find(g => g.description === gearDescription(message)).configHandler; +} + +function gearDescription(message) { + return message.text.replace("configure ", ""); +} diff --git a/src/lib/message-handler/handlers/gear-deactivate-handler.js b/src/lib/message-handler/handlers/gear-deactivate-handler.js new file mode 100644 index 0000000..c1e79a9 --- /dev/null +++ b/src/lib/message-handler/handlers/gear-deactivate-handler.js @@ -0,0 +1,50 @@ +'use strict'; + +exports.handle = handle; + +const speech = require(__base + 'src/lib/speech'); + +function handle(hubot, message) { + if (isGearDeactivateMessage(hubot, message)) { + + hubot._isAdminUser(message.user) + .then(getGear) + .then(deactivateGear); + + function getGear(isAdmin) { + if (isAdmin) { + var gearDescription = message.text.replace("deactivate ", ""); + + return hubot._getGear(gearDescription); + } + } + + function deactivateGear(gear) { + if (gear && 'NO' == gear.active) { + hubot.talk(message, 'This gear is already inactive.'); + } else { + hubot._deactivateGear(gear.description).then(function() { + hubot.talk(message, sucessMessage(gear.description)); + }, function() { + hubot.talk(message, errorMessage(gear.description)); + }); + } + } + } +} + +function isGearDeactivateMessage(hubot, message) { + return hubot.gears.find(function(gear) { + var configureMessage = 'deactivate ' + gear.description; + + return message.text === configureMessage; + }) != null; +} + +function sucessMessage(gearDescription) { + return speech.start('Successfully deactivated ').bold('gear ' + gearDescription).end(); +} + +function errorMessage(gearDescription) { + return speech.start('Could not deactivate ').bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() +} diff --git a/src/lib/message-handler/handlers/tasks-handler.js b/src/lib/message-handler/handlers/tasks-handler.js new file mode 100644 index 0000000..3489119 --- /dev/null +++ b/src/lib/message-handler/handlers/tasks-handler.js @@ -0,0 +1,35 @@ +'use strict'; + +exports.handle = handle; + +var trigger = require(__base + 'src/lib/trigger'); + +function handle(hubot, message) { + hubot.gears.forEach(function(gear) { + gear.tasks.forEach(function(task) { + + var acceptance = trigger.check(message.text, task.trigger); + + if (acceptance.ok) { + hubot._getGear(gear.description).then(function(result) { + if (result && 'YES' == result.active) { + var handler = getHandler(gear, task); + handler.handle(hubot, message, task, acceptance.params); + } else { + hubot.talk(message, "Sorry, this feature is disabled."); + } + + return true; + }); + + } + + }); + }); + + return false; +} + +function getHandler(gear, task) { + return gear.handlers.find(h => h.key === task.handler); +} diff --git a/src/lib/message-handler/message-handler.js b/src/lib/message-handler/message-handler.js new file mode 100644 index 0000000..8034572 --- /dev/null +++ b/src/lib/message-handler/message-handler.js @@ -0,0 +1,28 @@ +'use strict'; + +exports.callTasks = callTasks; + +function callTasks(message, hubot) { + let handlers = getHandlers(); + + for (let i = 0; i < handlers.length; i++) { + let handler = require(__base + 'src/lib/message-handler/handlers/' + handlers[i]); + + let isHandled = handler.handle(hubot, message); + + if (isHandled) { + break; + } + }; +} + +function getHandlers() { + return [ + 'first-run-handler', + 'conversation-handler', + 'gear-activate-handler', + 'gear-deactivate-handler', + 'gear-configure-handler', + 'tasks-handler' + ]; +} diff --git a/test/lib/assembler.js b/test/lib/assembler.js index 4ec2553..432ba76 100644 --- a/test/lib/assembler.js +++ b/test/lib/assembler.js @@ -2,52 +2,57 @@ var expect = require('chai').expect; var setup = require('../setup').start(); var Assembler = require('../../src/lib/assembler'); -describe('Hubot Assembler', function() { - describe('Hubot Assembler - Getting Paths', function() { - it('should provide correct path for tasks', function() { - var path = getAssembler().tasksPath('test'); +describe('The Hubot Assembler', function() { + + describe('should provide correct path', function() { + + it('for tasks', function() { + var gear = { name: 'test' }; + + var path = getAssembler().tasksPath(gear); + expect(path).to.equal(__nodeModules + 'test/config/tasks.json'); }); - it('should provide correct path for categories', function() { - var path = getAssembler().categoriesPath('test'); + it('for categories', function() { + var gear = { name: 'test' }; + + var path = getAssembler().categoriesPath(gear); + expect(path).to.equal(__nodeModules + 'test/config/categories.json'); }); - it('should provide correct path for handlers', function() { - var path = getAssembler().handlersPath('test', 'test-handler'); + it('for handlers', function() { + var gear = { name: 'test' }; + + var path = getAssembler().handlersPath(gear, 'test-handler'); + expect(path).to.equal(__nodeModules + 'test/src/handlers/test-handler'); }); + }); - describe('Hubot Assembler - Utils', function() { - it('should return true when handlers contains current handler', function() { + describe('should load', function() { + + it('task file', function() { var assembler = getAssembler(); - assembler.core.handlers.push({ key: 'test' }); - expect(assembler.containsHandler('test')).to.be.true; - }); + var gear = { name: 'gear-test' }; - it('should return false when handlers do not contains current handler', function() { - var assembler = getAssembler(); - assembler.core.handlers.push({ key: 'test' }); - expect(assembler.containsHandler('anything-else')).to.be.false; - }); - }); + assembler.loadTasks(gear, assembler); - describe('Hubot Assembler - Loader', function() { - it('should load task file correctly', function() { - var assembler = getAssembler(); - assembler.loadTasks('gear-test', assembler); - expect(assembler.core.tasks).to.be.deep.equal([{ + expect(gear.tasks).to.be.deep.equal([{ "handler": "test-handler", "trigger": "test-trigger" }]); }); - it('should load category file correctly', function() { + it('category file', function() { var assembler = getAssembler(); - assembler.loadCategories('gear-test', assembler); - expect(assembler.core.categories).to.be.deep.equal([{ + var gear = { name: 'gear-test' }; + + assembler.loadCategories(gear, assembler); + + expect(gear.categories).to.be.deep.equal([{ "key": "test", "name": "test", "description": "some test", @@ -55,57 +60,72 @@ describe('Hubot Assembler', function() { }]); }); - it('should not load handler file if there is not tasks', function() { + it('handler file based on tasks handlers', function() { var assembler = getAssembler(); - assembler.loadHandlers('gear-test', assembler); - expect(assembler.core.handlers).to.be.deep.equal([]); - }); + var gear = { name: 'gear-test' }; - it('should load handler file based on tasks handlers', function() { - var assembler = getAssembler(); - assembler.loadTasks('gear-test', assembler); - assembler.loadHandlers('gear-test', assembler); - expect(assembler.core.handlers).to.have.lengthOf(1); - expect(assembler.core.handlers[0].handle().key).to.be.equal('test-handle'); - }); + assembler.loadTasks(gear, assembler); + assembler.loadHandlers(gear, assembler); - it('should not throw error loading gears', function() { - var assembler = getAssembler(); - assembler.loadGear(null, null, null); - expect(assembler.core).to.be.deep.equal({ - tasks: [], - categories: [], - handlers: [] - }); + expect(gear.handlers).to.have.lengthOf(1); + expect(gear.handlers[0].handle().key).to.be.equal('test-handle'); }); - it('should not throw error loading invalid gear', function() { + it('and should not load when handler file if there is not tasks', function() { var assembler = getAssembler(); - assembler.loadGear([], { noKey: 'invalid' }, 0); - expect(assembler.core).to.be.deep.equal({ - tasks: [], - categories: [], - handlers: [] - }); + var gear = { name: 'gear-test', tasks: [] }; + + assembler.loadHandlers(gear, assembler); + + expect(gear.handlers).to.be.deep.equal([]); }); + + }); + + describe('should load gears', function() { - it('should load a valid gear', function() { + it('when is a valid gear', function() { var assembler = getAssembler(); - assembler.loadGear([], 'gear-test', 0); - expect(assembler.core.tasks).to.be.deep.equal([{ + var gear = { name: 'gear-test' }; + + assembler.loadGear([gear], gear, 0); + + expect(gear.tasks).to.be.deep.equal([{ "handler": "test-handler", "trigger": "test-trigger" }]); - expect(assembler.core.categories).to.be.deep.equal([{ + + expect(gear.categories).to.be.deep.equal([{ "key": "test", "name": "test", "description": "some test", "visible": false }]); - expect(assembler.core.handlers).to.have.lengthOf(1); - expect(assembler.core.handlers[0]).have.property('key').and.equal('test-handler'); + + expect(gear.handlers).to.have.lengthOf(1); + expect(gear.handlers[0]).have.property('key').and.equal('test-handler'); + }); + + it('and should not throw error when invalid parameters are informed', function() { + var assembler = getAssembler(); + + assembler.loadGear(null, null, null); + + expect(assembler.gears).to.be.deep.equal([]); }); + + it('neigther should throw error loading when informed an invalid gear', function() { + var assembler = getAssembler(); + var gear = { name: 'invalid' }; + + assembler.loadGear([gear], gear, 0); + + expect(assembler.gears).to.be.deep.equal([]); + }); + + }); + }); function getAssembler() { diff --git a/test/lib/trigger.js b/test/lib/trigger.js index e8c24d4..2dd6688 100644 --- a/test/lib/trigger.js +++ b/test/lib/trigger.js @@ -1,106 +1,106 @@ -var expect = require('chai').expect; -var trigger = require('../../src/lib/trigger'); - -describe('Task Trigger', function() { - describe('Task Trigger without parameters', function() { - it('should not match wrong message', function() { - var phrase = 'test'; - var message = 'anything else'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should matches exactly message', function() { - var phrase = 'test'; - var message = 'test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: [] } - ); - }); - - it('should matches message ignoring casing', function() { - var phrase = 'test'; - var message = 'TEST'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: [] } - ); - }); - - it('should ignore placeholder at beginning', function() { - var phrase = '$test'; - var message = 'test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should consider placeholder at beginning like a simple character', function() { - var phrase = '$test'; - var message = '$test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: []} - ); - }); - }); - - describe('Task Trigger with one parameter', function() { - it('should not match wrong message', function() { - var phrase = 'test $ deeply'; - var message = 'please test anything else deeply'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should get one parameter by placeholder at end', function() { - var phrase = 'test $'; - var message = 'test anything'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['anything']} - ); - }); - - it('should get one parameter by placeholder at middle', function() { - var phrase = 'test $ deeply'; - var message = 'test anything else deeply'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['anything else']} - ); - }); - }) - - describe('Task Trigger with multiple parameters', function() { - it('should not match wrong message', function() { - var phrase = 'come on $, light $!'; - var message = 'so come on baby, light my fire!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should get multiple parameters', function() { - var phrase = 'come on $, light $!'; - var message = 'come on baby, light my fire!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['baby', 'my fire']} - ); - }); - - it('should get multiple parameters ignoring casing', function() { - var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - var message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['me', 'paradise city', 'grass', 'green', 'girls', 'pretty']} - ); - }); - - it('should not match typo', function() { - var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - var message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - }); -}); +var expect = require('chai').expect; +var trigger = require('../../src/lib/trigger'); + +describe('Task Trigger', function() { + describe('Task Trigger without parameters', function() { + it('should not match wrong message', function() { + var phrase = 'test'; + var message = 'anything else'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: []} + ); + }); + + it('should matches exactly message', function() { + var phrase = 'test'; + var message = 'test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: [] } + ); + }); + + it('should matches message ignoring casing', function() { + var phrase = 'test'; + var message = 'TEST'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: [] } + ); + }); + + it('should ignore placeholder at beginning', function() { + var phrase = '$test'; + var message = 'test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: []} + ); + }); + + it('should consider placeholder at beginning like a simple character', function() { + var phrase = '$test'; + var message = '$test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: []} + ); + }); + }); + + describe('Task Trigger with one parameter', function() { + it('should not match wrong message', function() { + var phrase = 'test $ deeply'; + var message = 'please test anything else deeply'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: []} + ); + }); + + it('should get one parameter by placeholder at end', function() { + var phrase = 'test $'; + var message = 'test anything'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['anything']} + ); + }); + + it('should get one parameter by placeholder at middle', function() { + var phrase = 'test $ deeply'; + var message = 'test anything else deeply'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['anything else']} + ); + }); + }) + + describe('Task Trigger with multiple parameters', function() { + it('should not match wrong message', function() { + var phrase = 'come on $, light $!'; + var message = 'so come on baby, light my fire!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: []} + ); + }); + + it('should get multiple parameters', function() { + var phrase = 'come on $, light $!'; + var message = 'come on baby, light my fire!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['baby', 'my fire']} + ); + }); + + it('should get multiple parameters ignoring casing', function() { + var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + var message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['me', 'paradise city', 'grass', 'green', 'girls', 'pretty']} + ); + }); + + it('should not match typo', function() { + var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + var message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: []} + ); + }); + }); +}); diff --git a/test/resource/gears/test/config/categories.json b/test/resource/gears/gear-test/config/categories.json similarity index 100% rename from test/resource/gears/test/config/categories.json rename to test/resource/gears/gear-test/config/categories.json diff --git a/test/resource/gears/test/config/tasks.json b/test/resource/gears/gear-test/config/tasks.json similarity index 100% rename from test/resource/gears/test/config/tasks.json rename to test/resource/gears/gear-test/config/tasks.json diff --git a/test/resource/gears/test/handlers/test-handler.js b/test/resource/gears/gear-test/handlers/test-handler.js similarity index 100% rename from test/resource/gears/test/handlers/test-handler.js rename to test/resource/gears/gear-test/handlers/test-handler.js From 5a438e0c453c158d08b74c3dff9069316489ba3b Mon Sep 17 00:00:00 2001 From: Robson Date: Mon, 10 Oct 2016 19:26:25 -0300 Subject: [PATCH 04/26] Fix #26 - Change project structure --- src/{lib => }/assembler.js | 2 +- src/{lib => }/hubot.js | 8 +- src/{lib => message-handler}/conversation.js | 0 .../handlers/conversation-handler.js | 2 +- .../handlers/first-run-handler.js | 0 .../handlers/gear-activate-handler.js | 2 +- .../handlers/gear-configure-handler.js | 2 +- .../handlers/gear-deactivate-handler.js | 2 +- .../message-handler/handlers/tasks-handler.js | 2 +- .../message-handler/message-handler.js | 2 +- src/{lib => message-handler}/trigger.js | 146 +++++++++--------- src/{lib => }/speech.js | 0 test/lib/assembler.js | 2 +- test/lib/trigger.js | 2 +- 14 files changed, 86 insertions(+), 86 deletions(-) rename src/{lib => }/assembler.js (95%) rename src/{lib => }/hubot.js (93%) rename src/{lib => message-handler}/conversation.js (100%) rename src/{lib => }/message-handler/handlers/conversation-handler.js (70%) rename src/{lib => }/message-handler/handlers/first-run-handler.js (100%) rename src/{lib => }/message-handler/handlers/gear-activate-handler.js (93%) rename src/{lib => }/message-handler/handlers/gear-configure-handler.js (89%) rename src/{lib => }/message-handler/handlers/gear-deactivate-handler.js (93%) rename src/{lib => }/message-handler/handlers/tasks-handler.js (89%) rename src/{lib => }/message-handler/message-handler.js (81%) rename src/{lib => message-handler}/trigger.js (96%) rename src/{lib => }/speech.js (100%) diff --git a/src/lib/assembler.js b/src/assembler.js similarity index 95% rename from src/lib/assembler.js rename to src/assembler.js index ab03f5b..3eab5ba 100644 --- a/src/lib/assembler.js +++ b/src/assembler.js @@ -2,7 +2,7 @@ var fs = require('fs'); var log = require(__base + 'src/lib/log'); -var speech = require(__base + 'src/lib/speech'); +var speech = require(__base + 'src/speech'); var db = new (require(__base + 'src/lib/db')); const gearNamePrefix = 'gear-'; diff --git a/src/lib/hubot.js b/src/hubot.js similarity index 93% rename from src/lib/hubot.js rename to src/hubot.js index 26c5c86..3c8bf07 100644 --- a/src/lib/hubot.js +++ b/src/hubot.js @@ -3,11 +3,11 @@ var util = require('util'); var Bot = require('slackbots'); var log = require(__base + 'src/lib/log'); -var Assembler = require(__base + 'src/lib/assembler'); -var messageHandler = require(__base + 'src/lib/message-handler/message-handler'); -var speech = require(__base + 'src/lib/speech'); -let Q = require('q'); +var Assembler = require(__base + 'src/assembler'); +var messageHandler = require(__base + 'src/message-handler/message-handler'); +var speech = require(__base + 'src/speech'); var db = new (require(__base + 'src/lib/db')); +let Q = require('q'); process.on('uncaughtException', function (exception) { log.error(exception); diff --git a/src/lib/conversation.js b/src/message-handler/conversation.js similarity index 100% rename from src/lib/conversation.js rename to src/message-handler/conversation.js diff --git a/src/lib/message-handler/handlers/conversation-handler.js b/src/message-handler/handlers/conversation-handler.js similarity index 70% rename from src/lib/message-handler/handlers/conversation-handler.js rename to src/message-handler/handlers/conversation-handler.js index f32f999..f80cac3 100644 --- a/src/lib/message-handler/handlers/conversation-handler.js +++ b/src/message-handler/handlers/conversation-handler.js @@ -2,7 +2,7 @@ exports.handle = handle; -const conversation = require(__base + 'src/lib/conversation'); +const conversation = require(__base + 'src/message-handler/conversation'); function handle(hubot, message) { if (conversation.hasActiveConversation(message)) { diff --git a/src/lib/message-handler/handlers/first-run-handler.js b/src/message-handler/handlers/first-run-handler.js similarity index 100% rename from src/lib/message-handler/handlers/first-run-handler.js rename to src/message-handler/handlers/first-run-handler.js diff --git a/src/lib/message-handler/handlers/gear-activate-handler.js b/src/message-handler/handlers/gear-activate-handler.js similarity index 93% rename from src/lib/message-handler/handlers/gear-activate-handler.js rename to src/message-handler/handlers/gear-activate-handler.js index e6351a0..625f604 100644 --- a/src/lib/message-handler/handlers/gear-activate-handler.js +++ b/src/message-handler/handlers/gear-activate-handler.js @@ -2,7 +2,7 @@ exports.handle = handle; -const speech = require(__base + 'src/lib/speech'); +const speech = require(__base + 'src/speech'); function handle(hubot, message) { if (isGearActivateMessage(hubot, message)) { diff --git a/src/lib/message-handler/handlers/gear-configure-handler.js b/src/message-handler/handlers/gear-configure-handler.js similarity index 89% rename from src/lib/message-handler/handlers/gear-configure-handler.js rename to src/message-handler/handlers/gear-configure-handler.js index fb63104..b50be78 100644 --- a/src/lib/message-handler/handlers/gear-configure-handler.js +++ b/src/message-handler/handlers/gear-configure-handler.js @@ -2,7 +2,7 @@ exports.handle = handle; -const conversation = require(__base + 'src/lib/conversation'); +const conversation = require(__base + 'src/message-handler/conversation'); function handle(hubot, message) { if (isGearConfigureMessage(hubot, message)) { diff --git a/src/lib/message-handler/handlers/gear-deactivate-handler.js b/src/message-handler/handlers/gear-deactivate-handler.js similarity index 93% rename from src/lib/message-handler/handlers/gear-deactivate-handler.js rename to src/message-handler/handlers/gear-deactivate-handler.js index c1e79a9..80dcdd7 100644 --- a/src/lib/message-handler/handlers/gear-deactivate-handler.js +++ b/src/message-handler/handlers/gear-deactivate-handler.js @@ -2,7 +2,7 @@ exports.handle = handle; -const speech = require(__base + 'src/lib/speech'); +const speech = require(__base + 'src/speech'); function handle(hubot, message) { if (isGearDeactivateMessage(hubot, message)) { diff --git a/src/lib/message-handler/handlers/tasks-handler.js b/src/message-handler/handlers/tasks-handler.js similarity index 89% rename from src/lib/message-handler/handlers/tasks-handler.js rename to src/message-handler/handlers/tasks-handler.js index 3489119..e3649b1 100644 --- a/src/lib/message-handler/handlers/tasks-handler.js +++ b/src/message-handler/handlers/tasks-handler.js @@ -2,7 +2,7 @@ exports.handle = handle; -var trigger = require(__base + 'src/lib/trigger'); +var trigger = require(__base + 'src/message-handler/trigger'); function handle(hubot, message) { hubot.gears.forEach(function(gear) { diff --git a/src/lib/message-handler/message-handler.js b/src/message-handler/message-handler.js similarity index 81% rename from src/lib/message-handler/message-handler.js rename to src/message-handler/message-handler.js index 8034572..63f9303 100644 --- a/src/lib/message-handler/message-handler.js +++ b/src/message-handler/message-handler.js @@ -6,7 +6,7 @@ function callTasks(message, hubot) { let handlers = getHandlers(); for (let i = 0; i < handlers.length; i++) { - let handler = require(__base + 'src/lib/message-handler/handlers/' + handlers[i]); + let handler = require(__base + 'src/message-handler/handlers/' + handlers[i]); let isHandled = handler.handle(hubot, message); diff --git a/src/lib/trigger.js b/src/message-handler/trigger.js similarity index 96% rename from src/lib/trigger.js rename to src/message-handler/trigger.js index 5afaf4b..5eb2f38 100644 --- a/src/lib/trigger.js +++ b/src/message-handler/trigger.js @@ -1,73 +1,73 @@ -'use strict'; - -exports.check = check; - -var stringfy = require('string'); - -function check(message, trigger) { - return new Trigger('$').with(normalize(trigger)).accept(normalize(message)); -} - -class Trigger { - constructor(placeholder) { - this.placeholder = placeholder; - } - - with(trigger) { - this.trigger = trigger; - this.params = new TriggerParams(this.trigger, this.placeholder); - return this; - } - - accept(message) { - if (this.params.has()) { - return this.acceptWithParams(message); - } - - return this.acceptWithoutParams(message); - } - - acceptWithParams(message) { - var count = this.params.count(); - var params = this.params.capture(message); - var matches = params.length === count; - return { ok: matches, params: matches ? params : [] } - } - - acceptWithoutParams(message) { - return { ok: this.trigger === message, params: [] }; - } -} - -class TriggerParams { - constructor(trigger, placeholder) { - this.trigger = trigger; - this.placeholder = placeholder; - } - - has() { - return this.trigger.includes(this.placeholder) && !this.trigger.startsWith(this.placeholder); - } - - count() { - return this.trigger.match(new RegExp('\\' + this.placeholder, 'g')).length; - } - - capture(message) { - // trigger: 'get $ to $' > ['get ', ' to '] - var triggerParts = this.trigger.split(this.placeholder).filter(s => s); - - // message must includes all trigger parts - if (triggerParts.find(t => !message.includes(t))) return []; - - // message: 'get alpha to beta' > 'alpha$beta' - triggerParts.forEach(trigger => message = message.replace(trigger, this.placeholder)); - - // message: 'alpha$beta' > ['alpha', 'beta'] - return message.split(this.placeholder).filter(s => s); - } -} - -function normalize(text) { - return stringfy(text).trim().latinise().s.toLowerCase(); -} +'use strict'; + +exports.check = check; + +var stringfy = require('string'); + +function check(message, trigger) { + return new Trigger('$').with(normalize(trigger)).accept(normalize(message)); +} + +class Trigger { + constructor(placeholder) { + this.placeholder = placeholder; + } + + with(trigger) { + this.trigger = trigger; + this.params = new TriggerParams(this.trigger, this.placeholder); + return this; + } + + accept(message) { + if (this.params.has()) { + return this.acceptWithParams(message); + } + + return this.acceptWithoutParams(message); + } + + acceptWithParams(message) { + var count = this.params.count(); + var params = this.params.capture(message); + var matches = params.length === count; + return { ok: matches, params: matches ? params : [] } + } + + acceptWithoutParams(message) { + return { ok: this.trigger === message, params: [] }; + } +} + +class TriggerParams { + constructor(trigger, placeholder) { + this.trigger = trigger; + this.placeholder = placeholder; + } + + has() { + return this.trigger.includes(this.placeholder) && !this.trigger.startsWith(this.placeholder); + } + + count() { + return this.trigger.match(new RegExp('\\' + this.placeholder, 'g')).length; + } + + capture(message) { + // trigger: 'get $ to $' > ['get ', ' to '] + var triggerParts = this.trigger.split(this.placeholder).filter(s => s); + + // message must includes all trigger parts + if (triggerParts.find(t => !message.includes(t))) return []; + + // message: 'get alpha to beta' > 'alpha$beta' + triggerParts.forEach(trigger => message = message.replace(trigger, this.placeholder)); + + // message: 'alpha$beta' > ['alpha', 'beta'] + return message.split(this.placeholder).filter(s => s); + } +} + +function normalize(text) { + return stringfy(text).trim().latinise().s.toLowerCase(); +} diff --git a/src/lib/speech.js b/src/speech.js similarity index 100% rename from src/lib/speech.js rename to src/speech.js diff --git a/test/lib/assembler.js b/test/lib/assembler.js index 432ba76..6061a96 100644 --- a/test/lib/assembler.js +++ b/test/lib/assembler.js @@ -1,6 +1,6 @@ var expect = require('chai').expect; var setup = require('../setup').start(); -var Assembler = require('../../src/lib/assembler'); +var Assembler = require('../../src/assembler'); describe('The Hubot Assembler', function() { diff --git a/test/lib/trigger.js b/test/lib/trigger.js index 2dd6688..88f784d 100644 --- a/test/lib/trigger.js +++ b/test/lib/trigger.js @@ -1,5 +1,5 @@ var expect = require('chai').expect; -var trigger = require('../../src/lib/trigger'); +var trigger = require('../../src/message-handler/trigger'); describe('Task Trigger', function() { describe('Task Trigger without parameters', function() { From f65e8f459962fd878c93c6b19808c6103270ecc7 Mon Sep 17 00:00:00 2001 From: Robson Date: Wed, 12 Oct 2016 21:57:01 -0300 Subject: [PATCH 05/26] Fix #25 Separate hubot responsabilities --- .travis.yml | 2 +- app.js | 19 +- migrations/001-initial-schema.sql | 9 + package.json | 2 +- src/assembler.js | 20 +- src/core.js | 100 +++++++ src/first-run.js | 65 +++++ src/hubot.js | 256 ++++-------------- src/lib/db.js | 84 ++---- src/lib/log.js | 5 +- src/message-handler/conversation.js | 30 +- .../handlers/conversation-handler.js | 4 +- .../handlers/first-run-handler.js | 4 +- .../handlers/gear-activate-handler.js | 49 ---- .../handlers/gear-configure-handler.js | 8 +- .../handlers/gear-deactivate-handler.js | 50 ---- .../handlers/gear-status-handler.js | 75 +++++ .../handlers/gears-tasks-handler.js | 41 +++ src/message-handler/handlers/tasks-handler.js | 35 --- src/message-handler/message-handler.js | 13 +- src/message-handler/trigger.js | 4 +- src/speech.js | 2 +- test/lib/assembler.js | 46 ++-- test/lib/trigger.js | 54 ++-- .../gears/gear-test/handlers/test-handler.js | 12 +- 25 files changed, 481 insertions(+), 508 deletions(-) create mode 100644 migrations/001-initial-schema.sql create mode 100644 src/core.js create mode 100644 src/first-run.js delete mode 100644 src/message-handler/handlers/gear-activate-handler.js delete mode 100644 src/message-handler/handlers/gear-deactivate-handler.js create mode 100644 src/message-handler/handlers/gear-status-handler.js create mode 100644 src/message-handler/handlers/gears-tasks-handler.js delete mode 100644 src/message-handler/handlers/tasks-handler.js diff --git a/.travis.yml b/.travis.yml index 9e601bf..55a5fca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: required language: node_js node_js: - - "5.11" + - "6.7" services: - docker diff --git a/app.js b/app.js index 0a5bf60..5378581 100644 --- a/app.js +++ b/app.js @@ -4,13 +4,18 @@ global.__base = __dirname + '/'; global.__gears = __base + 'src/gears/'; global.__nodeModules = __base + 'node_modules/'; -var Hubot = require(__base + 'src/lib/hubot'); -var token = process.env.BOT_API_KEY -var name = process.env.BOT_NAME || 'hubot'; +const Core = require(__base + 'src/core'); +const db = require(__base + 'src/lib/db'); -var hubot = new Hubot({ - token: token, - name: name +const token = process.env.BOT_API_KEY +const name = process.env.BOT_NAME || 'hubot'; + +db.startDb().then(function() { + const core = new Core({ + token: token, + name: name + }); + + core.run(); }); -hubot.run(); diff --git a/migrations/001-initial-schema.sql b/migrations/001-initial-schema.sql new file mode 100644 index 0000000..3daeea4 --- /dev/null +++ b/migrations/001-initial-schema.sql @@ -0,0 +1,9 @@ +-- Up +CREATE TABLE admins (admin TEXT NOT NULL); +CREATE TABLE first_use (first_use TEXT NOT NULL); +CREATE TABLE gears (name TEXT NOT NULL, description TEXT NOT NULL, active TEXT NOT NULL); + +-- Down +DROP TABLE admins; +DROP TABLE first_use; +DROP TABLE gears; diff --git a/package.json b/package.json index 3f1e290..a7fa90e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "string": "^3.3.1", "winston": "^2.2.0", "q": "^1.4.1", - "sqlite3": "^3.1.4", + "sqlite": "^2.2.0", "gear-help": "^1.0.1", "gear-jenkins": "^1.0.1" }, diff --git a/src/assembler.js b/src/assembler.js index 3eab5ba..381995b 100644 --- a/src/assembler.js +++ b/src/assembler.js @@ -1,9 +1,9 @@ 'use strict'; -var fs = require('fs'); -var log = require(__base + 'src/lib/log'); -var speech = require(__base + 'src/speech'); -var db = new (require(__base + 'src/lib/db')); +const fs = require('fs'); +const log = require(__base + 'src/lib/log'); +const speech = require(__base + 'src/speech'); +const db = require(__base + 'src/lib/db'); const gearNamePrefix = 'gear-'; @@ -20,12 +20,12 @@ module.exports = class Assembler { loadGears(self) { fs.readdir(__nodeModules, function (error, list) { - var gearsNames = list.filter(function (e) { + const gearsNames = list.filter(function (e) { return e.startsWith(gearNamePrefix); }); gearsNames.forEach(function(gearName) { - var gearDescription = gearName.replace("gear-", ""); + const gearDescription = gearName.replace("gear-", ""); self.gears.push( { name: gearName, description: gearDescription } ); }); @@ -54,12 +54,12 @@ module.exports = class Assembler { } loadGearStatus(gear, self) { - db.get('SELECT * FROM gears WHERE name = ?', gear.name).then(function(record) { + db.getDb().get('SELECT * FROM gears WHERE name = ?', gear.name).then(function(record) { if (!record) { gear.active = false; - db.run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', [gear.name, gear.description, 'NO']); + db.getDb().run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, false); } else { - gear.active = (record.active === 'YES') ? true : false; + gear.active = record.active === "1"; } }); } @@ -83,7 +83,7 @@ module.exports = class Assembler { gear.handlers = []; gear.tasks.forEach(function(task) { - var handler = require(self.handlersPath(gear, task.handler)); + const handler = require(self.handlersPath(gear, task.handler)); gear.handlers.push({ key: task.handler, handle: handler.handle}); }); diff --git a/src/core.js b/src/core.js new file mode 100644 index 0000000..1ca9c65 --- /dev/null +++ b/src/core.js @@ -0,0 +1,100 @@ +'use strict'; + +const util = require('util'); +const Bot = require('slackbots'); +const Hubot = require(__base + 'src/hubot'); +const log = require(__base + 'src/lib/log'); +const Assembler = require(__base + 'src/assembler'); +const messageHandler = require(__base + 'src/message-handler/message-handler'); +const firstRun = require(__base + 'src/first-run'); +const db = require(__base + 'src/lib/db'); + +let botName; +let botUser; +let coreSettings; +let isFirstRun = false; + +process.on('uncaughtException', function (exception) { + log.error(exception); +}); + +var Core = function Constructor(settings) { + coreSettings = settings; + botName = settings.name; +}; + +util.inherits(Core, Bot); +module.exports = Core; + +Core.prototype.run = function () { + Core.super_.call(this, coreSettings); + + this.on('start', this.onStart); + this.on('message', this.onMessage); +}; + +Core.prototype.onStart = function () { + botUser = this.getUserByName(botName); + this.hubot = new Hubot(this); + this.hubot.gears = new Assembler().build(); + this.firstRunChecker(); +}; + +Core.prototype.onMessage = function (message) { + if (isChatMessage(message) && !isFromHubot(message)) { + if (isFirstInteraction(this, message)) { + isFirstRun = false; + firstRun.firstRun(this, message); + } else { + messageHandler.callTasks(message, this); + } + } +}; + +Core.prototype.firstRunChecker = function () { + db.getDb().get('SELECT * FROM first_use').then(function(record) { + if (!record || !record.first_use) { + isFirstRun = true; + } + }); +}; + +Core.prototype.getUserByName = function (name) { + return this.users.find(user => user.name === name); +}; + +Core.prototype.getUserById = function (userId) { + return this.users.find(user => user.id === userId); +}; + +Core.prototype.isChannelConversation = function (message) { + return typeof message.channel === 'string' && message.channel[0] === 'C'; +}; + +Core.prototype.isPrivateConversation = function (message) { + return typeof message.channel === 'string' && message.channel[0] === 'D'; +}; + +Core.prototype.getRecipient = function (message) { + if (this.isPrivateConversation(message)) { + return message.user; + } else { + return message.channel; + } +} + +Core.prototype.isAdminUser = function (user) { + return db.getDb().get('SELECT * FROM admins WHERE admin = ?', user); +}; + +function isFromHubot(message) { + return message.user === botUser.id; +}; + +function isChatMessage(message) { + return message.type === 'message' && Boolean(message.text); +}; + +function isFirstInteraction(core, message) { + return isFirstRun && core.isPrivateConversation(message) && message.text === botName; +} diff --git a/src/first-run.js b/src/first-run.js new file mode 100644 index 0000000..0f89187 --- /dev/null +++ b/src/first-run.js @@ -0,0 +1,65 @@ +'use strict'; + +const db = require(__base + 'src/lib/db'); + +exports.firstRun = firstRun; + +function firstRun(core, message) { + db.getDb().run("INSERT INTO first_use(first_use) VALUES('NO')"); + db.getDb().run("INSERT INTO admins(admin) VALUES(?)", message.user); + + const hubot = core.hubot; + const messageDelay = 3000; + + hubot.speak(message, message1(hubot, core, message), messageDelay) + .then(function() { + return hubot.speak(message, message2(hubot), messageDelay); + }) + .then(function() { + return hubot.speak(message, message3(hubot), messageDelay); + }) + .then(function() { + return hubot.speak(message, message4(hubot), messageDelay); + }) + .then(function() { + return hubot.speak(message, message5(hubot), messageDelay); + }) + .then(function() { + return hubot.speak(message, message6(hubot), messageDelay); + }) + .then(function() { + hubot.speak(message, postGearsNames(hubot), messageDelay); + }); +} + +function message1(hubot, core, message) { + return hubot.speech().hello(core.getUserById(message.user)).append("My name is ").append(core.name).append(" and from now on I will help you with some tasks using the Slack.").end(); +} + +function message2(hubot) { + return hubot.speech().append("Before I need you to do some settings. How was you who started me I will define you as my system administrator. So you can access the settings in the future.").end(); +} + +function message3(hubot) { + return hubot.speech().append("Initially I do not know perform tasks. But there are gears that when coupled to me add me skills.").end(); +} + +function message4(hubot) { + return hubot.speech().append("At this time all the gears are inactive. You can activate them using the command ").bold("activate gear-name").period().end(); +} + +function message5(hubot) { + return hubot.speech().append("Some gears have settings. To let them use the command ").bold("configure gear-name").period().end(); +} + +function message6(hubot) { + return hubot.speech().append("Below is a list of gears available:").end(); +} + +function postGearsNames(hubot) { + const speech = hubot.speech(); + + hubot.gears.forEach(g => speech.item(g.description).line()); + + return speech.end(); +} diff --git a/src/hubot.js b/src/hubot.js index 3c8bf07..8911441 100644 --- a/src/hubot.js +++ b/src/hubot.js @@ -1,223 +1,77 @@ - 'use strict'; - -var util = require('util'); -var Bot = require('slackbots'); -var log = require(__base + 'src/lib/log'); -var Assembler = require(__base + 'src/assembler'); -var messageHandler = require(__base + 'src/message-handler/message-handler'); -var speech = require(__base + 'src/speech'); -var db = new (require(__base + 'src/lib/db')); -let Q = require('q'); - -process.on('uncaughtException', function (exception) { - log.error(exception); -}); - -var Hubot = function Constructor(settings) { - this.settings = settings; - this.name = this.settings.name; - this.user = null; - this.isFirstRun = false; -}; - -util.inherits(Hubot, Bot); - -module.exports = Hubot; - -Hubot.prototype.run = function () { - Hubot.super_.call(this, this.settings); - - this.on('start', this._onStart); - this.on('message', this._onMessage); -}; - -Hubot.prototype._onStart = function () { - this._loadBotUser(); - this.gears = new Assembler().build(); - this._firstRunChecker(); -}; - -Hubot.prototype._firstRunChecker = function () { - let self = this; - - db.get('SELECT * FROM first_use').then(function(record) { - if (!record || !record.first_use) { - self.isFirstRun = true; - } - }); -}; - -Hubot.prototype._onMessage = function (message) { - if (this._isChatMessage(message) && !this._isFromHubot(message)) { - if (isFirstInteraction(this, message)) { - this._firstRun(message); - } else { - messageHandler.callTasks(message, this); - } - } -}; - -Hubot.prototype._firstRun = function(message) { - db.run("INSERT INTO first_use(first_use) VALUES('NO')"); - db.run("INSERT INTO admins(admin) VALUES(?)", message.user); - - let self = this; - - self.isFirstRun = false; - let messageDelay = 3000; - - self.talk(message, message1(self, message), messageDelay) - .then(function() { - return self.talk(message, message2(self), messageDelay); - }) - .then(function() { - return self.talk(message, message3(self), messageDelay); - }) - .then(function() { - return self.talk(message, message4(self), messageDelay); - }) - .then(function() { - return self.talk(message, message5(self), messageDelay); - }) - .then(function() { - return self.talk(message, message6(self), messageDelay); - }) - .then(function() { - self.talk(message, postGearsNames(self), messageDelay); - }); -} - -Hubot.prototype._loadBotUser = function () { - this.user = this._getUserByName(this.name); -}; +'use strict'; -Hubot.prototype._getUserByName = function (name) { - return this.users.find(user => user.name === name); -}; +const Q = require('q'); +const log = require(__base + 'src/lib/log'); +const speech = require(__base + 'src/speech'); -Hubot.prototype._getUserById = function (userId) { - return this.users.find(user => user.id === userId); -}; +let _core; -Hubot.prototype._isChatMessage = function (message) { - return message.type === 'message' && Boolean(message.text); -}; - -Hubot.prototype._isChannelConversation = function (message) { - return typeof message.channel === 'string' && message.channel[0] === 'C'; -}; - -Hubot.prototype._isPrivateConversation = function (message) { - return typeof message.channel === 'string' && message.channel[0] === 'D'; -}; - -Hubot.prototype._isFromHubot = function (message) { - return message.user === this.user.id; -}; - -Hubot.prototype.speech = function (message) { - return speech.start(message); -} - -Hubot.prototype.getRecipient = function (message) { - if (this._isPrivateConversation(message)) { - return message.user; - } else { - return message.channel; +module.exports = class Hubot { + + constructor(core) { + this.gears = []; + _core = core; } -} -Hubot.prototype.talkTo = function (recipient, text, message, delay = 1000) { - let deferred = Q.defer(); - let channel = message ? message.channel : recipient; + speakTo(recipient, text, message, delay = 1000) { + const deferred = Q.defer(); + const channel = message ? message.channel : recipient; - this.ws.send(JSON.stringify({ type: 'typing', channel: channel })); - - setTimeout(() => { + _core.ws.send(JSON.stringify({ type: 'typing', channel: channel })); - this.postMessage(recipient, text, {as_user: true}).then(function() { - deferred.resolve(); - }, function() { - deferred.reject(); - }); - - }, delay); - - return deferred.promise; -} - -Hubot.prototype.talk = function (message, text, delay) { - return this.talkTo(this.getRecipient(message), text, message, delay); -} + setTimeout(() => { + + _core.postMessage(recipient, text, {as_user: true}).then(function() { + deferred.resolve(); + }, function() { + deferred.reject(); + }); -Hubot.prototype._isAdminUser = function (user) { - return db.get('SELECT * FROM admins WHERE admin = ?', user); -}; - -Hubot.prototype._activateGear = function (gear) { - findGear(this, gear).active = true; - - return db.run('UPDATE gears SET active = "YES" WHERE description = ?', gear); -} - -Hubot.prototype._deactivateGear = function (gear) { - findGear(this, gear).active = false; - - return db.run('UPDATE gears SET active = "NO" WHERE description = ?', gear); -} + }, delay); -Hubot.prototype._getGear = function (gear) { - return db.get('SELECT * FROM gears WHERE description = ?', gear); -} - -Hubot.prototype.info = function (info) { - log.info(info); -} + return deferred.promise; + } -Hubot.prototype.error = function (error) { - log.error(error); -} + speak(message, text, delay) { + return this.speakTo(this.getRecipient(message), text, message, delay); + } -Hubot.prototype.detailedError = function (error, metadata) { - log.detailedError(error, metadata); -} + logInfo(info) { + log.info(info); + } -function isFirstInteraction(hubot, message) { - return hubot.isFirstRun && hubot._isPrivateConversation(message) && message.text === hubot.name; -} + logError(error) { + log.error(error); + } -function message1(hubot, message) { - return hubot.speech().hello(hubot._getUserById(message.user)).append("My name is ").append(hubot.name).append(" and from now on I will help you with some tasks using the Slack.").end(); -} + logDetailedError(error, metadata) { + log.detailedError(error, metadata); + } -function message2(hubot) { - return hubot.speech().append("Before I need you to do some settings. How was you who started me I will define it as my system administrator. So you can access the settings in the future.").end(); -} + isFromChannel(message) { + return _core.isChannelConversation(message); + } -function message3(hubot) { - return hubot.speech().append("Initially I do not know perform tasks. But there are gears that when coupled to me add me skills.").end(); -} + isFromPrivate(message) { + return _core.isPrivateConversation(message); + } -function message4(hubot) { - return hubot.speech().append("At this time all the gears are inactive. You can activate them using the command ").bold("activate gear-name").period().end(); -} + getUser(message) { + return _core.getUserById(message.user); + } -function message5(hubot) { - return hubot.speech().append("Some gears have settings. To let them use the command ").bold("configure gear-name").period().end(); -} + getRecipient(message) { + return _core.getRecipient(message); + } -function message6(hubot) { - return hubot.speech().append("Below is a list of gears available:").end(); -} + speech(message) { + return speech.start(message); + } -function postGearsNames(hubot) { - var speech = hubot.speech(); + findGear(gear) { + return this.gears.find(g => g.description === gear); + } - hubot.gears.forEach(g => speech.item(g.description).line()); - - return speech.end(); } -function findGear(hubot, gear) { - return hubot.gears.find(g => g.description === gear); -} + diff --git a/src/lib/db.js b/src/lib/db.js index 86f9587..9bd961d 100644 --- a/src/lib/db.js +++ b/src/lib/db.js @@ -1,78 +1,34 @@ 'use strict'; -let Q = require('q'); -let fs = require('fs'); -let log = require(__base + 'src/lib/log'); -let path = require('path'); -let sqlite3 = require('sqlite3'); +const db = require('sqlite'); +const path = require('path'); -module.exports = class DataBase { +exports.startDb = startDb; +exports.getDb = getDb; - constructor() { - this.outputFile = path.resolve(process.cwd(), 'data', 'hubot.db'); +let database; - if (!fs.existsSync(this.outputFile)) { - return createDb(this); - } +function startDb() { + const dbFile = path.resolve(process.cwd(), 'data', 'hubot.db'); + const migrations = path.resolve(process.cwd(), 'migrations'); - return updateDb(this); + function open(dbFile) { + return db.open(dbFile); } - run(sql, params) { - let deferred = Q.defer(); - - this.db.run(sql, params, function(err) { - resultHandler(deferred, err); + function migrate(db) { + db.migrate({migrationsPath: migrations}).then(function(result) { + database = result; }); - - return deferred.promise; - } - - get(sql, params) { - let deferred = Q.defer(); - - this.db.get(sql, params, function(err, row) { - resultHandler(deferred, err, row); - }); - - return deferred.promise; - } - - all(sql, params) { - let deferred = Q.defer(); - - this.db.all(sql, params, function(err, rows) { - resultHandler(deferred, err, rows); - }); - - return deferred.promise; } - -} - -function createDb(dataBase) { - dataBase.db = new sqlite3.Database(dataBase.outputFile); - - dataBase.db.serialize(); - dataBase.db.run('CREATE TABLE IF NOT EXISTS admins (admin TEXT NOT NULL)'); - dataBase.db.run('CREATE TABLE IF NOT EXISTS first_use (first_use TEXT NOT NULL)'); - dataBase.db.run('CREATE TABLE IF NOT EXISTS gears (name TEXT NOT NULL, description TEXT NOT NULL, active TEXT NOT NULL)'); - - return dataBase; + return open(dbFile) + .then(migrate) + .catch(function() { + //do nothing + }); } -function updateDb(dataBase) { - dataBase.db = new sqlite3.Database(dataBase.outputFile); - - return dataBase; -} - -function resultHandler(deferred, err, result) { - if (err) { - log.error(err); - deferred.reject(err); - } else { - deferred.resolve(result); - } +function getDb() { + return database; } diff --git a/src/lib/log.js b/src/lib/log.js index a644c35..2031504 100644 --- a/src/lib/log.js +++ b/src/lib/log.js @@ -1,10 +1,11 @@ 'use strict'; + +const winston = require('winston'); + exports.info = info; exports.error = error; exports.detailedError = detailedError; -var winston = require('winston'); - winston.add(winston.transports.File, { filename: __base + 'logs/hubot.log', handleExceptions: true }); winston.remove(winston.transports.Console); diff --git a/src/message-handler/conversation.js b/src/message-handler/conversation.js index bc866da..789770c 100644 --- a/src/message-handler/conversation.js +++ b/src/message-handler/conversation.js @@ -1,18 +1,16 @@ 'use strict'; +const Q = require('q'); +const EventEmitter = require('events'); + exports.startConversation = startConversation; exports.hasActiveConversation = hasActiveConversation; exports.notify = notify; -let Q = require('q'); - -const EventEmitter = require('events'); - class MyEmitter extends EventEmitter {} - const myEmitter = new MyEmitter(); -var activeConversations = []; +let activeConversations = []; function startConversation(hubot, conversation, message) { activeConversations.push(conversation); @@ -23,7 +21,7 @@ function startConversation(hubot, conversation, message) { } function start(hubot, conversation, message) { - var interactions = conversation.interactions; + const interactions = conversation.interactions; if (conversation.nextInteration < interactions.length) { speak(hubot, message, conversation, function(conversation) { @@ -41,9 +39,9 @@ function start(hubot, conversation, message) { } function speak(hubot, message, conversation, callback) { - var interaction = conversation.interactions[conversation.nextInteration]; + const interaction = conversation.interactions[conversation.nextInteration]; - hubot.talk(message, interaction.speak).then(function() { + hubot.speak(message, interaction.speak).then(function() { if(justSpeak(conversation, interaction, callback)) return; myEmitter.once(message.user, function(response) { @@ -55,7 +53,7 @@ function speak(hubot, message, conversation, callback) { conversation.nextInteration++; if(text) { - hubot.talk(message, text).then(function() { + hubot.speak(message, text).then(function() { if(hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; callback(conversation); }); @@ -96,7 +94,7 @@ function withoutExpectedResponse(conversation, interaction, response, hubot, mes function speakReturnedText(hubot, message, conversation, text, callback) { if(text) { - hubot.talk(message, text).then(function() { + hubot.speak(message, text).then(function() { callback(conversation); }); } else { @@ -106,7 +104,7 @@ function speakReturnedText(hubot, message, conversation, text, callback) { function withExpectedResponse(conversation, interaction, response, hubot, message, callback) { if (!getExpectedResponse(interaction.expectedResponses, response)) { - hubot.talk(message, invalidResponseMessage(hubot, getExpectedResponses(interaction))).then(function() { + hubot.speak(message, invalidResponseMessage(hubot, getExpectedResponses(interaction))).then(function() { callback(conversation); }); return true; @@ -116,10 +114,10 @@ function withExpectedResponse(conversation, interaction, response, hubot, messag } function hasAnotherInteraction(conversation, interaction, response, hubot, message) { - var expectedResponse = getExpectedResponse(interaction.expectedResponses, response); + const expectedResponse = getExpectedResponse(interaction.expectedResponses, response); if (expectedResponse.iteration) { - var newConversation = { + const newConversation = { user: message.user, interactions: [expectedResponse.iteration], gear: conversation.gear, @@ -136,7 +134,7 @@ function hasAnotherInteraction(conversation, interaction, response, hubot, messa function handleResponse(conversation, interaction, response) { if (interaction.handler) { - var handler = require(__nodeModules + 'gear-' + conversation.gear + '/' + interaction.handler); + const handler = require(__nodeModules + 'gear-' + conversation.gear + '/' + interaction.handler); return handler.handle(response.text); } } @@ -150,7 +148,7 @@ function getExpectedResponse(expectedResponses, response) { } function getExpectedResponses(interaction) { - let expectedResponses = []; + const expectedResponses = []; interaction.expectedResponses.forEach(e => expectedResponses.push(e.response)); diff --git a/src/message-handler/handlers/conversation-handler.js b/src/message-handler/handlers/conversation-handler.js index f80cac3..8358f5d 100644 --- a/src/message-handler/handlers/conversation-handler.js +++ b/src/message-handler/handlers/conversation-handler.js @@ -1,9 +1,9 @@ 'use strict'; -exports.handle = handle; - const conversation = require(__base + 'src/message-handler/conversation'); +exports.handle = handle; + function handle(hubot, message) { if (conversation.hasActiveConversation(message)) { conversation.notify(message); diff --git a/src/message-handler/handlers/first-run-handler.js b/src/message-handler/handlers/first-run-handler.js index 077ab3a..deb870b 100644 --- a/src/message-handler/handlers/first-run-handler.js +++ b/src/message-handler/handlers/first-run-handler.js @@ -2,8 +2,8 @@ exports.handle = handle; -function handle(hubot, message) { - if (hubot.isFirstRun) { +function handle(hubot, message, core) { + if (core.isFirstRun) { return true; } diff --git a/src/message-handler/handlers/gear-activate-handler.js b/src/message-handler/handlers/gear-activate-handler.js deleted file mode 100644 index 625f604..0000000 --- a/src/message-handler/handlers/gear-activate-handler.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; - -exports.handle = handle; - -const speech = require(__base + 'src/speech'); - -function handle(hubot, message) { - if (isGearActivateMessage(hubot, message)) { - hubot._isAdminUser(message.user) - .then(getGear) - .then(activateGear); - - function getGear(isAdmin) { - if (isAdmin) { - var gearDescription = message.text.replace("activate ", ""); - - return hubot._getGear(gearDescription); - } - } - - function activateGear(gear) { - if (gear && 'YES' == gear.active) { - hubot.talk(message, 'This gear is already active.'); - } else { - hubot._activateGear(gear.description).then(function() { - hubot.talk(message, sucessMessage(gear.description)); - }, function() { - hubot.talk(message, errorMessage(gear.description)); - }); - } - } - } -} - -function isGearActivateMessage(hubot, message) { - return hubot.gears.find(function(gear) { - var configureMessage = 'activate ' + gear.description; - - return message.text === configureMessage; - }) != null; -} - -function sucessMessage(gearDescription) { - return speech.start('Successfully activated ').bold('gear ' + gearDescription).end(); -} - -function errorMessage(gearDescription) { - return speech.start('Could not activate ').bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() -} diff --git a/src/message-handler/handlers/gear-configure-handler.js b/src/message-handler/handlers/gear-configure-handler.js index b50be78..338932c 100644 --- a/src/message-handler/handlers/gear-configure-handler.js +++ b/src/message-handler/handlers/gear-configure-handler.js @@ -1,12 +1,12 @@ 'use strict'; -exports.handle = handle; - const conversation = require(__base + 'src/message-handler/conversation'); +exports.handle = handle; + function handle(hubot, message) { if (isGearConfigureMessage(hubot, message)) { - var param = { + let param = { user: message.user, gear: gearDescription(message), interactions: discoverConfig(hubot, message) @@ -18,7 +18,7 @@ function handle(hubot, message) { function isGearConfigureMessage(hubot, message) { return hubot.gears.find(function(gear) { - var configureMessage = 'configure ' + gear.description; + const configureMessage = 'configure ' + gear.description; return message.text === configureMessage; }) != null; diff --git a/src/message-handler/handlers/gear-deactivate-handler.js b/src/message-handler/handlers/gear-deactivate-handler.js deleted file mode 100644 index 80dcdd7..0000000 --- a/src/message-handler/handlers/gear-deactivate-handler.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - -exports.handle = handle; - -const speech = require(__base + 'src/speech'); - -function handle(hubot, message) { - if (isGearDeactivateMessage(hubot, message)) { - - hubot._isAdminUser(message.user) - .then(getGear) - .then(deactivateGear); - - function getGear(isAdmin) { - if (isAdmin) { - var gearDescription = message.text.replace("deactivate ", ""); - - return hubot._getGear(gearDescription); - } - } - - function deactivateGear(gear) { - if (gear && 'NO' == gear.active) { - hubot.talk(message, 'This gear is already inactive.'); - } else { - hubot._deactivateGear(gear.description).then(function() { - hubot.talk(message, sucessMessage(gear.description)); - }, function() { - hubot.talk(message, errorMessage(gear.description)); - }); - } - } - } -} - -function isGearDeactivateMessage(hubot, message) { - return hubot.gears.find(function(gear) { - var configureMessage = 'deactivate ' + gear.description; - - return message.text === configureMessage; - }) != null; -} - -function sucessMessage(gearDescription) { - return speech.start('Successfully deactivated ').bold('gear ' + gearDescription).end(); -} - -function errorMessage(gearDescription) { - return speech.start('Could not deactivate ').bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() -} diff --git a/src/message-handler/handlers/gear-status-handler.js b/src/message-handler/handlers/gear-status-handler.js new file mode 100644 index 0000000..a3f980d --- /dev/null +++ b/src/message-handler/handlers/gear-status-handler.js @@ -0,0 +1,75 @@ +'use strict'; + +exports.handle = handle; + +const speech = require(__base + 'src/speech'); +const db = require(__base + 'src/lib/db'); + +function handle(hubot, message, core) { + const action = getAction(message); + + if (action && isGearChangeStatusMessage(action, hubot, message)) { + core.isAdminUser(message.user).then(changeStatus); + } else { + return false; + } + + function changeStatus(isAdmin) { + if (isAdmin) { + const gear = discoverGear(action, hubot, message); + + if (gear && gear.active === action.status) { + hubot.speak(message, 'This gear is already ' + action.statusDescription + '.'); + } else { + changeGearStatus(action, hubot, gear.description).then(function() { + hubot.speak(message, sucessMessage(action, gear.description)); + }, function() { + hubot.speak(message, errorMessage(action, gear.description)); + }); + } + + return true; + } + } +} + +function changeGearStatus(action, hubot, gear) { + hubot.findGear(gear).active = action.status; + + return db.getDb().run('UPDATE gears SET active = ? WHERE description = ?', action.status, gear); +} + +function isGearChangeStatusMessage(action, hubot, message) { + return hubot.gears.find(function(gear) { + const configureMessage = action.description + ' ' + gear.description; + + return message.text === configureMessage; + }) != null; +} + +function discoverGear(action, hubot, message) { + const gearDescription = message.text.replace(action.description + ' ', ''); + return hubot.findGear(gearDescription); +} + +function sucessMessage(action, gearDescription) { + return speech.start('Successfully ' + action.description + 'd ').bold('gear ' + gearDescription).end(); +} + +function errorMessage(gearDescription) { + return speech.start('Could not' + action.description + " ").bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() +} + +function getAction(message) { + if (message.text.startsWith('activate')) { + return { + description: 'activate', status: true, statusDescription: 'active' + }; + } else if (message.text.startsWith('deactivate')) { + return { + description: 'deactivate', status: false, statusDescription: 'inactive' + }; + } + + return null; +} diff --git a/src/message-handler/handlers/gears-tasks-handler.js b/src/message-handler/handlers/gears-tasks-handler.js new file mode 100644 index 0000000..7438f0e --- /dev/null +++ b/src/message-handler/handlers/gears-tasks-handler.js @@ -0,0 +1,41 @@ +'use strict'; + +const Hubot = require(__base + 'src/hubot'); +const trigger = require(__base + 'src/message-handler/trigger'); + +exports.handle = handle; + +function handle(hubot, message, core) { + hubot.gears.forEach(function(gear) { + gear.tasks.forEach(function(task) { + + const acceptance = trigger.check(message.text, task.trigger); + + if (acceptance.ok) { + if (gear.active) { + const hubotClone = getHubotClone(core); + const handler = getHandler(gear, task); + handler.handle(hubotClone, message, task, acceptance.params); + } else { + hubot.speak(message, "Sorry, this feature is disabled."); + } + + return true; + } + + }); + }); + + return false; +} + +function getHubotClone(core) { + const hubotClone = new Hubot(core); + hubotClone.gears = JSON.parse(JSON.stringify(core.hubot.gears)); + + return hubotClone; +} + +function getHandler(gear, task) { + return gear.handlers.find(h => h.key === task.handler); +} diff --git a/src/message-handler/handlers/tasks-handler.js b/src/message-handler/handlers/tasks-handler.js deleted file mode 100644 index e3649b1..0000000 --- a/src/message-handler/handlers/tasks-handler.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -exports.handle = handle; - -var trigger = require(__base + 'src/message-handler/trigger'); - -function handle(hubot, message) { - hubot.gears.forEach(function(gear) { - gear.tasks.forEach(function(task) { - - var acceptance = trigger.check(message.text, task.trigger); - - if (acceptance.ok) { - hubot._getGear(gear.description).then(function(result) { - if (result && 'YES' == result.active) { - var handler = getHandler(gear, task); - handler.handle(hubot, message, task, acceptance.params); - } else { - hubot.talk(message, "Sorry, this feature is disabled."); - } - - return true; - }); - - } - - }); - }); - - return false; -} - -function getHandler(gear, task) { - return gear.handlers.find(h => h.key === task.handler); -} diff --git a/src/message-handler/message-handler.js b/src/message-handler/message-handler.js index 63f9303..673a5d1 100644 --- a/src/message-handler/message-handler.js +++ b/src/message-handler/message-handler.js @@ -2,13 +2,13 @@ exports.callTasks = callTasks; -function callTasks(message, hubot) { - let handlers = getHandlers(); +function callTasks(message, core) { + const handlers = getHandlers(); for (let i = 0; i < handlers.length; i++) { - let handler = require(__base + 'src/message-handler/handlers/' + handlers[i]); + const handler = require(__base + 'src/message-handler/handlers/' + handlers[i]); - let isHandled = handler.handle(hubot, message); + const isHandled = handler.handle(core.hubot, message, core); if (isHandled) { break; @@ -20,9 +20,8 @@ function getHandlers() { return [ 'first-run-handler', 'conversation-handler', - 'gear-activate-handler', - 'gear-deactivate-handler', + 'gear-status-handler', 'gear-configure-handler', - 'tasks-handler' + 'gears-tasks-handler' ]; } diff --git a/src/message-handler/trigger.js b/src/message-handler/trigger.js index 5eb2f38..6864712 100644 --- a/src/message-handler/trigger.js +++ b/src/message-handler/trigger.js @@ -1,8 +1,8 @@ 'use strict'; -exports.check = check; +const stringfy = require('string'); -var stringfy = require('string'); +exports.check = check; function check(message, trigger) { return new Trigger('$').with(normalize(trigger)).accept(normalize(message)); diff --git a/src/speech.js b/src/speech.js index 5402824..1c2462a 100644 --- a/src/speech.js +++ b/src/speech.js @@ -11,7 +11,7 @@ function error(text) { return new Speecher().error(text); } -var Speecher = function () { +const Speecher = function () { this.message = null; } diff --git a/test/lib/assembler.js b/test/lib/assembler.js index 6061a96..a217b35 100644 --- a/test/lib/assembler.js +++ b/test/lib/assembler.js @@ -1,31 +1,33 @@ -var expect = require('chai').expect; -var setup = require('../setup').start(); -var Assembler = require('../../src/assembler'); +'use strict'; + +const expect = require('chai').expect; +const setup = require('../setup').start(); +const Assembler = require('../../src/assembler'); describe('The Hubot Assembler', function() { describe('should provide correct path', function() { it('for tasks', function() { - var gear = { name: 'test' }; + const gear = { name: 'test' }; - var path = getAssembler().tasksPath(gear); + const path = getAssembler().tasksPath(gear); expect(path).to.equal(__nodeModules + 'test/config/tasks.json'); }); it('for categories', function() { - var gear = { name: 'test' }; + const gear = { name: 'test' }; - var path = getAssembler().categoriesPath(gear); + const path = getAssembler().categoriesPath(gear); expect(path).to.equal(__nodeModules + 'test/config/categories.json'); }); it('for handlers', function() { - var gear = { name: 'test' }; + const gear = { name: 'test' }; - var path = getAssembler().handlersPath(gear, 'test-handler'); + const path = getAssembler().handlersPath(gear, 'test-handler'); expect(path).to.equal(__nodeModules + 'test/src/handlers/test-handler'); }); @@ -35,8 +37,8 @@ describe('The Hubot Assembler', function() { describe('should load', function() { it('task file', function() { - var assembler = getAssembler(); - var gear = { name: 'gear-test' }; + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; assembler.loadTasks(gear, assembler); @@ -47,8 +49,8 @@ describe('The Hubot Assembler', function() { }); it('category file', function() { - var assembler = getAssembler(); - var gear = { name: 'gear-test' }; + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; assembler.loadCategories(gear, assembler); @@ -61,8 +63,8 @@ describe('The Hubot Assembler', function() { }); it('handler file based on tasks handlers', function() { - var assembler = getAssembler(); - var gear = { name: 'gear-test' }; + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; assembler.loadTasks(gear, assembler); assembler.loadHandlers(gear, assembler); @@ -72,8 +74,8 @@ describe('The Hubot Assembler', function() { }); it('and should not load when handler file if there is not tasks', function() { - var assembler = getAssembler(); - var gear = { name: 'gear-test', tasks: [] }; + const assembler = getAssembler(); + const gear = { name: 'gear-test', tasks: [] }; assembler.loadHandlers(gear, assembler); @@ -85,8 +87,8 @@ describe('The Hubot Assembler', function() { describe('should load gears', function() { it('when is a valid gear', function() { - var assembler = getAssembler(); - var gear = { name: 'gear-test' }; + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; assembler.loadGear([gear], gear, 0); @@ -107,7 +109,7 @@ describe('The Hubot Assembler', function() { }); it('and should not throw error when invalid parameters are informed', function() { - var assembler = getAssembler(); + const assembler = getAssembler(); assembler.loadGear(null, null, null); @@ -115,8 +117,8 @@ describe('The Hubot Assembler', function() { }); it('neigther should throw error loading when informed an invalid gear', function() { - var assembler = getAssembler(); - var gear = { name: 'invalid' }; + const assembler = getAssembler(); + const gear = { name: 'invalid' }; assembler.loadGear([gear], gear, 0); diff --git a/test/lib/trigger.js b/test/lib/trigger.js index 88f784d..b79fce0 100644 --- a/test/lib/trigger.js +++ b/test/lib/trigger.js @@ -1,43 +1,45 @@ -var expect = require('chai').expect; -var trigger = require('../../src/message-handler/trigger'); +'use strict'; + +const expect = require('chai').expect; +const trigger = require('../../src/message-handler/trigger'); describe('Task Trigger', function() { describe('Task Trigger without parameters', function() { it('should not match wrong message', function() { - var phrase = 'test'; - var message = 'anything else'; + const phrase = 'test'; + const message = 'anything else'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: false, params: []} ); }); it('should matches exactly message', function() { - var phrase = 'test'; - var message = 'test'; + const phrase = 'test'; + const message = 'test'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: [] } ); }); it('should matches message ignoring casing', function() { - var phrase = 'test'; - var message = 'TEST'; + const phrase = 'test'; + const message = 'TEST'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: [] } ); }); it('should ignore placeholder at beginning', function() { - var phrase = '$test'; - var message = 'test'; + const phrase = '$test'; + const message = 'test'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: false, params: []} ); }); it('should consider placeholder at beginning like a simple character', function() { - var phrase = '$test'; - var message = '$test'; + const phrase = '$test'; + const message = '$test'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: []} ); @@ -46,24 +48,24 @@ describe('Task Trigger', function() { describe('Task Trigger with one parameter', function() { it('should not match wrong message', function() { - var phrase = 'test $ deeply'; - var message = 'please test anything else deeply'; + const phrase = 'test $ deeply'; + const message = 'please test anything else deeply'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: false, params: []} ); }); it('should get one parameter by placeholder at end', function() { - var phrase = 'test $'; - var message = 'test anything'; + const phrase = 'test $'; + const message = 'test anything'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: ['anything']} ); }); it('should get one parameter by placeholder at middle', function() { - var phrase = 'test $ deeply'; - var message = 'test anything else deeply'; + const phrase = 'test $ deeply'; + const message = 'test anything else deeply'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: ['anything else']} ); @@ -72,32 +74,32 @@ describe('Task Trigger', function() { describe('Task Trigger with multiple parameters', function() { it('should not match wrong message', function() { - var phrase = 'come on $, light $!'; - var message = 'so come on baby, light my fire!'; + const phrase = 'come on $, light $!'; + const message = 'so come on baby, light my fire!'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: false, params: []} ); }); it('should get multiple parameters', function() { - var phrase = 'come on $, light $!'; - var message = 'come on baby, light my fire!'; + const phrase = 'come on $, light $!'; + const message = 'come on baby, light my fire!'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: ['baby', 'my fire']} ); }); it('should get multiple parameters ignoring casing', function() { - var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - var message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; + const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + const message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: true, params: ['me', 'paradise city', 'grass', 'green', 'girls', 'pretty']} ); }); it('should not match typo', function() { - var phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - var message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; + const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + const message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; expect(trigger.check(message, phrase)).to.deep.equal( { ok: false, params: []} ); diff --git a/test/resource/gears/gear-test/handlers/test-handler.js b/test/resource/gears/gear-test/handlers/test-handler.js index d764417..c11717b 100644 --- a/test/resource/gears/gear-test/handlers/test-handler.js +++ b/test/resource/gears/gear-test/handlers/test-handler.js @@ -1,7 +1,7 @@ -'use strict'; - -exports.process = process; - -function process() { - return { key: 'test-process'}; +'use strict'; + +exports.process = process; + +function process() { + return { key: 'test-process'}; } \ No newline at end of file From 7c2a61837f7e261d5dd066639faec719aed6d183 Mon Sep 17 00:00:00 2001 From: Robson Date: Thu, 13 Oct 2016 21:52:01 -0300 Subject: [PATCH 06/26] Fix #17 Change de way to handle with private commands --- .../handlers/gears-tasks-handler.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/message-handler/handlers/gears-tasks-handler.js b/src/message-handler/handlers/gears-tasks-handler.js index 7438f0e..2546b47 100644 --- a/src/message-handler/handlers/gears-tasks-handler.js +++ b/src/message-handler/handlers/gears-tasks-handler.js @@ -13,6 +13,10 @@ function handle(hubot, message, core) { if (acceptance.ok) { if (gear.active) { + if (incorretMessageSource(hubot, task, message)) { + return true; + } + const hubotClone = getHubotClone(core); const handler = getHandler(gear, task); handler.handle(hubotClone, message, task, acceptance.params); @@ -29,6 +33,20 @@ function handle(hubot, message, core) { return false; } +function incorretMessageSource(hubot, task, message) { + if (task.onlyInChannel && !hubot.isFromChannel(message)) { + hubot.speak(message, "Sorry, this feature can only be performed on a channel."); + return true; + } + + if (task.onlyInPrivate && !hubot.isFromPrivate(message)) { + hubot.speak(message, "Sorry, this feature can only be performed directly with me in private."); + return true; + } + + return false; +} + function getHubotClone(core) { const hubotClone = new Hubot(core); hubotClone.gears = JSON.parse(JSON.stringify(core.hubot.gears)); From 98fb0c1331ba8c95f528d9ea62440537566dc0fe Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Thu, 13 Oct 2016 21:58:43 -0300 Subject: [PATCH 07/26] Include all files in test coverage metric --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7fa90e..f460cbd 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A small robot written in Javascript (He does not like coffeescript)", "main": "app.js", "scripts": { - "test": "istanbul cover _mocha -- --recursive --reporter spec", + "test": "istanbul cover --include-all-sources _mocha -- --recursive --reporter spec", "coveralls": "cat ./coverage/lcov.info | coveralls" }, "repository": { From a5f9f9c075e584951b17e5681c17d4423196d041 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Thu, 13 Oct 2016 21:59:20 -0300 Subject: [PATCH 08/26] Update node version to 6.8.0 in travis config file --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 55a5fca..321150e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: required language: node_js node_js: - - "6.7" + - "6.8.0" services: - docker From 2af1c89ad76c1750fc93eb1f00a34756371aa2a7 Mon Sep 17 00:00:00 2001 From: Robson Date: Mon, 17 Oct 2016 22:16:08 -0200 Subject: [PATCH 09/26] Fix #30 Add eslint e fix issues --- .dockerignore | 26 +- .editorconfig | 4 +- .eslintignore | 1 + .eslintrc.json | 30 ++ .gitignore | 86 ++--- .travis.yml | 37 +- app.js | 39 +- package.json | 88 +++-- src/assembler.js | 272 ++++++------- src/core.js | 201 +++++----- src/first-run.js | 124 +++--- src/hubot.js | 149 ++++---- src/lib/db.js | 67 ++-- src/lib/log.js | 44 +-- src/message-handler/conversation.js | 357 +++++++++--------- .../handlers/conversation-handler.js | 28 +- .../handlers/first-run-handler.js | 22 +- .../handlers/gear-configure-handler.js | 70 ++-- .../handlers/gear-status-handler.js | 146 ++++--- .../handlers/gears-tasks-handler.js | 126 ++++--- src/message-handler/message-handler.js | 58 +-- src/message-handler/trigger.js | 148 ++++---- src/speech.js | 237 ++++++------ test/lib/assembler.js | 266 +++++++------ test/lib/trigger.js | 216 +++++------ .../gears/gear-test/config/categories.json | 12 +- .../gears/gear-test/config/tasks.json | 10 +- .../gears/gear-test/handlers/test-handler.js | 14 +- .../gear-test/config/categories.json | 12 +- .../gear-test/config/tasks.json | 10 +- .../gear-test/src/handlers/test-handler.js | 14 +- test/setup.js | 17 +- 32 files changed, 1485 insertions(+), 1446 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.json diff --git a/.dockerignore b/.dockerignore index d54cd75..46b3645 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,13 +1,13 @@ -node_modules - -test - -.editorconfig - -.gitignore - -.travis.yml - -LICENSE - -README.md +node_modules + +test + +.editorconfig + +.gitignore + +.travis.yml + +LICENSE + +README.md diff --git a/.editorconfig b/.editorconfig index f97d33c..00e7b24 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,5 +4,5 @@ root = true charset = utf-8 insert_final_newline = true indent_style = space -indent_size = 3 -end_of_line = crlf +indent_size = 2 +end_of_line = lf diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..4ebc8ae --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +coverage diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..d133e4b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,30 @@ +//Extends from airbnb configs: https://github.com/airbnb/javascript +{ + "extends": "airbnb", + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "script" + }, + "rules": { + "class-methods-use-this": 0, + "comma-dangle": ["error", "never"], + "global-require": 0, + "import/no-dynamic-require": 0, + "import/no-extraneous-dependencies": 0, + "max-len": ["error", { "code": 120 }], + "new-cap": 0, + "newline-per-chained-call": 0, + "no-param-reassign": 0, + "no-plusplus": 0, + "no-underscore-dangle": 0, + "no-use-before-define": ["error", { "functions": false, "classes": false }], + "quotes": ["error", "single", { "avoidEscape": true }], + "space-before-function-paren": 0, + "strict": ["error", "global"] + } +} diff --git a/.gitignore b/.gitignore index 519be63..27b3ee5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,43 @@ -# Logs -*.log -npm-debug.log* -hubot.log - -hubot.db - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules -jspm_packages - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history - -hubot.db - -.vscode +# Logs +*.log +npm-debug.log* +hubot.log + +hubot.db + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +hubot.db + +.vscode diff --git a/.travis.yml b/.travis.yml index 321150e..6566657 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,20 @@ -sudo: required - -language: node_js -node_js: - - "6.8.0" - -services: - - docker - -after_success: - - if [[ "$TRAVIS_BRANCH" == "master" ]]; then - docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" ; - docker build -t robsonbittencourt/hubot.js:latest . ; - docker push docker.io/robsonbittencourt/hubot.js:latest ; - fi - - - 'npm run coveralls' +sudo: required + +language: node_js +node_js: + - "6.8.0" + +services: + - docker + +script: + - npm run lint + +after_success: + - if [[ "$TRAVIS_BRANCH" == "master" ]]; then + docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" ; + docker build -t robsonbittencourt/hubot.js:latest . ; + docker push docker.io/robsonbittencourt/hubot.js:latest ; + fi + + - 'npm run coveralls' diff --git a/app.js b/app.js index 5378581..761a727 100644 --- a/app.js +++ b/app.js @@ -1,21 +1,18 @@ -'use strict'; - -global.__base = __dirname + '/'; -global.__gears = __base + 'src/gears/'; -global.__nodeModules = __base + 'node_modules/'; - -const Core = require(__base + 'src/core'); -const db = require(__base + 'src/lib/db'); - -const token = process.env.BOT_API_KEY -const name = process.env.BOT_NAME || 'hubot'; - -db.startDb().then(function() { - const core = new Core({ - token: token, - name: name - }); - - core.run(); -}); - +'use strict'; + +const path = require('path'); + +const Core = require('./src/core'); +const db = require('./src/lib/db'); + +global.__nodeModules = path.join(__dirname, '/node_modules/'); + +const token = process.env.BOT_API_KEY; +const name = process.env.BOT_NAME || 'hubot'; + +db.startDb().then(() => { + const core = new Core({ token, name }); + + core.run(); +}); + diff --git a/package.json b/package.json index f460cbd..b49d484 100644 --- a/package.json +++ b/package.json @@ -1,41 +1,47 @@ -{ - "name": "hubot.js", - "version": "1.0.0", - "description": "A small robot written in Javascript (He does not like coffeescript)", - "main": "app.js", - "scripts": { - "test": "istanbul cover --include-all-sources _mocha -- --recursive --reporter spec", - "coveralls": "cat ./coverage/lcov.info | coveralls" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/robsonbittencourt/hubot.js.git" - }, - "keywords": [ - "hubot", - "slack", - "docker", - "jenkins" - ], - "author": "robsonbittencourt", - "license": "MIT", - "bugs": { - "url": "https://github.com/robsonbittencourt/hubot.js/issues" - }, - "homepage": "https://github.com/robsonbittencourt/hubot.js#readme", - "dependencies": { - "slackbots": "^0.5.2", - "string": "^3.3.1", - "winston": "^2.2.0", - "q": "^1.4.1", - "sqlite": "^2.2.0", - "gear-help": "^1.0.1", - "gear-jenkins": "^1.0.1" - }, - "devDependencies": { - "chai": "^3.5.0", - "mocha": "^3.0.2", - "istanbul": "^0.4.5", - "coveralls": "^2.11.12" - } -} +{ + "name": "hubot.js", + "version": "1.0.0", + "description": "A small robot written in Javascript (He does not like coffeescript)", + "main": "app.js", + "scripts": { + "test": "istanbul cover --include-all-sources _mocha -- --recursive --reporter spec", + "coveralls": "cat ./coverage/lcov.info | coveralls", + "lint": "eslint ." + }, + "repository": { + "type": "git", + "url": "git+https://github.com/robsonbittencourt/hubot.js.git" + }, + "keywords": [ + "hubot", + "slack", + "docker", + "jenkins" + ], + "author": "robsonbittencourt", + "license": "MIT", + "bugs": { + "url": "https://github.com/robsonbittencourt/hubot.js/issues" + }, + "homepage": "https://github.com/robsonbittencourt/hubot.js#readme", + "dependencies": { + "slackbots": "^0.5.2", + "string": "^3.3.1", + "winston": "^2.2.0", + "q": "^1.4.1", + "sqlite": "^2.2.0", + "gear-help": "^1.0.1", + "gear-jenkins": "^1.0.1" + }, + "devDependencies": { + "chai": "^3.5.0", + "coveralls": "^2.11.12", + "eslint": "^3.8.0", + "eslint-config-airbnb": "^12.0.0", + "eslint-plugin-import": "^1.16.0", + "eslint-plugin-jsx-a11y": "^2.2.3", + "eslint-plugin-react": "^6.4.1", + "istanbul": "^0.4.5", + "mocha": "^3.0.2" + } +} diff --git a/src/assembler.js b/src/assembler.js index 381995b..292b43e 100644 --- a/src/assembler.js +++ b/src/assembler.js @@ -1,135 +1,137 @@ -'use strict'; - -const fs = require('fs'); -const log = require(__base + 'src/lib/log'); -const speech = require(__base + 'src/speech'); -const db = require(__base + 'src/lib/db'); - -const gearNamePrefix = 'gear-'; - -module.exports = class Assembler { - - constructor() { - this.gears = []; - } - - build() { - this.loadGears(this); - return this.gears; - } - - loadGears(self) { - fs.readdir(__nodeModules, function (error, list) { - const gearsNames = list.filter(function (e) { - return e.startsWith(gearNamePrefix); - }); - - gearsNames.forEach(function(gearName) { - const gearDescription = gearName.replace("gear-", ""); - - self.gears.push( { name: gearName, description: gearDescription } ); - }); - - self.gears.forEach((gear, index) => self.loadGear(self.gears, gear, index)); - }); - } - - loadGear(gears, gear, index) { - logAddingGear(gears, gear, index); - this.tryToLoad('gearStatus', gear, this.loadGearStatus); - this.tryToLoad('configs', gear, this.loadConfigs); - this.tryToLoad('tasks', gear, this.loadTasks); - this.tryToLoad('categories', gear, this.loadCategories); - this.tryToLoad('handlers', gear, this.loadHandlers); - this.tryToLoad('configHandler', gear, this.loadConfigHandler); - } - - tryToLoad(type, gear, assemble) { - try { - logInfoLoadingGear(type); - assemble(gear, this); - } catch (error) { - logErrorLoadingGear(type, error); - } - } - - loadGearStatus(gear, self) { - db.getDb().get('SELECT * FROM gears WHERE name = ?', gear.name).then(function(record) { - if (!record) { - gear.active = false; - db.getDb().run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, false); - } else { - gear.active = record.active === "1"; - } - }); - } - - loadConfigs(gear, self) { - gear.configs = []; - gear.configs = gear.configs.concat(require(self.configsPath(gear))); - } - - loadTasks(gear, self) { - gear.tasks = []; - gear.tasks = gear.tasks.concat(require(self.tasksPath(gear))); - } - - loadCategories(gear, self) { - gear.categories = []; - gear.categories = gear.categories.concat(require(self.categoriesPath(gear))); - } - - loadHandlers(gear, self) { - gear.handlers = []; - - gear.tasks.forEach(function(task) { - const handler = require(self.handlersPath(gear, task.handler)); - - gear.handlers.push({ key: task.handler, handle: handler.handle}); - }); - } - - loadConfigHandler(gear, self) { - gear.configHandler = require(self.configsHandlersPath(gear)); - } - - configsPath(gear) { - return __nodeModules + gear.name + '/config/config.json'; - } - - tasksPath(gear) { - return __nodeModules + gear.name + '/config/tasks.json'; - } - - categoriesPath(gear) { - return __nodeModules + gear.name + '/config/categories.json'; - } - - handlersPath(gear, handler) { - return __nodeModules + gear.name + '/src/handlers/' + handler; - } - - configsHandlersPath(gear) { - return __nodeModules + gear.name + '/src/configHandler/configHandler'; - } - -} - -function logStartAssembling() { - log.info('Starting assembly hubot...'); -} - -function logAddingGear(gears, gear, index) { - if (!gears) return log.error('Could not load gears.'); - if (!gear) return log.error('Could not load gear at index ' + index); - log.info(speech.start('Adding ').refer(gear.name).progress(index + 1, gears.length).end()); -} - -function logInfoLoadingGear(gear) { - log.info(speech.start(' > Loading ').append(gear).append('...').end()); -} - -function logErrorLoadingGear(gear, error) { - log.error(speech.start(' > There was an error loading ').append(gear).append(' gear. This functionality can not be used.').end()); - log.error(error); -} +'use strict'; + +const fs = require('fs'); + +const db = require('./lib/db'); +const log = require('./lib/log'); +const speech = require('./speech'); + +const gearNamePrefix = 'gear-'; + +module.exports = class Assembler { + + constructor() { + this.gears = []; + } + + build() { + this.loadGears(this); + return this.gears; + } + + loadGears(self) { + fs.readdir(global.__nodeModules, (error, list) => { + const gearsNames = list.filter(e => e.startsWith(gearNamePrefix)); + + gearsNames.forEach((gearName) => { + const gearDescription = gearName.replace('gear-', ''); + + self.gears.push({ name: gearName, description: gearDescription }); + }); + + self.gears.forEach((gear, index) => self.loadGear(self.gears, gear, index)); + }); + } + + loadGear(gears, gear, index) { + logStartAssembling(); + logAddingGear(gears, gear, index); + this.tryToLoad('gearStatus', gear, this.loadGearStatus); + this.tryToLoad('configs', gear, this.loadConfigs); + this.tryToLoad('tasks', gear, this.loadTasks); + this.tryToLoad('categories', gear, this.loadCategories); + this.tryToLoad('handlers', gear, this.loadHandlers); + this.tryToLoad('configHandler', gear, this.loadConfigHandler); + } + + tryToLoad(type, gear, assemble) { + try { + logInfoLoadingGear(type); + assemble(gear, this); + } catch (error) { + logErrorLoadingGear(type, error); + } + } + + loadGearStatus(gear) { + db.getDb().get('SELECT * FROM gears WHERE name = ?', gear.name).then((record) => { + if (!record) { + gear.active = false; + db.getDb() + .run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, false); + } else { + gear.active = record.active === '1'; + } + }); + } + + loadConfigs(gear, self) { + gear.configs = []; + gear.configs = gear.configs.concat(require(self.configsPath(gear))); + } + + loadTasks(gear, self) { + gear.tasks = []; + gear.tasks = gear.tasks.concat(require(self.tasksPath(gear))); + } + + loadCategories(gear, self) { + gear.categories = []; + gear.categories = gear.categories.concat(require(self.categoriesPath(gear))); + } + + loadHandlers(gear, self) { + gear.handlers = []; + + gear.tasks.forEach((task) => { + const handler = require(self.handlersPath(gear, task.handler)); + + gear.handlers.push({ key: task.handler, handle: handler.handle }); + }); + } + + loadConfigHandler(gear, self) { + gear.configHandler = require(self.configsHandlersPath(gear)); + } + + configsPath(gear) { + return `${global.__nodeModules}${gear.name}/config/config.json`; + } + + tasksPath(gear) { + return `${global.__nodeModules}${gear.name}/config/tasks.json`; + } + + categoriesPath(gear) { + return `${global.__nodeModules}${gear.name}/config/categories.json`; + } + + handlersPath(gear, handler) { + return `${global.__nodeModules}${gear.name}/src/handlers/${handler}`; + } + + configsHandlersPath(gear) { + return `${global.__nodeModules}${gear.name}/src/configHandler/configHandler`; + } + +}; + +function logStartAssembling() { + log.info('Starting assembly hubot...'); +} + +function logAddingGear(gears, gear, index) { + if (!gears) return log.error('Could not load gears.'); + if (!gear) return log.error(`Could not load gear at index ${index}`); + return log.info(speech.start('Adding ').refer(gear.name).progress(index + 1, gears.length).end()); +} + +function logInfoLoadingGear(gear) { + log.info(speech.start(' > Loading ').append(gear).append('...').end()); +} + +function logErrorLoadingGear(gear, error) { + log.error(speech.start(' > There was an error loading ') + .append(gear).append(' gear. This functionality can not be used.').end()); + log.error(error); +} diff --git a/src/core.js b/src/core.js index 1ca9c65..b9bac99 100644 --- a/src/core.js +++ b/src/core.js @@ -1,100 +1,101 @@ -'use strict'; - -const util = require('util'); -const Bot = require('slackbots'); -const Hubot = require(__base + 'src/hubot'); -const log = require(__base + 'src/lib/log'); -const Assembler = require(__base + 'src/assembler'); -const messageHandler = require(__base + 'src/message-handler/message-handler'); -const firstRun = require(__base + 'src/first-run'); -const db = require(__base + 'src/lib/db'); - -let botName; -let botUser; -let coreSettings; -let isFirstRun = false; - -process.on('uncaughtException', function (exception) { - log.error(exception); -}); - -var Core = function Constructor(settings) { - coreSettings = settings; - botName = settings.name; -}; - -util.inherits(Core, Bot); -module.exports = Core; - -Core.prototype.run = function () { - Core.super_.call(this, coreSettings); - - this.on('start', this.onStart); - this.on('message', this.onMessage); -}; - -Core.prototype.onStart = function () { - botUser = this.getUserByName(botName); - this.hubot = new Hubot(this); - this.hubot.gears = new Assembler().build(); - this.firstRunChecker(); -}; - -Core.prototype.onMessage = function (message) { - if (isChatMessage(message) && !isFromHubot(message)) { - if (isFirstInteraction(this, message)) { - isFirstRun = false; - firstRun.firstRun(this, message); - } else { - messageHandler.callTasks(message, this); - } - } -}; - -Core.prototype.firstRunChecker = function () { - db.getDb().get('SELECT * FROM first_use').then(function(record) { - if (!record || !record.first_use) { - isFirstRun = true; - } - }); -}; - -Core.prototype.getUserByName = function (name) { - return this.users.find(user => user.name === name); -}; - -Core.prototype.getUserById = function (userId) { - return this.users.find(user => user.id === userId); -}; - -Core.prototype.isChannelConversation = function (message) { - return typeof message.channel === 'string' && message.channel[0] === 'C'; -}; - -Core.prototype.isPrivateConversation = function (message) { - return typeof message.channel === 'string' && message.channel[0] === 'D'; -}; - -Core.prototype.getRecipient = function (message) { - if (this.isPrivateConversation(message)) { - return message.user; - } else { - return message.channel; - } -} - -Core.prototype.isAdminUser = function (user) { - return db.getDb().get('SELECT * FROM admins WHERE admin = ?', user); -}; - -function isFromHubot(message) { - return message.user === botUser.id; -}; - -function isChatMessage(message) { - return message.type === 'message' && Boolean(message.text); -}; - -function isFirstInteraction(core, message) { - return isFirstRun && core.isPrivateConversation(message) && message.text === botName; -} +'use strict'; + +const util = require('util'); + +const Bot = require('slackbots'); + +const db = require('./lib/db'); +const Hubot = require('./hubot'); +const log = require('./lib/log'); +const firstRun = require('./first-run'); +const Assembler = require('./assembler'); +const messageHandler = require('./message-handler/message-handler'); + +let botName; +let botUser; +let coreSettings; +let isFirstRun = false; + +process.on('uncaughtException', (exception) => { + log.error(exception); +}); + +const Core = function Constructor(settings) { + coreSettings = settings; + botName = settings.name; +}; + +util.inherits(Core, Bot); +module.exports = Core; + +Core.prototype.run = function run() { + Core.super_.call(this, coreSettings); + + this.on('start', this.onStart); + this.on('message', this.onMessage); +}; + +Core.prototype.onStart = function onStart() { + botUser = this.getUserByName(botName); + this.hubot = new Hubot(this); + this.hubot.gears = new Assembler().build(); + this.firstRunChecker(); +}; + +Core.prototype.onMessage = function onMessage(message) { + if (isChatMessage(message) && !isFromHubot(message)) { + if (isFirstInteraction(this, message)) { + isFirstRun = false; + firstRun.firstRun(this, message); + } else { + messageHandler.callTasks(message, this); + } + } +}; + +Core.prototype.firstRunChecker = function firstRunChecker() { + db.getDb().get('SELECT * FROM first_use').then((record) => { + if (!record || !record.first_use) { + isFirstRun = true; + } + }); +}; + +Core.prototype.getUserByName = function getUserByName(name) { + return this.users.find(user => user.name === name); +}; + +Core.prototype.getUserById = function getUserById(userId) { + return this.users.find(user => user.id === userId); +}; + +Core.prototype.isChannelConversation = function isChannelConversation(message) { + return typeof message.channel === 'string' && message.channel[0] === 'C'; +}; + +Core.prototype.isPrivateConversation = function isPrivateConversation(message) { + return typeof message.channel === 'string' && message.channel[0] === 'D'; +}; + +Core.prototype.getRecipient = function getRecipient(message) { + if (this.isPrivateConversation(message)) { + return message.user; + } + return message.channel; +}; + +Core.prototype.isAdminUser = function isAdminUser(user) { + return db.getDb().get('SELECT * FROM admins WHERE admin = ?', user); +}; + +function isFromHubot(message) { + return message.user === botUser.id; +} + +function isChatMessage(message) { + return message.type === 'message' && Boolean(message.text); +} + +function isFirstInteraction(core, message) { + return isFirstRun && core.isPrivateConversation(message) && message.text === botName; +} diff --git a/src/first-run.js b/src/first-run.js index 0f89187..489315e 100644 --- a/src/first-run.js +++ b/src/first-run.js @@ -1,65 +1,59 @@ -'use strict'; - -const db = require(__base + 'src/lib/db'); - -exports.firstRun = firstRun; - -function firstRun(core, message) { - db.getDb().run("INSERT INTO first_use(first_use) VALUES('NO')"); - db.getDb().run("INSERT INTO admins(admin) VALUES(?)", message.user); - - const hubot = core.hubot; - const messageDelay = 3000; - - hubot.speak(message, message1(hubot, core, message), messageDelay) - .then(function() { - return hubot.speak(message, message2(hubot), messageDelay); - }) - .then(function() { - return hubot.speak(message, message3(hubot), messageDelay); - }) - .then(function() { - return hubot.speak(message, message4(hubot), messageDelay); - }) - .then(function() { - return hubot.speak(message, message5(hubot), messageDelay); - }) - .then(function() { - return hubot.speak(message, message6(hubot), messageDelay); - }) - .then(function() { - hubot.speak(message, postGearsNames(hubot), messageDelay); - }); -} - -function message1(hubot, core, message) { - return hubot.speech().hello(core.getUserById(message.user)).append("My name is ").append(core.name).append(" and from now on I will help you with some tasks using the Slack.").end(); -} - -function message2(hubot) { - return hubot.speech().append("Before I need you to do some settings. How was you who started me I will define you as my system administrator. So you can access the settings in the future.").end(); -} - -function message3(hubot) { - return hubot.speech().append("Initially I do not know perform tasks. But there are gears that when coupled to me add me skills.").end(); -} - -function message4(hubot) { - return hubot.speech().append("At this time all the gears are inactive. You can activate them using the command ").bold("activate gear-name").period().end(); -} - -function message5(hubot) { - return hubot.speech().append("Some gears have settings. To let them use the command ").bold("configure gear-name").period().end(); -} - -function message6(hubot) { - return hubot.speech().append("Below is a list of gears available:").end(); -} - -function postGearsNames(hubot) { - const speech = hubot.speech(); - - hubot.gears.forEach(g => speech.item(g.description).line()); - - return speech.end(); -} +'use strict'; + +const db = require('./lib/db'); + +exports.firstRun = firstRun; + +function firstRun(core, message) { + db.getDb().run("INSERT INTO first_use(first_use) VALUES('NO')"); + db.getDb().run('INSERT INTO admins(admin) VALUES(?)', message.user); + + const hubot = core.hubot; + const messageDelay = 3000; + + hubot.speak(message, message1(hubot, core, message), messageDelay) + .then(() => hubot.speak(message, message2(hubot), messageDelay)) + .then(() => hubot.speak(message, message3(hubot), messageDelay)) + .then(() => hubot.speak(message, message4(hubot), messageDelay)) + .then(() => hubot.speak(message, message5(hubot), messageDelay)) + .then(() => hubot.speak(message, message6(hubot), messageDelay)) + .then(() => hubot.speak(message, postGearsNames(hubot), messageDelay)); +} + +function message1(hubot, core, message) { + return hubot.speech().hello(core.getUserById(message.user)).append('My name is ').append(core.name) + .append(' and from now on I will help you with some tasks using the Slack.').end(); +} + +function message2(hubot) { + return hubot.speech().append('Before I need you to do some settings.') + .append(' How was you who started me I will define you as my system administrator.') + .append(' So you can access the settings in the future.').end(); +} + +function message3(hubot) { + return hubot.speech().append('Initially I do not know perform tasks.') + .append(' But there are gears that when coupled to me add me skills.').end(); +} + +function message4(hubot) { + return hubot.speech().append('At this time all the gears are inactive. You can activate them using the command ') + .bold('activate gear-name').period().end(); +} + +function message5(hubot) { + return hubot.speech().append('Some gears have settings. To let them use the command ') + .bold('configure gear-name').period().end(); +} + +function message6(hubot) { + return hubot.speech().append('Below is a list of gears available:').end(); +} + +function postGearsNames(hubot) { + const speech = hubot.speech(); + + hubot.gears.forEach(g => speech.item(g.description).line()); + + return speech.end(); +} diff --git a/src/hubot.js b/src/hubot.js index 8911441..187a957 100644 --- a/src/hubot.js +++ b/src/hubot.js @@ -1,77 +1,72 @@ -'use strict'; - -const Q = require('q'); -const log = require(__base + 'src/lib/log'); -const speech = require(__base + 'src/speech'); - -let _core; - -module.exports = class Hubot { - - constructor(core) { - this.gears = []; - _core = core; - } - - speakTo(recipient, text, message, delay = 1000) { - const deferred = Q.defer(); - const channel = message ? message.channel : recipient; - - _core.ws.send(JSON.stringify({ type: 'typing', channel: channel })); - - setTimeout(() => { - - _core.postMessage(recipient, text, {as_user: true}).then(function() { - deferred.resolve(); - }, function() { - deferred.reject(); - }); - - }, delay); - - return deferred.promise; - } - - speak(message, text, delay) { - return this.speakTo(this.getRecipient(message), text, message, delay); - } - - logInfo(info) { - log.info(info); - } - - logError(error) { - log.error(error); - } - - logDetailedError(error, metadata) { - log.detailedError(error, metadata); - } - - isFromChannel(message) { - return _core.isChannelConversation(message); - } - - isFromPrivate(message) { - return _core.isPrivateConversation(message); - } - - getUser(message) { - return _core.getUserById(message.user); - } - - getRecipient(message) { - return _core.getRecipient(message); - } - - speech(message) { - return speech.start(message); - } - - findGear(gear) { - return this.gears.find(g => g.description === gear); - } - -} - - +'use strict'; + +const Q = require('q'); + +const log = require('./lib/log'); +const speech = require('./speech'); + +let core; + +module.exports = class Hubot { + + constructor(receivedCore) { + this.gears = []; + core = receivedCore; + } + + speakTo(recipient, text, message, delay = 1000) { + const deferred = Q.defer(); + const channel = message ? message.channel : recipient; + + core.ws.send(JSON.stringify({ type: 'typing', channel })); + + setTimeout(() => { + core.postMessage(recipient, text, { as_user: true }) + .then(() => deferred.resolve(), + () => deferred.reject()); + }, delay); + + return deferred.promise; + } + + speak(message, text, delay) { + return this.speakTo(this.getRecipient(message), text, message, delay); + } + + logInfo(info) { + log.info(info); + } + + logError(error) { + log.error(error); + } + + logDetailedError(error, metadata) { + log.detailedError(error, metadata); + } + + isFromChannel(message) { + return core.isChannelConversation(message); + } + + isFromPrivate(message) { + return core.isPrivateConversation(message); + } + + getUser(message) { + return core.getUserById(message.user); + } + + getRecipient(message) { + return core.getRecipient(message); + } + + speech(message) { + return speech.start(message); + } + + findGear(gear) { + return this.gears.find(g => g.description === gear); + } + +}; diff --git a/src/lib/db.js b/src/lib/db.js index 9bd961d..8915702 100644 --- a/src/lib/db.js +++ b/src/lib/db.js @@ -1,34 +1,33 @@ -'use strict'; - -const db = require('sqlite'); -const path = require('path'); - -exports.startDb = startDb; -exports.getDb = getDb; - -let database; - -function startDb() { - const dbFile = path.resolve(process.cwd(), 'data', 'hubot.db'); - const migrations = path.resolve(process.cwd(), 'migrations'); - - function open(dbFile) { - return db.open(dbFile); - } - - function migrate(db) { - db.migrate({migrationsPath: migrations}).then(function(result) { - database = result; - }); - } - - return open(dbFile) - .then(migrate) - .catch(function() { - //do nothing - }); -} - -function getDb() { - return database; -} +'use strict'; + +const path = require('path'); + +const sqlite = require('sqlite'); + +exports.startDb = startDb; +exports.getDb = getDb; + +let database; + +function startDb() { + return open() + .then(migrate) + .catch(() => { }); // do nothing +} + +function open() { + const dbFile = path.resolve(process.cwd(), 'data', 'hubot.db'); + + return sqlite.open(dbFile); +} + +function migrate(sqliteDb) { + const migrations = path.resolve(process.cwd(), 'migrations'); + + return sqliteDb.migrate({ migrationsPath: migrations }) + .then((result) => { database = result; }); +} + +function getDb() { + return database; +} diff --git a/src/lib/log.js b/src/lib/log.js index 2031504..1187aef 100644 --- a/src/lib/log.js +++ b/src/lib/log.js @@ -1,22 +1,22 @@ -'use strict'; - -const winston = require('winston'); - -exports.info = info; -exports.error = error; -exports.detailedError = detailedError; - -winston.add(winston.transports.File, { filename: __base + 'logs/hubot.log', handleExceptions: true }); -winston.remove(winston.transports.Console); - -function info(info) { - winston.info(info); -} - -function error(error) { - winston.error(error); -} - -function detailedError(error, metadata) { - winston.error('error', error, {error: metadata}); -} +'use strict'; + +const winston = require('winston'); + +exports.info = info; +exports.error = error; +exports.detailedError = detailedError; + +winston.add(winston.transports.File, { filename: '../../logs/hubot.log', handleExceptions: true }); +winston.remove(winston.transports.Console); + +function info(logInfo) { + winston.info(logInfo); +} + +function error(logError) { + winston.error(logError); +} + +function detailedError(logError, metadata) { + winston.error('error', logError, { error: metadata }); +} diff --git a/src/message-handler/conversation.js b/src/message-handler/conversation.js index 789770c..80bbfb7 100644 --- a/src/message-handler/conversation.js +++ b/src/message-handler/conversation.js @@ -1,176 +1,181 @@ -'use strict'; - -const Q = require('q'); -const EventEmitter = require('events'); - -exports.startConversation = startConversation; -exports.hasActiveConversation = hasActiveConversation; -exports.notify = notify; - -class MyEmitter extends EventEmitter {} -const myEmitter = new MyEmitter(); - -let activeConversations = []; - -function startConversation(hubot, conversation, message) { - activeConversations.push(conversation); - - conversation.nextInteration = 0; - - start(hubot, conversation, message); -} - -function start(hubot, conversation, message) { - const interactions = conversation.interactions; - - if (conversation.nextInteration < interactions.length) { - speak(hubot, message, conversation, function(conversation) { - start(hubot, conversation, message); - }); - } - - if (conversation.nextInteration == interactions.length) { - if (conversation.previousConversation) { - start(hubot, conversation.previousConversation, message); - } else { - endConversations(conversation); - } - } -} - -function speak(hubot, message, conversation, callback) { - const interaction = conversation.interactions[conversation.nextInteration]; - - hubot.speak(message, interaction.speak).then(function() { - if(justSpeak(conversation, interaction, callback)) return; - - myEmitter.once(message.user, function(response) { - if (withoutExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; - - if (withExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; - - Q(handleResponse(conversation, interaction, response)).then(function(text) { - conversation.nextInteration++; - - if(text) { - hubot.speak(message, text).then(function() { - if(hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; - callback(conversation); - }); - } else { - if(hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; - callback(conversation); - } - }, function(text) { - speakReturnedText(hubot, message, conversation, text, callback); - }); - }); - }); -} - -function justSpeak(conversation, interaction, callback) { - if (!interaction.expectedResponses && !interaction.handler) { - conversation.nextInteration++; - callback(conversation); - return true; - } - - return false; -} - -function withoutExpectedResponse(conversation, interaction, response, hubot, message, callback) { - if (!interaction.expectedResponses) { - Q(handleResponse(conversation, interaction, response)).then(function(text) { - conversation.nextInteration++; - speakReturnedText(hubot, message, conversation, text, callback); - }, function(text) { - speakReturnedText(hubot, message, conversation, text, callback); - }); - return true; - } - - return false; -} - -function speakReturnedText(hubot, message, conversation, text, callback) { - if(text) { - hubot.speak(message, text).then(function() { - callback(conversation); - }); - } else { - callback(conversation); - } -} - -function withExpectedResponse(conversation, interaction, response, hubot, message, callback) { - if (!getExpectedResponse(interaction.expectedResponses, response)) { - hubot.speak(message, invalidResponseMessage(hubot, getExpectedResponses(interaction))).then(function() { - callback(conversation); - }); - return true; - } - - return false; -} - -function hasAnotherInteraction(conversation, interaction, response, hubot, message) { - const expectedResponse = getExpectedResponse(interaction.expectedResponses, response); - - if (expectedResponse.iteration) { - const newConversation = { - user: message.user, - interactions: [expectedResponse.iteration], - gear: conversation.gear, - nextInteration: 0, - previousConversation: conversation - }; - - start(hubot, newConversation, message); - return true; - } - - return false; -} - -function handleResponse(conversation, interaction, response) { - if (interaction.handler) { - const handler = require(__nodeModules + 'gear-' + conversation.gear + '/' + interaction.handler); - return handler.handle(response.text); - } -} - -function getExpectedResponse(expectedResponses, response) { - if (expectedResponses) { - return expectedResponses.find(r => r.response === response.text); - } - - return null; -} - -function getExpectedResponses(interaction) { - const expectedResponses = []; - - interaction.expectedResponses.forEach(e => expectedResponses.push(e.response)); - - return expectedResponses; -} - -function invalidResponseMessage(hubot, expectedResponses) { - return hubot.speech().append("Sorry, I didn't understand.").append("(Expected responses: ").bold(expectedResponses.join(", ")).append(").").end(); -} - -function hasActiveConversation(message) { - return getActiveConversation(message) != null; -} - -function notify(message) { - myEmitter.emit(message.user, message); -} - -function getActiveConversation(message) { - return activeConversations.find(c => c.user === message.user); -} - -function endConversations(conversation) { - activeConversations = activeConversations.filter(c => c.user !== conversation.user); -} +'use strict'; + +const EventEmitter = require('events'); + +const Q = require('q'); + +exports.startConversation = startConversation; +exports.hasActiveConversation = hasActiveConversation; +exports.notify = notify; + +class MyEmitter extends EventEmitter {} +const myEmitter = new MyEmitter(); + +let activeConversations = []; +const nodeModules = '../../node_modules/'; + +function startConversation(hubot, conversation, message) { + activeConversations.push(conversation); + + conversation.nextInteration = 0; + + start(hubot, conversation, message); +} + +function start(hubot, conversation, message) { + const interactions = conversation.interactions; + + if (conversation.nextInteration < interactions.length) { + speak(hubot, message, conversation, () => { + start(hubot, conversation, message); + }); + } + + if (conversation.nextInteration === interactions.length) { + if (conversation.previousConversation) { + start(hubot, conversation.previousConversation, message); + } else { + endConversations(conversation); + } + } +} + +function speak(hubot, message, conversation, callback) { + const interaction = conversation.interactions[conversation.nextInteration]; + + hubot.speak(message, interaction.speak).then(() => { + if (justSpeak(conversation, interaction, callback)) return; + + myEmitter.once(message.user, (response) => { + if (withoutExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; + + if (withExpectedResponse(conversation, interaction, response, hubot, message, callback)) return; + + Q(handleResponse(conversation, interaction, response)).then((text) => { + conversation.nextInteration++; + + if (text) { + hubot.speak(message, text).then(() => { + if (hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; + callback(conversation); + }); + } else { + if (hasAnotherInteraction(conversation, interaction, response, hubot, message)) return; + callback(conversation); + } + }, (text) => { + speakReturnedText(hubot, message, conversation, text, callback); + }); + }); + }); +} + +function justSpeak(conversation, interaction, callback) { + if (!interaction.expectedResponses && !interaction.handler) { + conversation.nextInteration++; + callback(conversation); + return true; + } + + return false; +} + +function withoutExpectedResponse(conversation, interaction, response, hubot, message, callback) { + if (!interaction.expectedResponses) { + Q(handleResponse(conversation, interaction, response)).then((text) => { + conversation.nextInteration++; + speakReturnedText(hubot, message, conversation, text, callback); + }, (text) => { + speakReturnedText(hubot, message, conversation, text, callback); + }); + return true; + } + + return false; +} + +function speakReturnedText(hubot, message, conversation, text, callback) { + if (text) { + hubot.speak(message, text).then(() => { + callback(conversation); + }); + } else { + callback(conversation); + } +} + +function withExpectedResponse(conversation, interaction, response, hubot, message, callback) { + if (!getExpectedResponse(interaction.expectedResponses, response)) { + hubot.speak(message, invalidResponseMessage(hubot, getExpectedResponses(interaction))).then(() => { + callback(conversation); + }); + return true; + } + + return false; +} + +function hasAnotherInteraction(conversation, interaction, response, hubot, message) { + const expectedResponse = getExpectedResponse(interaction.expectedResponses, response); + + if (expectedResponse.iteration) { + const newConversation = { + user: message.user, + interactions: [expectedResponse.iteration], + gear: conversation.gear, + nextInteration: 0, + previousConversation: conversation + }; + + start(hubot, newConversation, message); + return true; + } + + return false; +} + +function handleResponse(conversation, interaction, response) { + if (interaction.handler) { + const handler = require(`${nodeModules}gear-${conversation.gear}/${interaction.handler}`); + return handler.handle(response.text); + } + + return null; +} + +function getExpectedResponse(expectedResponses, response) { + if (expectedResponses) { + return expectedResponses.find(r => r.response === response.text); + } + + return null; +} + +function getExpectedResponses(interaction) { + const expectedResponses = []; + + interaction.expectedResponses.forEach(e => expectedResponses.push(e.response)); + + return expectedResponses; +} + +function invalidResponseMessage(hubot, expectedResponses) { + return hubot.speech().append('Sorry, I didn\'t understand.(Expected responses: ') + .bold(expectedResponses.join(', ')).append(').').end(); +} + +function hasActiveConversation(message) { + return getActiveConversation(message) != null; +} + +function notify(message) { + myEmitter.emit(message.user, message); +} + +function getActiveConversation(message) { + return activeConversations.find(c => c.user === message.user); +} + +function endConversations(conversation) { + activeConversations = activeConversations.filter(c => c.user !== conversation.user); +} diff --git a/src/message-handler/handlers/conversation-handler.js b/src/message-handler/handlers/conversation-handler.js index 8358f5d..6325454 100644 --- a/src/message-handler/handlers/conversation-handler.js +++ b/src/message-handler/handlers/conversation-handler.js @@ -1,14 +1,14 @@ -'use strict'; - -const conversation = require(__base + 'src/message-handler/conversation'); - -exports.handle = handle; - -function handle(hubot, message) { - if (conversation.hasActiveConversation(message)) { - conversation.notify(message); - return true; - } - - return false; -} +'use strict'; + +const conversation = require('../conversation'); + +exports.handle = handle; + +function handle(hubot, message) { + if (conversation.hasActiveConversation(message)) { + conversation.notify(message); + return true; + } + + return false; +} diff --git a/src/message-handler/handlers/first-run-handler.js b/src/message-handler/handlers/first-run-handler.js index deb870b..aaf6021 100644 --- a/src/message-handler/handlers/first-run-handler.js +++ b/src/message-handler/handlers/first-run-handler.js @@ -1,11 +1,11 @@ -'use strict'; - -exports.handle = handle; - -function handle(hubot, message, core) { - if (core.isFirstRun) { - return true; - } - - return false; -} +'use strict'; + +exports.handle = handle; + +function handle(hubot, message, core) { + if (core.isFirstRun) { + return true; + } + + return false; +} diff --git a/src/message-handler/handlers/gear-configure-handler.js b/src/message-handler/handlers/gear-configure-handler.js index 338932c..ec7977d 100644 --- a/src/message-handler/handlers/gear-configure-handler.js +++ b/src/message-handler/handlers/gear-configure-handler.js @@ -1,37 +1,33 @@ -'use strict'; - -const conversation = require(__base + 'src/message-handler/conversation'); - -exports.handle = handle; - -function handle(hubot, message) { - if (isGearConfigureMessage(hubot, message)) { - let param = { - user: message.user, - gear: gearDescription(message), - interactions: discoverConfig(hubot, message) - } - - conversation.startConversation(hubot, param, message); - } -} - -function isGearConfigureMessage(hubot, message) { - return hubot.gears.find(function(gear) { - const configureMessage = 'configure ' + gear.description; - - return message.text === configureMessage; - }) != null; -} - -function discoverConfig(hubot, message) { - return hubot.gears.find(g => g.description === gearDescription(message)).configs; -} - -function getConfigHandler(hubot, message) { - return hubot.gears.find(g => g.description === gearDescription(message)).configHandler; -} - -function gearDescription(message) { - return message.text.replace("configure ", ""); -} +'use strict'; + +const conversation = require('../conversation'); + +exports.handle = handle; + +function handle(hubot, message) { + if (isGearConfigureMessage(hubot, message)) { + const param = { + user: message.user, + gear: gearDescription(message), + interactions: discoverConfig(hubot, message) + }; + + conversation.startConversation(hubot, param, message); + } +} + +function isGearConfigureMessage(hubot, message) { + return hubot.gears.find((gear) => { + const configureMessage = `configure ${gear.description}`; + + return message.text === configureMessage; + }) != null; +} + +function discoverConfig(hubot, message) { + return hubot.gears.find(g => g.description === gearDescription(message)).configs; +} + +function gearDescription(message) { + return message.text.replace('configure ', ''); +} diff --git a/src/message-handler/handlers/gear-status-handler.js b/src/message-handler/handlers/gear-status-handler.js index a3f980d..d4e7e20 100644 --- a/src/message-handler/handlers/gear-status-handler.js +++ b/src/message-handler/handlers/gear-status-handler.js @@ -1,75 +1,71 @@ -'use strict'; - -exports.handle = handle; - -const speech = require(__base + 'src/speech'); -const db = require(__base + 'src/lib/db'); - -function handle(hubot, message, core) { - const action = getAction(message); - - if (action && isGearChangeStatusMessage(action, hubot, message)) { - core.isAdminUser(message.user).then(changeStatus); - } else { - return false; - } - - function changeStatus(isAdmin) { - if (isAdmin) { - const gear = discoverGear(action, hubot, message); - - if (gear && gear.active === action.status) { - hubot.speak(message, 'This gear is already ' + action.statusDescription + '.'); - } else { - changeGearStatus(action, hubot, gear.description).then(function() { - hubot.speak(message, sucessMessage(action, gear.description)); - }, function() { - hubot.speak(message, errorMessage(action, gear.description)); - }); - } - - return true; - } - } -} - -function changeGearStatus(action, hubot, gear) { - hubot.findGear(gear).active = action.status; - - return db.getDb().run('UPDATE gears SET active = ? WHERE description = ?', action.status, gear); -} - -function isGearChangeStatusMessage(action, hubot, message) { - return hubot.gears.find(function(gear) { - const configureMessage = action.description + ' ' + gear.description; - - return message.text === configureMessage; - }) != null; -} - -function discoverGear(action, hubot, message) { - const gearDescription = message.text.replace(action.description + ' ', ''); - return hubot.findGear(gearDescription); -} - -function sucessMessage(action, gearDescription) { - return speech.start('Successfully ' + action.description + 'd ').bold('gear ' + gearDescription).end(); -} - -function errorMessage(gearDescription) { - return speech.start('Could not' + action.description + " ").bold('gear ' + gearDescription).period().append('See the detailed error in logs').end() -} - -function getAction(message) { - if (message.text.startsWith('activate')) { - return { - description: 'activate', status: true, statusDescription: 'active' - }; - } else if (message.text.startsWith('deactivate')) { - return { - description: 'deactivate', status: false, statusDescription: 'inactive' - }; - } - - return null; -} +'use strict'; + +const db = require('../../lib/db'); +const speech = require('../../speech'); + +exports.handle = handle; + +function handle(hubot, message, core) { + const action = getAction(message); + + if (action && isGearChangeStatusMessage(action, hubot, message)) { + core.isAdminUser(message.user) + .then(isAdmin => changeStatus(isAdmin, action, hubot, message)); + + return true; + } + + return false; +} + +function changeStatus(isAdmin, action, hubot, message) { + if (isAdmin) { + const gear = discoverGear(action, hubot, message); + + if (gear && gear.active === action.status) { + hubot.speak(message, `This gear is already ${action.statusDescription}.`); + } else { + changeGearStatus(action, hubot, gear.description) + .then(() => hubot.speak(message, sucessMessage(action, gear.description)), + () => hubot.speak(message, errorMessage(action, gear.description))); + } + } +} + +function changeGearStatus(action, hubot, gear) { + hubot.findGear(gear).active = action.status; + + return db.getDb().run('UPDATE gears SET active = ? WHERE description = ?', action.status, gear); +} + +function isGearChangeStatusMessage(action, hubot, message) { + return hubot.gears.find(gear => message.text === `${action.description} ${gear.description}`) !== null; +} + +function discoverGear(action, hubot, message) { + const gearDescription = message.text.replace(`${action.description} `, ''); + return hubot.findGear(gearDescription); +} + +function sucessMessage(action, gearDescription) { + return speech.start(`Successfully ${action.description}d `).bold(`gear ${gearDescription}`).end(); +} + +function errorMessage(action, gearDescription) { + return speech.start(`Could not ${action.description} `).bold(`gear ${gearDescription}`).period() + .append('See the detailed error in logs').end(); +} + +function getAction(message) { + if (message.text.startsWith('activate')) { + return { + description: 'activate', status: true, statusDescription: 'active' + }; + } else if (message.text.startsWith('deactivate')) { + return { + description: 'deactivate', status: false, statusDescription: 'inactive' + }; + } + + return null; +} diff --git a/src/message-handler/handlers/gears-tasks-handler.js b/src/message-handler/handlers/gears-tasks-handler.js index 2546b47..c13dbce 100644 --- a/src/message-handler/handlers/gears-tasks-handler.js +++ b/src/message-handler/handlers/gears-tasks-handler.js @@ -1,59 +1,67 @@ -'use strict'; - -const Hubot = require(__base + 'src/hubot'); -const trigger = require(__base + 'src/message-handler/trigger'); - -exports.handle = handle; - -function handle(hubot, message, core) { - hubot.gears.forEach(function(gear) { - gear.tasks.forEach(function(task) { - - const acceptance = trigger.check(message.text, task.trigger); - - if (acceptance.ok) { - if (gear.active) { - if (incorretMessageSource(hubot, task, message)) { - return true; - } - - const hubotClone = getHubotClone(core); - const handler = getHandler(gear, task); - handler.handle(hubotClone, message, task, acceptance.params); - } else { - hubot.speak(message, "Sorry, this feature is disabled."); - } - - return true; - } - - }); - }); - - return false; -} - -function incorretMessageSource(hubot, task, message) { - if (task.onlyInChannel && !hubot.isFromChannel(message)) { - hubot.speak(message, "Sorry, this feature can only be performed on a channel."); - return true; - } - - if (task.onlyInPrivate && !hubot.isFromPrivate(message)) { - hubot.speak(message, "Sorry, this feature can only be performed directly with me in private."); - return true; - } - - return false; -} - -function getHubotClone(core) { - const hubotClone = new Hubot(core); - hubotClone.gears = JSON.parse(JSON.stringify(core.hubot.gears)); - - return hubotClone; -} - -function getHandler(gear, task) { - return gear.handlers.find(h => h.key === task.handler); -} +'use strict'; + +const Hubot = require('../../hubot'); +const trigger = require('../trigger'); + +exports.handle = handle; + +function handle(hubot, message, core) { + hubot.gears.forEach((gear) => { + gear.tasks.forEach((task) => { // eslint-disable-line consistent-return + const taskExecuted = tryExecuteTask(hubot, core, gear, message, task); + + if (taskExecuted) { + return true; + } + }); + }); + + return false; +} + +function tryExecuteTask(hubot, core, gear, message, task) { + const acceptance = trigger.check(message.text, task.trigger); + + if (acceptance.ok) { + if (gear.active) { + if (incorretMessageSource(hubot, task, message)) { + return true; + } + + const hubotClone = getHubotClone(core); + const handler = getHandler(gear, task); + handler.handle(hubotClone, message, task, acceptance.params); + } else { + hubot.speak(message, 'Sorry, this feature is disabled.'); + } + + return true; + } + + return false; +} + +function incorretMessageSource(hubot, task, message) { + if (task.onlyInChannel && !hubot.isFromChannel(message)) { + hubot.speak(message, 'Sorry, this feature can only be performed on a channel.'); + return true; + } + + if (task.onlyInPrivate && !hubot.isFromPrivate(message)) { + hubot.speak(message, 'Sorry, this feature can only be performed directly with me in private.'); + return true; + } + + return false; +} + +function getHubotClone(core) { + const hubotClone = new Hubot(core); + hubotClone.gears = JSON.parse(JSON.stringify(core.hubot.gears)); + + return hubotClone; +} + +function getHandler(gear, task) { + return gear.handlers.find(h => h.key === task.handler); +} diff --git a/src/message-handler/message-handler.js b/src/message-handler/message-handler.js index 673a5d1..55648bc 100644 --- a/src/message-handler/message-handler.js +++ b/src/message-handler/message-handler.js @@ -1,27 +1,31 @@ -'use strict'; - -exports.callTasks = callTasks; - -function callTasks(message, core) { - const handlers = getHandlers(); - - for (let i = 0; i < handlers.length; i++) { - const handler = require(__base + 'src/message-handler/handlers/' + handlers[i]); - - const isHandled = handler.handle(core.hubot, message, core); - - if (isHandled) { - break; - } - }; -} - -function getHandlers() { - return [ - 'first-run-handler', - 'conversation-handler', - 'gear-status-handler', - 'gear-configure-handler', - 'gears-tasks-handler' - ]; -} +'use strict'; + +const firstRun = require('./handlers/first-run-handler'); +const gearStatus = require('./handlers/gear-status-handler'); +const gearsTasks = require('./handlers/gears-tasks-handler'); +const conversation = require('./handlers/conversation-handler'); +const gearConfigure = require('./handlers/gear-configure-handler'); + +exports.callTasks = callTasks; + +function callTasks(message, core) { + const handlers = getHandlers(); + + for (let i = 0; i < handlers.length; i++) { + const isHandled = handlers[i].handle(core.hubot, message, core); + + if (isHandled) { + break; + } + } +} + +function getHandlers() { + return [ + firstRun, + conversation, + gearStatus, + gearConfigure, + gearsTasks + ]; +} diff --git a/src/message-handler/trigger.js b/src/message-handler/trigger.js index 6864712..b5c6bef 100644 --- a/src/message-handler/trigger.js +++ b/src/message-handler/trigger.js @@ -1,73 +1,75 @@ -'use strict'; - -const stringfy = require('string'); - -exports.check = check; - -function check(message, trigger) { - return new Trigger('$').with(normalize(trigger)).accept(normalize(message)); -} - -class Trigger { - constructor(placeholder) { - this.placeholder = placeholder; - } - - with(trigger) { - this.trigger = trigger; - this.params = new TriggerParams(this.trigger, this.placeholder); - return this; - } - - accept(message) { - if (this.params.has()) { - return this.acceptWithParams(message); - } - - return this.acceptWithoutParams(message); - } - - acceptWithParams(message) { - var count = this.params.count(); - var params = this.params.capture(message); - var matches = params.length === count; - return { ok: matches, params: matches ? params : [] } - } - - acceptWithoutParams(message) { - return { ok: this.trigger === message, params: [] }; - } -} - -class TriggerParams { - constructor(trigger, placeholder) { - this.trigger = trigger; - this.placeholder = placeholder; - } - - has() { - return this.trigger.includes(this.placeholder) && !this.trigger.startsWith(this.placeholder); - } - - count() { - return this.trigger.match(new RegExp('\\' + this.placeholder, 'g')).length; - } - - capture(message) { - // trigger: 'get $ to $' > ['get ', ' to '] - var triggerParts = this.trigger.split(this.placeholder).filter(s => s); - - // message must includes all trigger parts - if (triggerParts.find(t => !message.includes(t))) return []; - - // message: 'get alpha to beta' > 'alpha$beta' - triggerParts.forEach(trigger => message = message.replace(trigger, this.placeholder)); - - // message: 'alpha$beta' > ['alpha', 'beta'] - return message.split(this.placeholder).filter(s => s); - } -} - -function normalize(text) { - return stringfy(text).trim().latinise().s.toLowerCase(); -} +'use strict'; + +const stringfy = require('string'); + +exports.check = check; + +function check(message, trigger) { + return new Trigger('$').with(normalize(trigger)).accept(normalize(message)); +} + +class Trigger { + constructor(placeholder) { + this.placeholder = placeholder; + } + + with(trigger) { + this.trigger = trigger; + this.params = new TriggerParams(this.trigger, this.placeholder); + return this; + } + + accept(message) { + if (this.params.has()) { + return this.acceptWithParams(message); + } + + return this.acceptWithoutParams(message); + } + + acceptWithParams(message) { + const count = this.params.count(); + const params = this.params.capture(message); + const matches = params.length === count; + return { ok: matches, params: matches ? params : [] }; + } + + acceptWithoutParams(message) { + return { ok: this.trigger === message, params: [] }; + } +} + +class TriggerParams { + constructor(trigger, placeholder) { + this.trigger = trigger; + this.placeholder = placeholder; + } + + has() { + return this.trigger.includes(this.placeholder) && !this.trigger.startsWith(this.placeholder); + } + + count() { + return this.trigger.match(new RegExp(`\\${this.placeholder}`, 'g')).length; + } + + capture(message) { + let newMessage = message; + + // trigger: 'get $ to $' > ['get ', ' to '] + const triggerParts = this.trigger.split(this.placeholder).filter(s => s); + + // message must includes all trigger parts + if (triggerParts.find(t => !newMessage.includes(t))) return []; + + // message: 'get alpha to beta' > 'alpha$beta' + triggerParts.forEach(trigger => (newMessage = newMessage.replace(trigger, this.placeholder))); + + // message: 'alpha$beta' > ['alpha', 'beta'] + return newMessage.split(this.placeholder).filter(s => s); + } +} + +function normalize(text) { + return stringfy(text).trim().latinise().s.toLowerCase(); +} diff --git a/src/speech.js b/src/speech.js index 1c2462a..bce30be 100644 --- a/src/speech.js +++ b/src/speech.js @@ -1,117 +1,120 @@ -'use strict'; - -exports.start = start; -exports.error = error; - -function start(text) { - return new Speecher().start(text); -} - -function error(text) { - return new Speecher().error(text); -} - -const Speecher = function () { - this.message = null; -} - -Speecher.prototype.start = Speecher.prototype.restart = function(text) { - this.message = ''; - this.append(optionalText(text)); - return this; -}; - -Speecher.prototype.append = function(text) { - if (this.initialized()) this.message += text; - return this; -}; - -Speecher.prototype.hello = function(user) { - this.append(`Hello,`).user(user).append(`! `); - return this; -}; - -Speecher.prototype.thanks = function(user) { - this.append(`Thanks,`).user(user).append(`!! `); - return this; -}; - -Speecher.prototype.user = function(user) { - this.append(` <@${user.id}|${user.name}> `); - return this; -}; - -Speecher.prototype.channel = function() { - this.append(` `); - return this; -}; - -Speecher.prototype.bold = function(text) { - this.append(`*${text}*`); - return this; -}; - -Speecher.prototype.italic = function(text) { - this.append(`_${text}_`); - return this; -}; - -Speecher.prototype.error = function(text) { - this.isError = true; - this.start().append(':exclamation: _').append(`Ops! ${optionalText(text)}`); - return this; -}; - -Speecher.prototype.refer = function(text) { - this.append(`'${text}'`); - return this; -}; - -Speecher.prototype.progress = function(current, max) { - this.append(` [${current} of ${max}] `); - return this; -}; - -Speecher.prototype.item = function(text) { - this.append(`• ${optionalText(text)}`); - return this; -}; - -Speecher.prototype.period = function(text) { - this.append(`. ${optionalText(text)}`); - return this; -}; - -Speecher.prototype.line = function(text) { - this.append(`\n${optionalText(text)}`); - return this; -}; - -Speecher.prototype.paragraph = function(text) { - this.append(`\n\n${optionalText(text)}`); - return this; -}; - -Speecher.prototype.separator = function(text) { - this.append(` - ${optionalText(text)}`); - return this; -}; - -Speecher.prototype.replace = function(key, text) { - this.message = this.message.replace('${' + key + '}', optionalText(text)); - return this; -}; - -Speecher.prototype.end = function() { - if (this.isError) this.append('_'); - return this.message; -}; - -Speecher.prototype.initialized = function() { - if (this.message === null) throw new Speecher().start('Speecher uninitialized').period().append('Always start with ').bold('speecher.start()').append(' or ').bold('speecher.error()').end(); - return true; -}; - -function optionalText(text) { - return text || ''; -} +'use strict'; + +exports.start = start; +exports.error = error; + +const Speecher = function Speecher() { + this.message = null; +}; + +function start(text) { + return new Speecher().init(text); +} + +function error(text) { + return new Speecher().errorOccurs(text); +} + +Speecher.prototype.init = function init(text) { + this.message = ''; + this.append(optionalText(text)); + return this; +}; + +Speecher.prototype.append = function append(text) { + if (this.initialized()) this.message += text; + return this; +}; + +Speecher.prototype.hello = function hello(user) { + this.append('Hello,').user(user).append('! '); + return this; +}; + +Speecher.prototype.thanks = function thanks(user) { + this.append('Thanks,').user(user).append('!! '); + return this; +}; + +Speecher.prototype.user = function user(theUser) { + this.append(` <@${theUser.id}|${theUser.name}> `); + return this; +}; + +Speecher.prototype.channel = function channel() { + this.append(' '); + return this; +}; + +Speecher.prototype.bold = function bold(text) { + this.append(`*${text}*`); + return this; +}; + +Speecher.prototype.italic = function italic(text) { + this.append(`_${text}_`); + return this; +}; + +Speecher.prototype.errorOccurs = function errorOccurs(text) { + this.isError = true; + this.init().append(':exclamation: _').append(`Ops! ${optionalText(text)}`); + return this; +}; + +Speecher.prototype.refer = function refer(text) { + this.append(`'${text}'`); + return this; +}; + +Speecher.prototype.progress = function progress(current, max) { + this.append(` [${current} of ${max}] `); + return this; +}; + +Speecher.prototype.item = function item(text) { + this.append(`• ${optionalText(text)}`); + return this; +}; + +Speecher.prototype.period = function period(text) { + this.append(`. ${optionalText(text)}`); + return this; +}; + +Speecher.prototype.line = function line(text) { + this.append(`\n${optionalText(text)}`); + return this; +}; + +Speecher.prototype.paragraph = function paragraph(text) { + this.append(`\n\n${optionalText(text)}`); + return this; +}; + +Speecher.prototype.separator = function separator(text) { + this.append(` - ${optionalText(text)}`); + return this; +}; + +Speecher.prototype.replace = function replace(key, text) { + this.message = this.message.replace(`\${${key}}`, optionalText(text)); + return this; +}; + +Speecher.prototype.end = function end() { + if (this.isError) this.append('_'); + return this.message; +}; + +Speecher.prototype.initialized = function initialized() { + if (this.message === null) { + throw new Speecher().init('Speecher uninitialized').period().append('Always start with ') + .bold('speecher.start()').append(' or ').bold('speecher.error()').end(); + } + return true; +}; + +function optionalText(text) { + return text || ''; +} diff --git a/test/lib/assembler.js b/test/lib/assembler.js index a217b35..9a40979 100644 --- a/test/lib/assembler.js +++ b/test/lib/assembler.js @@ -1,135 +1,131 @@ -'use strict'; - -const expect = require('chai').expect; -const setup = require('../setup').start(); -const Assembler = require('../../src/assembler'); - -describe('The Hubot Assembler', function() { - - describe('should provide correct path', function() { - - it('for tasks', function() { - const gear = { name: 'test' }; - - const path = getAssembler().tasksPath(gear); - - expect(path).to.equal(__nodeModules + 'test/config/tasks.json'); - }); - - it('for categories', function() { - const gear = { name: 'test' }; - - const path = getAssembler().categoriesPath(gear); - - expect(path).to.equal(__nodeModules + 'test/config/categories.json'); - }); - - it('for handlers', function() { - const gear = { name: 'test' }; - - const path = getAssembler().handlersPath(gear, 'test-handler'); - - expect(path).to.equal(__nodeModules + 'test/src/handlers/test-handler'); - }); - - }); - - describe('should load', function() { - - it('task file', function() { - const assembler = getAssembler(); - const gear = { name: 'gear-test' }; - - assembler.loadTasks(gear, assembler); - - expect(gear.tasks).to.be.deep.equal([{ - "handler": "test-handler", - "trigger": "test-trigger" - }]); - }); - - it('category file', function() { - const assembler = getAssembler(); - const gear = { name: 'gear-test' }; - - assembler.loadCategories(gear, assembler); - - expect(gear.categories).to.be.deep.equal([{ - "key": "test", - "name": "test", - "description": "some test", - "visible": false - }]); - }); - - it('handler file based on tasks handlers', function() { - const assembler = getAssembler(); - const gear = { name: 'gear-test' }; - - assembler.loadTasks(gear, assembler); - assembler.loadHandlers(gear, assembler); - - expect(gear.handlers).to.have.lengthOf(1); - expect(gear.handlers[0].handle().key).to.be.equal('test-handle'); - }); - - it('and should not load when handler file if there is not tasks', function() { - const assembler = getAssembler(); - const gear = { name: 'gear-test', tasks: [] }; - - assembler.loadHandlers(gear, assembler); - - expect(gear.handlers).to.be.deep.equal([]); - }); - - }); - - describe('should load gears', function() { - - it('when is a valid gear', function() { - const assembler = getAssembler(); - const gear = { name: 'gear-test' }; - - assembler.loadGear([gear], gear, 0); - - expect(gear.tasks).to.be.deep.equal([{ - "handler": "test-handler", - "trigger": "test-trigger" - }]); - - expect(gear.categories).to.be.deep.equal([{ - "key": "test", - "name": "test", - "description": "some test", - "visible": false - }]); - - expect(gear.handlers).to.have.lengthOf(1); - expect(gear.handlers[0]).have.property('key').and.equal('test-handler'); - }); - - it('and should not throw error when invalid parameters are informed', function() { - const assembler = getAssembler(); - - assembler.loadGear(null, null, null); - - expect(assembler.gears).to.be.deep.equal([]); - }); - - it('neigther should throw error loading when informed an invalid gear', function() { - const assembler = getAssembler(); - const gear = { name: 'invalid' }; - - assembler.loadGear([gear], gear, 0); - - expect(assembler.gears).to.be.deep.equal([]); - }); - - - }); - -}); - -function getAssembler() { - return new Assembler(); -} +'use strict'; + +const expect = require('chai').expect; + +const setup = require('../setup'); +const Assembler = require('../../src/assembler'); + +describe('The Hubot Assembler', () => { + before(() => { + setup.start(); + }); + + describe('should provide correct path', () => { + it('for tasks', () => { + const gear = { name: 'test' }; + + const tasksPath = getAssembler().tasksPath(gear); + + expect(tasksPath).to.equal(`${global.__nodeModules}test/config/tasks.json`); + }); + + it('for categories', () => { + const gear = { name: 'test' }; + + const categoriesPath = getAssembler().categoriesPath(gear); + + expect(categoriesPath).to.equal(`${global.__nodeModules}test/config/categories.json`); + }); + + it('for handlers', () => { + const gear = { name: 'test' }; + + const handlersPath = getAssembler().handlersPath(gear, 'test-handler'); + + expect(handlersPath).to.equal(`${global.__nodeModules}test/src/handlers/test-handler`); + }); + }); + + describe('should load', () => { + it('task file', () => { + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; + + assembler.loadTasks(gear, assembler); + + expect(gear.tasks).to.be.deep.equal([{ + handler: 'test-handler', + trigger: 'test-trigger' + }]); + }); + + it('category file', () => { + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; + + assembler.loadCategories(gear, assembler); + + expect(gear.categories).to.be.deep.equal([{ + key: 'test', + name: 'test', + description: 'some test', + visible: false + }]); + }); + + it('handler file based on tasks handlers', () => { + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; + + assembler.loadTasks(gear, assembler); + assembler.loadHandlers(gear, assembler); + + expect(gear.handlers).to.have.lengthOf(1); + expect(gear.handlers[0].handle().key).to.be.equal('test-handle'); + }); + + it('and should not load when handler file if there is not tasks', () => { + const assembler = getAssembler(); + const gear = { name: 'gear-test', tasks: [] }; + + assembler.loadHandlers(gear, assembler); + + expect(gear.handlers).to.be.deep.equal([]); + }); + }); + + describe('should load gears', () => { + it('when is a valid gear', () => { + const assembler = getAssembler(); + const gear = { name: 'gear-test' }; + + assembler.loadGear([gear], gear, 0); + + expect(gear.tasks).to.be.deep.equal([{ + handler: 'test-handler', + trigger: 'test-trigger' + }]); + + expect(gear.categories).to.be.deep.equal([{ + key: 'test', + name: 'test', + description: 'some test', + visible: false + }]); + + expect(gear.handlers).to.have.lengthOf(1); + expect(gear.handlers[0]).have.property('key').and.equal('test-handler'); + }); + + it('and should not throw error when invalid parameters are informed', () => { + const assembler = getAssembler(); + + assembler.loadGear(null, null, null); + + expect(assembler.gears).to.be.deep.equal([]); + }); + + it('neigther should throw error loading when informed an invalid gear', () => { + const assembler = getAssembler(); + const gear = { name: 'invalid' }; + + assembler.loadGear([gear], gear, 0); + + expect(assembler.gears).to.be.deep.equal([]); + }); + }); +}); + +function getAssembler() { + return new Assembler(); +} diff --git a/test/lib/trigger.js b/test/lib/trigger.js index b79fce0..4b36e45 100644 --- a/test/lib/trigger.js +++ b/test/lib/trigger.js @@ -1,108 +1,108 @@ -'use strict'; - -const expect = require('chai').expect; -const trigger = require('../../src/message-handler/trigger'); - -describe('Task Trigger', function() { - describe('Task Trigger without parameters', function() { - it('should not match wrong message', function() { - const phrase = 'test'; - const message = 'anything else'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should matches exactly message', function() { - const phrase = 'test'; - const message = 'test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: [] } - ); - }); - - it('should matches message ignoring casing', function() { - const phrase = 'test'; - const message = 'TEST'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: [] } - ); - }); - - it('should ignore placeholder at beginning', function() { - const phrase = '$test'; - const message = 'test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should consider placeholder at beginning like a simple character', function() { - const phrase = '$test'; - const message = '$test'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: []} - ); - }); - }); - - describe('Task Trigger with one parameter', function() { - it('should not match wrong message', function() { - const phrase = 'test $ deeply'; - const message = 'please test anything else deeply'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should get one parameter by placeholder at end', function() { - const phrase = 'test $'; - const message = 'test anything'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['anything']} - ); - }); - - it('should get one parameter by placeholder at middle', function() { - const phrase = 'test $ deeply'; - const message = 'test anything else deeply'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['anything else']} - ); - }); - }) - - describe('Task Trigger with multiple parameters', function() { - it('should not match wrong message', function() { - const phrase = 'come on $, light $!'; - const message = 'so come on baby, light my fire!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - - it('should get multiple parameters', function() { - const phrase = 'come on $, light $!'; - const message = 'come on baby, light my fire!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['baby', 'my fire']} - ); - }); - - it('should get multiple parameters ignoring casing', function() { - const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - const message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: true, params: ['me', 'paradise city', 'grass', 'green', 'girls', 'pretty']} - ); - }); - - it('should not match typo', function() { - const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; - const message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; - expect(trigger.check(message, phrase)).to.deep.equal( - { ok: false, params: []} - ); - }); - }); -}); +'use strict'; + +const expect = require('chai').expect; +const trigger = require('../../src/message-handler/trigger'); + +describe('Task Trigger', () => { + describe('Task Trigger without parameters', () => { + it('should not match wrong message', () => { + const phrase = 'test'; + const message = 'anything else'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: [] } + ); + }); + + it('should matches exactly message', () => { + const phrase = 'test'; + const message = 'test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: [] } + ); + }); + + it('should matches message ignoring casing', () => { + const phrase = 'test'; + const message = 'TEST'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: [] } + ); + }); + + it('should ignore placeholder at beginning', () => { + const phrase = '$test'; + const message = 'test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: [] } + ); + }); + + it('should consider placeholder at beginning like a simple character', () => { + const phrase = '$test'; + const message = '$test'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: [] } + ); + }); + }); + + describe('Task Trigger with one parameter', () => { + it('should not match wrong message', () => { + const phrase = 'test $ deeply'; + const message = 'please test anything else deeply'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: [] } + ); + }); + + it('should get one parameter by placeholder at end', () => { + const phrase = 'test $'; + const message = 'test anything'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['anything'] } + ); + }); + + it('should get one parameter by placeholder at middle', () => { + const phrase = 'test $ deeply'; + const message = 'test anything else deeply'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['anything else'] } + ); + }); + }); + + describe('Task Trigger with multiple parameters', () => { + it('should not match wrong message', () => { + const phrase = 'come on $, light $!'; + const message = 'so come on baby, light my fire!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: [] } + ); + }); + + it('should get multiple parameters', () => { + const phrase = 'come on $, light $!'; + const message = 'come on baby, light my fire!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['baby', 'my fire'] } + ); + }); + + it('should get multiple parameters ignoring casing', () => { + const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + const message = 'Take me down to the Paradise City Where the grass is green and the girls are pretty!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: true, params: ['me', 'paradise city', 'grass', 'green', 'girls', 'pretty'] } + ); + }); + + it('should not match typo', () => { + const phrase = 'take $ down to the $ where the $ is $ and the $ are $!'; + const message = 'Take me donw to the Paradise City Where the grass is green and the girls are pretty!'; + expect(trigger.check(message, phrase)).to.deep.equal( + { ok: false, params: [] } + ); + }); + }); +}); diff --git a/test/resource/gears/gear-test/config/categories.json b/test/resource/gears/gear-test/config/categories.json index a62cde5..1c14bfd 100644 --- a/test/resource/gears/gear-test/config/categories.json +++ b/test/resource/gears/gear-test/config/categories.json @@ -1,8 +1,8 @@ [ - { - "key": "test", - "name": "test", - "description": "some test", - "visible": false - } + { + "key": "test", + "name": "test", + "description": "some test", + "visible": false + } ] diff --git a/test/resource/gears/gear-test/config/tasks.json b/test/resource/gears/gear-test/config/tasks.json index 550e6d4..82ecc75 100644 --- a/test/resource/gears/gear-test/config/tasks.json +++ b/test/resource/gears/gear-test/config/tasks.json @@ -1,6 +1,6 @@ [ - { - "handler": "test-handler", - "trigger": "test-trigger" - } -] \ No newline at end of file + { + "handler": "test-handler", + "trigger": "test-trigger" + } +] diff --git a/test/resource/gears/gear-test/handlers/test-handler.js b/test/resource/gears/gear-test/handlers/test-handler.js index c11717b..32116e3 100644 --- a/test/resource/gears/gear-test/handlers/test-handler.js +++ b/test/resource/gears/gear-test/handlers/test-handler.js @@ -1,7 +1,7 @@ -'use strict'; - -exports.process = process; - -function process() { - return { key: 'test-process'}; -} \ No newline at end of file +'use strict'; + +exports.process = process; + +function process() { + return { key: 'test-process' }; +} diff --git a/test/resource/node_modules_test/gear-test/config/categories.json b/test/resource/node_modules_test/gear-test/config/categories.json index a62cde5..1c14bfd 100644 --- a/test/resource/node_modules_test/gear-test/config/categories.json +++ b/test/resource/node_modules_test/gear-test/config/categories.json @@ -1,8 +1,8 @@ [ - { - "key": "test", - "name": "test", - "description": "some test", - "visible": false - } + { + "key": "test", + "name": "test", + "description": "some test", + "visible": false + } ] diff --git a/test/resource/node_modules_test/gear-test/config/tasks.json b/test/resource/node_modules_test/gear-test/config/tasks.json index 550e6d4..82ecc75 100644 --- a/test/resource/node_modules_test/gear-test/config/tasks.json +++ b/test/resource/node_modules_test/gear-test/config/tasks.json @@ -1,6 +1,6 @@ [ - { - "handler": "test-handler", - "trigger": "test-trigger" - } -] \ No newline at end of file + { + "handler": "test-handler", + "trigger": "test-trigger" + } +] diff --git a/test/resource/node_modules_test/gear-test/src/handlers/test-handler.js b/test/resource/node_modules_test/gear-test/src/handlers/test-handler.js index 5f99825..939636b 100644 --- a/test/resource/node_modules_test/gear-test/src/handlers/test-handler.js +++ b/test/resource/node_modules_test/gear-test/src/handlers/test-handler.js @@ -1,7 +1,7 @@ -'use strict'; - -exports.handle = handle; - -function handle() { - return { key: 'test-handle'}; -} +'use strict'; + +exports.handle = handle; + +function handle() { + return { key: 'test-handle' }; +} diff --git a/test/setup.js b/test/setup.js index e10a4c3..bd80ca6 100644 --- a/test/setup.js +++ b/test/setup.js @@ -1,8 +1,9 @@ -'use strict'; - -exports.start = start; - -function start() { - global.__base = __dirname.replace('test', ''); - global.__nodeModules = __dirname + '/resource/node_modules_test/'; -} +'use strict'; + +const path = require('path'); + +exports.start = start; + +function start() { + global.__nodeModules = path.join(__dirname, '/resource/node_modules_test/'); +} From c628e34a1139e34ac670c8a09ff385209e9cadfe Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sat, 22 Oct 2016 15:42:47 -0200 Subject: [PATCH 10/26] Change eslint config to eslint-config-hubot-js --- .eslintrc.json | 29 +---------------------------- package.json | 5 +---- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d133e4b..78c04aa 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,30 +1,3 @@ -//Extends from airbnb configs: https://github.com/airbnb/javascript { - "extends": "airbnb", - "env": { - "es6": true, - "node": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "script" - }, - "rules": { - "class-methods-use-this": 0, - "comma-dangle": ["error", "never"], - "global-require": 0, - "import/no-dynamic-require": 0, - "import/no-extraneous-dependencies": 0, - "max-len": ["error", { "code": 120 }], - "new-cap": 0, - "newline-per-chained-call": 0, - "no-param-reassign": 0, - "no-plusplus": 0, - "no-underscore-dangle": 0, - "no-use-before-define": ["error", { "functions": false, "classes": false }], - "quotes": ["error", "single", { "avoidEscape": true }], - "space-before-function-paren": 0, - "strict": ["error", "global"] - } + "extends": "hubot-js" } diff --git a/package.json b/package.json index b49d484..d45abe3 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,7 @@ "chai": "^3.5.0", "coveralls": "^2.11.12", "eslint": "^3.8.0", - "eslint-config-airbnb": "^12.0.0", - "eslint-plugin-import": "^1.16.0", - "eslint-plugin-jsx-a11y": "^2.2.3", - "eslint-plugin-react": "^6.4.1", + "eslint-config-hubot-js": "^1.0.2", "istanbul": "^0.4.5", "mocha": "^3.0.2" } From b34a60650e7f477129ac6cca12cfd50a31439b43 Mon Sep 17 00:00:00 2001 From: Robson Date: Wed, 9 Nov 2016 19:35:32 -0200 Subject: [PATCH 11/26] Fix #32 Transforms the hubot into a CLI --- app.js | 18 --------- index.js | 5 +++ migrations/001-initial-schema.sql | 21 +++++----- package.json | 7 +++- src/cli/cli.js | 65 +++++++++++++++++++++++++++++++ src/cli/configure.js | 48 +++++++++++++++++++++++ src/cli/init-core.js | 47 ++++++++++++++++++++++ src/lib/db.js | 4 +- 8 files changed, 185 insertions(+), 30 deletions(-) delete mode 100644 app.js create mode 100755 index.js create mode 100644 src/cli/cli.js create mode 100644 src/cli/configure.js create mode 100644 src/cli/init-core.js diff --git a/app.js b/app.js deleted file mode 100644 index 761a727..0000000 --- a/app.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -const path = require('path'); - -const Core = require('./src/core'); -const db = require('./src/lib/db'); - -global.__nodeModules = path.join(__dirname, '/node_modules/'); - -const token = process.env.BOT_API_KEY; -const name = process.env.BOT_NAME || 'hubot'; - -db.startDb().then(() => { - const core = new Core({ token, name }); - - core.run(); -}); - diff --git a/index.js b/index.js new file mode 100755 index 0000000..0114c78 --- /dev/null +++ b/index.js @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +'use strict'; + +require('./src/cli/cli.js'); diff --git a/migrations/001-initial-schema.sql b/migrations/001-initial-schema.sql index 3daeea4..d5c5df0 100644 --- a/migrations/001-initial-schema.sql +++ b/migrations/001-initial-schema.sql @@ -1,9 +1,12 @@ --- Up -CREATE TABLE admins (admin TEXT NOT NULL); -CREATE TABLE first_use (first_use TEXT NOT NULL); -CREATE TABLE gears (name TEXT NOT NULL, description TEXT NOT NULL, active TEXT NOT NULL); - --- Down -DROP TABLE admins; -DROP TABLE first_use; -DROP TABLE gears; +-- Up +CREATE TABLE admins (admin TEXT NOT NULL); +CREATE TABLE first_use (first_use TEXT NOT NULL); +CREATE TABLE gears (name TEXT NOT NULL, description TEXT NOT NULL, active TEXT NOT NULL); +CREATE TABLE config (token TEXT, name TEXT); +INSERT INTO config values (null, null); + +-- Down +DROP TABLE admins; +DROP TABLE first_use; +DROP TABLE gears; +DROP TABLE config; diff --git a/package.json b/package.json index d45abe3..94d5f4f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "hubot.js", "version": "1.0.0", "description": "A small robot written in Javascript (He does not like coffeescript)", - "main": "app.js", + "main": "index.js", + "bin": { + "hubot": "index.js" + }, "scripts": { "test": "istanbul cover --include-all-sources _mocha -- --recursive --reporter spec", "coveralls": "cat ./coverage/lcov.info | coveralls", @@ -30,6 +33,8 @@ "winston": "^2.2.0", "q": "^1.4.1", "sqlite": "^2.2.0", + "pm2": "2.0.19", + "dialog": "0.2.0", "gear-help": "^1.0.1", "gear-jenkins": "^1.0.1" }, diff --git a/src/cli/cli.js b/src/cli/cli.js new file mode 100644 index 0000000..9a521ed --- /dev/null +++ b/src/cli/cli.js @@ -0,0 +1,65 @@ +'use strict'; + +const pm2 = require('pm2'); +const yargs = require('yargs'); + +const configure = require('./configure'); + +const START_COMMAND = 'start'; +const STOP_COMMAND = 'stop'; +const RESTART_COMMAND = 'restart'; +const CONFIGURE_COMMAND = 'configure'; + +const argv = yargs.usage(`Pluralsight Downloader \n +Usage: hubot [options]`) + .command(START_COMMAND, 'Start the hubot') + .command(STOP_COMMAND, 'Stop the hubot') + .command(RESTART_COMMAND, 'Restart the hubot') + .command(CONFIGURE_COMMAND, 'Restart the hubot') + .alias('t', 'token') + .alias('n', 'name') + .describe('t', 'Use the token') + .describe('n', 'Use the bot name') + .argv; + +const command = argv._[0]; + +switch (command) { + case START_COMMAND: + executeProcessManager(start); + break; + case STOP_COMMAND: + executeProcessManager(stop); + break; + case RESTART_COMMAND: + executeProcessManager(restart); + break; + case CONFIGURE_COMMAND: + configure.configure(argv); + break; + default: + yargs.showHelp(); + process.exit(0); + break; +} + +function start() { + const config = { script: 'src/cli/init-core.js', name: 'hubot', maxRestarts: 2 }; + pm2.start(config, () => pm2.disconnect()); +} + +function stop() { + pm2.stop('hubot', () => pm2.disconnect()); +} + +function restart() { + pm2.restart('hubot', () => pm2.disconnect()); +} + +function executeProcessManager(action) { + try { + pm2.connect(() => action()); + } catch (err) { + process.exit(2); + } +} diff --git a/src/cli/configure.js b/src/cli/configure.js new file mode 100644 index 0000000..1dcd46a --- /dev/null +++ b/src/cli/configure.js @@ -0,0 +1,48 @@ +'use strict'; + +const db = require('../lib/db'); + +exports.configure = configure; + +function configure(args) { + db.startDb() + .then(getConfig) + .then((config) => { + updateConfig(config, args); + }); +} + +function getConfig() { + return db.getDb().get('SELECT * FROM config'); +} + +function updateConfig(config, args) { + const token = getToken(config, args); + const name = getName(config, args); + + db.getDb().run('UPDATE config SET token = ?, name = ?', token, name); +} + +function getToken(config, args) { + if (args && args.token) { + return args.token; + } + + if (config && config.token) { + return config.token; + } + + return null; +} + +function getName(config, args) { + if (args && args.name) { + return args.name; + } + + if (config && config.name) { + return config.name; + } + + return null; +} diff --git a/src/cli/init-core.js b/src/cli/init-core.js new file mode 100644 index 0000000..e0f7ee7 --- /dev/null +++ b/src/cli/init-core.js @@ -0,0 +1,47 @@ +'use strict'; + +const Q = require('q'); +const pm2 = require('pm2'); +const dialog = require('dialog'); + +const Core = require('../core'); +const db = require('../lib/db'); +const path = require('path'); + +global.__nodeModules = path.join(__dirname, '../../node_modules/'); + +db.startDb() + .then(getConfig) + .then(validate) + .then(initCore) + .catch(showErrorMessage); + +function getConfig() { + return db.getDb().get('SELECT * FROM config'); +} + +function validate(config) { + const deferred = Q.defer(); + + if (!config) { + deferred.reject('Please make config before start'); + } else if (!config.token) { + deferred.reject('Please config token before start'); + } else if (!config.name) { + deferred.reject('Please config name before start'); + } else { + deferred.resolve(config); + } + + return deferred.promise; +} + +function initCore(config) { + new Core({ token: config.token, name: config.name }).run(); +} + +function showErrorMessage(err) { + dialog.err(err, 'Error', () => { + pm2.stop('hubot', () => pm2.disconnect()); + }); +} diff --git a/src/lib/db.js b/src/lib/db.js index 8915702..396d6e6 100644 --- a/src/lib/db.js +++ b/src/lib/db.js @@ -16,13 +16,13 @@ function startDb() { } function open() { - const dbFile = path.resolve(process.cwd(), 'data', 'hubot.db'); + const dbFile = path.join(__dirname, '../..', 'data', 'hubot.db'); return sqlite.open(dbFile); } function migrate(sqliteDb) { - const migrations = path.resolve(process.cwd(), 'migrations'); + const migrations = path.join(__dirname, '../..', 'migrations'); return sqliteDb.migrate({ migrationsPath: migrations }) .then((result) => { database = result; }); From 66c16a10f8866538605cab032491a6efc54317e8 Mon Sep 17 00:00:00 2001 From: Robson Date: Wed, 9 Nov 2016 20:38:19 -0200 Subject: [PATCH 12/26] Fix #33 Add Node 7 to Travis-CI build --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6566657..ab9e5a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,17 @@ sudo: required language: node_js node_js: - - "6.8.0" + - "6.9.1" + - "7.0.0" + - "7.1.0" services: - docker script: - npm run lint - + - npm test + after_success: - if [[ "$TRAVIS_BRANCH" == "master" ]]; then docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" ; From 3d717a37906f8b3a4e6f73ce8685d4db2965be23 Mon Sep 17 00:00:00 2001 From: Robson Date: Wed, 16 Nov 2016 22:38:39 -0200 Subject: [PATCH 13/26] Fix #36 Adapt to docker --- Dockerfile | 24 +++++------ package.json | 7 ++-- src/cli/cli.js | 96 ++++++++++++++++++++++++++++---------------- src/cli/configure.js | 26 ++++-------- src/cli/init-core.js | 9 +++++ 5 files changed, 92 insertions(+), 70 deletions(-) diff --git a/Dockerfile b/Dockerfile index 74d8526..376ff1f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,11 @@ -FROM alpine - -RUN apk add --update bash nodejs curl && rm -rf /var/cache/apk/* - -WORKDIR /hubot - -COPY ./package.json /hubot/ - -RUN npm install --production - -COPY ./ /hubot/ - -CMD BOT_API_TOKEN=$BOT_API_TOKEN BOT_NAME=$BOT_NAME node app.js +FROM node:7.1.0-alpine + +RUN apk add --update bash curl && rm -rf /var/cache/apk/* + +WORKDIR /hubot + +COPY ./hubot.js-1.0.0.tgz /hubot/ + +RUN npm install -g hubot.js-1.0.0.tgz + +CMD hubot start --t $BOT_API_TOKEN --n $BOT_NAME && tail -F -n0 /etc/hosts diff --git a/package.json b/package.json index 94d5f4f..f56ab8d 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,9 @@ "winston": "^2.2.0", "q": "^1.4.1", "sqlite": "^2.2.0", - "pm2": "2.0.19", - "dialog": "0.2.0", + "pm2": "^2.0.19", + "dialog": "^0.2.0", + "yargs": "^6.2.0", "gear-help": "^1.0.1", "gear-jenkins": "^1.0.1" }, @@ -42,7 +43,7 @@ "chai": "^3.5.0", "coveralls": "^2.11.12", "eslint": "^3.8.0", - "eslint-config-hubot-js": "^1.0.2", + "eslint-config-hubot-js": "^1.0.4", "istanbul": "^0.4.5", "mocha": "^3.0.2" } diff --git a/src/cli/cli.js b/src/cli/cli.js index 9a521ed..884f88f 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -10,41 +10,55 @@ const STOP_COMMAND = 'stop'; const RESTART_COMMAND = 'restart'; const CONFIGURE_COMMAND = 'configure'; -const argv = yargs.usage(`Pluralsight Downloader \n -Usage: hubot [options]`) - .command(START_COMMAND, 'Start the hubot') - .command(STOP_COMMAND, 'Stop the hubot') - .command(RESTART_COMMAND, 'Restart the hubot') - .command(CONFIGURE_COMMAND, 'Restart the hubot') - .alias('t', 'token') - .alias('n', 'name') - .describe('t', 'Use the token') - .describe('n', 'Use the bot name') - .argv; - -const command = argv._[0]; - -switch (command) { - case START_COMMAND: - executeProcessManager(start); - break; - case STOP_COMMAND: - executeProcessManager(stop); - break; - case RESTART_COMMAND: - executeProcessManager(restart); - break; - case CONFIGURE_COMMAND: - configure.configure(argv); - break; - default: - yargs.showHelp(); - process.exit(0); - break; +createParameters(); +createHelpMessage(); +chooseCommand(); + +function chooseCommand() { + const argv = yargs.argv; + const command = argv._[0]; + + switch (command) { + case START_COMMAND: + executeProcessManager(start, argv); + break; + case STOP_COMMAND: + executeProcessManager(stop); + break; + case RESTART_COMMAND: + executeProcessManager(restart); + break; + case CONFIGURE_COMMAND: + configure.configure(argv); + break; + default: + yargs.showHelp(); + process.exit(0); + break; + } +} + +function createParameters() { + yargs.alias('t', 'token') + .alias('n', 'name') + .global('token') + .global('name'); +} + +function createHelpMessage() { + yargs.usage(`Hubot.js \nUsage: hubot [options]`) + .command(START_COMMAND, 'Start the hubot') + .command(STOP_COMMAND, 'Stop the hubot') + .command(RESTART_COMMAND, 'Restart the hubot') + .command(CONFIGURE_COMMAND, 'Restart the hubot') + .describe('t', 'Inform Slack API Token') + .describe('n', 'Inform the bot name'); } -function start() { - const config = { script: 'src/cli/init-core.js', name: 'hubot', maxRestarts: 2 }; +function start(args) { + const argsArray = buildArgsArray(args); + const config = { cwd: __dirname, script: 'init-core.js', name: 'hubot', args: argsArray, maxRestarts: 2 }; + pm2.start(config, () => pm2.disconnect()); } @@ -56,10 +70,22 @@ function restart() { pm2.restart('hubot', () => pm2.disconnect()); } -function executeProcessManager(action) { +function executeProcessManager(action, args) { try { - pm2.connect(() => action()); + pm2.connect(() => action(args)); } catch (err) { process.exit(2); } } + +function buildArgsArray(args) { + const argsArray = []; + + Object.keys(args).forEach((key) => { + if (args[key]) { + argsArray.push(`--${key}=${args[key]}`); + } + }); + + return argsArray; +} diff --git a/src/cli/configure.js b/src/cli/configure.js index 1dcd46a..dd7dc92 100644 --- a/src/cli/configure.js +++ b/src/cli/configure.js @@ -17,31 +17,19 @@ function getConfig() { } function updateConfig(config, args) { - const token = getToken(config, args); - const name = getName(config, args); + const token = chooseConfig(config, args, 'token'); + const name = chooseConfig(config, args, 'name'); db.getDb().run('UPDATE config SET token = ?, name = ?', token, name); } -function getToken(config, args) { - if (args && args.token) { - return args.token; +function chooseConfig(config, args, propertie) { + if (args && args[propertie]) { + return args[propertie]; } - if (config && config.token) { - return config.token; - } - - return null; -} - -function getName(config, args) { - if (args && args.name) { - return args.name; - } - - if (config && config.name) { - return config.name; + if (config && config[propertie]) { + return config[propertie]; } return null; diff --git a/src/cli/init-core.js b/src/cli/init-core.js index e0f7ee7..e795163 100644 --- a/src/cli/init-core.js +++ b/src/cli/init-core.js @@ -3,10 +3,12 @@ const Q = require('q'); const pm2 = require('pm2'); const dialog = require('dialog'); +const yargs = require('yargs'); const Core = require('../core'); const db = require('../lib/db'); const path = require('path'); +const configure = require('./configure'); global.__nodeModules = path.join(__dirname, '../../node_modules/'); @@ -17,6 +19,13 @@ db.startDb() .catch(showErrorMessage); function getConfig() { + const hasParameter = yargs.argv.token || yargs.argv.name; + + if (hasParameter) { + configure.configure(yargs.argv); + return { token: yargs.argv.token, name: yargs.argv.name }; + } + return db.getDb().get('SELECT * FROM config'); } From 692990b34cb0370c25ba404b591ed1d04c43a622 Mon Sep 17 00:00:00 2001 From: Robson Date: Thu, 17 Nov 2016 22:39:56 -0200 Subject: [PATCH 14/26] Fix #37 Improve build --- .travis.yml | 32 +++++++++++++++++++++++--------- Dockerfile | 8 +++----- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index ab9e5a6..6ef51dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ sudo: required language: node_js + node_js: - - "6.9.1" - - "7.0.0" - - "7.1.0" + - 7.1.0 services: - docker @@ -12,12 +11,27 @@ services: script: - npm run lint - npm test - + after_success: + - npm run coveralls + +deploy: + provider: npm + email: "robson.luizv@gmail.com" + api_key: + secure: PNVxGGp2oUF/XVy81PiBDeJsytnMu8lTiUImX6tkgqepPm6OKjKUau7vNsTH6shYGMm7bo/S6RvOAuqYZiYWbm3k1PZK/GIlHqq/zSsNV6B4fo3F1w9BpMN8xOS+kfHcpeyhm1LO0wUk4iFhzIIlmUmrMR5dBaBz6jCQj6aKFl1yRKNRzSxl4NfKA5N3mR5yPI852XR6d1nHlWafvo6Q3+7+hcedoQn8wzxmHmRWxdWUT7NG/LcoYjpGWR3zNg0/4buMuHCze+kGwQBTZnUXAN2fPBHRq+57e9Vsbxz4UK/zvaUs8wuDCppFUJ0qDtA2Jh3sM19WG97y3kETNC6mtDSdfpiszlb37ipp2/ilx8Db5KV7PGB+8tXUvjt2510o+l/ZUk/MWd3GTk5m9Og5CGTDrCZTLW6DlRmBTgew9Bssdyid2SkfkR20cU1AgsBFRLAhI/qI0CGXcLQTsnWGhKo2zqTOdZEteKgo/U/Js7N/R7TTFjPakeslxq4DmrYiMDIiwtMDRLPTHXPq0NoDq+s7BKPeIui3cS9kNxPqlHzsSh/91qrfnGphhQbHMMt0LZ/Kws53MPqSrWfgcclI0eqE9a6kNGiu+QxmOMTtud+KREo2gidq5Aa8mzHUYro8FtQfO2kCDwDD0KnqNTjVN2R7atuBmc25q6LL6INloWo= + on: + branch: master + +after_deploy: - if [[ "$TRAVIS_BRANCH" == "master" ]]; then - docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" ; - docker build -t robsonbittencourt/hubot.js:latest . ; - docker push docker.io/robsonbittencourt/hubot.js:latest ; - fi + docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" ; + + export VERSION=$(node -p -e "JSON.parse(require('fs').readFileSync('package.json', 'utf8')).version") + + docker build --build-arg version=${VERSION} -t robsonbittencourt/hubot.js:latest -t robsonbittencourt/hubot.js:${VERSION} . ; + + docker push docker.io/robsonbittencourt/hubot.js:latest ; - - 'npm run coveralls' + docker push docker.io/robsonbittencourt/hubot.js:${VERSION} ; + fi diff --git a/Dockerfile b/Dockerfile index 376ff1f..f193f1f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,8 @@ FROM node:7.1.0-alpine RUN apk add --update bash curl && rm -rf /var/cache/apk/* -WORKDIR /hubot +ARG version -COPY ./hubot.js-1.0.0.tgz /hubot/ +RUN npm install -g huboty@$version -RUN npm install -g hubot.js-1.0.0.tgz - -CMD hubot start --t $BOT_API_TOKEN --n $BOT_NAME && tail -F -n0 /etc/hosts +CMD hubot start --t $BOT_API_KEY --n $BOT_NAME && tail -F -n0 /etc/hosts From d05f7fe51ba2c92b2d30ad2add3cf7945670e1ca Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sat, 19 Nov 2016 16:44:53 -0200 Subject: [PATCH 15/26] Fix npm module name --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f193f1f..19c1efa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,6 @@ RUN apk add --update bash curl && rm -rf /var/cache/apk/* ARG version -RUN npm install -g huboty@$version +RUN npm install -g hubot.js@$version CMD hubot start --t $BOT_API_KEY --n $BOT_NAME && tail -F -n0 /etc/hosts From e226bc4ca2de1586c9174d4332f17d21cf581330 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 12:06:20 -0200 Subject: [PATCH 16/26] Remove unnecessary entries --- .gitignore | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/.gitignore b/.gitignore index 27b3ee5..97147eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,5 @@ # Logs *.log -npm-debug.log* -hubot.log - -hubot.db - -# Runtime data -pids -*.pid -*.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov @@ -16,27 +7,8 @@ lib-cov # Coverage directory used by tools like istanbul coverage -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - # Dependency directories node_modules -jspm_packages - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history hubot.db From d2d314356cff813b3e341e313a764acac17ed9e6 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 12:06:31 -0200 Subject: [PATCH 17/26] Add file to log output --- src/cli/cli.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cli/cli.js b/src/cli/cli.js index 884f88f..0bb8a20 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -56,8 +56,14 @@ function createHelpMessage() { } function start(args) { - const argsArray = buildArgsArray(args); - const config = { cwd: __dirname, script: 'init-core.js', name: 'hubot', args: argsArray, maxRestarts: 2 }; + const config = { + cwd: __dirname, + script: 'init-core.js', + name: 'hubot', + output: '../../logs/output.log', + args: buildArgsArray(args), + maxRestarts: 2 + }; pm2.start(config, () => pm2.disconnect()); } From 3898ca2780837dd577ce26228882f0285c61f795 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 15:10:40 -0200 Subject: [PATCH 18/26] Only admins can config --- .../handlers/gear-configure-handler.js | 20 +++++++++++-------- .../handlers/gear-status-handler.js | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/message-handler/handlers/gear-configure-handler.js b/src/message-handler/handlers/gear-configure-handler.js index ec7977d..b4615dc 100644 --- a/src/message-handler/handlers/gear-configure-handler.js +++ b/src/message-handler/handlers/gear-configure-handler.js @@ -4,15 +4,19 @@ const conversation = require('../conversation'); exports.handle = handle; -function handle(hubot, message) { +function handle(hubot, message, core) { if (isGearConfigureMessage(hubot, message)) { - const param = { - user: message.user, - gear: gearDescription(message), - interactions: discoverConfig(hubot, message) - }; - - conversation.startConversation(hubot, param, message); + core.isAdminUser(message.user).then((isAdmin) => { + if (isAdmin) { + const param = { + user: message.user, + gear: gearDescription(message), + interactions: discoverConfig(hubot, message) + }; + + conversation.startConversation(hubot, param, message); + } + }); } } diff --git a/src/message-handler/handlers/gear-status-handler.js b/src/message-handler/handlers/gear-status-handler.js index d4e7e20..652bb6d 100644 --- a/src/message-handler/handlers/gear-status-handler.js +++ b/src/message-handler/handlers/gear-status-handler.js @@ -10,7 +10,7 @@ function handle(hubot, message, core) { if (action && isGearChangeStatusMessage(action, hubot, message)) { core.isAdminUser(message.user) - .then(isAdmin => changeStatus(isAdmin, action, hubot, message)); + .then(isAdmin => changeStatus(isAdmin, action, hubot, message)); return true; } From 3c0115f7370d261bc752f1821d0bfd679a49110b Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 15:17:49 -0200 Subject: [PATCH 19/26] Turn gears active by default --- src/assembler.js | 4 ++-- src/first-run.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assembler.js b/src/assembler.js index 292b43e..ba1cf47 100644 --- a/src/assembler.js +++ b/src/assembler.js @@ -56,9 +56,9 @@ module.exports = class Assembler { loadGearStatus(gear) { db.getDb().get('SELECT * FROM gears WHERE name = ?', gear.name).then((record) => { if (!record) { - gear.active = false; + gear.active = true; db.getDb() - .run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, false); + .run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, gear.active); } else { gear.active = record.active === '1'; } diff --git a/src/first-run.js b/src/first-run.js index 489315e..c1f864a 100644 --- a/src/first-run.js +++ b/src/first-run.js @@ -37,8 +37,8 @@ function message3(hubot) { } function message4(hubot) { - return hubot.speech().append('At this time all the gears are inactive. You can activate them using the command ') - .bold('activate gear-name').period().end(); + return hubot.speech().append('At this time all the gears are active. You can deactivate them using the command ') + .bold('deactivate gear-name').period().end(); } function message5(hubot) { From f529d26522eea8d23d909b30a59d51d68e3d685a Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 16:39:47 -0200 Subject: [PATCH 20/26] Create debug helper --- debug-helper.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 debug-helper.js diff --git a/debug-helper.js b/debug-helper.js new file mode 100644 index 0000000..fad1ecf --- /dev/null +++ b/debug-helper.js @@ -0,0 +1,16 @@ +'use strict'; + +// This file is an alternative to the CLI. When using hubot as CLI it is not possible to debug. +// If you wish to debug fill in the token and bot name and start this file. + +const path = require('path'); + +const db = require('./src/lib/db'); +const Core = require('./src/core'); + +global.__nodeModules = path.join(__dirname, './node_modules/'); + +db.startDb().then(() => { + new Core({ token: 'botToken', name: 'botName' }).run(); +}); + From d784a83ad26e4ab9ec876f9048b7d05c372d985a Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 20 Nov 2016 22:12:33 -0200 Subject: [PATCH 21/26] Reduce line length --- src/assembler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assembler.js b/src/assembler.js index ba1cf47..076a57f 100644 --- a/src/assembler.js +++ b/src/assembler.js @@ -57,8 +57,8 @@ module.exports = class Assembler { db.getDb().get('SELECT * FROM gears WHERE name = ?', gear.name).then((record) => { if (!record) { gear.active = true; - db.getDb() - .run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', gear.name, gear.description, gear.active); + db.getDb().run('INSERT INTO gears(name, description, active) VALUES(?, ?, ?)', + gear.name, gear.description, gear.active); } else { gear.active = record.active === '1'; } From 2a15d76a2ea8610f629f448e13e414baf59fc1b6 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Mon, 21 Nov 2016 21:52:29 -0200 Subject: [PATCH 22/26] Allow chain iteractions --- src/message-handler/conversation.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/message-handler/conversation.js b/src/message-handler/conversation.js index 80bbfb7..2fc09ee 100644 --- a/src/message-handler/conversation.js +++ b/src/message-handler/conversation.js @@ -145,6 +145,12 @@ function handleResponse(conversation, interaction, response) { function getExpectedResponse(expectedResponses, response) { if (expectedResponses) { + const responses = expectedResponses.filter(expectedResponse => expectedResponse.response); + + if (responses.length === 0) { + return expectedResponses[0]; + } + return expectedResponses.find(r => r.response === response.text); } From ddcb2fa7737a993b529a6ab1896688e62de675e0 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Sun, 27 Nov 2016 23:49:17 -0200 Subject: [PATCH 23/26] Update README --- src/cli/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/cli.js b/src/cli/cli.js index 0bb8a20..9746763 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -46,7 +46,7 @@ function createParameters() { } function createHelpMessage() { - yargs.usage(`Hubot.js \nUsage: hubot [options]`) + yargs.usage('Hubot.js \nUsage: hubot [options]') .command(START_COMMAND, 'Start the hubot') .command(STOP_COMMAND, 'Stop the hubot') .command(RESTART_COMMAND, 'Restart the hubot') From e08f5ffa3fe59eb83900aa0791286d7e3eaf3104 Mon Sep 17 00:00:00 2001 From: Robson Date: Mon, 28 Nov 2016 00:15:00 -0200 Subject: [PATCH 24/26] Fix #21 Update README --- .npmignore | 17 +++ Dockerfile | 2 +- README.md | 216 +++++++++++++++++------------ media/activate-deactivate-gear.gif | Bin 0 -> 121315 bytes media/configure-gear.gif | Bin 0 -> 184186 bytes media/first-iteraction.png | Bin 0 -> 50412 bytes media/help.png | Bin 0 -> 25489 bytes media/start-job.gif | Bin 0 -> 40154 bytes media/start-job.png | Bin 0 -> 17392 bytes 9 files changed, 144 insertions(+), 91 deletions(-) create mode 100644 .npmignore create mode 100644 media/activate-deactivate-gear.gif create mode 100644 media/configure-gear.gif create mode 100644 media/first-iteraction.png create mode 100644 media/help.png create mode 100644 media/start-job.gif create mode 100644 media/start-job.png diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..1630d37 --- /dev/null +++ b/.npmignore @@ -0,0 +1,17 @@ +# Logs +*.log + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Dependency directories +node_modules + +hubot.db + +.vscode + +/media diff --git a/Dockerfile b/Dockerfile index 19c1efa..6ec81d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,4 @@ ARG version RUN npm install -g hubot.js@$version -CMD hubot start --t $BOT_API_KEY --n $BOT_NAME && tail -F -n0 /etc/hosts +CMD hubot start --t $BOT_API_TOKEN --n $BOT_NAME && tail -F -n0 /etc/hosts diff --git a/README.md b/README.md index 789e830..e49cce2 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,126 @@ -# hubot.js -[![Build Status](https://travis-ci.org/hubot-js/hubot.js.svg?branch=master)](https://travis-ci.org/hubot-js/hubot.js) [![Coverage Status](https://coveralls.io/repos/github/hubot-js/hubot.js/badge.svg?branch=master)](https://coveralls.io/github/hubot-js/hubot.js?branch=master) [![Code Climate](https://img.shields.io/codeclimate/github/hubot-js/hubot.js.svg)](https://codeclimate.com/github/hubot-js/hubot.js) [![dependencies-badge](https://david-dm.org/hubot-js/hubot.js.svg)](https://david-dm.org/hubot-js/hubot.js) [![devDependencies Status](https://david-dm.org/hubot-js/hubot.js/dev-status.svg)](https://david-dm.org/hubot-js/hubot.js?type=dev) [![Docker Stars](https://img.shields.io/docker/stars/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![Docker Pulls](https://img.shields.io/docker/pulls/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![image-size](https://images.microbadger.com/badges/image/robsonbittencourt/hubot.js.svg)](http://microbadger.com/images/robsonbittencourt/hubot.js) - -> A small robot written in Javascript (He doesn't like coffeescript) - -## Hello world - -Hello! My name is Hubot. I'm a robot and my job is to do stuff in Slack chats. At first, I don't know many things, but when gears are attached everything is possible. I love new gears. Feel free to create them. - -![start-deploy-gif](https://s10.postimg.org/jl5ptldnt/hubot_start_deploy2.gif) - -## How to turn me on? - -The first step is to create a bot user on Slack. For this, you can follow [these steps](https://api.slack.com/bot-users). With a bot user created and the token on hand we can go to the next step. - -### Docker - -To enable me with Docker it's a piece of cake. I have a recipe of how to build me in [Dockerhub](https://hub.docker.com/r/robsonbittencourt/hubot.js/). Just run the following command: - -``` -docker run -d -e BOT_API_KEY=your_slack_api_key \ - -e BOT_NAME=name_of_your_bot \ - --restart="unless-stopped" - --name=hubot \ - robsonbittencourt/hubot.js -``` - -### Node.js - -If you don't use Docker no problem. You can turn me on using Node.js commands. For this set variables before node command. - -``` -BOT_API_KEY=your_slack_api_key BOT_NAME=name_of_your_bot node app.js - -``` - -## Usage - -For now, I don't know how to do many things. But I'm able to understand and to use new gears (features). You can create your own gears. If you think they can be useful for other users, please share it with the world. - -### Jenkins - -I know how to invoke your jobs in Jenkins. For this, you need to enter your authorization link to build me. - -``` -docker run -d -e BOT_API_KEY=your_slack_api_key \ - -e BOT_NAME=name_of_your_bot \ - -e JENKINS_AUTH_URL=your_jenkins_auth_url \ - --restart="unless-stopped" \ - --name=hubot \ - robsonbittencourt/hubot.js -``` -If you use Jenkins without security (authentication) the authorization link is simply the access url. For example: `http://your.jenkins.com:8080` - -If you use the Jenkins authentication, you need to find your access token. It can be obtained from `yourJenkinsUrl/me/configure`. See more details [here](https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients). In this case your authorization link should be in this format: `http://your_user:your_token@your_jenkins_url` - -After that, you can ask me to do your jobs. - -``` -hubot start job my-deploy -``` - -![start-deploy](https://s9.postimg.org/g9dt1se9b/hubot_job.png) - -### Help - -If you have doubt about the available commands, please ask me for help. I'll be glad to use my gears and knowledge to answer your questions. - -``` -hubot help -``` - -![hubot-help](https://s9.postimg.org/rf26x119b/hubot_help.png) - -## Development setup -- Fork and clone this project -- In the main directory run ```npm install```to install dependencies. -- Use node command (see before) for run Hubot.js -- Write your code -- To run tests use ```npm test``` command - -## Contributors -[Robson Rosa](https://github.com/robsonrosa) - -## Meta -Robson Bittencourt - @rluizv - robson.luizv@gmail.com - -Distributed under the MIT license. See [LICENSE](LICENSE) for more information. - -https://github.com/robsonbittencourt/hubot.js +# hubot.js +[![Build Status](https://travis-ci.org/hubot-js/hubot.js.svg?branch=master)](https://travis-ci.org/hubot-js/hubot.js) [![npm](https://img.shields.io/npm/v/gear-hubot.js.svg)](https://www.npmjs.com/package/hubot.js) [![Coverage Status](https://coveralls.io/repos/github/hubot-js/hubot.js/badge.svg?branch=master)](https://coveralls.io/github/hubot-js/hubot.js?branch=master) [![Code Climate](https://img.shields.io/codeclimate/github/hubot-js/hubot.js.svg)](https://codeclimate.com/github/hubot-js/hubot.js) [![dependencies-badge](https://david-dm.org/hubot-js/hubot.js.svg)](https://david-dm.org/hubot-js/hubot.js) [![devDependencies Status](https://david-dm.org/hubot-js/hubot.js/dev-status.svg)](https://david-dm.org/hubot-js/hubot.js?type=dev) [![Docker Stars](https://img.shields.io/docker/stars/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![Docker Pulls](https://img.shields.io/docker/pulls/robsonbittencourt/hubot.js.svg)](https://hub.docker.com/r/robsonbittencourt/hubot.js/) [![image-size](https://images.microbadger.com/badges/image/robsonbittencourt/hubot.js.svg)](http://microbadger.com/images/robsonbittencourt/hubot.js) + +> A small robot written in Javascript (He doesn't like coffeescript) + +## Hello world + +Hello! My name is Hubot. I'm a robot and my job is to do stuff in Slack chats. At first, I don't know many things, but when gears are attached everything is possible. I love new gears. Feel free to create them. + +![start-deploy-gif](media/start-job.gif) + +## How to turn me on? + +The first step is to have a bot user in Slack. If you don't have a bot yet [click here](https://api.slack.com/bot-users) to create one. With a bot user created get the token that was generated in the bot creation and go to the next step. + +### npm + +Very simple. Run the command below. + +```bash +npm install -g hubot.js +``` + +### Docker + +To enable me with Docker it's a piece of cake. I have a recipe of how to build me in [Dockerhub](https://hub.docker.com/r/robsonbittencourt/hubot.js/). Just run the following command: + +```bash +docker run -d -e BOT_API_TOKEN=bot_token \ + -e BOT_NAME=bot_name \ + --name=hubot \ + robsonbittencourt/hubot.js +``` + +## Usage + +After you install me through npm some commands are avaliable in your command line. If you start me with Docker these commands won't are available. Help and configure are commands exclusively for console with npm installation. The other commands can be executed with Docker commands - like docker start/stop/restart. + +### CLI Commands Overview + +```bash +# Show the help with available commands +$ hubot help + +# Saves the required settings. These settings are stored, so you just need to do them once. +# But if necessary can make them again. +$ hubot configure -t botToken -n botName + +# Start the hubot. To use this command, the settings must have been already set up. +$ hubot start + +# Start the hubot. This command saves the configuration and starts. +$ hubot start -t botToken -n botName + +# Stop the hubot. +$ hubot stop + +# Restart the hubot. +$ hubot restart +``` + +### First iteration + +After you start me call me by my name in private chat. With this I show to you some first instructions. + +![first-iteraction](media/first-iteraction.png) + +**_An important detail. To ask me things on a channel I have to be participating in it._** + +### Activate/Deactivate Gears + +You don't want to use some gear? You can disable it. If you want to activate it again it is also possible. Use `activate gear-name` or `deactivate gear-name`. + +![activate-deactivate-gear](media/activate-deactivate-gear.gif) + +### Configure Gears + +Some gears need to be set up before first use. Use `configure gear-name` command. + +![configure-gear](media/configure-gear.gif) + +## Gears + +For now, I don't know how to do many things. But I'm able to understand and to use new gears (features). You can create your own gears. If you think they can be useful for other users, please share it with the world. + +### Jenkins + +I know how to invoke your jobs in Jenkins. For this, you need to do the setup before. + +``` +configure jenkins +``` + +After that, you can ask me to do your jobs. + +``` +hubot start job my-deploy +``` + +![start-job](media/start-job.png) + +### Help + +If you have doubt about the available commands, please ask me for help. I'll be glad to use my gears and knowledge to answer your questions. + +``` +hubot help +``` + +![help](media/help.png) + +## Development setup +- Fork and clone this project +- In the main directory run ```npm install```to install dependencies. +- Write your code +- To run tests use ```npm test``` command + +## Contributors +[Robson Rosa](https://github.com/robsonrosa) + +## Meta +Robson Bittencourt - @rluizv - robson.luizv@gmail.com + +Distributed under the MIT license. See [LICENSE](LICENSE) for more information. + +https://github.com/hubot-js/hubot.js diff --git a/media/activate-deactivate-gear.gif b/media/activate-deactivate-gear.gif new file mode 100644 index 0000000000000000000000000000000000000000..554aa7ef67858f92a96deb5e295a1a3486693110 GIT binary patch literal 121315 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⋘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%0AUkjmg!?Q<)krx(wAOiq7SZ{hd_tQCb*I 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 ck{`(snuN?YEQByWIZ5ZR3ZhkcVA+4 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 z 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 literal 0 HcmV?d00001 diff --git a/media/help.png b/media/help.png new file mode 100644 index 0000000000000000000000000000000000000000..370d76dabb691b10c2aa785e3d3a08cf30126f22 GIT binary patch literal 25489 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 literal 0 HcmV?d00001 From 0941275a24f46bae6bd5aa8495083618c155176b Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Mon, 28 Nov 2016 23:49:22 -0200 Subject: [PATCH 25/26] Fix #22 Update dependencies --- package.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index f56ab8d..6d46077 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/robsonbittencourt/hubot.js.git" + "url": "git+https://github.com/hubot-js/hubot.js.git" }, "keywords": [ "hubot", @@ -24,27 +24,27 @@ "author": "robsonbittencourt", "license": "MIT", "bugs": { - "url": "https://github.com/robsonbittencourt/hubot.js/issues" + "url": "https://github.com/hubot-js/hubot.js/issues" }, - "homepage": "https://github.com/robsonbittencourt/hubot.js#readme", + "homepage": "https://github.com/hubot-js/hubot.js#readme", "dependencies": { - "slackbots": "^0.5.2", - "string": "^3.3.1", - "winston": "^2.2.0", + "slackbots": "^0.5.3", + "string": "^3.3.3", + "winston": "^2.3.0", "q": "^1.4.1", - "sqlite": "^2.2.0", - "pm2": "^2.0.19", + "sqlite": "^2.2.3", + "pm2": "^2.1.6", "dialog": "^0.2.0", - "yargs": "^6.2.0", - "gear-help": "^1.0.1", - "gear-jenkins": "^1.0.1" + "yargs": "^6.4.0", + "gear-help": "^2.0.0", + "gear-jenkins": "^2.0.0" }, "devDependencies": { "chai": "^3.5.0", - "coveralls": "^2.11.12", - "eslint": "^3.8.0", + "coveralls": "^2.11.15", + "eslint": "^3.11.1", "eslint-config-hubot-js": "^1.0.4", "istanbul": "^0.4.5", - "mocha": "^3.0.2" + "mocha": "^3.2.0" } } From 1d4fe59cd5e885a1708e52f8f61c151d259f47a2 Mon Sep 17 00:00:00 2001 From: robsonbittencourt Date: Tue, 29 Nov 2016 00:50:02 -0200 Subject: [PATCH 26/26] Add codeclimate config file --- .codeclimate.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .codeclimate.yml diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..7183799 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,18 @@ +--- +engines: + duplication: + enabled: true + config: + languages: + javascript: + mass_threshold: 70 + + fixme: + enabled: true +ratings: + paths: + - "**.js" + - "**.module" +exclude_paths: +- config/ +- test/