📣

URLクエリを使ったissueの起票とGitHub ActionsによるSlack通知を実現する

2024/06/08に公開

こんにちは!@Ryo54388667です!☺️

普段は都内でエンジニアとして業務をしてます!
主にTypeScriptやNext.jsといった技術を触っています。

今回はURLクエリを使ったissueの起票とGitHub ActionsによるSlack通知の実装を紹介していきます!

📌 実装したいもの

Webメディアなどの運用について、誤った情報をいかに早くキャッチするかが重要です!昨今は炎上に繋がりかねませんし。。😇管理者としても誤った情報を放置し続けたいとは思っていませんし、意図せず誤った情報を掲載してしまうケースもあるでしょう。いずれにせよ、Web上には正しい情報を掲載したいと思っているはずです。

そのために下記の2つポイントがあるのかなと思います。

  1. ユーザーの報告するハードルを下げる
  2. 管理者に内容を迅速に通知する

この点を工夫して実装すると良いのかなと。
それを踏まえて実現したいのは、下の画像のようなワークフローです。

ユーザーがWebページにあるボタン(GitHubと連携するとZennのページ上にも表示されますよね!)を押下すると、対象のリポジトリのissueのページに遷移するようにします。そして、そのissueが起票されると、管理者のSlackに通知するようにします。

では、URLクエリを使ったissueの起票の実装とGitHub ActionsによるSlack通知の実装とそれぞれ実装の説明に移ります。

📌 GitHubのURLクエリを使ったissueの起票

ユーザーの報告するハードルを下げるために、理想としては1クリックでissueの作成画面に遷移でき、ある程度issueの雛形がすでに入力済みだとありがたいな、と思いました。いろいろ調べた結果、GitHubのURLクエリからissueを作成する方法が良さそうです!
https://docs.github.com/ja/issues/tracking-your-work-with-issues/creating-an-issue#creating-an-issue-from-a-url-query
title,labelなどをクエリパラメータで指定するとissueの作成画面に反映されるものです。イイですね👍雛形を反映できそうなパラメータはtemplateとbodyパラメータですかね。これらを実装していきます。

templateパラメータについて

まずtemplateパラメータですが、結論から言えば、自分の環境ではうまく反映しませんでした。。😇

issue 本文にテンプレートが含まれる issue が作成されます。 template クエリ パラメーターは、リポジトリのルート、docs/、または .github/ ディレクトリ内の ISSUE_TEMPLATE サブディレクトリに格納されているテンプレートで動作します。

とあるので、docs/の中にissue_template.mdを作成し、mainブランチに反映後、下記のURLに遷移したのですが、うまく反映されていませんでした。

https://github.com/<org_name>/<repo_name>/issues/new?template=issue_template.md

GitHubのGUI上で「New issue」ボタンからissueを作成すると雛形が反映されます。ただ、URLからだとうまく反映されませんでした。試しに、.github/ ディレクトリ内の ISSUE_TEMPLATE サブディレクトリにissue_template.mdを作成してやってみましたが、こちらも意図通りにいかず。。自分の環境ではうまくいかなかったので断念しました😇

bodyパラメータについて

最終的にはこちらのbodyパラメータで実装しました!
当初「bodyに指定すれば良いだけやん」と思ってやってみたのですが、少し工夫が必要な箇所もあったので共有します〜

https://github.com/octo-org/octo-repo/issues/new?title=New+bug+report&body=Describe+the+problem. では、タイトルが "New bug report" で、issue 本文に "Describe the problem" というコメントが含まれる、issue が作成されます。

とドキュメントにあるので、下記のようなURLを試してみました。

https://github.com/<org_name>/<repo_name>/issues/new?body=■修正箇所+\n\n■修正の理由+\n\n■改善提案+\n\n■その他\n

結果は下の画像の通り、改行が反映されていませんでした。。

そこで、なかば力技ではありますが、encodeして試してみました。

const bodyText = `■修正箇所\n\n■修正の理由\n\n■改善提案\n\n■その他\n`;
const encodedBodyText = encodeURIComponent(bodyText);
const href = `https://github.com/<org_name>/<repo_name>/issues/new?body=${encodedBodyText}`;

改行がうまく反映されました!👏

意図通りにはなりましたが、より良い方法があれば教えてください〜

追加ですが、修正の対象ページの情報もあると管理者としてはありがたいので、こちらの情報も雛形に加えました。

const bodyText = `対象ページ: ${currentPath}\n\n■修正箇所\n\n■修正の理由\n\n■改善提案\n\n■その他\n`;

1クリックで、雛形が反映されたissueの画面に遷移するので、ユーザーのハードルを下げられるのかなと思います!ぜひ!

📌 GitHub ActionsによるSlack通知

管理者に内容を迅速に通知するために、何らかのチャットアプリとの連携が必須かなと思いました。
できればissueの内容も合わせて通知できると良い。そうすればGitHubのissueページに遷移する必要がなく、issueの内容次第で緊急度(優先度)を測ることもできます。ということで、調べてみると、GitHub Actionsでissueの起票をトリガーとしてイベント通知が可能とわかったので、その方針でやっていきます。今回、チャットツールはSlackを想定します。

SlackのWebhookの準備

まず、利用先のSlackのチャンネルにWebhookの設定をする必要があります。

作成できたら、Webhook URLをコピーし、GitHubのシークレットに設定します。GitHub Actionsを利用してアクセスできるようにするためです。

設定方法は下記の記事の手順がわかりやすかったです!ありがたいです🙏
https://qiita.com/mkin/items/75a4928a1fafe5eacd17#シークレット情報の設定

これで準備OKです!

GitHub Actionsのymlファイルの作成

リポジトリのルートに.github/workflowsを作成します。workflowsディレクトリ内に任意の名称のymlファイルを作成します。本記事では、issues-to-slack.ymlとします。結論としてはymlファイルに下記のコードを記載します。

# .github/workflows/issues-to-slack.yml
name: Notify Slack on Issue

on:
  issues:
    types: [opened]

jobs:
  notify_slack:
    runs-on: ubuntu-latest

    steps:
      - name: Send notification to Slack
        uses: slackapi/slack-github-action@v1.24.0
        with:
          payload: |
            {
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "💬 : issueが起票されました!"
                  }
                },
                {
                  "type": "divider"
                },
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*${{ github.event.issue.title }}*\n\nURL:${{ github.event.issue.html_url }}"
                  }
                },
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": ${{ toJSON(github.event.issue.body) }}
                  }
                },
                {
                  "type": "divider"
                }
              ]
            }
        env:
          # ↓シークレットに保存した変数名
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

Slackの通知画面

いくつか、つまずいた箇所があるので詳細を解説します。

下記のコードでトリガーのタイミングを設定しています。新しいissueが起票された時にActionsが起動します。自分の環境ではmainブランチに反映済みのときにはじめて動作しました。

on:
  issues:
    types: [opened]

今回はslack-github-actionを利用しました!

uses: slackapi/slack-github-action@v1.24.0

このpayloadがくせものでして。。

payload: |
            {
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "💬 : issueが起票されました!"
                  }
                },
                {
                  "type": "divider"
                },

typeblocksの仕様がGitHubに記載がなく、調査に時間がかかりました。。😇
Slackの仕様なのですね。。知りませんでした。。

本記事ではdividerとsectionしか利用しませんでしたが、ボタンなどを表示することもできるようです。
詳細は下記のslackのドキュメントを参照してください。
https://api.slack.com/reference/surfaces/formatting#attachments

便利なこちらのブロックビルダーツールもありますので、利用してみてください👍

次に、issueの内容(body)についてですが、こちらもつまづきポイントがあります。
issueのbodyに複数の改行がある場合、github.event.issue.bodyがエラーになります。

なので下記のようにtoJSON関数でフォーマットする必要があります。詳しくはこちらのリンクを見てみてください。

{
    "type": "section",
    "text": {
        "type": "mrkdwn",
        "text": ${{ toJSON(github.event.issue.body) }}
    }
}

ちなみにですが下記も注意です!ダブルクオートは不要です。

⭕️ "text": ${{ toJSON(github.event.issue.body) }}
❌ "text": "${{ toJSON(github.event.issue.body) }}"

最後に、以下の文字列も必要になります。INCOMING_WEBHOOKは変数ではなく、純粋な文字列です。内部的に条件分岐に利用しているのだと思います。

SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

以上の仕組みで、管理者にissueの内容を迅速に通知することができるのかなと思います!

📌 まとめ

URLクエリを使ったissueの起票とGitHub ActionsによるSlack通知を実現する方法

  1. GitHubのURLクエリを使ったissueの起票の実装
  2. GitHub ActionsによるSlack通知の実装

より良い方法があれば教えてください〜

最後まで読んでいただきありがとうございます!
気ままにつぶやいているので、気軽にフォローをお願いします!🥺
https://twitter.com/Ryo54388667/status/1733434994016862256

Discussion