Skip to content

Commit

Permalink
📓
Browse files Browse the repository at this point in the history
closes #2 Make possible move the bot in another channel not just the general chat
closes #9 Add new functionality 1.0 in readme
  • Loading branch information
eromano committed Apr 10, 2016
1 parent d2337de commit 6aace21
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 33 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ Ci-alarm is a simple node.js slack bot to help to turn on a light alarm through

```$ npm run-script start```

## Command list

* To show the command list

```@BotName command list ```
<p align="left" style="width:200px;height:200px">
<img title="ci alarm" src='doc/img/command list.png' />
</p>
```@BotName status "repository name" ```
<p align="left" style="width:100px;height:100px">
<img title="ci alarm" src='doc/img/status.png' />
</p>
```@BotName repository list ```
<p align="left" style="width:200px;height:200px">
<img title="ci alarm" src='doc/img/repo list.png' />
</p>


## Contributing

1. Fork it!
Expand Down
Binary file added doc/img/command list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/img/repo list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/img/status.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ci-alarm",
"version": "1.0.0",
"version": "1.1.0",
"description": "continuous integration server that trigger a light allarm on Raspberry GPIO",
"keywords": [
"continuous",
Expand Down
79 changes: 67 additions & 12 deletions src/slackMessageInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class slackMessageInterface {
}

startChannelMessage() {
this.bot.on('start', (function () {
this.bot.on('start', (()=> {
var params = {
icon_emoji: ':robot_face:',
attachments: [
Expand All @@ -48,27 +48,34 @@ class slackMessageInterface {
}
]
};
var allJoinedChannelsByUserId = this._getAllJoinedChannelsByUserId(this.bot.self.id);

this.bot.postMessageToChannel('general', '', params);
}).bind(this));
if (allJoinedChannelsByUserId) {
allJoinedChannelsByUserId.forEach((channel)=> {
console.log('channel' + channel);

this.bot.postTo(channel, '', params);
});
}
}));
}

listenerRequestStatusBuild() {
this.bot.on('message', ((message) => {
if (this.isValidCiMentionMessage(message) && this.isStatusRequest(message)) {
var repoName = this.getRepositoriesNameInMessage(message);

if (repoName) {
this.ciService.getLastBuildStatusByRepository(repoName).then((statusBuild)=> {
var fields = this._createFieldsAdditionInformationMessage(statusBuild);
var lastBuildState = statusBuild.last_build_state ? statusBuild.last_build_state : 'unknown';
var nameChannelOrUser = this._getSlackNameById(message).name;

this.postSlackMessageToChannel('Hi <@' + message.user + '> the build Status was ' + lastBuildState + ' ' + moment(statusBuild.last_build_finished_at).fromNow(), 'Ci status', this.colorByStatus(lastBuildState), fields, 'Build status', statusBuild.linkBuild); // jscs:ignore maximumLineLength
this.postSlackMessage('Hi <@' + message.user + '> the build Status was ' + lastBuildState + ' ' + moment(statusBuild.last_build_finished_at).fromNow(), 'Ci status', this.colorByStatus(lastBuildState), fields, 'Build status', statusBuild.linkBuild, nameChannelOrUser); // jscs:ignore maximumLineLength
}, (error)=> {
this.postSlackMessageToChannel(error.toString(), 'Ci status', this.failColor, null, 'Build status');
this.postSlackMessage(error.toString(), 'Ci status', this.failColor, null, 'Build status');
});
} else {
this.postSlackMessageToChannel('Maybe you want use the command : "status username/example-project" but' +
this.postSlackMessage('Maybe you want use the command : "status username/example-project" but' +
' you forgot to add the repository slug', 'Ci status', this.infoColor, null, 'Build status');
}
}
Expand All @@ -83,8 +90,9 @@ class slackMessageInterface {
if (this.isValidCiMentionMessage(message) && this.isListRepositoryRequest(message)) {

this.ciService.getUserRepositoriesSlugList().then((repositories)=> {
this.postSlackMessageToChannel('Hi <@' + message.user + '> this is the repository list: \n • ' +
repositories.join('\n• ') + 'Repository list', this.infoColor, null, 'Repositories list');
var nameChannelOrUser = this._getSlackNameById(message).name;
this.postSlackMessage('Hi <@' + message.user + '> this is the repository list: \n • ' + repositories.join('\n• ') , 'Repository list',
this.infoColor, null, 'Repositories list', '', nameChannelOrUser);
});
}
}));
Expand All @@ -96,7 +104,10 @@ class slackMessageInterface {
listenerCommandListMessage() {
this.bot.on('message', ((message) => {
if (this.isValidCiMentionMessage(message) && this.isCommandListRequest(message)) {
this.postSlackMessageToChannel('Command list: \n • repository list \n • status username/example-project', this.infoColor, null, 'Repository list');
var nameChannelOrUser = this._getSlackNameById(message).name;
console.log('nameChannelOrUser ' + nameChannelOrUser);
this.postSlackMessage('Hi <@' + message.user + '> this is the command list \n • status username/example-project', 'Command list',
this.infoColor, null, 'Command list', '', nameChannelOrUser);
}
}));
}
Expand All @@ -108,8 +119,11 @@ class slackMessageInterface {
* @param {String} fallback
* @param {successColor|failColor|infoColor} color of the vertical line before the message default infoColor yellow
* @param {Array} fields is an Array of messages { 'title': 'Project', 'value': 'Awesome Project','short': true},
* @param {String} title title message,
* @param {String} titleLink link message
* @param {String} nameChannelOrUser where posts a message channel | group | user by name,
*/
postSlackMessageToChannel(message, fallback, color, fields, title, titleLink) {
postSlackMessage(message, fallback, color, fields, title, titleLink, nameChannelOrUser) {
var params = {
icon_emoji: ':robot_face:',
attachments: [
Expand All @@ -123,7 +137,8 @@ class slackMessageInterface {
}
]
};
this.bot.postMessageToChannel('general', '', params);

this.bot.postTo(nameChannelOrUser, '', params);
}

isFromCiAlarmBotMessage(message) {
Expand Down Expand Up @@ -172,6 +187,46 @@ class slackMessageInterface {
return !this.isFromCiAlarmBotMessage(message) && this.isChatMessage(message) && this.isMentioningCiAlarm(message);
}

/**
* get the message channel Name or user Name by ID
*/
_getSlackNameById(message) {
var name = this.bot.channels.find(function (item) {
return item.id === message.channel;
});

if (!name && this.bot.users) {
name = this.bot.users.find(function (item) {
return item.id === message.user;
});
}
return name;
}

/**
* get all the channel where a user is member
*
* @param {String} userId
*
* @return {Array} Array of all the channels where the user is member
*/
_getAllJoinedChannelsByUserId(userId) {
var userChannels = [];

this.bot.channels.forEach((channel)=> {
if (channel.members) {
var member = channel.members.find((member)=> {
return member === userId;
});
if (member) {
userChannels.push(channel.name);
}
}
});

return userChannels;
}

colorByStatus(status) {
var color = this.infoColor;

Expand Down
51 changes: 51 additions & 0 deletions test/mockObjects/channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';
var _ = require('lodash');

class channel {

static createChannel(attributes) {

var defaultAttributes = {
'id': 'fake-general-channel-id',
'name': 'general',
'is_channel': true,
'created': 1458000230,
'creator': 'U0SNL23B4',
'is_archived': false,
'is_general': true,
'has_pins': false,
'is_member': true,
'unread_count': 807,
'unread_count_display': 806,
'_status': 0,
'_fulfilledCallbacks': [],
'_rejectedCallbacks': [],
'_progressCallbacks': [],
'members': [
'U0SNL23B4',
'1234'
],
'topic': {
'value': 'Company-wide announcements and work-based matters',
'creator': '',
'last_set': 0
},
'purpose': {
'value': 'This channel is for team-wide communication and announcements. All team members are in this channel.',
'creator': '',
'last_set': 0
}
};

return _.extend(defaultAttributes, attributes);
}

static createChannelList() {
return [
this.createChannel()
];
}

}

module.exports = channel;
10 changes: 7 additions & 3 deletions test/slackMessageInterface.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ var expect = require('chai').expect;
var sinon = require('sinon');
var Bot = require('slackbots');

var Channel = require('../test/mockObjects/channel');

describe('Bot Initialization', function () {

beforeEach(function () {
this.textCheck = '';

this.slackbotStub = sinon.stub(Bot.prototype, '_post', (function (type, name, text, message) {
this.textCheck = message.attachments[0].text;
}).bind(this));
this.slackbotStub = sinon.stub(Bot.prototype, 'postTo', (name, text, params) => {
this.textCheck = params.attachments[0].text;
});

this.loginStub = sinon.stub(Bot.prototype, 'login', function () {});

this.slackMessageInterface = new SlackMessageInterface('Fake-token-slack');
this.slackMessageInterface.bot.self = {id: '1234'};
this.slackMessageInterface.bot.channels = Channel.createChannelList();
this.slackMessageInterface.run();
});

Expand Down
26 changes: 17 additions & 9 deletions test/slackMessageInterfaceBotStatusNotify.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,38 @@
'use strict';

var SlackMessageInterface = require('../src/slackMessageInterface');
var TravisService = require('../src/travisService');

var expect = require('chai').expect;
var sinon = require('sinon');
var Bot = require('slackbots');
var TravisService = require('../src/travisService');
var nock = require('nock');

var Repository = require('../test/mockObjects/repository');
var Channel = require('../test/mockObjects/channel');

describe('Bot CI build communication', function () {

beforeEach(function () {
this.textCheck = '';

this.slackbotStub = sinon.stub(Bot.prototype, '_post', (function (type, name, text, message) {
this.textCheck = message.attachments[0].text;
this.colorMessage = message.attachments[0].color;
this.fields = message.attachments[0].fields;
this.title = message.attachments[0].title;
this.title_link = message.attachments[0].title_link;
}).bind(this));
this.slackbotStub = sinon.stub(Bot.prototype, 'postTo', (name, text, params) => {
this.textCheck = params.attachments[0].text;
this.colorMessage = params.attachments[0].color;
this.fields = params.attachments[0].fields;
this.title = params.attachments[0].title;
this.title_link = params.attachments[0].title_link;
});

this.loginStub = sinon.stub(Bot.prototype, 'login', function () {});

this.travisService = new TravisService('github-token');
this.travisService.username = 'mbros';

this.slackMessageInterface = new SlackMessageInterface('Fake-token-slack', this.travisService);
this.slackMessageInterface.run();
this.slackMessageInterface.bot.self = {id: '1234'};
this.slackMessageInterface.bot.channels = Channel.createChannelList();
this.slackMessageInterface.run();
});

afterEach(function () {
Expand Down Expand Up @@ -85,6 +88,7 @@ describe('Bot CI build communication', function () {
this.slackMessageInterface.bot.emit('message', {
username: 'Sonikku',
user: 'C3P0',
channel: 'fake-general-channel-id',
type: 'message',
text: '<@' + this.slackMessageInterface.bot.self.id + '>: status fakeuser/fake-project1'
});
Expand All @@ -109,6 +113,7 @@ describe('Bot CI build communication', function () {
this.slackMessageInterface.bot.emit('message', {
username: 'Sonikku',
user: 'C3P0',
channel: 'fake-general-channel-id',
type: 'message',
text: '<@' + this.slackMessageInterface.bot.self.id + '>: status fakeuser/fake-project2'
});
Expand All @@ -134,6 +139,7 @@ describe('Bot CI build communication', function () {
this.slackMessageInterface.bot.emit('message', {
username: 'Sonikku',
user: 'C3P0',
channel: 'fake-general-channel-id',
type: 'message',
text: '<@' + this.slackMessageInterface.bot.self.id + '>: status fakeuser/fake-project3'
});
Expand All @@ -158,6 +164,7 @@ describe('Bot CI build communication', function () {
this.slackMessageInterface.bot.emit('message', {
username: 'Sonikku',
user: 'C3P0',
channel: 'fake-general-channel-id',
type: 'message',
text: '<@' + this.slackMessageInterface.bot.self.id + '>: status fakeuser/fake-project3 '
});
Expand All @@ -183,6 +190,7 @@ describe('Bot CI build communication', function () {
this.slackMessageInterface.bot.emit('message', {
username: 'Sonikku',
user: 'C3P0',
channel: 'fake-general-channel-id',
type: 'message',
text: '<@' + this.slackMessageInterface.bot.self.id + '>: status fake-project2'
});
Expand Down
Loading

0 comments on commit 6aace21

Please sign in to comment.