ガイド
選定・比較
ドキュメント
スケジューラーを使う(ベータ版)
決まった時刻にアプリの URL へリクエストを送る「スケジューラー」の使い方。アプリ側の受け口の書き方、画面と hanamii.json の 2 つの設定方法、実行履歴と利用時間の見方、止まったときの対処まで。
hanamii のスケジューラーは、「毎朝 10 時に」「毎時 0 分に」のように決めた時刻に、デプロイしたアプリの指定した URL(パス)へ hanamii がリクエストを送る機能です(ベータ版)。いわゆる cron の代わりに使えます。
たとえば次のような処理に向いています。
スケジューラーはプロジェクト詳細の スケジューラー タブで管理します。

Authorization: Bearer <秘密の値> ヘッダーが付きます。秘密の値は hanamii が自動で作り、アプリの環境変数 HANAMII_SCHEDULER_SECRET として渡しますつまり、スケジューラーは「時刻になったらアプリを呼ぶ」役割だけを持ち、実際の処理はアプリの中に書きます。設定しただけでは何も実行されません。 処理を受け取る入口をアプリ側に用意してください。
スケジューラーが呼ぶパスに、GET を受け付ける API を作ります。hanamii 以外からの呼び出しを弾くため、HANAMII_SCHEDULER_SECRET と Authorization ヘッダーの照合を必ず入れてください。
HANAMII_SCHEDULER_SECRET は hanamii が自動で設定します。値を自分で見たり、環境変数の画面で登録したりする必要はありません(hanamii の予約名のため、自分で同じ名前の環境変数を登録することはできません)。
app/api/cron/route.ts
export async function GET(request: Request) {
const secret = process.env.HANAMII_SCHEDULER_SECRET
const authorization = request.headers.get('authorization')
if (!secret || authorization !== `Bearer ${secret}`) {
return new Response('Unauthorized', { status: 401 })
}
// ここに定期実行したい処理を書きます
return Response.json({ ok: true })
}
app.get('/api/cron', async (req, res) => {
const secret = process.env.HANAMII_SCHEDULER_SECRET
if (!secret || req.headers.authorization !== `Bearer ${secret}`) {
return res.status(401).send('Unauthorized')
}
// ここに定期実行したい処理を書きます
res.json({ ok: true })
})
import os
from flask import request, abort, jsonify
@app.get("/api/cron")
def cron():
secret = os.environ.get("HANAMII_SCHEDULER_SECRET")
if not secret or request.headers.get("Authorization") != f"Bearer {secret}":
abort(401)
# ここに定期実行したい処理を書きます
return jsonify(ok=True)
/ から始まる相対パスで、英数字と . _ - が使えます。/health や /ready など hanamii が内部で使うパスは指定できません設定方法は 2 つあります。画面から設定する 方法と、プロジェクトのルートに hanamii.json を置く 方法です。どちらか一方を使ってください。同じパスを両方で設定した場合はファイルの内容が優先され、画面からはそのパスを変更できなくなります。
| 方法 | 向いている場面 | 反映されるタイミング |
|---|---|---|
| 画面から設定 | まず試したい。コードを変えずに時刻だけ調整したい | 保存した時点 |
hanamii.json | 設定をコードと一緒に管理したい。GitHub 連携で複数人が触る | デプロイが成功した時点 |
/api/cron)を入力する
| 実行間隔 | 入力するもの | 例 |
|---|---|---|
| 毎分 | なし | 毎分に実行(動作確認用。本番ではおすすめしません) |
| 毎時 | 分 | 毎時 30 分に実行 |
| 毎日 | 時・分 | 毎日 10 時 0 分に実行 |
| 毎週 | 曜日(複数可)・時・分 | 毎週 月・木曜日 9 時 0 分に実行 |
| 毎月 | 日・時・分 | 毎月 1 日 0 時 0 分に実行 |
| 個別 | cron 式の 5 項目を直接入力 | 分 0 時 9-18 → 9 時から 18 時の毎時 0 分 |
保存したスケジュールは一覧に表示され、編集 と 削除 ができます。追加した時点で有効になり、一覧に「次回: 2026/10/14 10:00 JST」のように次の実行時刻が出ます。
プロジェクトのルート(package.json などと同じ階層)に hanamii.json を置きます。GitHub 連携でルートディレクトリを指定している場合は、そのディレクトリの直下に置いてください。
{
"schedules": [
{
"path": "/api/cron",
"schedule": "0 10 * * *"
},
{
"path": "/api/cleanup",
"schedule": "30 3 * * 1",
"timezone": "UTC"
}
]
}
| 項目 | 必須 | 内容 |
|---|---|---|
path | 必須 | リクエストを送るパス。/ から始める |
schedule | 必須 | 時刻を表す cron 式(数値 5 項目) |
timezone | 任意 | 時刻の基準。省略すると 日本時間(Asia/Tokyo)。UTC にしたいときは "UTC" |
schedules の中の path / schedule / timezone だけです。それ以外の項目があるとデプロイ時にエラーになりますpath を 2 つ書くことはできませんhanamii.json を置いたときの動きは次のとおりです。
「個別」タブと hanamii.json では、cron 式を直接書きます。左から 分・時・日・月・曜日 の 5 項目を半角スペースで区切ります。
┌ 分(0〜59)
│ ┌ 時(0〜23)
│ │ ┌ 日(1〜31)
│ │ │ ┌ 月(1〜12)
│ │ │ │ ┌ 曜日(0〜7、0 と 7 が日曜)
│ │ │ │ │
0 10 * * *
| 書きたい内容 | cron 式 |
|---|---|
| 毎日 10:00 | 0 10 * * * |
| 毎時 15 分 | 15 * * * * |
| 10 分ごと | */10 * * * * |
| 平日(月〜金)の 9:00 | 0 9 * * 1-5 |
| 毎月 1 日の 0:00 | 0 0 1 * * |
| 9 時から 18 時の毎時 0 分 | 0 9-18 * * * |
| 毎週 月・木の 9:30 | 30 9 * * 1,4 |
* , - / だけです。@daily や MON のような文字の指定はできません* にします)画面から設定した場合は保存した時点で、hanamii.json の場合はデプロイが成功した時点で、スケジュールが登録されます。
はじめて有効化したときは、hanamii が「今動いているアプリへ安全に送れるか」を確認します。その間は スケジューラーを準備しています と表示されます。しばらくして一覧のラベルが 有効 になれば準備完了です。
一覧のラベルの意味は次のとおりです。
| ラベル | 意味 |
|---|---|
| 有効 | 次回の時刻にリクエストが送られます |
| 無効 | スケジュール自体を止めています。時刻が来ても送りません |
| 実行停止中 | スケジュールは有効ですが、hanamii 側の確認が終わっていないか、配送を止めています。画面上部の案内を確認してください |
スケジューラータブの下部に、過去 30 日間 の実行履歴が新しい順に並びます。1 行に「予定時刻・パス・結果・HTTP ステータス・処理時間」が出ます。
| 表示 | 意味 | 対処 |
|---|---|---|
| (表示なし)HTTP 200 | 成功。2xx が返りました | 不要 |
| 失敗(HTTP 500 など) | アプリが 2xx 以外を返しました | アプリのランタイムログでエラーを確認してください。401 なら認証の照合コードを見直します |
| 配送失敗 | アプリに接続できませんでした | アプリが起動しているか、パスが正しいかを確認してください |
| タイムアウト(5分) | 5 分以内に応答が返りませんでした | 処理を短くするか、分割してください |
| 結果不明 | 送信を始めたあとに接続が切れるなどして、届いて処理されたかを確認できませんでした | 必要に応じてアプリのログを確認してください。処理が完了していることもあります |
| 未配送 | hanamii 側の準備が終わっておらず、送れませんでした | 画面上部の案内に沿って、必要なら再デプロイしてください |
| 混雑で未実行 / 処理遅れで未実行 / 開始期限切れ | hanamii 側の混み合いや遅れで、その回を見送りました | 次の回は通常どおり実行されます。続く場合はお問い合わせください |
| 待機中 / 配送準備中 / 実行中 | 進行中の回です | 不要 |
ヒント: 履歴には hanamii から見た結果だけが残ります。処理の中身(何件処理したか、どこでエラーになったか)は、アプリ側で ランタイムログ に出力しておくと追いやすくなります。
スケジューラータブの 今月の利用時間(このワークスペース) に、ワークスペース全体の実行時間(リクエストを送ってから応答が返るまでの合計)が表示されます。
hanamii.json で設定したもの: 画面からは止められません。ファイルから項目を消して再デプロイしてください。ファイル由来のスケジュールが 1 つでも有効なあいだは、画面の 利用しない は選べませんデプロイ タブのバージョン情報から過去のバージョンへ切り替えると、スケジューラーは安全のため 一時停止 します(切り替え完了時にその旨が表示されます)。再開するには、現在のスケジューラー設定を含めてもう一度デプロイし、一覧のラベルが 有効 に戻ることを確認してください。
アクセス制御で接続元 IP を制限しているプロジェクトでは、hanamii からのスケジューラー通信を通すため、hanamii が管理する許可ルールを 1 つ自動で追加します。許可 IP の枠は全体で 10 件のため、自分で登録できる IP は 9 件まで になります。すでに 10 件登録している場合は、スケジュールを有効化できません。アクセス制御タブに「Hanamii管理のスケジューラー通信がAppRunの10枠中1枠を使用中です」と表示されます。カスタムドメインを使っている場合は、この制限はありません。
ローカル開発環境には HANAMII_SCHEDULER_SECRET がありません。.env.local などに任意の値を入れ、次のように手で呼べば動作確認できます。
curl -H "Authorization: Bearer <ローカル用に決めた値>" http://localhost:3000/api/cron
時刻になっても実行されません
次の順で確認してください。
POST で受けたいです
スケジューラーが送るのは GET だけです。受け口は GET で用意してください。
秘密の値(HANAMII_SCHEDULER_SECRET)を確認したいです
画面には表示されません。アプリの中で process.env.HANAMII_SCHEDULER_SECRET のように読むだけで照合できるため、値を知る必要はありません。環境変数の画面に同じ名前で登録することもできません。
1 つのプロジェクトで複数の処理を動かしたいです
パスを分けてスケジュールを複数登録してください(例: /api/cron/daily と /api/cron/hourly)。hanamii.json なら schedules に複数書けます。
失敗した回はやり直されますか
失敗した回を hanamii がやり直すことは期待しないでください。次の予定時刻に通常どおり実行されます。取りこぼしが困る処理は、アプリ側で「前回どこまで処理したか」を記録して、次回にまとめて処理する作りにしてください。
次のガイド
カスタムドメインを設定する
日本の空に咲くクラウド
Calm. Fast. Trusted.
© 2026 hanamii. All rights reserved. 🌸