Last active
August 29, 2015 14:13
-
-
Save dalehamel/ce9bfe7c8a2f4addb03a to your computer and use it in GitHub Desktop.
Victorops coffeescript WIP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Description: | |
# This script can be used to interact with VictorOps schedules, and page VictorOps teams | |
# | |
# Configuration: | |
# HUBOT_VICTOROPS_USER - The username of the hubot user in the VictorOps org | |
# HUBOT_VICTOROPS_PASS - The password of the hubot user in the VictorOps org | |
# HUBOT_VICTOROPS_REST - The API token to use | |
# Commands: | |
# hubot oncall - Lists the teams you can check (working) | |
# hubot oncall <team> - Shows who is on-call right now for a team (working but only for the first rotation in a schedule due to victorops API bug) | |
# hubot page - Lists the teams you can page (working) | |
# hubot page <team> [message] - Pages the team specified | |
moment = require 'moment' | |
module.exports = (robot) -> | |
# maybe move this out into a config variable but whatever good enough for now | |
aliases = | |
"operations" : [ "op","ops","operation"] | |
class VictorOps | |
constructor: -> | |
@hubot_user = process.env.HUBOT_VICTOROPS_USER | |
@hubot_pass = process.env.HUBOT_VICTOROPS_PASS | |
@vo_rest = process.env.HUBOT_VICTOROPS_REST | |
@sched_api = "https://#{@hubot_user}:#{@hubot_pass}@portal.victorops.com/api/v1/org/shopify-inc/teams?days_forward=1" | |
@pager_api = "https://alert.victorops.com/integrations/generic/20131114/alert/#{@vo_rest}" | |
# Queries VictorOps for the oncall schedule | |
get_schedule: (callback) -> | |
robot.http(@sched_api).get() (err,res,body) -> | |
callback? JSON.parse(body) | |
# Get an object containing the current oncall data for each team | |
parse_schedule: (schedule) -> | |
oncall = {} | |
# At the minimum, add all teams to the oncall object | |
oncall[team["slug"]] = {} for team in schedule | |
for team in schedule | |
# A shift that has an on | |
current_shift = shift for shift in team["oncall"] when "oncall" of shift | |
# Add the information for the current shift to the oncall object | |
if current_shift? | |
user = current_shift["oncall"] | |
name = current_shift["shift_name"] | |
end_stamp = roll["until"] for roll in current_shift["rolls"] when roll["change"] == current_shift["shift_roll"] | |
end = moment.unix(end_stamp / 1000).format('YYYY-MM-DD HH:mm:ss') | |
oncall[team["slug"]]["primary"] = { user : user, shift : name, end: end} # FIXME VictorOps isn't returning all rotations for a schedule | |
current_shift = null | |
return oncall | |
page_team: (team, message, user, cb) -> | |
response = "Paged!" | |
robot.victorops.get_schedule (schedule) -> | |
oncall = robot.victorops.parse_schedule schedule | |
# If the team requested to be paged doesn't exist, abort | |
response = "I'm sorry #{user}, I don't know about the #{team} team" unless team of oncall | |
cb? response unless team of oncall | |
return unless team of oncall | |
# Build the webook payload | |
payload = | |
entity_id: 'hubot_page' | |
paged_by: user | |
message_type: 'CRITICAL' | |
state_message: message | |
entity_display_name: "#{user} manually paged via hubot: #{message}" | |
endpoint = "#{robot.victorops.pager_api}/#{team}" | |
# Send the payload | |
robot.http(endpoint) | |
.post(JSON.stringify(payload)) (err, res, body) -> | |
result = JSON.parse(body) | |
# Notify of any errors | |
response = "Sorry #{user}, I failed to page #{team} because: #{result["message"]}" unless result["result"] == "success" | |
cb? response | |
# Add the victorops object to the robot, so other scripts can page if needed | |
robot.victorops = new VictorOps | |
# A bit of a hack, allows for dereferencing aliase to a team | |
dealias = (alias) -> | |
return alias if alias of aliases | |
teams = ( team for team,teams_aliases of aliases when alias in teams_aliases) | |
return teams[0] if teams.length > 0 | |
return alias if teams.length == 0 | |
# Page a team, optionally supply a message | |
robot.respond /page\s+(\S+)(\s+)?(.+)?/, (msg) -> | |
alias = msg.match[1] | |
message = msg.match[3] or "No message provided" | |
team = dealias alias | |
robot.victorops.page_team team, message, msg.message.user.name, (response) -> | |
msg.send response | |
# Notify of who is on call | |
robot.respond /on(\s*)call\s+(\S+)/, (msg) -> | |
alias = msg.match[2] | |
team = dealias alias | |
robot.victorops.get_schedule (schedule) -> | |
oncall = robot.victorops.parse_schedule schedule | |
return msg.send "I'm sorry #{msg.message.user.name}, I don't know about the #{team} team" unless team of oncall | |
return msg.send "Uh oh #{msg.message.user.name}, it looks like no on is oncall for #{team} team" if Object.keys(oncall[team]).length == 0 | |
msg.send """Hi #{msg.message.user.name}, the following users are oncall for the #{team} team: | |
#{( "#{rotation}: #{shift['user']} is on call for the #{shift['shift']} shift until #{shift['end']}" for rotation,shift of oncall[team]).join("\n")} | |
IMPORTANT: #{robot.name} did not page #{team}. Use #{robot.name} page #{team} [message] | |
""" | |
# Provide a list of teams with oncall schedules | |
robot.respond /(oncall|page)$/i, (msg) -> | |
action = msg.match[1] | |
robot.victorops.get_schedule (schedule) -> | |
oncall = robot.victorops.parse_schedule schedule | |
teams= "#{("#{team}#{if team of aliases then " (#{aliases[team].join("|")})" else ""}" for team,rotations of oncall).join(', ')}" | |
msg.send """ | |
Hi #{msg.message.user.name}, which oncall team did you need? | |
I know about these teams: #{teams} | |
Usage: #{robot.name} #{action} <team> | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment