hubotを使用してGithubのメンションされたコミットを通知する


開発していて悩みなのがGithubからメンションされたコミットをスルーしてしまうこと。
なのでhubot、hubot-slackを使ってGithubのメンションを拾うことにする

前提としてはhubot、hubot-slackをインストールしてある状態で既にサーバーを実行できる状態であること

注意点:hubot-slackはversion4.0がうまくいかないのでversion3を使っております

issueとpullリクエストに対応しています

1.scriptsフォルダに下記のファイルを追加し、.github_id_historyファイルをプロジェクトのルートパスに追加

robot.router.postにあるパスは自由に決めていただいてかまいません
USER_NAMEに入る名前は左はgithubに使われてるメンション名、右はslackで使われてるメンション名を先頭に@をつけて入力してください

github.coffee

USER_NAME = {
  "@あなたのguthubのメンション名": "@あなたのslackのメンション名"
}

module.exports = (robot) ->
  robot.router.post "/github/webhook", (req, res) ->
    request = req.body
    if !hasGithubID(request)
      IdFileWrite(request)
      robot.send {room: "#channel名"}, parentMessage(request)
    robot.send {room: "#channel名"}, childrenMessage(request)

parentMessage = (request) ->
  type = ""
  user = ""
  body = ""
  comment_url = ""
  if request.issue
    type = "issue"
    user = request.issue.user.login
    body = request.issue.body
    comment_url = request.issue.html_url
  else if request.pull_request
    type = "pull_request"
    user = request.pull_request.user.login
    body = request.pull_request.body
    comment_url = request.pull_request.html_url
  messageFormat(request, type, user, comment_url, body)

childrenMessage = (request) ->
  type = ""
  user = ""
  body = ""
  comment_url = ""
  if request.issue
    type = "issue"
  else if request.pull_request
    type = "pull_request"
  body = request.comment.body
  comment_url = request.comment.html_url
  user = request.comment.user.login
  messageFormat(request, type, user, comment_url, body)

messageFormat = (request, type, user, comment_url, body) ->
  username = mentionsSearch(body)
  if username
    msg = ""
    msg += username
    msg += "[#{request.repository.name}] #{request.action}: ##{request[type].number} #{request[type].title} by #{user}\n"
    msg += "#{comment_url}\n"
    msg += "```" + "\n" + "#{body}" + "\n" + "```"
    msg

# コメント本文のメンションを取得
mentionsSearch = (body) ->
  mentions = []
  regexp_str = body.match /(^|\s)(@[\w\-\/]+)/g
  if regexp_str
    for mention in regexp_str
      mentions.push(mention.trim())
    userNameSearch(mentions)
  else
    null

# ユーザーをチェックする
userNameSearch = (mentions) ->
  username = ""
  for mention in mentions
    if USER_NAME[mention]
      username += USER_NAME[mention] + " "
  if username
    username
  else
    null

# GitHubのissue, pull_requestのidを確認する
hasGithubID = (request) ->
  fs = require('fs')
  path = fs.realpathSync('./')
  fileName = path + "/.github_id_history"
  contents = fs.readFileSync(fileName)
  lines = contents.toString().trim().split('\n')
  type = ""
  if request.issue
    type = request.issue
  else if request.pull_request
    type = request.pull_request
  else
    return false
  for line in lines
    if Number(line) == type.id
      return true
  false

# .github_id_historyファイルにIDがなければ書き込む
IdFileWrite = (request) ->
  fs = require('fs')
  path = fs.realpathSync('./')
  fileName = path + "/.github_id_history"
  id = ''
  if request.issue
    id = request.issue.id
  else if request.pull_request
    id = request.pull_request.id
  if id
    fs.appendFile(fileName, id + '\n', 'utf8')

外部にサーバーを上げるのは面倒なのでngrokというツールをインストールしてください

2.ngrokをインストール

ngrokはlocalhostで動いているサーバーを外部(LAN外)からアクセスできるように、リレーしてくれるツールです

ngrokの使用法は公式サイトを参考にしてください。ngrokを実行した時のURLをWebhooksに登録してください

3.ngrokのURLをgithubのWebhooksに登録する

Webhooksの登録方法は公式サイトを参考にしてください

4.slackにhubotをintegrateして発行されたトークンを登録

bin/hubotファイルに以下の行を追記

export HUBOT_SLACK_TOKEN=発行されたトークン

slackにhubotの統合方法、トークンの確認方法は公式サイトを参考にしてください

最後にサーバー起動して動作確認してください