hubot-pairbot
Version:
Simple support for pair programming in Hubot
218 lines (181 loc) • 5.58 kB
text/coffeescript
# Description
# Forwards messages to a pair.
#
# Dependencies
#
#
# Configuration
#
#
# Commands
# pairbot start pairing with <user>
# pairbot stop pairing
# pairbot clear pairs
# pairbot list pairs
# pairbot help
#
# Notes
# - 'start pairing' will clobber any previous pairing.
#
# Author:
# fhwrdh@fhwrdh.net
_ = require 'underscore'
moment = require 'moment'
stringify = JSON.stringify
metadata = require('../package.json')
commands =
start: [
'spw'
'pair with'
'pairing with'
'start pairing with'
'start with'
'start'
'i\'m pairing with'
].join('|')
stop: [
'spw'
'stop pairing'
'done pairing'
'end pairing'
'not pairing'
'stop'
'done'
].join('|')
list: [
'list pairs'
'list pairing'
'list'
].join('|')
clear: [
'clear pairs'
'clear pairing'
'clear'
].join('|')
about: [
'about'
'version'
'tell .* about yourself'
'who are you(\\?*)'
'what are you(\\?*)'
].join('|')
START_PAIRING = ///(#{commands.start})\s+(.+)///i
STOP_PAIRING = ///(#{commands.stop})$///i
LIST_PAIRS = ///(#{commands.list})$///i
CLEAR_PAIRS = ///(#{commands.clear})$///i
ABOUT = ///(#{commands.about})$///i
HELP = ///(\?|help)///i
getStorage = (robot) ->
return JSON.parse(robot.brain.get 'pairbot') or {}
setStorage = (robot, data) ->
robot.brain.set 'pairbot', stringify(data)
startPair = (robot, msg) ->
data = getStorage robot
user = msg.message.user.name
pair = msg.match[2]
if user == pair
msg.reply "Pairing with yourself is considered harmful :)"
return
data[user] = { pair: pair, ts: moment.utc() }
setStorage robot, data
msg.reply "Got it, you are now pairing with #{pair}"
stopPair = (robot, msg) ->
data = getStorage robot
sender = msg.message.user.name
# the sender could be on either side of the pairing
# did it come from the principal?
if data[sender]?
foundPair = data[sender]
principal = sender
other = foundPair["pair"]
else
# iterate through all pairs, looking for the sender as the other
foundPair = _.find _.pairs(data), (pair) ->
return pair[1].pair == sender
if foundPair?
principal = foundPair[0]
other = sender
if not foundPair?
msg.reply "Hmmm, didn't have you in the list"
else
delete data[principal]
setStorage robot, data
notSender = if principal == sender then other else principal
msg.reply "Got it, you are done pairing with #{notSender}"
listPairs = (robot, msg) ->
data = getStorage robot
if not data or _.keys(data).length == 0
msg.send "Looks like nobody is pairing right now? Weird."
else
count = _.keys(data).length
msg.send "Listing #{count} pairs:"
_.each data, (value, key) ->
time = moment(value.ts).fromNow()
msg.send " #{key} pairing with #{value.pair} since #{time}"
clearPairs = (robot, msg) ->
data = getStorage robot
setStorage robot, {}
msg.send "Ok, hope you know what you are doing. All pairs cleared."
sendAbout = (robot, msg) ->
msg.send "#{robot.name} v#{metadata.version}"
sendHelp = (robot, msg) ->
msg.send "Need help? I respond to the following commands (and a few aliases):"
msg.send " start pairing with <user>"
msg.send " stop pairing"
msg.send " list pairs"
msg.send " help"
msg.send " about"
handleError = (robot, error, msg) ->
robot.logger.error "Error: #{error} / #{msg}"
if msg?
msg.reply "Ouch. that made me uncomfortable and I don't know why. Maybe a bug? You might file something to #{metadata.bugs.url}"
extras =
Shell: 'testing'
getExtrasFor = (user) ->
extra = extras[user]
if extra?
return " (#{extra})"
''
listen = (robot, msg) ->
return if STOP_PAIRING.test msg.message
return if START_PAIRING.test msg.message
return if LIST_PAIRS.test msg.message
return if CLEAR_PAIRS.test msg.message
data = getStorage robot
found = _.find _.keys(data), (key) ->
return ///\b#{key}\b///.test msg.message.text
return unless found
pairing = data[found]
# dont repeat the message is the pair is already mentioned
pairMentioned = ///\b#{pairing.pair}\b///.test msg.message.text
return if pairMentioned
# don't repeat the message if sent from the pair
sender = msg.message.user.name
return if sender == pairing.pair
extrasForFound = getExtrasFor found
msg.send "#{pairing.pair}: ^^^^^ #{extrasForFound}"
module.exports = (robot) ->
robot.respond HELP, (msg) ->
sendHelp robot, msg
robot.respond ABOUT, (msg) ->
sendAbout robot, msg
robot.respond START_PAIRING, (msg) ->
startPair robot, msg
robot.respond STOP_PAIRING, (msg) ->
stopPair robot, msg
robot.respond LIST_PAIRS, (msg) ->
listPairs robot, msg
robot.respond CLEAR_PAIRS, (msg) ->
clearPairs robot, msg
robot.respond /(.*)/, (msg) ->
if msg.match[1] == ''
sendHelp robot, msg
robot.hear /(.*)/, (msg) ->
listen robot, msg
robot.error (error, msg) ->
handleError robot, error, msg
testHelper =
testListen: listen
testStartPair: startPair
testStopPair: stopPair
return testHelper