🐡

LIFF CLI + Github ActionsでLIFFアプリをメンテナンス画面に切り替えてみた(ミニアプリだと不可)

2024/11/29に公開

運用保守の作業として、夜間のシステムメンテナンス中に、LINEミニアプリをメンテナンス画面に切り替えたい場合があると思います。しかし切り替え作業のために深夜まで起きておくのは大変です。

LIFF CLIにはupdateコマンドがあり、LIFFアプリのエンドポイントURLを切り替えることができます。github actionsでcronを設定してLIFF CLIを使うと、夜間にLIFFアプリを自動的にメンテナンス画面に切り替えることが出来ると思い試してみることにしました。

ミニアプリだと出来ません

しかし、LIFF CLIが使えるのはLIFFアプリに対してのみで、ミニアプリに対しては使えませんでした。

liff-cli app update \
   --liff-id <ミニアプリのID> \
   --channel-id <チャネルID> \
   --endpoint-url "https://example.com/maintenance"
liff-cli app list --channel-id <チャネルID>
file:///Users/username/.volta/tools/image/packages/@line/liff-cli/lib/node_modules/@line/liff-cli/dist/api/liff.js:19
            throw new Error(`Failed to fetch LIFF apps: ${res.status} ${res.statusText}`);
                  ^

Error: Failed to fetch LIFF apps: 403 Forbidden

updateコマンドだけでなく、list, createなどの他のコマンドでもミニアプリのIDを指定した場合は同様のエラーが表示されました。仕様上、LIFF CLIはミニアプリに対しては使えないようです。

それを知らずに、リポジトリまで作って検証してたので、実用性には乏しいですが一応記事にしておくことにしました。今回の記事はLIFFアプリのみで利用できます。

https://github.com/shogo0421/liff-switch-maintenance

Github Actionsでメンテナンス画面に切り替えてみる

メンテナンス画面はすでに用意していて、後はLIFF CLIでエンドポイントURLをメンテナンス画面に切り替えるだけという状況です。
LIFF CLIはCLIツールなので、今回の場合はシェルスクリプトを定時で実行する手段が必要です。ローカル環境でcronを設定しておいても良いですが、PCがスリープ状態だと実行できない場合や、ネットワークの接続不良などに気をつけなければいけません。出来ればsaasやクラウドを使って実行した方が安全です。

もしlambdaでシェルスクリプトを実行しようと思うと、カスタムランタイムを使用しないといけないので少し複雑です。そこでgithub actionsのscheduleイベント(cron)を使うことを考えました。

ワークフローの作成

.github/workflows/switch-app.yml

name: switch maintennce
on:
  schedule:
    - cron: "20 6 24 10 *"

jobs:
  update-liff-endpoint:
    runs-on: ubuntu-latest

    steps:
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: switch endpoint to maintenance
        run: |
          npm install -g @line/liff-cli
          echo '${{ secrets.CHANNEL_SECRET }}' | liff-cli channel add ${{ vars.CHANNEL_ID }} 
          liff-cli channel use ${{ vars.CHANNEL_ID }} 
          liff-cli app update \
          --liff-id ${{ vars.LIFF_ID }} \
          --endpoint-url "https://example.com/maintenance"

LIFF CLIでnode v22を要求されたためバージョン指定しています。変数についてはgithubのRepository secrets, variablesを使っています。

cronだと一度だけ実行といったことができず、年に一回などの定期実行を設定することになります。使用しない場合はworkflowを無効化しておいた方が良さそうです。

遅れて実行される

使ってみると、実際にLIFFアプリをメンテナンス画面に切り替えることが出来ました。
しかし、毎回指定した時間から20分程度遅れて実行されました。

githubのドキュメントに、ワークフローの負荷が高い時間帯にはスケジュールイベントが遅延する、といったことが書かれていました。

Events that trigger workflows - GitHub Docs

• The schedule event can be delayed during periods of high loads of GitHub Actions workflow runs. High load times include the start of every hour. If the load is sufficiently high enough, some queued jobs may be dropped. To decrease the chance of delay, schedule your workflow to run at a different time of the hour.

メンテナンス画面への切り替えが予定より遅れては困るので別の方法を取った方が良さそうでした。

代案?

github actionsはwebhookのようにリクエストを受け取った時に実行することもできます。

workflowには以下のように記述して、

name: switch maintennce
on:
  repository_dispatch:
    types: [siwtch-app]

curlを定時で実行するとworkflowを呼び出せます。

curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer XXXXXXXXXXXXX" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/shogo0421/liff-switch-maintenance/dispatches \
-d '{"event_type":"siwtch-maintenance"}'

ただこの方法もcurlをどうやって定時で飛ばすか考えないといけません。

その他

今回のLIFFアプリのメンテナンス画面への切り替えは、LIFFアプリのエンドポイントURLを切り替えることで行なっています。このやり方だと、メンテナンス画面へ切り替える前からミニアプリを訪問中だったユーザーはリロードをしてもメンテナンス画面へは遷移しません。切り替え後にミニアプリを訪問したユーザーのみがメンテナンス画面に飛びます。

少し大掛かりではありますが、以下のようにAWS WAFを使うとその辺の問題も解決できます。
https://dev.classmethod.jp/articles/waf-maintenance/

Discussion