Skip to content

Instantly share code, notes, and snippets.

@doitian
Created December 9, 2013 19:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doitian/7879278 to your computer and use it in GitHub Desktop.
Save doitian/7879278 to your computer and use it in GitHub Desktop.
Send gitlab notifications through hubot API, customized color and messages comparing to the bult-in hipchat service integration in Gitlab
# Description:
# Post gitlab related events using gitlab hooks and hipchat API
#
# Dependencies:
# "url" : ""
# "querystring" : ""
#
# Configuration:
# HIPCHAT_TOKEN
# GITLAB_ROOT
# GITLAB_TOKEN
# GITLAB_HIPCHAT_ROOMS
# GITLAB_HIPCHAT_DEBUG
# GITLAB_HIPCHAT_LANG
#
# Put http://<HUBOT_URL>:<PORT>/gitlab/system as your system hook
# Put http://<HUBOT_URL>:<PORT>/gitlab/web as your web hook (per repository)
# You can also append "?targets=#room1,#room2" to the URL to control the
# message destination.
#
# Commands:
# None
#
# URLS:
# /gitlab/system
# /gitlab/web
#
# Author:
# ian
url = require 'url'
querystring = require 'querystring'
http = require 'http'
https = require 'https'
class Formatter
constructor: (@gh) ->
h: (str) ->
str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
b: (str) ->
"<b>#{@h(str)}</b>"
linkTo: (str, href = '#') ->
"<a href=\"#{href}\">#{@h(str)}</a>"
linkToUser: (name, id, cb) ->
if id
@gh.getGitlabUserName id, (err, username) =>
unless err
cb @linkTo(name, [@gh.config.gitlab_root, 'u', username].join('/'))
else
cb @b(name)
linkToProject: (name, id, cb) ->
@gh.getGitlabProjectUrl id, (err, url) =>
cb @linkTo(name, url) unless err
linkToCommit: (id, url) ->
@linkTo id[0..5], url
project_create_color: 'green'
project_create: (hook, cb) ->
projectUrl = [@gh.config.gitlab_root, hook.path_with_namespace].join('/')
cb "#{@b(hook.owner_name)} created project #{@linkTo(hook.name, projectUrl)}"
project_destroy_color: 'red'
project_destroy: (hook, cb) ->
cb "Project #{@b(hook.name)} was deleted"
user_add_to_team_color: 'yellow'
user_add_to_team: (hook, cb) ->
@linkToProject hook.project_name, hook.project_id, (projectLink) =>
cb "#{@b(hook.project_access)} access to project #{projectLink} was granted to #{@b(hook.user_name)}"
user_remove_from_team_color: 'red'
user_remove_from_team: (hook, cb) ->
@linkToProject hook.project_name, hook.project_id, (projectLink) =>
cb "#{@b(hook.project_access)} access to project #{projectLink} was revoked from #{@b(hook.user_name)}"
user_create_color: 'yellow'
user_create: (hook, cb) ->
@linkToUser hook.name, hook.user_id, (userLink) =>
cb "Welcome #{userLink} join #{@linkTo('Gitlab', @gh.gitlab_root)}"
user_destroy_color: 'red'
user_destroy: (hook, cb) ->
cb "#{@b(hook.name)} Gitlab account was deleted"
web_color: 'green'
web: (hook, cb) ->
branch = hook.ref.split("/")[2..].join("/")
branchUrl = [hook.repository.homepage, 'tree', branch].join('/')
@linkToUser hook.user_name, hook.user_id, (userLink) =>
message = []
# if the ref before the commit is 00000, this is a new branch
if hook.total_commits_count > 0
message.push "#{userLink} pushed to branch #{@linkTo(branch, branchUrl)} of #{@linkTo(hook.repository.name, hook.repository.homepage)} "
compareTitle = hook.before.substr(0,9) + '...' + hook.after.substr(0,9)
compareUrl = hook.repository.homepage + '/compare/' + compareTitle
message.push '(' + @linkTo(compareTitle, compareUrl) + ')'
for c in hook.commits
message.push "<br />- #{@h(c.message)} (#{@linkToCommit(c.id, c.url)})"
else
beforeUrl = [hook.repository.homepage, 'commit', hook.before].join('/')
afterUrl = [hook.repository.homepage, 'commit', hook.after].join('/')
message.push "#{userLink} force-pushed branch #{@linkTo(branch, branchUrl)} of #{@linkTo(hook.repository.name, hook.repository.homepage)} from #{@linkToCommit(hook.before, beforeUrl)} to #{@linkToCommit(hook.after, afterUrl)}"
cb message.join('')
class GitlabHipchat
constructor: (@robot) ->
@config =
from: 'Gitlab'
rooms: []
language: 'en'
configure: (env = process.env)->
@config.gitlab_root = env.GITLAB_ROOT
@config.rooms = env.GITLAB_HIPCHAT_ROOMS?.split(',') || []
@config.debug = env.GITLAB_HIPCHAT_DEBUG?
@config.lang = env.GITLAB_HIPCHAT_LANG || 'en'
@gitlab_client = @robot.http(@config.gitlab_root).header(
'PRIVATE-TOKEN', env.GITLAB_TOKEN
)
@message_api = @robot.http('https://api.hipchat.com/v1/rooms/message').query
auth_token: env.HIPCHAT_TOKEN
format: 'json'
message_format: 'html'
from: 'Gitlab'
start: ->
self = @
@robot.router.post "/gitlab/system", (req, res) ->
self.onSystem req, res
res.end ""
@robot.router.post "/gitlab/web", (req, res) ->
self.onWeb req, res
res.end ""
onSystem: (req, res) ->
@onHook('system', req, res)
onWeb: (req, res) ->
@onHook('web', req, res)
onHook: (type, req, res) ->
query = querystring.parse(url.parse(req.url).query)
hook = req.body
if @config.debug
console.log('query', query)
console.log('hook', hook)
rooms = if query.targets then @config.rooms.concat(query.targets.split(",")) else @config.rooms
f = new Formatter(@)
key = if type == 'web' then 'web' else hook.event_name
color = f["#{key}_color"]
(f["#{key}_#{@config.lang}"] || f[key]).call f, hook, (message) =>
@send(rooms, color: color, message: message)
getGitlabUserName: (id, cb) ->
key = "gitlab:username:#{id}"
username = @robot.brain.get key
if username
cb(null, username)
else
robot = @robot
@gitlab_client.scope "/api/v3/users/#{id}", (cli) ->
cli.get() (err, resp, body) ->
if err
cb(err)
else
json = JSON.parse body
robot.brain.set key, json.username
cb(null, json.username)
getGitlabProjectUrl: (id, cb) ->
key = "gitlab:project_url:#{id}"
projectUrl = @robot.brain.get key
if projectUrl
cb(null, projectUrl)
else
robot = @robot
@gitlab_client.scope "/api/v3/projects/#{id}", (cli) ->
cli.get() (err, resp, body) ->
if err
cb(err)
else
json = JSON.parse body
robot.brain.set key, json.web_url
cb(null, json.web_url)
send: (room_ids, query) ->
if typeof(room_ids) == 'string'
room_ids = [room_ids]
if typeof(query) == 'string'
query = message: query
debug = @config.debug
for id in room_ids
@message_api.scope (cli) ->
cli.query('room_id', id).query(query).post('') (err, resp, body)->
if err then console.log err else console.log body
module.exports = (robot) ->
gh = new GitlabHipchat(robot)
gh.configure()
gh.start()
@dafang
Copy link

dafang commented Jan 31, 2015

通过搜索过来的, 发现是认识的人写的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment