毎週月曜日の東京時間 09:00 に、分析 API から先週の数値を読み取り、短いレポートを書いて Slack またはメールで送信します。エージェントは GET だけを許可する接続を通じて読み取るため、数値を見ることはできても、変更することはできません。
実行には約 10 秒かかります。費用の大半はコンピュートで 1 秒あたり $0.0002 で課金されるため、月 4 回の実行で約 1 セントです。モデルの利用料はそのモデル自体の価格で課金され、選んだモデルによって変わります。最初の数回の実行で cost_micros を確認してください。
必要なものを用意する
- 接続とスケジュールを作成できるのはオーナーと管理者だけなので、管理者ロールの API キー。ロールとキーを参照してください。
- HTTPS でアクセスできる分析 API と、その読み取り専用キー。このレシピでは、
GET /metrics?period=…があり、periodにはlast_weekまたは2026-W40のような ISO 週を 指定できるものと仮定しています。パスは、お使いの API に合わせて読み替えてください。 - Slack の Incoming Webhook URL、またはメールを送信する独自のエンドポイント。
読み取り専用の接続を作成する
接続は、API キーを Ephemeral の内部に保管し、
GETのみを許可します。instructionsは、その API で何ができるかをエージェントに伝えます。curl -X PUT $EPHEMERAL_URL/v1/connections/analytics-api \ -H "Authorization: Bearer $EPHEMERAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "http", "url": "https://analytics.example.com/v2", "auth": { "type": "header", "header": "X-API-Key", "token": "an_live_…" }, "allowed_methods": ["GET"], "instructions": "GET /metrics?period=last_week or period=2026-W40 returns signups, active_users, revenue_cents and churned_accounts for that ISO week, with the same figures for the week before. Amounts are in cents." }'ワークフローを保存する
プロンプトは、期間を実行の入力から読み取ります。エージェントは信頼できるカレンダーを持っていないため、日付をエージェントに計算させるのではなく、
last_weekのように API が解決できる期間を渡してください。curl -X PUT $EPHEMERAL_URL/v1/workflows/weekly-report \ -H "Authorization: Bearer $EPHEMERAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Write the weekly business report for input.period. Call GET /metrics?period=<input.period> on the analytics connection and use only what it returns. Reply in Markdown, at most 150 words: a one-line headline, then signups, active users, revenue in dollars and churned accounts, each with the change from the week before. If the call fails, say so instead of estimating.", "connections": { "analytics": { "ref": "analytics-api", "allowed_methods": ["GET"] } }, "shell": false, "timeout_seconds": 120 }'webの設定がないため、この実行にはインターネットへのアクセスが一切ありません。届くのは分析用の接続だけです。ワークフローはinput、予算、コールバックを保持できません。これらは各実行とともに渡されます。月曜日の朝にスケジュールする
0 9 * * 1は毎週月曜日の 09:00 で、スケジュールのtimezoneで解釈されます。スケジュールのinputは、スケジュールが開始するすべての実行に渡されるため、期間はここで設定します。 まずプレビューします。curl -X POST $EPHEMERAL_URL/v1/schedules/preview \ -H "Authorization: Bearer $EPHEMERAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "cron": "0 9 * * 1", "timezone": "Asia/Tokyo" }'時刻は UTC で表示されています。UTC の 00:00 は東京の 09:00 です。スケジュールを作成します。
curl -X POST $EPHEMERAL_URL/v1/schedules \ -H "Authorization: Bearer $EPHEMERAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "workflow": "weekly-report", "name": "Monday report", "cron": "0 9 * * 1", "timezone": "Asia/Tokyo", "input": { "period": "last_week" }, "max_cost_micros": 300000 }'予算の $0.30 は、開始のたびに確保され、実行が精算されると解放されます。入力はスケジュールが持つため、同じワークフローに、別の入力を持つスケジュールを追加できます。また、後から
PATCH /v1/schedules/{id}と新しいinputで、このスケジュールを変更することもできます。月曜日を待たずに動作を確認するには、POST /v1/schedules/{id}/runまたはephemeral schedules run IDで、今すぐ 1 回開始してください。レポートを送信する
スケジュールされた実行はコールバックを送らないため、結果を取りに行って送信します。このスクリプトは、cron または CI から 10 分おきに実行し、スケジュールの最新の成功した実行を取得して、その出力を 1 回だけ送信し、実行 ID を記憶します。メールで送りたい場合は、Slack の呼び出しをメールサービスの呼び出しに置き換えてください。
import { readFile, writeFile } from "node:fs/promises"; const { EPHEMERAL_URL, EPHEMERAL_API_KEY, SCHEDULE_ID, SLACK_WEBHOOK_URL } = process.env; const stateFile = "report-state.json"; const { sent } = JSON.parse(await readFile(stateFile, "utf8").catch(() => "{}")); const response = await fetch(`${EPHEMERAL_URL}/v1/runs?schedule=${SCHEDULE_ID}&status=succeeded&limit=1`, { headers: { Authorization: `Bearer ${EPHEMERAL_API_KEY}` }, }); if (!response.ok) throw new Error(`Ephemeral returned ${response.status}`); const [run] = (await response.json()).items; if (!run || run.id === sent) process.exit(0); // nothing new since the last report await fetch(SLACK_WEBHOOK_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: run.output }), }); await writeFile(stateFile, JSON.stringify({ sent: run.id }));失敗した実行は何も送信しません。レポートが届かないことに気づかないまま過ごさないよう、
GET /v1/runs?schedule={id}&status=failed&limit=1も確認するか、スケジュールのlast_errorを監視してください。過去の週のレポートを再実行する
「今すぐ開始」はスケジュールの入力を再利用するため、別の週のレポートが必要なときは、目的の期間を指定してワークフローを直接開始します。今回は署名付きのコールバックを指定でき、結果が出たらすぐにエンドポイントへ届きます。週を表す冪等キーを使えば、リクエストを繰り返しても、2 通目のレポートが送られることはありません。
curl $EPHEMERAL_URL/v1/runs \ -H "Authorization: Bearer $EPHEMERAL_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: weekly-report-2026-W38" \ -d '{ "workflow": "weekly-report", "input": { "period": "2026-W38" }, "max_cost_micros": 300000, "callback": { "url": "https://example.com/hooks/ephemeral", "secret": "'"$EPHEMERAL_CALLBACK_SECRET"'" } }'コールバックのエンドポイントは、署名を検証して
run.outputを転送します。受信側は 支払い調査のレシピにあります。この方法で開始した実行はスケジュールの ID を持たないため、?schedule=の一覧には表示されません。
知っておくとよいこと
| 項目 | 動作 |
|---|---|
| タイムゾーン | 時刻はスケジュールの timezone で解釈されるため、09:00 に設定したレポートは、夏時間の切り替えをまたいでも現地時間の 09:00 のままです。 |
| 開始の取りこぼし | 09:00 に Ephemeral が利用できなかった場合は、復旧後にレポートが 1 回だけ実行され、その後はタイムテーブルどおりに戻ります。 |
| 重複 | skip_if_running がオンの場合、前回の実行が続いている間は開始がスキップされます。 |
| 一時停止 | 休暇の前に ephemeral schedules pause ID を実行し、休暇の後に resume します。 |
GET のみを許可し、キーが microVM に渡ることはありません。ワークフローには Web アクセスもシェルもないため、実行が読み取れるのは分析 API だけです。予算により、各実行は $0.30 に制限されます。 分析用のキーは読み取り専用にしてください。そうすれば、接続のほうで書き込みを許可していたとしても、書き込みはできません。