UNPKG

hubot-bamboo-goodmorning

Version:

A hubot scripts that says goodmorning in the way we like it

210 lines (176 loc) 4.72 kB
// 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> 'use strict'; 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]._)); }); }); }