webhookとHubotを使ってBacklogをslack対応させる

slackというチャットツールが流行ってます。いろんなサービスと連携しやすいのが特徴で、例えばgithubとかはホント簡単に連携することが出来るのですが、国内サービスは対応していない場合があります。
国産の課題管理ツールBacklogもそのご多分に漏れずslack非対応で、これまではAPIを使って連携する方法しかありませんでした(git機能は別)が、Backlogの更新情報がwebhookで提供されるようになり、より簡単に連携出来るようになりました。

webhookはhttp postを使ったpush型APIで、この場合

  • Backlog -> Hubot
  • Hubot -> slask

と2段階でリクエストを送ることになります。

ここではslack, backlogを使っていること、herokuの知識があることを前提に

  1. Hubotの設定
    1. herokuへのデプロイ
  2. slackとHubotの連携
  3. BacklogとHubotの連携

という順番で設定方法を説明していきます。環境はMac OSX yosemiteです。

1.Hubotの設定

Hubotのインストール

HubotはNode.jsで動くボットフレームワークです。Node.jsをインストールしていない場合はインストールします。

以下のように、nodeとnpmがインストールされていることを確認して下さい。

$ node --version
v0.12.0
$ npm --version
2.5.1

npmコマンドを使ってhubotをインストールします。

globalにインストールする( globalかlocalかは http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation )ので、-gオプションを付けます。

$ sudo npm install -g hubot

そのままだとエラーになるのでcoffeeをインストール
$ hubot
env: coffee: No such file or directory

$ sudo npm install -g coffee-script

これでhubotが使えるようになりました。

botの作成

botの生成するのにgenerator-hubotをインストールします。

$ sudo npm install -g yo generator-hubot

ディレクトリを作成し、botを作成します。

$ mkdir -p bot
$ cd bot
$ yo hubot
_____________________________
/ \
//\ | Extracting input for |
////\ _____ | self-replication process |
//////\ /_____\ \ /
======= |[^_/\_]| /----------------------------
| | _|___@@__|__
+===+/ /// \_\
| |_\ /// HUBOT/\\
|___/\// / \\
\ / +---+
\____/ | |
| //| +===+
\// |xx|

botの名前などを入力します。Bot adapterにはslackを指定します。

? Owner:
? Bot name:
? Description: A simple helpful robot for your Company
? Bot adapter: (campfire) slack
? Bot adapter: slack
create bin/hubot
create bin/hubot.cmd
create Procfile
create README.md
create external-scripts.json
create hubot-scripts.json
create .gitignore
create package.json
create scripts/example.coffee
create .editorconfig
_____________________________
_____ / \
\ \ | Self-replication process |
| | _____ | complete... |
|__\\| /_____\ \ Good luck with that. /
|//+ |[^_/\_]| /----------------------------
| | _|___@@__|__
+===+/ /// \_\
| |_\ /// HUBOT/\\
|___/\// / \\
\ / +---+
\____/ | |
| //| +===+
\// |xx|

以上でボットのひな形が作成できました。

herokuにデプロイする

Hubotはhttpリスエストを受けるサーバになるのでデプロイ先が必要になります。ここではherokuにデプロイします。

heroku command line toolを使うのでインストールしてない場合はインストールします。
https://devcenter.heroku.com/articles/heroku-command

herokuにデプロイするためにgit管理下に置きます。

$ git init
$ git add .
$ git commit -m 'First commit.'

herokuにログインします。

$ heroku login
Enter your Heroku credentials.
Email:
Password (typing will be hidden):

アプリを作成します。

$ heroku create

HubotをどうさせるのにはRedisが必要なのでAddonを追加します。

$ heroku addons:add redistogo:nano --app

(以下--appオプションは省略)

herokuにデプロイします。

$ git push heroku master

slackとHubotの連携

slackはHubotインテグレーションをサポートしているので、slackのUIからHubot integrationを追加します。
"Configure Integrations"からHubotを選択します。
Hubotのslack上でのユーザ名を入力します。

以下トークンが取得できます。

HUBOT_SLACK_TOKEN=

これをherokuに設定しておきましょう。

$ heroku config:set HUBOT_SLACK_TOKEN= --app

また、botをidelingにさせないためにpingを送るような設定をします。

$ heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=

は"https://.herokuapp.com/"です。

$ heroku apps:info

で確認できます。

動作確認

ここまででひとまずボットが動くようになっているので確認しましょう。

slackでbotに対してpingとダイレクトメッセージを送ってPONGと帰ってくればOK.

Backlog-Hubot間のwebhook設定

公式ヘルプページ
http://www.backlog.jp/help/adminsguide/webhook-setting/userguide2493.html

Hubotにscriptを追加する

Hubotのscriptsディレクトリに以下内容で"backlog.coffee"を作成します。

# Description:
#   Backlog to Slack
#
# Commands:
#   None

backlogUrl = 'https://mobileclip.backlog.jp/'

module.exports = (robot) ->
  robot.router.post "/room/:room", (req, res) ->
    room = req.params.room
    body = req.body

    console.log 'body type = ' + body.type
    console.log 'room = ' + room

    try
      switch body.type
          when 1
              label = '課題の追加'
          when 2, 3
              # 「更新」と「コメント」は実際は一緒に使うので、一緒に。
              label = '課題の更新'
          else
              # 課題関連以外はスルー
              return

      # 投稿メッセージを整形
      url = "#{backlogUrl}view/#{body.project.projectKey}-#{body.content.key_id}"
      if body.content.comment?.id?
          url += "#comment-#{body.content.comment.id}"

      message = "*Backlog #{label}*\n"
      message += "[#{body.project.projectKey}-#{body.content.key_id}] - "
      message += "#{body.content.summary} _by #{body.createdUser.name}_\n>>> "
      if body.content.comment?.content?
          message += "#{body.content.comment.content}\n"
      message += "#{url}"

      console.log 'message = ' + message
      # Slack に投稿
      if message?
          robot.messageRoom room, message
          res.end "OK"
      else
          robot.messageRoom room, "Backlog integration error."
          res.end "Error"
    catch error
      robot.send
      res.end "Error"

参照) http://qiita.com/mayukojpn/items/a9a9408c21a761adb7d0

Backlog側の設定

Backlogの"プロジェクト設定"から"Webhook"を選択します。

webhook urlに以下を入力します。

https://.herokuapp.com/room/

この画面で「通知するイベント」を選択することが出来るのですが、フィルター・整形はhubot側でやらせる前提で「すべてのイベント」にチェックを入れます。

編集画面の下の方からテスト送信ができ、以下の様なデータが送信されます。

{
"id": 10,
"project": {
"id": 100,
"projectKey": "TEST",
"name": "TestProject",
"chartEnabled": false,
"subtaskingEnabled": false,
"textFormattingRule": null,
"archived": false
},
"type": 1,
"content": {
"id": 100,
"key_id": 100,
"summary": "test issue",
"description": "test description"
},
"notifications": [],
"createdUser": {
"id": 1073863424,
"userId": null,
"name": "itog",
"roleType": 1,
"lang": "ja",
"mailAddress": null
},
"created": "2015-02-23T22:52:28Z"
}

以下のように、slackにBacklogの更新情報がポストされていればOKです。