レシピ

週次レポートを送信する

分析 API から、月曜の朝のレポートをスケジュールで作成します。

毎週月曜日の東京時間 09:00 に、分析 API から先週の数値を読み取り、短いレポートを書いて Slack またはメールで送信します。エージェントは GET だけを許可する接続を通じて読み取るため、数値を見ることはできても、変更することはできません。

実行には約 10 秒かかります。費用の大半はコンピュートで 1 秒あたり $0.0002 で課金されるため、月 4 回の実行で約 1 セントです。モデルの利用料はそのモデル自体の価格で課金され、選んだモデルによって変わります。最初の数回の実行で cost_micros を確認してください。

  1. 必要なものを用意する

    • 接続とスケジュールを作成できるのはオーナーと管理者だけなので、管理者ロールの API キー。ロールとキーを参照してください。
    • HTTPS でアクセスできる分析 API と、その読み取り専用キー。このレシピでは、GET /metrics?period=… があり、period には last_week または 2026-W40 のような ISO 週を 指定できるものと仮定しています。パスは、お使いの API に合わせて読み替えてください。
    • Slack の Incoming Webhook URL、またはメールを送信する独自のエンドポイント。
  2. 読み取り専用の接続を作成する

    接続は、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."
      }'
  3. ワークフローを保存する

    プロンプトは、期間を実行の入力から読み取ります。エージェントは信頼できるカレンダーを持っていないため、日付をエージェントに計算させるのではなく、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、予算、コールバックを保持できません。これらは各実行とともに渡されます。

  4. 月曜日の朝にスケジュールする

    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 回開始してください。

  5. レポートを送信する

    スケジュールされた実行はコールバックを送らないため、結果を取りに行って送信します。このスクリプトは、cron または CI から 10 分おきに実行し、スケジュールの最新の成功した実行を取得して、その出力を 1 回だけ送信し、実行 ID を記憶します。メールで送りたい場合は、Slack の呼び出しをメールサービスの呼び出しに置き換えてください。

    report.mjs (Node.js 18 以降)
    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 を監視してください。

  6. 過去の週のレポートを再実行する

    「今すぐ開始」はスケジュールの入力を再利用するため、別の週のレポートが必要なときは、目的の期間を指定してワークフローを直接開始します。今回は署名付きのコールバックを指定でき、結果が出たらすぐにエンドポイントへ届きます。週を表す冪等キーを使えば、リクエストを繰り返しても、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 に制限されます。 分析用のキーは読み取り専用にしてください。そうすれば、接続のほうで書き込みを許可していたとしても、書き込みはできません。
© 2026 Ephemeral制作: erni.works
esc

「」に一致する項目はありません。