前説
うちのチームは、全員がやらなければならないタスクをTrelloで管理しています。
(カードにタスク、チェックリストに個人名が並び、タスク完了者は☑をつける形式)
上司は、毎回Trello開いて、各カード開いて、進捗を確認しなければなりません。
絶対面倒くさい。
そして、Trello Alertでは、カードの変更や新規作成、リストに☑をつけた時などにslack通知を出せますが、☑を付けるたびに通知が来るし、完了者と未完了者が一覧で見れるわけではありません。
基本的に、通知はslackのチャンネルを汚していきます(個人的な見解)。
そして、一覧で見れないのはやっぱり面倒くさい。
じゃあ、定期的に(チャンネルを汚さない範囲で)タスク未完了者を通知するアプリを作ってしまおう。
そして、やるならAWS使って実装しよう。と思いつき、作ってみました。
開発
開発フロー
大まかな開発フローは、
①TrelloのAPI叩く
②コード書く
③AWS lambdaに実装
④EventBridge(CloudWatch Events)をトリガーにする
⑤Slack appを作成する
⑥slackに投稿する
というような感じです。一つずつ見ていきます。
TrelloのAPI叩く
ここにアクセスします。
Trello API Keys
一番上にあるKeyをコピーしておきます。(メモ帳なんかにおいておくと◎)
Trello API Token
Key:の下のToKen:内にあるTokenのリンクをクリック。
そうすると、
Would you like to give the following application access to your account?
と聞いてくるので、スクロールしてAllowします。
上記ページに移動したら、Token Keyが書いてあるので、これもコピーしておきます。
次は、ライブラリ(py-trello)のインストールをしていきましょう。
今回は、Lambdaを使う予定なので、ライブラリをpythonコードと同じフォルダ内(trello_alert)にインストールします。(フォルダ内が汚くなるのは置いておきます)
mkdir trello_alert
cd trello_alert
pip install py-trello --target .
これで、APIをたたく準備ができました。
実際に叩いていきましょう。
from trello import TrelloClient
#trelloにAPI接続
client=TrelloClient(
api_key='ここにAPI Key書く',
api_secret='ここにAPI Token書く'
)
print(client.list_boards())
これで実行して、trelloのリストの一覧が出力されていればAPIをたたくタスクは完了です。
コード書く
では、リストを取得して、期限が近いタスクが未完了な人を出力していきます。
基本的に、このGitHubにTrelloClientのクラスのコードが上がっているので、必要に応じて確認してみてください。
自分の書いたコードを参考に挙げておきます。
(lamdaに上げるので、lamda用のコードになってます)
#Dateが近づいているTask未完了者を取得
import re
import datetime
from trello import TrelloClient
import json
def lambda_handler(event, context):
result = {}
#今日と来週の日付を取得
today = datetime.date.today()
next_week = today + datetime.timedelta(weeks=1)
#trelloにAPI接続
client = TrelloClient(
api_key='ここにAPI Key書く',
api_secret='ここにAPI Token書く'
)
#trelloのカードを取得する
board = client.get_board(`注①:ここにボードidを書く`) #ボードを取得
target_list = board.get_list(`注②:ここにリストidを書く`) #リストを取得
cards = target_list.list_cards() #リスト上のカードの一覧を取得
#カード毎のタスク未完了者と期限を取得
#期限が1週間後のものと今日のものを通知
for c in cards:
#カードを取得
card = client.get_card(c.id)
card.fetch()
#カードの期限を取得
due = re.match("[0-9]{4}-[0-9]{2}-[0-9]{2}", c.due).group()
#期限が今日のものと1週間後のもののチェックリストを取得
if(str(due) == str(today) or str(due) == str(next_week)):
#チェックリストを1件ずつ取得
for checklist in card.checklists:
not_finish = []
for i, item in enumerate(checklist.items):
#タスク未完了者を出力
if(item["checked"]== False):
not_finish.append(item["name"])
#カード名とタスク未完了者を辞書形式で格納
result[c.name] = not_finish
return {
'statusCode': 200,
'body': json.dumps(result, ensure_ascii=False)
}
注1:trelloのboardを開いたときのurlのbの後ろがボードidです。
https://trello.com/b/ボードid/ボード名
注2:boardクラスにall_list関数があるので、それを出力してリストidを探します。
print(board.all_list())
こんな感じで、期限の近いタスクとタスク未完了者を取得することができました。
(ローカルで実行してみたいよという方は、8行目、45行目~48行目
をコメントアウトして`print(result)を最後に付け加えれば実行できます。)
ファイル名を'lambda_function'にしておかないと、lamdaにアップしたときに動かないので注意しましょう。
とりあえず、コードができました。
lambdaに上げていきます。
AWS lambdaに実装
zipファイル化
lambdaにコードを上げるのにzipファイルにする必要があるので、
trello_alertフォルダ内にあるすべてを選択し、圧縮し、zipファイルにしましょう。
zipファイル名はtrelloとかにしておきましょう。
AWSにログイン
Find Servicesからlambdaと検索するとAWS Lambdaが候補に出てくるので選択。
このページに移動したら、create function
をクリック。
こんな感じに記入します。(trello_alert既にあるよって言われてるので赤字ですね)
そして、create functionをクリック。
Lambdaのところに、trello_alertが追加されます。
trello_alertをクリックして、コードをアップしていきます。
このページに移動したら、右下のActionの部分をクリック。
Upload a .zip file
を選択し、先ほど作っておいたtrello.zipをアップロードします。
こんな感じで、ファイルがアップされます。
(デフォルトで用意されているlambda_functionが邪魔してきたらdeleteしておきましょう)
あとは、上記画面のsaveを押して、testを実行します。
テストを押すと以下のような画面になるので、Event nameをtestにして、createします。
前の画面に戻るので、もう一度testを実行します。
Execution Resultに200応答が返ってきていればlambdaにアップ完了です。
環境変数設定(オプション)
API KeyやAPI Tokenを生のままコードに書いておくのは..という方は、
Function codeの下に、Enviroment variablesがあるので、
そこに環境変数を設定し、コード上では、
api_key=os.environ['API_KEY']
と書けば、問題なく実行されます。
EventBridge(CloudWatch Events)をトリガーにする
定期実行したいのでCloudWatch Eventsを利用します。
Lambda(trello_alert)の画面からAdd triggerを選択します。
今回は、平日の朝9時に定期的に投稿したかったので、
cron(0 9 ? * MON-FRI *)
とSchedule expressionを書いています。
毎分したい場合は、
rate(1 minute)
と設定すればOK!
##Slack appを作成
以下の記事を参考にSlack appを作成しました。
【2020年版】slackAPIでメッセージ投稿するボットアプリ作成・設定(スコープ権限を詳細解説)
slackに投稿する
lambda_function.py以下のコードを書き加えます。
import requests
# slackに投稿
url = "https://slack.com/api/chat.postMessage"
msg = {
"token": "ここにACCESS TOKEN書きます",
"channel": "ここに投稿したいチャンネルID書きます",
"text": result
}
requests.post(url, data=msg)
まとめ
AWSも使えて、APIも叩けて、業務も改善が見込めていい経験でした。