[TypeScript] BoltでSlack Appを作成する ③GitHub APIを叩いてGAEにデプロイする

2022/08/04

TypeScript
Slack API
Bolt
GitHub Actions
GAE
GitHub API

TypeScriptでSlack Appを作成してみたので、その方法の紹介です。

作成したアプリはこちら

https://github.com/irori-dev/SlackApp

前回までで、

  1. ローカルで動くところまで
  2. GAEへのデプロイと、GirtHub Actionsでデプロイできるように

という状態になっています。

今回は、GitHub APIを叩いて、前回作成したworkflowを動かしてデプロイさせようと思います🎉

前回までの記事はこちら。

  1. [TypeScript] BoltでSlack Appを作成する ①ローカルで動かそう

  2. [TypeScript] BoltでSlack Appを作成する ②GAEにGitHub Actionsでデプロイする

作っていきましょう

まず、GitHub APIで何をさわればいいか確認しましょう。

今回叩くAPIはこちらになります。

/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches を叩くと、指定したworkflowを動かせるよ!ということです。

Actions - GitHub Docs

そして、nodeから叩く方法として簡単にできるよう、octkitというpackageがあります。

公式ではないようですが、更新がそれほど遅れているわけではなさそうなこと(直近では4ヶ月前)、割と色々なところで使われているpackageであることから今回採用しました。

https://github.com/octokit/core.js

1. octkit/core.jsの設定

% npm install @octokit/rest —save

を実行後、package.jsonに入っていることを確認しましょう。

その後、以下のファイルを作成します。

src/initializers/octokit.ts
import { Octokit } from "@octokit/core";

export const octokit = new Octokit({
  auth: process.env.GH_TOKEN,
});

.envGH_TOKENを入れましょう。

GH_TOKENという名前にしてるのは、後ほどGitHubにsecretを入れるときにGITHUB_というprefixが入れられないので、わかりやすさのためにこれに統一しています。

ここからトークンを発行できます。

https://github.com/settings/tokens

2. 対応ファイルを作成する

src/commands/deploySlackApp.ts
import { app } from '../initializers/bolt'
import { octokit } from '../initializers/octokit'

const WORKFROW_ID = 000000000

export default (): void => {
  app.message(`sample deploy slack app`, async ({ _message, say }): Promise<void> => {
    try {
      await octokit.request(`POST /repos/irori-dev/SlackApp/actions/workflows/${WORKFROW_ID}/dispatches`, {ref: 'main'})
      await say('Deployment started')
    } catch (_err) {
      await say('Deployment not started')
    }
  })
}

上記でしれっと出てきているWORKFROW_ID ですが、以下のように確認ができます。

% curl -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/*************/***********/actions/workflows
{
  "total_count": 6,
  "workflows": [
    {
      "id": 123456, # これです
      "node_id": "***********",
      "name": "CI",
      "path": ".github/workflows/******.yml",
      "state": "active",
      "created_at": "2021-01-27T19:40:50.000Z",
      "updated_at": "2021-09-23T17:31:53.000Z",
      "url": "https://api.github.com/repos/*******",
      "html_url": "https://github.com/*********",
      "badge_url": "https://github.com/***********"
    }, …
  ]
}

また、以降commands 配下にメッセージなどへの対応は作成していきます。

こちらで作成したpingもcommands配下に移しておきましょう。

src/commands/ping.ts
import { app } from '../initializers/bolt'

export default (): void => {
  app.message(`sample ping`, async ({ _message, say }): Promise<void> => {
    await say('pong')
  })
}

src/index.ts の変更も忘れずに。

src/index.ts
import { app } from './initializers/bolt'
import ping from './commands/ping'
import deploySlackApp from './commands/deploySlackApp'

;(async () => {
  // Start your app
  const server = await app.start(8080)

  console.log(`⚡️ Bolt app is running! PORT: ${server.address().port}`)
})()

ping()
deploySlackApp()

その後、GH_TOKEN をちゃんと渡せるように以下のように修正しましょう。

app.yaml
runtime: nodejs16
instance_class: F1
automatic_scaling:
  min_idle_instances: automatic
  max_idle_instances: 1
  min_pending_latency: 3000ms
  max_pending_latency: automatic
  target_cpu_utilization: 0.95
  target_throughput_utilization: 0.95
  max_concurrent_requests: 80
env_variables:
  SLACK_BOT_TOKEN: "$SLACK_BOT_TOKEN"
  SLACK_SIGNING_SECRET: "$SLACK_SIGNING_SECRET"
  GH_TOKEN: "$GH_TOKEN"
.github/workflows/gae-deploy.yaml
name: Deploy to Google App Engine

on: workflow_dispatch

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Replace credentials in app.yaml
        run: |
          sed -i -e 's/$SLACK_BOT_TOKEN/${{ secrets.SLACK_BOT_TOKEN }}/g' app.yaml
          sed -i -e 's/$SLACK_SIGNING_SECRET/${{ secrets.SLACK_SIGNING_SECRET }}/g' app.yaml
          sed -i -e 's/$GH_TOKEN/${{ secrets.GH_TOKEN }}/g' app.yaml
      - name: Deploy to App Engine
        id: deploy
        uses: google-github-actions/deploy-appengine@v0.2.0
        with:
          deliverables: app.yaml
          project_id: ${{ secrets.GCP_PROJECT }}
          credentials: ${{ secrets.GCP_SA_KEY }}
      - name: Show App Engine application URL
        run: echo ${{ steps.deploy.outputs.url }}

GitHubの対象リポジトリのSecretにGH_TOKEN を追加するのを忘れないようにしましょう。

そして、slack Appのmanifestファイルをローカルで開いているURLに差し替えた後、以下のように実行してみましょう。

1.png

iroriとなっていますが、sampleとしてください。

Deployment startedと返ってきたら、無事にアクションが動いているか確認しましょう🎉

3. 成功したらNotificationが返ってくるようにしよう

さあ、これでデプロイ自体はできるようになったのですが、完了通知がありませんね。

完了通知はもっと簡単にできるので、完了通知を最後にやっちゃいましょう!

.github/workflows/gae-deploy.yaml
name: Deploy to Google App Engine

on: workflow_dispatch

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Replace credentials in app.yaml
        run: |
          sed -i -e 's/$SLACK_BOT_TOKEN/${{ secrets.SLACK_BOT_TOKEN }}/g' app.yaml
          sed -i -e 's/$SLACK_SIGNING_SECRET/${{ secrets.SLACK_SIGNING_SECRET }}/g' app.yaml
          sed -i -e 's/$GH_TOKEN/${{ secrets.GH_TOKEN }}/g' app.yaml
      - name: Deploy to App Engine
        id: deploy
        uses: google-github-actions/deploy-appengine@v0.2.0
        with:
          deliverables: app.yaml
          project_id: ${{ secrets.GCP_PROJECT }}
          credentials: ${{ secrets.GCP_SA_KEY }}
      - name: Notify deployment
        uses: 8398a7/action-slack@v3.8.0
        with:
          status: ${{ job.status }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: always()

SLACK_WEBHOOK_URL は以下のように設定しましょう

https://qiita.com/ik-fib/items/b4a502d173a22b3947a0

これもGitHubの対象リポジトリのSecretに追加し忘れないようにしてくださいね。

再度実行して、しばらくしたら以下のようになっていれば成功です!🎉

2.png

次回は、FirebaseのFirestoreを活用しながらNotion APIを叩いてNotionのDBの値を引っ張ってくるみたいなことをしてみようと思っています😎

ちょっと長くなるかもしれませんがよろしくお願いします!

Related Posts

[TypeScript] BoltでSlack Appを作成する ②GAEにGitHub Actionsでデプロイする

[TypeScript] BoltでSlack Appを作成する ②GAEにGitHub Actionsでデプロイする

[TypeScript] BoltでSlack Appを作成する ④Notion APIを叩いてタスク一覧を取得する

[TypeScript] BoltでSlack Appを作成する ④Notion APIを叩いてタスク一覧を取得する

[TypeScript] BoltでSlack Appを作成する ⑤Slack上でスタンプを押すとNotionに保存する

[TypeScript] BoltでSlack Appを作成する ⑤Slack上でスタンプを押すとNotionに保存する