家計簿アプリを作る #80:Cloudflare Cron Triggersの基礎知識
家計簿アプリ作成シリーズの第80回です。月末に自動で収支サマリーをメール送信する機能を作るにあたり、Cloudflareの Cron Triggers(定期実行)について学んだことをまとめます。今回は仕組みと設定編、次回は実装編に分けてお届けします。
wrangler.jsoncはCloudflareの設定をコードで管理する仕組み
wrangler はCloudflare Workers/Pagesの開発・デプロイ用CLIツールで、wrangler.jsonc(またはwrangler.toml)にD1・R2・環境変数などのリソース定義をまとめて記述します。wrangler deploy を実行すると、この設定ファイルの内容がCloudflare側に反映されます。
Infrastructure as Code(IaC)の一種で、AWSでいうCDKに近い役割ですが、CDKのようにコードでインフラを組み立てる仕組みというよりは、serverless.yml やSAMのテンプレートに近い、宣言的な設定ファイルそのものです。「設定をソースコードと一緒にバージョン管理し、デプロイ時に反映する」という大枠の考え方は共通しています。
Cron Triggerの設定でハマったポイント
wrangler.jsonc にCron Triggerを追加する際、最初は以下のように書いてしまいました。
// ❌ bindingやオブジェクト形式は不要
"triggers": {
"crons": [
{ "binding": "send_budget_alerts", "pattern": "0 9 1 * *" }
]
}
正しくは、cron式の文字列だけの配列です。
// ✅ 文字列だけの配列
"triggers": {
"crons": ["0 0 1 * *"]
}
D1やR2のような「bindingを介してコードからアクセスするリソース」とは違い、Cron Triggerには名前付けの概念が無く、scheduled ハンドラ側で event.cron(発火した cron式)を見て複数スケジュールを判別する設計になっています。
また、Cron式の時刻は常に UTC で評価されます。日本時間の朝9時に実行したい場合は、9時間前のUTC時刻("0 0 1 * *")を指定する必要がありました。
scheduledハンドラはHTTP APIとは別物
scheduled ハンドラは、URLを持つ通常のAPI(+server.ts の GET/POST など)とは全く異なる仕組みです。
- 通常のAPI: ブラウザや他のサービスがURLにリクエストすることで呼び出される
scheduledハンドラ: URLは存在せず、Cloudflareのランタイムが指定時刻に内部的に呼び出す特殊なイベントハンドラ。外部から直接呼び出すことはできない
コード上は、Workerのエントリポイントに fetch ハンドラ(通常のリクエスト処理)とは別に scheduled を追加でexportする形になります。
export default {
async fetch(request, env, ctx) {
// 通常のHTTPリクエスト処理
},
async scheduled(event, env, ctx) {
// Cron Triggerから呼ばれる処理
},
};
ローカルでのテスト方法
wrangler dev は、scheduled を自動発火してくれません。代わりに専用のエンドポイントを叩いて手動発火させます。
curl "http://localhost:8787/cdn-cgi/handler/scheduled"
ただし、環境によっては --test-scheduled フラグを付けて起動しないと、このエンドポイントが正しく機能しないことがありました。
npx wrangler dev --test-scheduled
さらに、assets(静的アセット配信)と scheduled を組み合わせた構成では、Wranglerのバージョンによっては正しく動かない不具合があるようで、最新版へのアップデートで解消しました。原因の切り分けに時間がかかったので、次回の実装編で詳しく触れます。
まとめ
| ポイント | 内容 |
|---|---|
cronsの書式 |
cron式の文字列だけの配列。bindingやオブジェクト形式は不要 |
| Cron式の時刻 | 常にUTC。JSTで動かしたい時刻から9時間引いて指定する |
scheduledハンドラ |
HTTPのAPIとは別物。URLを持たず、Cloudflareが内部的に呼び出す |
| ローカルテスト | curlで専用エンドポイントを叩く。--test-scheduledが必要な場合がある |
| バージョン起因の不具合 | assets+scheduledの組み合わせで、Wranglerのバージョンによる不具合があった |