Recettes

Envoyer un rapport hebdomadaire

Un rapport du lundi matin à partir de votre API d'analytique, selon une planification.

Chaque lundi à 09:00 à Tokyo, lisez les chiffres de la semaine précédente depuis votre API d'analytique, rédigez un court rapport et envoyez-le sur Slack ou par e-mail. L'agent lit via une connexion qui n'autorise que GET : il peut consulter vos chiffres, mais pas les modifier.

L'exécution dure environ 10 secondes. L'essentiel du coût est le calcul, facturé 0,0002 $ par seconde : quatre exécutions par mois reviennent donc à environ un centime. La part du modèle dépend du modèle que vous choisissez ; lisez cost_micros sur les premières exécutions pour la voir.

  1. Rassembler ce qu'il vous faut

    • Une clé API avec le rôle administrateur, car seuls les propriétaires et les administrateurs créent des connexions et des planifications. Voir rôles et clés.
    • Votre API d'analytique en HTTPS, et une clé en lecture seule pour celle-ci. Cette recette suppose qu'elle expose GET /metrics?period=…, où period vaut last_week ou une semaine ISO telle que 2026-W40. Adaptez les chemins à votre API.
    • L'URL d'un webhook entrant Slack, ou un point de terminaison de votre côté qui envoie des e-mails.
  2. Créer la connexion en lecture seule

    La connexion garde la clé API à l'intérieur d'Ephemeral et n'autorise que GET. Les instructions indiquent à l'agent ce que l'API propose.

    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. Enregistrer le workflow

    Le prompt lit la période dans l'entrée de l'exécution. L'agent ne dispose pas d'un calendrier fiable : transmettez donc une période que votre API sait résoudre, comme last_week, plutôt que de demander à l'agent de calculer des dates.

    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
      }'

    Il n'y a pas de paramètre web : l'exécution n'a donc aucun accès à Internet ; sa seule portée est la connexion d'analytique. Un workflow ne peut pas contenir d'input, de budget ni de callback ; ceux-ci viennent avec chaque exécution.

  4. La planifier pour le lundi matin

    0 9 * * 1 correspond à 09:00 le lundi, interprété dans le timezone de la planification. L'input de la planification est ce que reçoit chaque exécution qu'elle lance : c'est donc ici que vous définissez la période. Prévisualisez-la d'abord.

    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" }'

    Les heures sont en UTC : 00:00 UTC correspond à 09:00 à Tokyo. Créez la planification :

    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
      }'

    Le budget de 0,30 $ est réservé à chaque lancement et libéré lorsque l'exécution est réglée. Comme la planification possède l'entrée, vous pouvez ajouter une autre planification sur le même workflow avec une entrée différente, ou modifier celle-ci plus tard avec PATCH /v1/schedules/{id} et un nouvel input. Pour la voir fonctionner avant lundi, lancez-en une maintenant avec POST /v1/schedules/{id}/run ou ephemeral schedules run ID.

  5. Livrer le rapport

    Les exécutions planifiées n'envoient pas de callbacks ; la livraison passe donc par la collecte du résultat. Ce script, exécuté toutes les dix minutes depuis cron ou la CI, demande la dernière exécution réussie de la planification, envoie son résultat une seule fois et mémorise l'ID de l'exécution. Remplacez l'appel Slack par un appel à votre service de messagerie si vous préférez l'e-mail.

    report.mjs (Node.js 18 ou version ultérieure)
    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 }));

    Une exécution qui a échoué n'envoie rien : consultez donc aussi GET /v1/runs?schedule={id}&status=failed&limit=1, ou surveillez le last_error de la planification, afin qu'un rapport manquant ne passe pas inaperçu.

  6. Relancer un rapport pour une semaine passée

    "Lancer maintenant" réutilise l'entrée de la planification : pour une autre semaine, lancez donc directement le workflow avec la période souhaitée. Cette fois, vous pouvez demander un callback signé, qui livre le résultat à votre point de terminaison dès qu'il est prêt. Utilisez une clé d'idempotence qui nomme la semaine, afin qu'une requête répétée n'envoie jamais un second rapport.

    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"'"
        }
      }'

    Votre point de terminaison de callback vérifie la signature et transmet run.output ; le récepteur se trouve dans la recette d'investigation de paiement. Une exécution lancée ainsi ne porte pas l'ID de la planification : elle n'apparaît donc pas sous ?schedule=.

À savoir

SujetComportement
Fuseau horaireLes heures sont interprétées dans le timezone de la planification : un rapport réglé sur 09:00 reste donc à 09:00 heure locale lors des changements d'heure.
Lancements manquésSi Ephemeral était indisponible à 09:00, le rapport s'exécute une fois à son retour, puis le calendrier reprend.
ChevauchementAvec skip_if_running activé, un lancement est ignoré tant que l'exécution précédente est en cours.
Pausingephemeral schedules pause ID avant des congés et resume après.
Pourquoi c'est sûr
La connexion n'autorise que GET, et la clé n'atteint jamais la microVM. Le workflow n'a ni accès web ni shell : l'exécution peut donc lire votre API d'analytique, et rien d'autre. Le budget plafonne chaque exécution à 0,30 $. Utilisez une clé d'analytique en lecture seule, pour que même la connexion ne puisse rien écrire.
© 2026 EphemeralRéalisé par erni.works
esc

Aucun résultat pour « ».