Zenn
🐟

[GAS/js]サーモンランのスケジュールをDiscordに定期投稿する

2025/03/24に公開
1

はじめに

こんにちは。サービス開始から毎シフト1オカシラはやってるサモラン好きです。

GAS(GoogleAppsScript)でDiscordのWebhook用APIを作れると知ったので、javascriptの勉強がてら作ってみることにしました。

実装時に参考にしたものなど、備忘録として投稿します。
成果物はこちら

サーモンランのスケジュールはこちらから取得させていただいてます。感謝🙏🙏🙏
https://spla3.yuu26.com/

処理フロー

ざっくりこんな感じのフローになります。

  1. サーモンランのスケジュールを取得(API実行)
  2. メッセージを生成
  3. シフト分ループ
    • embedにシフトの情報を詰める
    • ビッグランだったらちょっと表示を変える
  4. 投稿

実装時に参考にしたもの

GASから外部APIを実行

GASでは一部API(fetch等)を使う際、独自の記述が必要でした。
日付のフォーマットや投稿処理について、以下を参考にさせていただきました。
https://github.com/tatsumin39/youtube-to-discord-notifier

Embed

Discordに投稿する際、Embedを使うことで少しリッチな表示にできます。
こちらを参考にさせていただきました。
https://qiita.com/Eai/items/1165d08dce9f183eac74

全部盛りのembedを参考にobjectを生成しました。対象処理

ハマったポイント

colorを指定する際、数字のみの場合は0#をつけずに""で囲う必要があるようでした。
※Discordから400エラーが返ってくる
エラー原因を特定するのに結構時間がかかったのでご注意

実行タイミングの調整

サーモンランのシフトは通常40時間ごとに更新されますが、ビッグラン発生時にズレるので単純に40時間ごとでスケジューリングするといずれズレます。

そのため、1日1回APIを実行し、次回シフト分のトリガーをセットする方針としました。
トリガーセットの処理フロー

  • 次回トリガー生成済か確認(生成済であればreturn)
  • 次回シフトの日時を取得
  • トリガーを生成
    ※投稿処理実行時にトリガー削除

こちらを参考にさせていただきました。
https://qiita.com/kakakaori830/items/c06674252513b8d1c42e

ちなみに、GASはトリガーの上限が決まってます。(20件)
初回実装時トリガー削除処理を実装し忘れていて、いつの間にか定期投稿がストップしていました。

補足

GASはトリガー設定で定期実行をスケジューリングできますが、「毎日1時ちょうど」といった細かい指定はできません。
※「0時~1時」のように実行時間の範囲を設定

キッチリスケジューリングをしたい場合は上記のように指定日時のトリガーを都度生成する必要があります。

開発環境について

claspを利用

試作を実装してる際はGASのWebページ(スクリプトエディタ)を使っていましたが、GASはファイルを分けることができず、ソースが長くなるほど辛いです。
claspを利用することでローカルでコーディングできることがわかりました。

環境構築にあたり、こちらを参考にさせていただきました。
https://qiita.com/HeRo/items/4e65dcc82783b2766c03

開発環境と本場環境の切替

claspの反映先は.clasp.jsonscriptIdで指定しています。
動作確認用サーバーで確認後に公開サーバーにアップしたかったので楽に切り替える方法を考えました。
※後述のasideには標準機能として存在しているようです。

package.jsonにコマンドを定義することで解決しました。

{
  "scripts": {
    "pull": "clasp pull",
    "push": "clasp push",
    "open": "clasp open-script",
    "dev": "cp -f .clasp.json.dev .clasp.json",
    "prod": "cp -f .clasp.json.prod .clasp.json"
  }
}

例)本番環境にpushする場合

$ npm run prod
$ npm run push

asideを利用(しなかった)

後発のasideでは、claspの機能に加えてフォーマッターやテスト環境を構築できるようです。
あまり必要性がなく、無駄にスプレッドシートが作られてしまう弊害もあったので今回は見送りました。

TypeScriptでの実装(しなかった)

TypeScriptで実装すればファイルの分離ができるようなので、勉強がてら使ってみようと思いましたが、以下の理由で見送りました。

  • 都度build&pushが必要となり手間がかかること
  • スクリプトエディタで微修正して動作確認がしづらくなること
    ※動作確認後ローカルにpullができなくなる

さいごに

jsをほとんど触ってこなかったので勉強になりました。
※objectの浅いコピーでハマるなど

ついでにバトルのシフト投稿APIもつくりました。(現状未公開)
サーモンランのブキ編成画像を生成する処理もできそうなら追加したいと思ってます。

おわり。サーモンランやろう!!

Discussion

ログインするとコメントできます