From 7ca6785959863d53c7995b3d5469e8b9c687cb30 Mon Sep 17 00:00:00 2001 From: Mike Bland Date: Fri, 7 Oct 2016 12:59:59 -0400 Subject: [PATCH] Update to use hubot-slack 4.10.0 Thanks to the new @slack/client npm, slackhq/hubot-slack#360, and slackhq/hubot-slack#363, the `SlackBot` will now emit a `ReactionMessage` object for `reaction_added` and `reaction_removed` events. A future commit will repackage the logic so that it is no longer middleware, but called as part of a `robot.listen` or `robot.react` callback. --- lib/middleware.js | 4 ++-- lib/slack-client.js | 14 ++++++++++---- package.json | 8 ++++---- test/helpers/index.js | 26 +++++++++++++++++--------- test/integration-test.js | 8 +++++--- test/middleware-test.js | 4 ++-- test/rule-test.js | 17 +++++++++++------ 7 files changed, 51 insertions(+), 30 deletions(-) diff --git a/lib/middleware.js b/lib/middleware.js index 9c991b1..d348526 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -25,7 +25,7 @@ Middleware.prototype.execute = function(context, next, done) { } catch (err) { errorMessage = 'unhandled error: ' + (err instanceof Error ? err.message : err) + '\nmessage: ' + - JSON.stringify(context.response.message.rawMessage, null, 2); + JSON.stringify(context.response.message, null, 2); this.logger.error(null, errorMessage); context.response.reply(errorMessage); return next(done); @@ -34,7 +34,7 @@ Middleware.prototype.execute = function(context, next, done) { function doExecute(middleware, context, next, done) { var response = context.response, - message = response.message.rawMessage, + message = response.message, rule = middleware.findMatchingRule(message), msgId, finish; diff --git a/lib/slack-client.js b/lib/slack-client.js index 863f0e4..cc7812c 100644 --- a/lib/slack-client.js +++ b/lib/slack-client.js @@ -7,6 +7,7 @@ var url = require('url'); module.exports = SlackClient; +// robotSlackClient should be of type RtmClient from @slack/client function SlackClient(robotSlackClient, config) { this.client = robotSlackClient; this.timeout = config.slackTimeout; @@ -17,23 +18,28 @@ function SlackClient(robotSlackClient, config) { SlackClient.API_BASE_URL = 'https://slack.com/api/'; -// From: https://api.slack.com/events/reaction_added -// May get this directly from a future version of the slack-client package. -SlackClient.REACTION_ADDED = 'reaction_added'; +// https://api.slack.com/events/reaction_added +// ReactionMessage (node_modules/hubot-slack/src/reaction-message.coffee) will +// trim the 'reaction_' prefix from 'reaction_added'. +SlackClient.REACTION_ADDED = 'added'; +// https://api.slack.com/types/channel SlackClient.prototype.getChannelName = function(channelId) { - return this.client.getChannelByID(channelId).name; + return this.client.dataStore.getChannelById(channelId).name; }; +// https://api.slack.com/methods/rtm.start SlackClient.prototype.getTeamDomain = function() { return this.client.team.domain; }; +// https://api.slack.com/methods/reactions.get SlackClient.prototype.getReactions = function(channel, timestamp) { return makeApiCall(this, 'reactions.get', { channel: channel, timestamp: timestamp }); }; +// https://api.slack.com/methods/reactions.add SlackClient.prototype.addSuccessReaction = function(channel, timestamp) { return makeApiCall(this, 'reactions.add', { channel: channel, timestamp: timestamp, name: this.successReaction }); diff --git a/package.json b/package.json index d8f4717..e8610ea 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dependencies": {}, "peerDependencies": { "hubot": "2.x", - "hubot-slack": "3.x" + "hubot-slack": "4.x" }, "devDependencies": { "browserify": "^13.0.0", @@ -27,13 +27,13 @@ "gulp-eslint": "^2.0.0", "gulp-istanbul": "^0.10.3", "gulp-mocha": "^2.2.0", - "hubot": "^2.17.0", - "hubot-slack": "^3.4.2", + "hubot": "^2.19.0", + "hubot-slack": "^4.10.0", "hubot-test-helper": "^1.3.0", "istanbul": "^0.4.1", "mocha": "^2.3.4", "sinon": "^1.17.2", - "slack-client": "^1.5.1", + "@slack/client": "^3.6.0", "temp": "^0.8.3", "yargs": "^3.31.0" }, diff --git a/test/helpers/index.js b/test/helpers/index.js index 8f16981..e0cde3a 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -2,12 +2,13 @@ var testConfig = require('./test-config.json'); var SlackClient = require('../../lib/slack-client'); -var Hubot = require('hubot'); -var SlackBot = require('hubot-slack'); +var User = require('@slack/client/lib/models/user'); +var ReactionMessage = require('hubot-slack/src/reaction-message'); exports = module.exports = { REACTION: 'evergreen_tree', USER_ID: 'U5150OU812', + ITEM_USER_ID: 'U1984OU812', CHANNEL_ID: 'C5150OU812', TIMESTAMP: '1360782804.083113', PERMALINK: 'https://18f.slack.com/archives/handbook/p1360782804083113', @@ -18,28 +19,35 @@ exports = module.exports = { return JSON.parse(JSON.stringify(testConfig)); }, + // https://api.slack.com/events/reaction_added reactionAddedMessage: function() { return { type: SlackClient.REACTION_ADDED, user: exports.USER_ID, + reaction: exports.REACTION, + item_user: exports.ITEM_USER_ID, // eslint-disable-line camelcase item: { type: 'message', channel: exports.CHANNEL_ID, ts: exports.TIMESTAMP }, - reaction: exports.REACTION, 'event_ts': exports.TIMESTAMP }; }, fullReactionAddedMessage: function() { - var user, text, message; - - user = new Hubot.User(exports.USER_ID, - { id: exports.USER_ID, name: 'jquser', room: 'handbook' }); - text = exports.REACTION; + var user, itemUser, message; message = exports.reactionAddedMessage(); - return new SlackBot.SlackTextMessage(user, text, text, message); + + // https://api.slack.com/types/user + // node_modules/hubot-slack/src/bot.coffee + user = new User({ id: message.user, name: 'jquser' }); + user.room = message.item.channel; + itemUser = new User({ id: message.item_user, name: 'rando' }); + + // node_modules/hubot-slack/src/reaction-message.coffee + return new ReactionMessage(message.type, user, message.reaction, + itemUser, message.item, message.event_ts); }, messageWithReactions: function() { diff --git a/test/integration-test.js b/test/integration-test.js index 6ffcaaa..5a12eae 100644 --- a/test/integration-test.js +++ b/test/integration-test.js @@ -60,8 +60,10 @@ describe('Integration test', function() { }); patchReactMethodOntoRoom(room); room.robot.middleware.receive.stack[0].impl.slackClient.client = { - getChannelByID: function() { - return { name: 'handbook' }; + dataStore: { + getChannelById: function() { + return { name: 'handbook' }; + } }, team: { domain: '18f' } }; @@ -111,7 +113,7 @@ describe('Integration test', function() { room.messages.push([userName, reaction]); reactionMessage.user.name = userName; - reactionMessage.rawMessage.reaction = reaction; + reactionMessage.reaction = reaction; room.robot.receive(reactionMessage, resolve); }); }; diff --git a/test/middleware-test.js b/test/middleware-test.js index e33c3de..ae7c84b 100644 --- a/test/middleware-test.js +++ b/test/middleware-test.js @@ -141,7 +141,7 @@ describe('Middleware', function() { }); it('should ignore messages that do not match', function() { - delete context.response.message.rawMessage; + delete context.response.message; expect(middleware.execute(context, next, hubotDone)).to.be.undefined; next.calledWith(hubotDone).should.be.true; }); @@ -247,7 +247,7 @@ describe('Middleware', function() { it('should catch and log unanticipated errors', function() { var errorMessage = 'unhandled error: Error\nmessage: ' + - JSON.stringify(helpers.reactionAddedMessage(), null, 2); + JSON.stringify(helpers.fullReactionAddedMessage(), null, 2); slackClient.getChannelName.throws(); expect(middleware.execute(context, next, hubotDone)).to.be.undefined; diff --git a/test/rule-test.js b/test/rule-test.js index 4877190..09f3ff4 100644 --- a/test/rule-test.js +++ b/test/rule-test.js @@ -2,19 +2,23 @@ var Rule = require('../lib/rule'); var SlackClient = require('../lib/slack-client'); -var Channel = require('slack-client/src/channel'); +var Channel = require('@slack/client/lib/models/channel'); var config = require('./helpers/test-config.json'); var chai = require('chai'); var expect = chai.expect; function SlackClientImplStub(channelName) { + var clientStub = this; this.channelName = channelName; -} -SlackClientImplStub.prototype.getChannelByID = function(channelId) { - this.channelId = channelId; - return new Channel(this, { name: this.channelName }); -}; + this.dataStore = { + getChannelById: function (channelId) { + clientStub.channelId = channelId; + // https://api.slack.com/types/channel + return new Channel({ id: channelId, name: clientStub.channelName }); + } + }; +} describe('Rule', function() { var makeConfigRule = function() { @@ -29,6 +33,7 @@ describe('Rule', function() { return { type: 'reaction_added', user: 'U024BE7LH', + item_user: 'U1984OU812', // eslint-disable-line camelcase item: { type: 'message', channel: 'C2147483705',