UNPKG

hubot-victorops-bot

Version:

A hubot script to quickly view or page the person on call in victorops

132 lines (116 loc) 4.08 kB
# Description: # Quickly view or page the person on call in victorops # # Dependencies: # - coffee-script # - node-fetch # - moment # - ical # - fuzzy # - underscore # # Configuration: # HUBOT_VICTOROPS_POST_URL - REST Endpoint for Victorops # HUBOT_VICTOROPS_TEAMS_MAP `\{\"ops\":\"devops\",\"data\":\"data\"\}` # HUBOT_VICTOROPS_TEAMS_ICAL `\{\"devops\":\"URL_TO_ICS\",\"data\":\"URL_TO_ICS\"\}` # # Commands: # hubot page oncall <optional message> # hubot whois oncall # # Author: # ndaversa _ = require 'underscore' fetch = require 'node-fetch' moment = require 'moment' ical = require 'ical' fuzzy = require 'fuzzy' module.exports = (robot) -> users = robot.adapter?.client?.rtm?.dataStore?.users or robot.brain.users() url = process.env.HUBOT_VICTOROPS_POST_URL teams = JSON.parse process.env.HUBOT_VICTOROPS_TEAMS_MAP calendars = JSON.parse process.env.HUBOT_VICTOROPS_TEAMS_ICAL getRoom = (context) -> room = robot.adapter.client.rtm.dataStore.getChannelOrGroupByName context.message.room room = robot.adapter.client.rtm.dataStore.getChannelGroupOrDMById context.message.room unless room room parseJSON = (response) -> return response.json() checkStatus = (response) -> if response.status >= 200 and response.status < 300 return response else error = new Error(response.statusText) error.response = response throw error invalidChannel = (msg) -> channels = [] for team, key of teams channel = getRoom message: room: team channels.push " <\##{channel.id}|#{channel.name}>" if channel return msg.reply "You can only page for oncall in one of the following project channels: #{channels}" lookupUser = (name) -> name = name.replace '.', ' ' if name? users = _(users).keys().map (id) -> user = users[id] id: id name: user.real_name || user.name results = fuzzy.filter name, users, extract: (user) -> user.name if results?.length >= 1 return "<@#{results[0].original.id}>" else return name whoIsOncall = (team, cb) -> now = moment() calendar = calendars[team] ical.fromURL calendar, {}, (err, data) -> events = _(data).keys().map (id) -> event = data[id] start: moment event.start end: moment event.end summary: event.summary id: id .filter (event) -> now.isBetween event.start, event.end if events.length is 1 oncall = events[0] else events = events.filter (event) -> event.summary.indexOf('OVERRIDE') > -1 if events.length is 1 oncall = events[0] if oncall [ __, person ] = oncall.summary.match /(?:OVERRIDE:\s)?(.*)/ cb person robot.respond /page on\s?call(?:\s+(.*))?/, (msg) -> [ __, message ] = msg.match room = getRoom msg team = teams[room.name] return invalidChannel msg unless team whoIsOncall team, (person) -> if person fetch "#{url}#{team}", method: "POST" body: JSON.stringify entity_id: "slack-ops" message_type: "critical" entity_display_name: "Paged by @#{msg.message.user.name} in ##{room.name}" state_message: message .then (res) -> checkStatus res .then (res) -> parseJSON res .then (json) -> msg.reply "Paged #{lookupUser person} whom is on call for the `#{team}` team in victorops" .catch (error) -> console.log "*[Error]* #{error}" msg.reply "I have failed at paging #{lookupUser person}. I am shamed" else msg.reply "I can't determine who is on call, please contact your friendly administrator" robot.respond /who\s?is on\s?call/, (msg) -> room = getRoom msg team = teams[room.name] return invalidChannel msg unless team whoIsOncall team, (person) -> if person msg.reply "#{lookupUser person} is on duty for the `#{team}` team" else msg.reply "I can't determine who is on call, please contact your friendly administrator"