
この記事は、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側は候補を送ることに集中し、保存時の重複処理はサーバー側に寄せる判断です。
作業手順
- Script PropertiesにAPIのURL、トークン、User-Agentを入れる
- 必要なら設定JSONで取得先を上書きする
- 5分トリガーを一度だけ作成する
- GASの実行ログで対象ごとのスキップと取得を確認する
- Workerの管理画面で候補が重複せず更新されるか確認する
GASは大規模なジョブ基盤ではありません。それでも、個人開発で小さく定期処理を始めるには十分です。大切なのは、トリガーを増やすことではなく、取得間隔、認証、エラー、重複を最初に分けておくことです。
参考資料
-
developers.google.com developers.google.com の記事を開く /apps-script/guides/triggers/installable developers.google.com -
developers.google.com developers.google.com の記事を開く /apps-script/guides/properties developers.google.com -
developers.google.com developers.google.com の記事を開く /apps-script/reference/url-fetch/url-fetch-app developers.google.com