
Backlogタスクの定期チェックと通知をSlackで受け取る方法
2022.02.18
本記事では、Backlogの通知をSlackで受け取る方法をご紹介します。
流れとしては、APIを活用してBacklogに割り当てられたタスクを検索し、ヒットした場合にSlackへ通知するための処理を、Lambdaで設定していきます。Lambdaを定期的に実行することでタスクをチェックする手間を減らし、対応漏れを防ぐことが可能です。
なお、定期実行するためにAmazon EventBridgeをLambdaに連携したり、ほかにもAPIキーをコードに平文で記述しないためにAWS Key Management Service (KMS)を使用したりするなど複数のAWSサービスを活用しています。
初心者の方でも設定いただけるよう、画像付きの分かりやすい手順書形式で解説します。
はじめに
国内外170万人以上が利用するプロジェクト管理ツール「Backlog」ですが、チームの課題やタスク管理、お客様のやりとりなどで利用される方も多いと思います。
このBacklogですが、日々テンプレート化されたようなタスクを数多く受け取っており、タスクがないかチケットを検索して確認するのが面倒だと、手間に感じる方もいらっしゃるのではないでしょうか?
そこで今回は、Backlog APIとAWSのサービスを活用して、backlogのタスクを自動で定期チェックし、ビジネスチャットツールslackへ通知する方法をご紹介します。
> Amazon Web Services (AWS) 運用監視 – 代行サービス 詳細はこちら
対応事項 概要
「サーバ設定変更依頼」というキーワードでBacklogの課題を検索し、ヒットしたものの中から「未対処」もしくは「処理中」の状態の課題をタスクとしてslackで通知できることを目標にします。また、この処理を平日AM10:00に定期実行するよう設定します。
本記事では以下のサービス・言語を使用しています。
AWSサービス
言語

事前準備
Slackの Webhook URLを取得
まずはじめに、Slack に通知するために必要な『Incoming Webhook』を設定します。
Slackのデスクトップアプリを使用している場合は、左上の『メニューボタン』→『開始』→『App』と進みます。

検索欄に「incoming webhook」を入力して、利用可能なアプリに表示された『Incoming WebHooks』をクリックすると、Webブラウザで設定ページが開きます。

『Slack』に追加をクリックして設定画面に進みます。

通知するチャンネルを指定し、『Incoming Webhook インテグレーションの追加』をクリックします。

遷移した画面で『Webhook URL』をコピーして控えておき、『設定を保存する』をクリックします。
※名前やアイコンは必要に応じて適宜設定してください。

Backlogの APIキーを取得
ユーザーのアイコンをクリックし、『個人設定』を選択します。

画面左の『API』を選択し、『登録』でAPIキーを発行後、コピーして控えておきます。

KMSキーを作成
APIキーを平文でコードに埋め込むことを避けるために、AWS KMSの「KMSキー」を使用します。
APIキーをLambdaの設定画面上で環境変数として設定し暗号化します。コード内で環境変数を呼び出して復号化させる処理を行います。
AWSのコンソールにログインし、KMSの画面に遷移後、『カスタマー管理型のキー』より『キーの作成』をクリックします。

キーの作成画面で以下の通り選択し、『次へ』をクリックして進みます。

『エイリアス』に任意の名前を設定し、『次へ』をクリックして進みます。

『キーの管理アクセス許可』画面では、以下の通り設定し、『次へ』をクリックして進みます。

『キーの使用アクセス許可』画面では、Lambdaを実行するユーザーを指定し、『次へ』をクリックして進みます。

確認画面で『完了』をクリックしてKMSキーを作成します。

作成したKMSキーのARNを控えます。
次にKMSで復号するためのIAMポリシーを作成します。
IAMポリシーの画面に進み、『ポリシーを作成』をクリックします。

以下の通り設定し、『次のステップ: タグ』をクリックして進みます。

ARNの追加の画面では、『KMS keyのARNの指定』に作成したKMSキーのARNを入力し、『変更の保存』をクリックして元の画面に戻ります。
※ARNを入力すれば、『Region』『Account』『Key id』は自動入力されます。

タグの設定画面は必要に応じて設定し、『次のステップ: 確認』をクリックして進みます。
『ポリシーの確認』画面では『名前』に任意のポリシー名を入力し、『ポリシーの作成』をクリックします。

本作業
コーディング
import requests import json import boto3 import os from base64 import b64decode def lambda_handler(event, context): backlog_apikey = apikey backlog_api_url = '〓https://xxxxxxxx.backlog.jp〓/api/v2/issues' slack_url = "〓slackのwebhook URL〓" backlog_search_url = "〓Backlogの対象プロジェクトのURL〓" #--------------------------------------------------------------------------------- # 検索フィルタ payload_check = { 'apiKey': backlog_apikey, 'projectId[]': '〓プロジェクトID〓', 'issueTypeId[]': '〓種別ID〓', 'keyword': '〓サーバ設定変更依頼〓', 'statusId[]': ['1', '2'] #(4:完了, 3:処理済み, 2:処理中, 1:未対応) } # チケット検索 search_issues = requests.get(backlog_api_url, params=payload_check) # slack通知用の関数 def slack_message(msg): requests.post(slack_url, data=json.dumps(msg)) # slack通知内容 ## 要確認 info_msg = { "text":f"〓未対応の<{backlog_search_url}|サーバ設定変更依頼>があります。〓", "username":"〓Task Checker〓", "icon_emoji":"〓:warning:〓" } # チケットを検索し、該当するチケットが存在する場合は、slack通知 try: get_issue = search_issues.json()[0]['issueKey'] slack_message(info_msg) except IndexError: pass
コードの補足説明
コード内の〓で括った個所は環境に応じて編集が必要な個所です。
※後ほど、Lambdaの環境変数で設定します。
※slackのメッセージにこのリンクを含めるために使用します。
※短縮URLでなくても問題ありません。
・projectId[]:『プロジェクトID』
・issueTypeId[]:『種別ID』
・keyword:課題の検索ワードを入力(本記事では『サーバ設定変更依頼』とする)
・statusId[]:『状態ID』を取得して記述。
※各IDについては「▼Backlogの『プロジェクトID』などを取得する方法」を参照
・text:ここにメッセージの内容を記述します。
・username:通知するユーザー名を指定します。
・icon_emoji:アイコンを指定することができます。
※アイコンの文字コードは https://www.webfx.com/tools/emoji-cheat-sheet/ を参照

Backlogの『プロジェクトID』などを取得する方法
BacklogAPIを実行するためには、プロジェクトIDなどを取得する必要があります。
例として以下の条件に該当する課題が検索で見つかった場合にslackで通知する想定で課題を検索してCSVを出力します。
状態:『未対処』or『処理中』
種別:『その他』
キーワード:『サーバ設定変更依頼』

CSVに各IDが含まれているので『プロジェクトID』『種別ID』『状態ID』を控えておき、コードに記述します。
※『状態ID』はデフォルトで[1:未対応/2:処理中/3:処理済み/4:完了]になっていると思われます。

Lambda関数作成
AWSコンソールでLambdaの画面を開き、『関数』→『関数の作成』と進みます。

『一から作成』を選択し、以下の通り設定して『関数の作成』をクリックします。

作成後、レイヤーの設定を行います。
レイヤー作成
LambdaでPythonの外部ライブラリであるrequestsを使用するために、レイヤーを作成します。
まずは、外部ライブラリのzipファイルを作成します。
※作業はpipがインストールされているマシンで実施してください。
最初に任意のディレクトリに移動し、以下のコマンドを実行してください。
# mkdir python
※ディレクトリ名はpythonとしてください。
# pip install -t ./python requests
# zip -r layer.zip ./python
※zipファイルは任意のファイル名で構いません。
AWSコンソールのLambdaの画面より『レイヤーの作成』をクリックします。

作成画面では以下の通り設定して『作成』をクリックします。

関数の画面に戻り、

『レイヤーの追加』をクリックします。
遷移した画面で以下の通り設定して『追加』をクリックし、レイヤーを追加します。

次にLambdaでKMSキーを使用するための設定を行います。
『設定』→『アクセス権限』→割り当てられたロールをクリックしてIAMロールの画面に進みます。

『ポリシーをアタッチします』をクリックします。

先ほど用意した、KMSで復号化するためのポリシーを選択し、『ポリシーのアタッチ』をクリックしてポリシーを付与します。


ポリシーが追加されたことを確認し、Lambda関数の画面に戻ります。
『設定』→『環境変数』→『編集』をクリックして進みます。

以下の通り設定後、『暗号化』をクリックしてAPIキーを暗号化します。

転送時の暗号化の画面では、KMSキーを指定し、『シークレットスニペットの復号』に表示されているコードを控えてから、『暗号化』をクリックします。

▼コード修正
復号化の処理をコードに追加する。
import requests import json import boto3 import os from base64 import b64decode def lambda_handler(event, context): backlog_apikey = apikey backlog_api_url = '〓https://xxxxxxxx.backlog.jp〓/api/v2/issues' slack_url = "〓slackのwebhook URL〓" backlog_search_url = "〓Backlogの対象プロジェクトのURL〓" #--------------------------------------------------------------------------------- # APIキー復号化 ENCRYPTED = os.environ['apikey'] backlog_apikey = boto3.client('kms').decrypt( CiphertextBlob=b64decode(ENCRYPTED), EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']} )['Plaintext'].decode('utf-8') #--------------------------------------------------------------------------------- # 検索フィルタ payload_check = { 'apiKey': backlog_apikey, 'projectId[]': '〓プロジェクトID〓', 'issueTypeId[]': '〓種別ID〓', 'keyword': '〓サーバ設定変更依頼〓', 'statusId[]': ['1', '2'] #(4:完了, 3:処理済み, 2:処理中, 1:未対応) } # チケット検索 search_issues = requests.get(backlog_api_url, params=payload_check) # slack通知用の関数 def slack_message(msg): requests.post(slack_url, data=json.dumps(msg)) # slack通知内容 ## 要確認 info_msg = { "text":f"〓未対応の<{backlog_search_url}|サーバ設定変更依頼>があります。〓", "username":"〓Task Checker〓", "icon_emoji":"〓:warning:〓" } # チケットを検索し、該当するチケットが存在する場合は、slack通知 try: get_issue = search_issues.json()[0]['issueKey'] slack_message(info_msg) except IndexError: pass
修正後、Lambdaのコードソースに貼り付けて、『Deploy』をクリックして適用する。

最後に定期実行のための『EventBridge』の設定を行います。
Lambda関数の画面で『+トリガーを追加』をクリックします。

トリガーの設定画面で以下の通り設定して、『追加』をクリックする。
cron式については公式ドキュメントを参照ください。
https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html

EventBridgeがトリガーに追加され、全ての設定が完了しました。

動作確認
コードソースの画面で『Test』をクリックします。

『テストイベントの設定』画面で任意のイベント名を入力し、『作成』をクリックします。

元の画面に戻り、再度『Test』をクリックしてコードがLambdaで動作することを確認します。

『Status: Succeeded』が表示されればテストは成功です。

slackにもメッセージが届いたことを確認できました。

おわりに
無事に動作させることができました。
今回、Lambdaということもあり定期実行にはEventBridgeを活用していますが、サーバ上で実行する場合は、Linuxであればcron、Windowsであればタスクスケジューラで設定することになるかと思います。
本記事ではタスクを通知するところまでの処理としていますが、タスクの内容次第では、それらの処理と課題クローズまでワンストップで自動化することも可能ですので、興味がある方はぜひ挑戦してみてください。
最後に、当社はシステムの監視・運用代行サービスをご提供している会社です。もしご興味がございましたらお気軽にご相談ください。最後までお読みいただきありがとうございました。
> Amazon Web Services (AWS) 運用監視 – 代行サービス 詳細はこちら