HubotでSlackのChannelとTrelloのBoardを連携

  • 20
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

10/31(土)開催の香川大学工学部祭の実行委員会が発足しました.
情報系学科のメンバが多いため,SlackTrelloを導入して,脱LINEのモダンなチーム運営を目指しています.

Hubotを使ってSlackのChannelとTrelloのBoardを連携させてみたので,紹介します.

前提条件

Slackでは「stage(ステージ企画)」や「public(広報)」など,担当毎にChannelを分けています.
Trelloでは実行委員会のOrganizationを作成し,同様に「Stage」や「Public」など,担当毎にBoardを分けています.

ここで言う連携とは,「stage」ChannelでHubotを使ってTrelloを操作した場合,「stage」Boardに反映されるということです.
HubotでBoardを指定する必要が無くなり,直感的に連携できるかなと思います.

実装方法

HubotからTrelloを操作するためにnode-trelloを使っています.
ここではhubot trello list <list>で,指定したListのCard一覧を返すコマンドを示します.
(Listは「Todo」「Doing」「Done」の3段階に設定しています.)

node-trelloは非同期で結果が帰るため,API毎に関数を分け,配列に積んで順に処理するようにしています.
コードに多少コメントを付けているので,参考にして下さい.

trelloAPI = require('node-trello')

module.exports = (robot) ->
  ORG = process.env.HUBOT_TRELLO_ORGANIZATION

  trello = new trelloAPI(
    process.env.HUBOT_TRELLO_API_KEY
    process.env.HUBOT_TRELLO_API_TOKEN
  )

  # OrganizationのBoard一覧を取得
  # https://trello.com/docs/api/organization/index.html#get-1-organizations-idorg-or-name-boards
  getOrganizationsBoards = (msg, args) ->
    url = "/1/organizations/#{ORG}/boards"
    trello.get url, (err, data) =>
      for board in data
        # BoardをChannel名で特定 (Stage, Publicなど)
        if board.name.toLowerCase() is msg.envelope.room
          args['boardID'] = board.id
          return args['callbacks'].shift()(msg, args)

  # BoardのList一覧を取得
  # https://trello.com/docs/api/board/index.html#get-1-boards-board-id-lists
  getBoardsLists = (msg, args) ->
    url = "/1/boards/#{args['boardID']}/lists"
    trello.get url, (err, data) =>
      for list in data
        # Listを名前で特定 (Todo, Doing, Doneなど)
        if list.name.toLowerCase() is args['listName']
          args['listID'] = list.id
          return args['callbacks'].shift()(msg, args)

  # ListのCard一覧を取得
  # https://trello.com/docs/api/list/index.html#get-1-lists-idlist-cards
  getListsCards = (msg, args) ->
    url = "/1/lists/#{args['listID']}/cards"
    trello.get url, (err, data) =>
      names = []
      for card in data
        names.push(card.name)
      msg.reply("```¥n#{names.join('¥n')}¥n```")

  robot.respond /trello\s+list\s+(\S+)$/i, (msg) ->
    # getOrganizationsBoards, getBoardsLists, getListsCardsの順で呼出
    getOrganizationsBoards(msg, {
      callbacks: [getBoardsLists, getListsCards]
      listName: msg.match[1]
    })

Slackで動かすと,このようになります.
(実際にはeasy-tableを使って,表形式でDueやMembersを表示しています.)

trello_list.png

Kaonashi

上記のコードはKaonashiという名前のBotとして運用中です.
他にも,下記のようなTrelloとの連携機能を実装しているので,ぜひご覧下さい.

hubot trello list    <list>          - カードの一覧を表示
hubot trello add     <list> <name>   - カードをリストに追加
hubot trello move    <list> <card>   - カードをリストに移動
hubot trello show    <card>          - カードの詳細を表示
hubot trello archive <card>          - カードをアーカイブ
hubot trello comment <card> <text>   - カードにコメントを追加
hubot trello assign  <card> <member> - カードに担当者を追加
hubot trello due     <card> <date>   - カードに締切を設定
hubot trello member                  - ボードのメンバーの一覧を表示
hubot trello member  <name>          - メンバーが担当するカードの一覧を表示

Hubot×ChatOps勉強会

08/22(土)に神戸で第2回 Hubot×ChatOps勉強会を開催します!
HubotやChatOpsに興味のある方,Pluginを開発している方など,ぜひお越し下さい.
発表して頂ける方も募集中ですので,@hico_horiuchiまで気軽にお声掛け下さい.

4f4f7c00342367d0b2b51d51510dab0a.png