Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
AIP endpoint to notify given user
Browse files Browse the repository at this point in the history
command for notifying particular user
readme update
tests
#1
  • Loading branch information
gacek85 committed Apr 21, 2015
1 parent f98de8b commit 9157f46
Show file tree
Hide file tree
Showing 12 changed files with 272 additions and 20 deletions.
12 changes: 8 additions & 4 deletions README.md
Expand Up @@ -37,7 +37,7 @@ For the moment, harvest communication may be only set up using an account. To ha

###SLACK configuration

The Slack part uses a simple **incoming WebHook** that need to be created within the Slack application itself (See [https://api.slack.com/incoming-webhooks](https://api.slack.com/incoming-webhooks)). The only mandatory parameter that need to be set is `endpoint` which is the webhook endpoint. The configuration below contains additional params which are overriding the default settings for the webhook. All [params available for the webhook](https://api.slack.com/incoming-webhooks) can be used except `channel`, which will always be overridden by **slack username** of the user that receives the notifications.
The Slack part uses a simple **incoming WebHook** that needs to be created within the Slack application itself (See [https://api.slack.com/incoming-webhooks](https://api.slack.com/incoming-webhooks)). The only mandatory parameter that need to be set is `endpoint` which is the webhook endpoint. The configuration below contains additional params which are overriding the default settings for the webhook. All [params available for the webhook](https://api.slack.com/incoming-webhooks) can be used except `channel`, which will always be overridden by **slack username** of the user that receives the notifications.

```
"slack" : {
Expand Down Expand Up @@ -68,6 +68,8 @@ For the moment the application is able to:

- send periodical report notifications on Slack management channel defined in `cron.report.channel` setting according to cron time provided in `cron.report.cronTime` section

- send reminder messages via Slack to people who have no timers running according to `cron.remind.cronTime` setting.

```
"cron" : {
"notify" : {
Expand All @@ -93,11 +95,13 @@ If any of the section for `cron` settings are not provided, the cron job will no

The API provides given endpoints:

- `http|https://your.domain.you/notify-all` Notifies all users present in the users config
- `http|https://your.domain.you/notify-all` Notifies all users present in the users config providing information about their started tasks.

- `http|https://your.domain.you/notify-user/user_id` Notifies user given by `user_id` which represents **either Harvest user ID or Slack username** about her/his started tasks.

- `http|https://your.domain.you/notify-user/user_id` Notifies user given by `user_id` which represents **either Harvest user ID or Slack username**
- `http|https://your.domain.you/notify-management` Notifies management channel provided in the `channel` property of the `POST` request.

- `http|https://your.domain.you/notify-management` Notifies management channel provided in the `channel` property of the `POST` request
- `http|https://your.domain.you/remind-all` Triggers notifications to users wo have no tasks started on Harvest.

The `notify-all` and `notify-user` are **actions names**; this will be useful when creating authorization token.

Expand Down
2 changes: 1 addition & 1 deletion app/api/controllers/actions/notify_management.js
Expand Up @@ -36,7 +36,7 @@ function validateCreateDate (dateString)
* @param {Function} next The next callback to apply
* @returns {undefined}
*/
function notifyManagementController(req, res, next)
function notifyManagementController (req, res, next)
{
var from = req.body.from || null,
to = req.body.to || null,
Expand Down
4 changes: 2 additions & 2 deletions app/api/controllers/actions/reminder_all.js
Expand Up @@ -35,10 +35,10 @@ function doNotify (harvestResponse, userId)
*/
function remindAllController (req, res, next)
{
reminder.remind(harvest.users, function () {
reminder.remind(harvest.users, function () {
res.success = true;
next();
});
});
}

module.exports = function (app, config)
Expand Down
59 changes: 59 additions & 0 deletions app/api/controllers/actions/reminder_user.js
@@ -0,0 +1,59 @@
/*jshint node: true*/
'use strict';

var harvest = require('./../../../services/harvest')('default'),
notifier = require('./../../../services/notifier'),
_ = require('lodash'),
logger = require('./../../../services/logger.js')('default'),
reminder = require('./../../../services/reminder/index'),
tools = require('./../../../services/tools.js')
;


/**
* Notifies the users on Slack
*
* @param {Object} harvestResponse The harvest API response
* @param {Number} userId The harvest user Id
* @returns {undefined}
*/
function doNotify (harvestResponse, userId)
{
notifier.notify('reminder', {
harvestUserId : userId,
harvestResponse : harvestResponse
});
}


/**
* Notifies all mapped slack users to activate their Harvest if that's not done.
*
* @param {Object} req The request object
* @param {Object} res The response object
* @param {Function} next The next callback to apply
* @returns {undefined}
*/
function remindUserController (req, res, next)
{
var users;
try {
users = tools.validateGetUser(harvest.users, req.params.user);
} catch (err) {
res.success = false;
res.errors = [
err.message
];
next();
return;
}
reminder.remind(users, function () {
res.success = true;
next();
});
}

module.exports = function (app, config)
{
app.use('/api/remind-user/:user', remindUserController);
};
3 changes: 2 additions & 1 deletion app/services/cronjobs/lib/jobs.js
Expand Up @@ -56,7 +56,8 @@ JobsHolder.prototype = {
cronTime = job.getCronTime(config),
handler = job.getJob(config),
description = job.getDescription(),
autoRun = job.shouldRunNow();
autoRun = job.shouldRunNow()
;

logger.info('Setting up cron job for: "' + description + '" with cron time: ', cronTime, {});

Expand Down
32 changes: 30 additions & 2 deletions app/services/interactive_session/index.js
Expand Up @@ -145,16 +145,39 @@ if (resolver === null) {
remind : {
execute : function (params, callback)
{
var userId = params.name,
users,
error = null
;
if (!!userId) {
try {
users = tools.validateGetUser(harvest.users, userId);
} catch (err) {
users = null;
error = err;
}
} else {
users = harvest.users;
}
var step = interactiveSession
.getDefault()
.createStep(params.userId, {}, params.action)
.addParam('users', users)
.addParam('error', error)
;
callback(null, step);
},

postExecute : function (step, callback)
{
reminder.remind(harvest.users, null, function (results) {
var users = step.getParam('users'),
error = step.getParam('error')
;
if (error !== null) {
callback();
return;
}
reminder.remind(users, null, function (results) {
step.addParam('results', results);

var userId = step.getParam('userId');
Expand All @@ -175,7 +198,12 @@ if (resolver === null) {
getView : function (step)
{
var results = step.getParam('results'),
view = [];
error = step.getParam('error'),
view = []
;
if (error) {
return error.message;
}

if (Object.size(results.notified) > 0) {
view.push('Notified given users:');
Expand Down
30 changes: 30 additions & 0 deletions app/services/tools.js
Expand Up @@ -145,6 +145,36 @@ module.exports = {
}

return obj[param];
},


/**
* Validates if correct user has been sent
*
* @param {Object} users A map of harvest id -> slack name of all
* configured users
* @param {String} userId Either harvest id or slack name
* @returns {Object} A hashmap of harvestId -> slackName
* @throws {Error} If invalid user provided
*/
validateGetUser : function (users, userId)
{
var userMap = {},
found = false
;

_.each(users, function (slackName, harvestId) {
if ((String(harvestId) === String(userId)) || (String(slackName) === String(userId))) {
userMap[harvestId] = slackName;
found = true;
}
});

if (!found) {
throw new Error('Invalid user provided.');
} else {
return userMap;
}
}

};
3 changes: 3 additions & 0 deletions config.dist.json
Expand Up @@ -40,6 +40,9 @@
"report" : {
"reportTitle" : "Weekly activity report",
"channel" : "#channel_name"
},
"remind" : {
"cronTime" : "00 00 12 * * 1-5"
}
},
"logger" : {
Expand Down
74 changes: 74 additions & 0 deletions test/functional/commands.js
Expand Up @@ -189,6 +189,80 @@ describe('Functional: Non-dialogue commands', function () {
});
});

it ([
'Should call harvest API and grab given user current timeline ',
'Send remind messages to this user with empty timeline. ',
'Returns message that says which user received the notification.'
].join('\n'), function (done) {

var sendMessage = slack.sendMessage;
harvestModule.client.get = function (url, data, cb) {
cb(null, []);
};

slack.sendMessage = function (text, config, callback)
{
callback(null, true, '');
};


harvest.users = {
23456 : 'some_user'
};

request.post({
url : 'http://localhost:3333/api/timer',
form : {
token : 'thisissomeauthtoken',
user_name : 'some_user',
text : 'remind 23456'
}
}, function (err, res, body) {
slack.sendMessage = sendMessage;
var view = [
'Notified given users:',
'',
'some_user'
];
expect(body).to.be.equal(view.join('\n'));
done();
});
});


it ('Should return an error response if invalid user was provided.', function (done) {

var sendMessage = slack.sendMessage;
harvestModule.client.get = function (url, data, cb) {
cb(null, []);
};

slack.sendMessage = function (text, config, callback)
{
callback(null, true, '');
};


harvest.users = {
23456 : 'some_user'
};

request.post({
url : 'http://localhost:3333/api/timer',
form : {
token : 'thisissomeauthtoken',
user_name : 'some_user',
text : 'remind some_non_existing_user'
}
}, function (err, res, body) {
slack.sendMessage = sendMessage;

expect(body).to.be.equal('Invalid user provided.');

done();
});
});


it ([
'Should call harvest API and grab all users current timelines. ',
Expand Down
2 changes: 1 addition & 1 deletion test/functional/notifications.js
Expand Up @@ -39,7 +39,7 @@ describe('Functional: Notifications', function () {
var userId = 2345;

harvestMock.setUsers({
'2345' : 'some_test_user'
'23456' : 'some_test_user'
});


Expand Down
18 changes: 9 additions & 9 deletions test/unit/services/reminder/index.js
Expand Up @@ -56,10 +56,10 @@ describe('reminder', function () {
describe('remind', function () {

it('Should send reminder messages to all people whose harvest day entries reports are empty.', function (done) {
var users = {
'1234' : 'some_user1',
'2345' : 'some_user2',
'3456' : 'some_user3'
var users = {
'12345' : 'some_user1',
'23456' : 'some_user2',
'34567' : 'some_user3'
},
counter = 0,
sendMessage = slack.sendMessage
Expand Down Expand Up @@ -99,14 +99,14 @@ describe('reminder', function () {


expect(results.successes).to.be.deep.equal({
'1234' : 'some_user1',
'2345' : 'some_user2',
'3456' : 'some_user3'
'12345' : 'some_user1',
'23456' : 'some_user2',
'34567' : 'some_user3'
});

expect(results.notified).to.be.deep.equal({
'1234' : 'some_user1',
'3456' : 'some_user3'
'12345' : 'some_user1',
'34567' : 'some_user3'
});

expect(results.errors).to.be.deep.equal({});
Expand Down

0 comments on commit 9157f46

Please sign in to comment.