以前の記事で、SlackにHubotを導入し、リマインド機能を実装するところまで行ったので、今回はTrelloによってタスク管理をしている場合に、Slackからタスクのリマインドをさせ、そのタスクが完了したらSlackからカードをクローズできるようにします。
1. Trello APIを使えるようにする
まずはTrelloのAPIの使用に必要なAPIKeyを取得します。
https://trello.com/1/appKey/generateにアクセスすると、APIKeyが確認できます。
Key:
で表示されている部分がAPIKeyになるのでメモしておきます。
続いて、TrelloのAPIを実行するためのトークンを取得します。
https://trello.com/1/authorize?key=<取得したAPIKey>&name=&expiration=never&response_type=token&scope=read,write
上記のURLの<取得したAPIKey>を書き換えてアクセスします。
トークンが表示されたらメモしておきます。
APIKeyとトークンが分かったら、目的のカードが登録されているボードのIDを取得します。
https://trello.com/1/members/<Trelloでの自分のID>/boards?key=<取得したAPIKey>&token=<取得したToken>&fields=name
上記にアクセスすると、自分がメンバーになっているボードの名前とIDがjson形式で表示されるので、対象のボードIDをメモっときます。
次に、リマインドさせたいカードが置かれているListのIDを取得します。
https://trello.com/1/boards/<取得したボードのID>/lists?key=<取得したAPIKey>&token=<取得したToken>&fields=name
ListのIDが分かると、そのリストの含まれるカードの情報を取得できるようになります。
https://trello.com/1/lists/<取得したリストのID>/cards?key=<取得したAPIKey>&token=<取得したToken>
上記にアクセスすると、リストに含まれるカードの情報が、json形式で取得できます。
その他のAPIは、API Referenceを確認してください。
2. HubotにTrello APIを実行させる
Trello APIが使えるようになったら、HubotがAPI実行してcard情報が取得できるようにコードを書いていきます。
まずは、Node.jsでTrelloのAPIを扱うのに必要な、node-trello
をインストールします。
$ npm i node-trello --save
ここでは、List内のカードのDue Dateが過ぎているものをHubotにリマインドさせてみたいと思います。
コードの全体は以下のようになります。
# Description:
# Trello Task Remind
cronJob = require('cron').CronJob
Trello = require('node-trello')
moment = require('moment')
createMsg = (data) ->
msg = "\n"
msg = "以下のタスクの期限が過ぎています!\n"
msg += "Trello ID:" + data.id + "\n"
msg += "タイトル:" + data.name + "\n"
msg += "期限:" + data.due + "\n"
msg += "URL:" + data.url + "\n"
return msg
module.exports = (robot) ->
trello = new Trello(
process.env.HUBOT_TRELLO_KEY,
process.env.HUBOT_TRELLO_TOKEN
)
trelloListID = process.env.HUBOT_TRELLO_JOB_LIST_ID
cronJob = new cronJob('00 00 11 * * *', () ->
now = moment()
envelope = room: "#general"
mention = "@yourname: "
trello.get "/1/lists/#{trelloListID}/cards", {}, (err, data) ->
if err
robot.send(err)
return
for card in data
if !(card.due == null)
due = moment(card.due)
diff = now.diff(due, 'minutes')
if diff >= 0
remindData = {}
remindData.id = card.id
remindData.name = card.name
remindData.due = due.format("YYYY/MM/DD h:mm A")
remindData.url = card.url
msg = createMsg(remindData)
robot.send(envelope, mention + msg)
)
cronJob.start()
APIによってcard情報を取得している部分が、
trello.get "/1/lists/#{trelloListID}/cards", {}, (err, data) ->
から始まる部分になります。コードの前半で、
trello = new Trello(
process.env.HUBOT_TRELLO_KEY,
process.env.HUBOT_TRELLO_TOKEN
)
と、APIKeyとトークンを渡してtrello
インスタンスを作成していて、そのtrello
インスタンスgetメソッドの第一引数に実行したいAPIのURLを渡すことで、APIを実行したときのデータがdata
に入ってきます。
インスタンス作成時に、APIKeyとトークンを渡しているので、getメソッドの実行時には渡さなくてもデータを取得できます。
あとの部分は、毎朝11時に現在の時間とカードのDue Dateを比較して、Due Dateが過ぎているものをリマインドさせているコードになります。
3. SlackからTrelloのカードをcloseする
最後に、タスクが完了したらカードをcloseできるようにしたいと思います。
ここでは、 「close card [closeしたいカードのID]」とSlack上で発言すると、指定したカードIDのものがcloseされるようにします。
以下がカードclose用コードの全体になります。
# Description:
# close Trello Card
Trello = require('node-trello')
module.exports = (robot) ->
trello = new Trello(
process.env.HUBOT_TRELLO_KEY,
process.env.HUBOT_TRELLO_TOKEN
)
robot.hear /\bclose card\s+(\S+)/i, (msg) ->
closeCardID = msg.match[1]
trello.put "/1/cards/#{closeCardID}/closed", {value: true}, (err, data) ->
if err
msg.reply(err)
return
trello.get "/1/cards/#{closeCardID}", {}, (error, _data) ->
if error
msg.reply(error)
return
successMsg = "#{_data.name} is closed."
msg.reply(successMsg)
コードの内容としては、Slackで入力した内容を、
robot.hear /\bclose card\s+(\S+)/i, (msg) ->
で、受け取っています。
robot.hear
でチャンネル上の発言に反応するようにし、削除対象のカードIDを渡せるように、正規表現の中で()
を使い、msg.match
に配列で入ってくるようにしています。
そのあとは、trello.put
を使い、close用のAPIが成功したら、trello.get
でcardの名前を取得し、入力した相手に完了のメッセージを送るようにしています。