FORCIA CUBEフォルシアの情報を多面的に発信するブログ

Backlogの特定のチケットをSlackに通知するBotを作ってみた

2022.03.22

テクノロジー エンジニア

こんにちは、エンジニアの山門です。

日々仕事をしていると、ちらほら手動で行っている定型作業というものが出てきてしまいます。それを自動化出来れば、これまでその作業に費やしていた時間が他のことに使え、業務効率の向上に繋がります。

今回はその定型作業を解消するためにBotを作ってみた話をしたいと思います。


経緯

  • あるときPMから1件のコメントがチャンネルに寄せられる

    001.png
  • 手動で毎回アラートするのが大変
  • そうだBacklog アラートBotを作成しよう


目的

フォルシアの一部では、プロジェクト管理ツールとして、Backlogを利用しています。私の参加していたプロジェクトでも利用していたのですが、大規模プロジェクトだったこともあり、大量の課題の起票・更新が行われ、反応が遅れてしまうケースがありました。
これに対して、Backlogを開き、該当チケットを抽出することは出来るのですが、

  • 課題を抽出するために画面を開く
  • 条件を指定して検索する
  • 該当チケットを取得
  • Slack上に通知

と手間がかかり、これを手動で時間を取って行うのは無駄なコストで且つ、ストレスのかかる作業だと感じました。当時私はチームの1エンジニアではありましたが、今後のプロジェクト進行を考えると、今の段階でBotを作り、こちらから情報を取りに行かずともSlackに通知してくれればHappyになれるのでは?と考え、Bot作成に乗り出しました。



使っている技術

今回技術要素としては以下を利用しました。

  • API: Baklog API, Slack API
  • HTTP client: axios
  • webApp: TypeScript
  • Notification: GitLab CI


API

BacklogにはNulab社が提供するAPIがあり、公式の丁寧に書かれた定義書があったので、そちらを採用しました。

また、Slackへの通知に関しては、Incoming webhookを使うと手軽なのですが、message形式が比較的柔軟に作れる、スレッドに返信といったことができる、message送るときは今後は chat.postMessageの利用が推奨されている、などの理由でchat.postMessageを選択しています。
(個人的に使ってみたかったから、という理由もあります。)

HTTP client

私の参加していたプロジェクトで既に axiosを利用しており、勝手がわかっていたため axios を採用しましたが、fetch APIとかでもいいと思います。

webApp

こちらも同様に、現プロジェクトで採用していたためTypeScriptにしました。

Notification

自分のPC上でcronを仕込んで動かすでも良かったのですが、折角なら別のところで動いている方が個人の事情に左右されないので GitLab CI を採用しました。
(フォルシアではGitHubではなく、GitLabを利用しています。)



機能(2022/03/15現在)

  • 予め定義した人たちが担当者になっている、反応が遅れたチケットを通知
  • 期間によって段階を区切って、3パターンにグルーピングしてalert
  • CIのスケジュール実行で1日1回Slackに通知



構成

  • root
├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── src
└── tsconfig.json
  • src以下
├── definitions
│   ├── apiDefinition.ts
│   ├── searchConditionDefinition.ts
│   └── userDefinition.ts
├── fetchData.ts
├── index.ts
├── sendMessage.ts
├── types
│   ├── comments.d.ts
│   └── issues.d.ts
├── util
│   ├── dateUtil.ts
│   └── typeUtil.ts
└── view-data
    ├── comments.ts
    ├── issues.ts
    └── sendMessage.ts

構成はざっくり以下の構成になっています。

  • root: 設定回り
  • src: APIリクエスト周りのコード
    • definitions: userIDやAPIのurl定義等
    • types: 型定義
    • util: module系
    • view-data: データ加工処理系



事前準備

Botの利用にあたって、事前にBacklogとSlackで準備が必要です。

Backlog API のAPIキーの発行

  • プロジェクトの個人設定に進みAPIの項目から新しいAPIキーを登録すれば完了です

    002.png

Slack Botの登録

Slack APIのAPIキーを発行するには、Slack Appを作成する必要があります。詳細は割愛しますが、

  • https://api.slack.com/apps に進みCreate New App
  • Add features and functionality でBotsを選択し、アプリの名前を決める
  • Add features and functionality でPermissionsを選択し、 Scopesをchat:write, users:readにする
    • xoxb-から始まるキー情報が上の方に表示されているはずなので、これを控えておく(これがAPIキーです)
  • Install your app to your workspace でforciaのワークスペースにinstall
  • 通知を入れたいチャンネルに対して、アプリをinviteする
    • 自分はこれを忘れていて少してこずりました



ポイント

Backlog API

  • Backlog APIのメインで使っているAPIは /api/v2/issues です。
    • updatedSince, updatedUntilを更新日の範囲が絞れるので、これを使って特定の期間内のチケットを取得しています
  • DoS攻撃対策なのか、短時間に数十リクエストを投げるとアクセス制限がかけられてしまうので、リクエスト数は注意して作っています
  • issuesの1回のレスポンス上限が100件なので、担当者のチケットが100件以上ある場合はリクエストを分けるなど注意が必要です
    • (イケてないですが、)現状は担当チケットが多い特定の人の場合に個別で条件分岐させています

Slackに送るメッセージ

  • Slackが提供しているBlock Kitというものを利用してメッセージを組み立てています
    • 記法に従ってjsonを組み立ててchat.postMessageに投げると、それに応じた形式でslack上に表示してくれます
    • BlockKit Builder を使うとプレビューを見ながら必要な形式を確認できるのでお勧め

      003.png

  • メッセージは大きく分けて3ブロックで構成しています
    • ヘッダー部分
    • メンション部分
    • スレッド部分

      004.png

基本的には必要なパラメータを用意してAPIを投げればSlackに通知できますが、スレッドに返信するには一工夫必要です。

chat.postMessageでリクエストを投げると、下記のようなレスポンスが返って来るのですが、その中のtsという値がリクエストしたメッセージに紐づいているタイムスタンプです。このタイムスタンプをthread_tsパラメータに指定して再度chat.postMessageにリクエストすることで、該当のメッセージのスレッドにリクエストすることができます。
※ID情報等は保護のため仮の値で表現しています。

{
	ok: true,
	channel: '<channel名>',
	ts: '1593849552.024700',
	message: {
		bot_id: '<bot_id>',
		type: 'message',
		text: 'このコンテンツは表示できません。',
		user: '<user_id>',
		ts: '1593849552.024700',
		team: '<team_id>',
		bot_profile: {
			id: '<id>',
			deleted: false,
			name: 'backlog-watcher',
			updated: 1592644323,
			app_id: '<app_id>',
			icons: [Object],
			team_id: '<team_id>'
		},
		blocks: [ [Object] ]
	}
}

実際にスレッドに飛ばすと以下のように期間ごとに分けたメッセージが通知されます。(表示センスはご容赦ください、、 )


backlog_attention.png

slackへのmention

  • mentionを飛ばすためのslackIDの取得には https://api.slack.com/methods/users.list を利用しました
    • users:read の権限があれば、ワークスペース内の人のuser情報を取得できます
    • 純粋に@yamakado などとしてもmentionされないので、IDを持ってくる必要があります
  • 今回はメンバーがある程度固定されているので、実装時にIDを取得してそれを定義で持つようにしています

定期実行

  • 日次で1回実行しているのですが、GitLab CIのschedule機能を使って実行しています
  • APIキーなどは基本的にcommitしないほうが良いため、GitLab上のVariablesに登録して、スクリプト実行時に環境変数で渡すようにしています


最後に

日常の不便を見つけて自主的に取り組んだBot作成ですが、個々人に対して通知する仕組みが作れたため、結果的にチーム全体で活用することが出来ています。
実際に導入されてから1年以上が経ちますが、こちらから主体的に情報を取りに行かずとも、コミュニケーションの主軸であるSlackに自動で通知してくれるので、とても快適に感じています。
副次的な効果として、通知で可視化されたことでチームメンバーの目にも留まり、チケットの相談やヘルプがしやすくなった気がします。
これからも日々の定型作業を自動化して、業務効率をどんどんあげていきたいです!

この記事を書いた人

山門 峻

2017年度新卒入社のエンジニア。大手旅行会社のシステムを担当。
最近になって在宅環境の整備欲が再燃。

フォルシアではフォルシアに興味をお持ちいただけた方に、社員との面談のご案内をしています。
採用応募の方、まずはカジュアルにお話をしてみたいという方は、お気軽に下記よりご連絡ください。


採用お問い合わせフォーム 募集要項

※ 弊社社員に対する営業行為などはお断りしております。ご希望に沿えない場合がございますので予めご了承ください。