arthur-1 Mackerel Advent Calendar 2023 マラソン24日目・およびSlack Japan Champions Network (JCN) アドベントカレンダー 2023 24日目の記事です。
MackerelとSlackのインテグレーション
Mackerelの通知チャンネルとして、Slackを選択することができます。これはIncoming WebhookのURLを設定する方式になっており、Mackerelでアラート発報などのイベントが起こるとSlackのWebhookにリクエストを送り、結果としてメッセージが投稿されます。
これでも十分便利なのですが、Slackアプリとして提供するともっと良い体験ができるはずだと思っています。例えば、
- *Mackerelのリンクが貼られたらその情報を展開する
- Slack上でアラートを閉じられる
- アラートの状況が変化したらSlackの投稿も変化する
- 同じアラートに関する通知が1つのスレッドにまとまる
などのことができるようになるでしょう。
今回はお試しとして、「*Mackerelのリンクが貼られたらその情報を展開する」が実現できるSlackアプリを作っていきましょう。
リンクの展開
SlackにURLが貼られたとき、その下にサイトの情報が表示されることがあります。これをリンクの展開(unfurling)と呼びます。
基本はSlackのクローラーかアプリがリクエストを投げて取ってくるのでパブリックなサイトでしか表示できないのですが、Slackアプリを使うとプライベートなサイトのリンクに対しても展開することができるようになります。
この機能を用いて、Mackerelのアラートのリンクが貼られた時にその情報を展開するようなSlackアプリを作ります。
できたもの
Mackerelのアラートリンクを貼ると展開してくれるSlackアプリが以下のようにできました。
ソースコードはGitHubの以下のリポジトリに掲載しています。
コードの解説
Slackアプリが簡単に作れるBolt for Javascriptフレームワークを用いています。Slackにリンクが貼られたときのイベントをハンドリングするには以下のような関数を作ります。
app.event("link_shared", async ({ event, client, logger }) => { // ここにリンクが貼られたときの処理を書く })
event.links
の中にURLの情報が入っているので、これをパースしてMackerelのアラートのURLかを判定します。MackerelのアラートURLであればURLの最後のパスはアラートIDなので、これを取り出してMackerelのAPIのアラート取得エンドポイントにリクエストを投げます。
const url = new URL(link.url); const paths = url.pathname.split("/"); const res = await fetch( `https://api.mackerelio.com/api/v0/alerts/${paths[4]}`, { headers: { "X-Api-Key": process.env.MACKEREL_API_KEY ?? "", }, } ); const alert = await res.json();
あとはSlackのchat.unfurl APIにリクエストするclient methhodを呼び出し、先ほど取得したアラート情報から組み立てたLinkUnfurlsというオブジェクトや、情報を付与したい投稿のID(ts: タイムスタンプ)やチャンネルIDを渡します。
const unfurls: LinkUnfurls = { [link.url]: { blocks: [ { type: "section", text: { type: "mrkdwn", text: alert.status, }, }, ], }, }; client.chat.unfurl({ ts: event.message_ts, channel: event.channel, unfurls: unfurls, });
これでアプリケーションとしては完成ですが、Slack Appとして動かすにはSlack側での設定も必要です。Slackアプリのmanifestファイルを以下に掲載しておきます。
display_information: name: Mackerel features: bot_user: display_name: Mackerel always_online: false unfurl_domains: - mackerel.io oauth_config: scopes: bot: - links:read - links:write settings: event_subscriptions: request_url: ***your_request_url*** bot_events: - link_shared org_deploy_enabled: false socket_mode_enabled: false token_rotation_enabled: false
ポイントはlink_sharedイベントを購読する際にはunfurl_domainsの指定が必要なことです。今回はMackerelのドメインだけを引っ掛けてイベントを送信するようにmackerel.ioと指定しました。
最後に
このようにSlackアプリは簡単に作ることができます。このソースコードを育てて機能を増やすとともに、最終的には認証認可周りも頑張って、ユーザーが各自のワークスペースにインストールするものとして仕上げられたら良いなと思っています。