hubot-bamboo-goodmorning
Version:
A hubot scripts that says goodmorning in the way we like it
210 lines (176 loc) • 4.72 kB
JavaScript
// Description
//
// A hubot scripts that says goodmorning in the way we like it.
//
// Configuration:
//
// MORNING_ROOM_ID
// MORNING_TIME - The latest time that it should post to the room. like 9:15
// HUBOT_BAMBOOHR_APIKEY
// HUBOT_BAMBOOHR_DOMAIN
//
// Commands
//
// Notes:
//
// Author:
// Farid Nouri Neshat <Farid@Olindata.com>
;
const random = require('just-random');
const Bamboohr = require('node-bamboohr');
const moment = require('moment');
const arrayToSentence = require('array-to-sentence');
const schedule = require('node-schedule');
const uniq = require('lodash.uniq');
const giphy = require('giphy-api')();
const bamboohr = new Bamboohr({
apikey: process.env.HUBOT_BAMBOOHR_APIKEY,
subdomain: process.env.HUBOT_BAMBOOHR_DOMAIN,
});
const ONE_HOUR = 1000 * 60 * 60;
const MAX_CLUMSY_TIME = ONE_HOUR / 2;
const ONE_DAY = ONE_HOUR * 24;
const mornings = [
'marnin',
'morning',
'morning',
'morning',
'morning',
'morning',
'morning',
'moin',
'morgen',
'goedemorgen',
'buenos días',
'salamat pagi',
'bonjour'
];
const place = [
'AWS',
'cloud',
'home',
'the VPC',
'EC2',
'office'
];
const WEEK_DAY = Symbol('week day');
const giphyTerms = [
WEEK_DAY,
'good morning',
'good morning',
'morning',
'morning',
'start working',
'happy'
];
const endings = ['.', '.', '.', '!', '!', '...', '...', '!!!'];
const smileys = ['', '', '', '', '', '', ' :D', ' :)', ' ;)'];
const isLikely = (p = 0.15) => Math.random() < p;
const isMorning = () => {
const hour = new Date().getHours();
return hour <= 11 && hour >= 5;
};
const rule = new schedule.RecurrenceRule();
[rule.hour, rule.minute] = process.env.MORNING_TIME.split(':');
rule.dayOfWeek = new schedule.Range(1, 5);
const morningsRegex = new RegExp('.*(' + uniq(mornings).join('|') + ')', 'i');
module.exports = function (robot) {
schedule.scheduleJob(rule, post);
robot.respond(morningsRegex, post);
robot.hear(morningsRegex, res => {
if (res.message.room !== process.env.MORNING_ROOM_ID) {
return;
}
if (isMorning()) {
const next = moment().startOf('hour').hour(rule.hour).minute(rule.minute);
const timeSet = Math.min(next - Date.now(), MAX_CLUMSY_TIME);
setTimeout(post, Math.random() * timeSet);
}
});
let lastTime = null;
async function post() {
const day = Math.floor(Date.now() / ONE_DAY);
if (day <= lastTime) {
return;
}
lastTime = day;
let message = random(mornings);
if (isLikely()) {
if (isLikely()) {
message += ' awesome';
}
message += ' people';
}
if (isLikely()) {
message += random(endings) + ' ';
if (isLikely()) {
message += 'I\'m';
}
message += 'working from ' + random(place);
if (isLikely()) {
message += ' today';
}
}
if (isLikely()) {
message += '. Ready for your commands';
}
message += random(endings) + random(smileys);
const gifPromise = getGif();
// We call this function without await, so it runs parallel to getTimeOffs
const timeOffs = await getTimeOffs();
if (isLikely()) {
message += '\nLet me see who\'s off today.';
if (!timeOffs.length) {
message += 'Seems to be everyone is coming to work today!'
}
}
if (timeOffs.length) {
if (isLikely(0.5)) {
message += ' Today ';
if (timeOffs.length === 1) {
message += timeOffs[0] + ' is off.';
} else {
message += arrayToSentence(timeOffs) + ' are off.';
}
} else {
if (timeOffs.length === 1) {
message += ' ' + timeOffs[0] + ' is off today.';
} else {
message += ' ' + arrayToSentence(timeOffs) + ' are off today.';
}
}
}
message += await gifPromise;
robot.messageRoom(process.env.MORNING_ROOM_ID, message);
}
};
async function getGif() {
if (!isLikely()) {
return '';
}
const randomOffset = Math.round(Math.random() * 100);
let term = random(giphyTerms);
if (term === WEEK_DAY) {
term = moment().format('dddd')
}
const giphySearch = await giphy.search({
q: term,
offset: randomOffset,
limit: 1
});
return giphySearch.data[0] && ('\n' + giphySearch.data[0].images.original.url) || '';
}
function getTimeOffs() {
return new Promise((resolve, reject) => {
bamboohr.whosOut(moment().startOf('day').toDate(), moment().endOf('day').toDate(), (err, result) => {
if (err) {
reject(err);
return;
}
if (!result.calendar) {
return resolve([]);
}
resolve(result.calendar.item.map(item => item.employee[0]._));
});
});
}