Zenn
🍣

[GAS]サーモンランのステージ・ブキ画像を結合してDiscordに投稿する

2025/03/26に公開

はじめに

https://zenn.dev/mkhana/articles/d108f75f9c7040
の続きです。
上記で、Webhookを利用してサーモンランのスケジュールを定期投稿することができました。

ステージとブキ編成の画像を結合することができたので、備忘録として投稿します。
成果物はこちら差分

処理フロー

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

  1. サーモンランのスケジュールを取得(API実行)
  2. メッセージを生成
  3. シフト分ループ
    1. embedにシフトの情報を詰める
    2. ビッグランだったらちょっと表示を変える
    3. シフト画像を追加(今回追加した部分)
      1. GoogleDrive内に既に画像があればそれを使う
      2. なければ生成(ステージ画像とブキ画像を結合)
      3. GoogleDriveに保存
  4. 投稿

画像結合

使用したライブラリ

https://github.com/tanaikech/ImgApp
ここにやりたいことがそのまま記載してありました。

画像生成処理

当初1回のマージ処理で画像を生成していましたが、ステージの横幅とブキ編成の横幅が合わず、余白ができていました。

そのため、先にステージ画像の横幅(800px)に合わせてブキ編成画像を生成し、その後ステージ画像と結合することにしました。

変更前

const imageObj = {
  merge: [
    [stageBlob],
    [weaponBlob1, weaponBlob2, weaponBlob3, weaponBlob4],
  ],
  outputWidth: 800,
};
ImgApp.editImage(imageObj);

変更後

// ブキ画像を結合
const weaponsObj = {
  merge: [
    [weaponBlob1, weaponBlob2, weaponBlob3, weaponBlob4],
  ],
  outputWidth: 800,
};
const weaponsBlob = ImgApp.editImage(weaponsObj);

// ステージ画像とブキ画像を結合
const imageObj = {
  merge: [
    [stageBlob],
    [weaponsBlob],
  ],
  outputWidth: 800,
};
ImgApp.editImage(imageObj);

GoogleDriveに保存

画像を投稿するにあたり、URLが必要だったのでGoogleDriveの共有フォルダに保存しています。
※保存先フォルダのIDは環境変数(プロパティ)で管理
画像のバイナリを直接送信できればGoogleDriveへの保存は不要でしたが、後述のパフォーマンス問題もあるので結果的にこの形で良かったかもしれません。

パフォーマンス対策

5シフト分の画像を生成して投稿した場合、1分以上かかっていました。
2時間おきに5件保存されていくのもよろしくなかったので、GoogleDriveをファイル名で検索して既に生成済であれば利用するようにしました。

const imageFilename = formatDate(schedule.start_time, 'YYYYMMDDTHHmmss');
// 既に生成済の画像があればそれを返す
const files = tmpFolder.getFilesByName(imageFilename);
while (files.hasNext()) {
  file = files.next();
  return file.getId();
}

結果、実行時間が10秒程度になったのでよかったです。

今後の課題

今後時間があれば↓の対応もしていきたいと思ってます。

編成画像の崩れ対策

ブキごとに画像サイズが異なる?ようで、ブキ画像のサイズがまちまちになってます。
先にサイズを揃えて結合してみようと思ってます。
※パフォーマンスに影響が出るようであれば見送り

複数Webhookとの連携

現状WebhookごとにGASを作成する必要があるので、1対多に対応したいです。
※スプレッドシートを使えば割と簡単にできるはず

編成画像をオシャレにしたい

現状画像をくっつけているだけですが、せっかくブキの背景も透過されてるので、いずれちょっとおしゃれに加工したいですね。

過去の画像を削除

1枚100KB程度ですが、放置しすぎると容量を圧迫しそうなのでそのうち削除用のGASを作ろうと思ってます。

おわりに

ライブラリのおかげで思ったよりサクッと実装できました。

流用してバトルのステージ画像を生成して投稿することもできます✌️

おわり。ガチアサリやろう!!

Discussion

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