GASの5分トリガーで複数の取得先を間隔制御する実装 AI・自動化

GASの5分トリガーで複数の取得先を間隔制御する実装

AI・自動化

1つのGASトリガーで複数の取得先を巡回したい人向けに、intervalMinutes、PropertiesService、UrlFetchApp、Worker API連携を実コードで整理します。

GASで複数対象の取得間隔を制御する図解
1つの5分トリガーから、取得先ごとのintervalMinutesを見て実行可否を判定します。

この記事は、Google Apps Scriptで定期処理を作りたいけれど、取得先ごとに実行間隔を変えたい人向けです。5分ごとに起動するトリガーを1つだけ作り、その中で30分ごと、2時間ごと、4時間ごとのように処理を分ける方法を整理します。

題材は、このCMSに残している外部データ取得の仕組みです。公開サイト側に出す内容ではなく、管理画面へ候補データを送るための裏側の処理として使います。RSS監視、API定期取得、在庫チェック、通知バッチにも応用できる構成です。

対象読者と解決する問題

GASの時間主導トリガーは手軽ですが、取得先ごとにトリガーを増やすと管理がつらくなります。あとから対象を増やしたり、取得間隔を変えたり、止めたりするたびにGASのトリガー画面を触ることになります。

この実装では、トリガーはメイン関数だけです。取得先ごとの間隔は設定値として持ち、前回実行時刻との差で実行可否を判定します。

設定の持ち方

const DEFAULT_TARGETS = [
  {
    key: "targetA",
    name: "取得先A",
    url: "https://example.com/feed.txt",
    intervalMinutes: 30,
    encoding: "UTF-8"
  },
  {
    key: "targetB",
    name: "取得先B",
    url: "https://example.com/api/list",
    intervalMinutes: 120,
    encoding: "UTF-8"
  }
];

実際のコードでは、設定JSONをScript Propertiesに入れると、デフォルト設定を上書きできます。コードを書き換えずに対象を調整できるようにするためです。

前回実行時刻でスキップする

function shouldFetchTarget_(props, target, now) {
  const intervalMinutes = Number(target.intervalMinutes || 60);
  const lastFetchMs = Number(props.getProperty(lastFetchKey_(target.key)) || 0);
  return now.getTime() - lastFetchMs >= intervalMinutes * 60 * 1000;
}

ここで PropertiesService を使います。LAST_FETCH_targetA のようなキーに前回実行時刻を保存し、間隔を満たしていなければ処理しません。トリガー自体は5分ごとに起動しても、外部アクセスは取得先ごとの間隔に抑えられます。

UrlFetchAppで取得する

const response = UrlFetchApp.fetch(target.url, {
  method: "get",
  muteHttpExceptions: true,
  followRedirects: true,
  headers: {
    "User-Agent": userAgent
  }
});

muteHttpExceptions をtrueにしているのは、HTTPエラー時にもレスポンスコードと本文を見てログ化できるようにするためです。失敗時に例外だけで終わると、どの取得先がなぜ失敗したか追いづらくなります。

Worker APIへPOSTする

UrlFetchApp.fetch(apiBaseUrl + "/api/thread-candidates/import", {
  method: "post",
  contentType: "application/json",
  headers: {
    Authorization: "Bearer " + importToken
  },
  payload: JSON.stringify({ candidates: candidates })
});

APIトークンはコードに直書きせず、Script Propertiesから読みます。Worker側では環境変数のトークンと照合します。ここを分けることで、GASコードを共有しても秘密情報が漏れにくくなります。

失敗しやすい判断

  • 取得先ごとにGASトリガーを作りすぎる
  • 前回実行時刻を保存せず、毎回すべて取得する
  • HTTPエラーを本文なしで捨てる
  • APIトークンをコードに直書きする
  • 重複データをinsertだけで処理する

このCMSでは、Worker側のimport APIが重複URLを更新として扱います。GAS側は候補を送ることに集中し、保存時の重複処理はサーバー側に寄せる判断です。

作業手順

  1. Script PropertiesにAPIのURL、トークン、User-Agentを入れる
  2. 必要なら設定JSONで取得先を上書きする
  3. 5分トリガーを一度だけ作成する
  4. GASの実行ログで対象ごとのスキップと取得を確認する
  5. Workerの管理画面で候補が重複せず更新されるか確認する

GASは大規模なジョブ基盤ではありません。それでも、個人開発で小さく定期処理を始めるには十分です。大切なのは、トリガーを増やすことではなく、取得間隔、認証、エラー、重複を最初に分けておくことです。

参考資料