Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

231 lines (188 sloc) 6.947 kb
# Description:
# Messing with the JIRA REST API
#
# Dependencies:
# None
#
# Configuration:
# HUBOT_JIRA_URL
# HUBOT_JIRA_USER
# HUBOT_JIRA_PASSWORD
# Optional environment variables:
# HUBOT_JIRA_USE_V2
# HUBOT_JIRA_MAXLIST
# HUBOT_JIRA_ISSUEDELAY
# HUBOT_JIRA_IGNOREUSERS
#
# Commands:
# <Project Key>-<Issue ID> - Displays information about the ticket (if it exists)
# hubot show watchers for <Issue Key> - Shows watchers for the given issue
# hubot search for <JQL> - Search JIRA with JQL
# hubot save filter <JQL> as <name> - Save JQL as filter in the brain
# hubot use filter - Use a filter from the brain
# hubot show filter(s) - Show all filters
# hubot show filter <name> - Show a specific filter
#
# Author:
# codec
class IssueFilters
constructor: (@robot) ->
@cache = []
@robot.brain.on 'loaded', =>
@cache = @robot.brain.data.jqls
add: (filter) ->
@cache.push filter
@robot.brain.data.jqls = @cache
delete: (name) ->
result = []
@cache.forEach (filter) ->
if filter.name isnt name
result.push filter
@cache = result
@robot.brain.data.jqls = @cache
get: (name) ->
result = null
@cache.forEach (filter) ->
if filter.name is name
result = filter
result
all: ->
return @cache
class IssueFilter
constructor: (@name, @jql) ->
return {name: @name, jql: @jql}
# keeps track of recently displayed issues, to prevent spamming
class RecentIssues
constructor: (@maxage) ->
@issues = []
cleanup: ->
for issue,time of @issues
age = Math.round(((new Date()).getTime() - time) / 1000)
if age > @maxage
#console.log 'removing old issue', issue
delete @issues[issue]
0
contains: (issue) ->
@cleanup()
@issues[issue]?
add: (issue,time) ->
time = time || (new Date()).getTime()
@issues[issue] = time
module.exports = (robot) ->
filters = new IssueFilters robot
useV2 = process.env.HUBOT_JIRA_USE_V2 || false
# max number of issues to list during a search
maxlist = process.env.HUBOT_JIRA_MAXLIST || 10
# how long (seconds) to wait between repeating the same JIRA issue link
issuedelay = process.env.HUBOT_JIRA_ISSUEDELAY || 30
# array of users that are ignored
ignoredusers = (process.env.HUBOT_JIRA_IGNOREUSERS.split(',') if process.env.HUBOT_JIRA_IGNOREUSERS?) || []
recentissues = new RecentIssues issuedelay
get = (msg, where, cb) ->
console.log(process.env.HUBOT_JIRA_URL + "/rest/api/latest/" + where)
authdata = new Buffer(process.env.HUBOT_JIRA_USER+':'+process.env.HUBOT_JIRA_PASSWORD).toString('base64')
msg.http(process.env.HUBOT_JIRA_URL + "/rest/api/latest/" + where).
header('Authorization', 'Basic ' + authdata).
get() (err, res, body) ->
cb JSON.parse(body)
watchers = (msg, issue, cb) ->
get msg, "issue/#{issue}/watchers", (watchers) ->
if watchers.errors?
return
cb watchers.watchers.map((watcher) -> return watcher.displayName).join(", ")
info = (msg, issue, cb) ->
get msg, "issue/#{issue}", (issues) ->
if issues.errors?
return
if useV2
issue =
key: issues.key
summary: issues.fields.summary
assignee: ->
if issues.fields.assignee != null
issues.fields.assignee.displayName
else
"no assignee"
status: issues.fields.status.name
fixVersion: ->
if issues.fields.fixVersions? and issues.fields.fixVersions.length > 0
issues.fields.fixVersions.map((fixVersion) -> return fixVersion.name).join(", ")
else
"no fix version"
url: process.env.HUBOT_JIRA_URL + '/browse/' + issues.key
else
issue =
key: issues.key
summary: issues.fields.summary.value
assignee: ->
if issues.fields.assignee.value != undefined
issues.fields.assignee.value.displayName
else
"no assignee"
status: issues.fields.status.value.name
fixVersion: ->
if issues.fields.fixVersions? and issues.fields.fixVersions.value != undefined
issues.fields.fixVersions.value.map((fixVersion) -> return fixVersion.name).join(", ")
else
"no fix version"
url: process.env.HUBOT_JIRA_URL + '/browse/' + issues.key
cb "[#{issue.key}] #{issue.summary}. #{issue.assignee()} / #{issue.status}, #{issue.fixVersion()} #{issue.url}"
search = (msg, jql, cb) ->
get msg, "search/?jql=#{escape(jql)}", (result) ->
if result.errors?
return
resultText = "I found #{result.total} issues for your search. #{process.env.HUBOT_JIRA_URL}/secure/IssueNavigator.jspa?reset=true&jqlQuery=#{escape(jql)}"
if result.issues.length <= maxlist
cb resultText
result.issues.forEach (issue) ->
info msg, issue.key, (info) ->
cb info
else
cb resultText + " (too many to list)"
robot.respond /(show )?watchers (for )?(\w+-[0-9]+)/i, (msg) ->
if msg.message.user.id is robot.name
return
watchers msg, msg.match[3], (text) ->
msg.send text
robot.respond /search (for )?(.*)/i, (msg) ->
if msg.message.user.id is robot.name
return
search msg, msg.match[2], (text) ->
msg.reply text
robot.respond /([^\w\-]|^)(\w+-[0-9]+)(?=[^\w]|$)/ig, (msg) ->
if msg.message.user.id is robot.name
return
if (ignoredusers.some (user) -> user == msg.message.user.name)
console.log 'ignoring user due to blacklist:', msg.message.user.name
return
for matched in msg.match
ticket = (matched.match /(\w+-[0-9]+)/)[0]
if !recentissues.contains msg.message.user.room+ticket
info msg, ticket, (text) ->
msg.send text
recentissues.add msg.message.user.room+ticket
robot.respond /save filter (.*) as (.*)/i, (msg) ->
filter = filters.get msg.match[2]
if filter
filters.delete filter.name
msg.reply "Updated filter #{filter.name} for you"
filter = new IssueFilter msg.match[2], msg.match[1]
filters.add filter
robot.respond /delete filter (.*)/i, (msg) ->
filters.delete msg.match[1]
robot.respond /(use )?filter (.*)/i, (msg) ->
name = msg.match[2]
filter = filters.get name
search msg, filter.jql, (text) ->
msg.reply text
robot.respond /(show )?filter(s)? ?(.*)?/i, (msg) ->
if filters.all().length == 0
msg.reply "Sorry, I don't remember any filters."
return
if msg.match[3] == undefined
msg.reply "I remember #{filters.all().length} filters"
filters.all().forEach (filter) ->
msg.reply "#{filter.name}: #{filter.jql}"
else
filter = filters.get msg.match[3]
msg.reply "#{filter.name}: #{filter.jql}"
Jump to Line
Something went wrong with that request. Please try again.