TypeScriptでSlack Appを作成してみたので、その方法の紹介です。
作成したアプリはこちら
https://github.com/irori-dev/SlackApp
前回までで、
- ローカルで動くところまで
- GAEへのデプロイと、GirtHub Actionsでデプロイできるように
という状態になっています。
今回は、GitHub APIを叩いて、前回作成したworkflowを動かしてデプロイさせようと思います🎉
前回までの記事はこちら。
作っていきましょう
まず、GitHub APIで何をさわればいいか確認しましょう。
今回叩くAPIはこちらになります。
/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches
を叩くと、指定したworkflowを動かせるよ!ということです。
そして、nodeから叩く方法として簡単にできるよう、octkitというpackageがあります。
公式ではないようですが、更新がそれほど遅れているわけではなさそうなこと(直近では4ヶ月前)、割と色々なところで使われているpackageであることから今回採用しました。
https://github.com/octokit/core.js
1. octkit/core.jsの設定
% npm install @octokit/rest —save
を実行後、package.jsonに入っていることを確認しましょう。
その後、以下のファイルを作成します。
import { Octokit } from "@octokit/core";
export const octokit = new Octokit({
auth: process.env.GH_TOKEN,
});
.env
にGH_TOKEN
を入れましょう。
GH_TOKEN
という名前にしてるのは、後ほどGitHubにsecretを入れるときにGITHUB_
というprefixが入れられないので、わかりやすさのためにこれに統一しています。
ここからトークンを発行できます。
https://github.com/settings/tokens
2. 対応ファイルを作成する
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配下に移しておきましょう。
import { app } from '../initializers/bolt'
export default (): void => {
app.message(`sample ping`, async ({ _message, say }): Promise<void> => {
await say('pong')
})
}
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
をちゃんと渡せるように以下のように修正しましょう。
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"
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に差し替えた後、以下のように実行してみましょう。
iroriとなっていますが、sampleとしてください。
Deployment startedと返ってきたら、無事にアクションが動いているか確認しましょう🎉
3. 成功したらNotificationが返ってくるようにしよう
さあ、これでデプロイ自体はできるようになったのですが、完了通知がありませんね。
完了通知はもっと簡単にできるので、完了通知を最後にやっちゃいましょう!
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に追加し忘れないようにしてくださいね。
再度実行して、しばらくしたら以下のようになっていれば成功です!🎉
次回は、FirebaseのFirestoreを活用しながらNotion APIを叩いてNotionのDBの値を引っ張ってくるみたいなことをしてみようと思っています😎
ちょっと長くなるかもしれませんがよろしくお願いします!