Receitas

Observe uma página e receba alertas

Verifique uma página a cada 15 minutos e alerte o Slack apenas quando o estado dela mudar.

Verifique uma página ou API pública a cada 15 minutos, peça ao agente que informe o que encontrar em JSON e publique no Slack apenas quando o estado mudar. O Ephemeral executa a verificação em um agendamento; um pequeno script seu lê o resultado e decide se deve alertar.

Uma verificação que busca uma página leva cerca de 20 segundos. A maior parte do custo é a computação, cobrada a $0.0002 por segundo, mais $0.001 pela busca da página. A parte do modelo depende do modelo que você escolher; por isso, leia cost_micros nas primeiras execuções e ajuste o agendamento ou o modelo a partir daí.

  1. Reúna o que você precisa

    • Uma chave de API com a função de administrador, porque só proprietários e administradores podem criar agendamentos. Veja funções e chaves.
    • A página ou API a observar, em um único domínio, aqui https://status.example.com.
    • Uma URL de webhook de entrada do Slack, ou o endereço do seu próprio serviço de alertas.
    • Um lugar para executar um script a cada poucos minutos: cron, uma tarefa de CI agendada ou um timer serverless.
  2. Salve o fluxo de trabalho

    O fluxo de trabalho busca a página e responde em um formato JSON fixo. O Ephemeral não impõe um esquema de saída: a saída da execução é texto livre. Por isso o prompt pede apenas JSON, e o seu script o interpreta com cautela no passo 4.

    curl -X PUT $EPHEMERAL_URL/v1/workflows/check-status-page \
      -H "Authorization: Bearer $EPHEMERAL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "Fetch the page at input.url with web_fetch. Reply with one JSON object and nothing else: {\"ok\": boolean, \"http_status\": number, \"summary\": string}. Set ok to true only when the response status is 200 and the page reports no ongoing incident, outage or degraded service; resolved past incidents do not count. summary is one sentence of at most 200 characters.",
        "web": { "allow": ["status.example.com"], "search": false },
        "shell": false,
        "timeout_seconds": 90
      }'

    O acesso à web fica limitado a status.example.com e a pesquisa fica desligada, então a verificação pode ler esse site e mais nada. A URL a verificar chega como entrada, de modo que o mesmo fluxo de trabalho pode atender a mais de um agendamento nesse domínio.

  3. Crie o agendamento

    Primeiro, pré-visualize a programação. Ela retorna os próximos cinco horários de início e não salva nada.

    curl -X POST $EPHEMERAL_URL/v1/schedules/preview \
      -H "Authorization: Bearer $EPHEMERAL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "cron": "*/15 * * * *", "timezone": "UTC" }'

    Depois, crie-o. A entrada e o orçamento são os mesmos em todas as execuções.

    curl -X POST $EPHEMERAL_URL/v1/schedules \
      -H "Authorization: Bearer $EPHEMERAL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "workflow": "check-status-page",
        "name": "Status page, every 15 minutes",
        "cron": "*/15 * * * *",
        "input": { "url": "https://status.example.com" },
        "max_cost_micros": 100000
      }'

    Guarde o id do agendamento. O orçamento de 100.000 micros ($0.10) é reservado dos seus créditos a cada início e liberado quando a execução é liquidada; ele precisa cobrir a computação do tempo limite inteiro, que aqui é de 90 segundos, ou $0.018. Se uma verificação ainda estiver em andamento quando o próximo início estiver previsto, esse início é ignorado, porque skip_if_running é true por padrão.

  4. Inicie uma agora e leia a resposta

    Não espere pela programação. POST /v1/schedules/{id}/run inicia o fluxo de trabalho agora com a entrada e o orçamento do agendamento e responde 202 com uma execução que carrega o ID do agendamento. Depois, liste as execuções do agendamento, da mais recente para a mais antiga:

    curl -X POST $EPHEMERAL_URL/v1/schedules/$SCHEDULE_ID/run \
      -H "Authorization: Bearer $EPHEMERAL_API_KEY"
    
    curl "$EPHEMERAL_URL/v1/runs?schedule=$SCHEDULE_ID&limit=1" \
      -H "Authorization: Bearer $EPHEMERAL_API_KEY"

    output é uma string que contém o JSON. Às vezes os modelos o envolvem em um bloco de código ou acrescentam uma frase apesar da instrução, então o script abaixo pega tudo desde o primeiro { até o último } e interpreta esse trecho.

  5. Alerte apenas quando algo mudar

    As execuções agendadas não enviam callbacks, então o seu script consulta a execução mais recente do agendamento. Ele memoriza em um arquivo a última execução e o último estado, ignora as execuções que já viu ou que ainda estão em andamento e publica no Slack apenas quando o estado difere do anterior. Uma verificação que falha ou retorna algo ilegível conta como um estado próprio, unknown, para que um monitor quebrado não pareça uma página saudável.

    monitor.mjs (Node.js 18 ou posterior)
    import { readFile, writeFile } from "node:fs/promises";
    
    const { EPHEMERAL_URL, EPHEMERAL_API_KEY, SCHEDULE_ID, SLACK_WEBHOOK_URL } = process.env;
    const ACTIVE = new Set(["reserving", "queued", "starting", "running"]);
    const stateFile = "monitor-state.json";
    const state = JSON.parse(await readFile(stateFile, "utf8").catch(() => "{}"));
    
    const response = await fetch(`${EPHEMERAL_URL}/v1/runs?schedule=${SCHEDULE_ID}&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 || ACTIVE.has(run.status) || run.id === state.run) process.exit(0); // nothing new to judge
    
    let label = "unknown"; // the check itself did not produce an answer
    let summary = run.error ?? `The run ${run.status}.`;
    if (run.status === "succeeded") {
      try {
        const result = JSON.parse(run.output.match(/\{[\s\S]*\}/)[0]); // tolerate text or a code fence around the JSON
        label = result.ok === true ? "ok" : "down";
        summary = result.summary;
      } catch {
        summary = "The check did not return valid JSON.";
      }
    }
    
    if (label !== (state.label ?? "ok")) {
      await fetch(SLACK_WEBHOOK_URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text: `Status page: ${label}. ${summary} (${run.id})` }),
      });
    }
    await writeFile(stateFile, JSON.stringify({ run: run.id, label }));

    Execute-o a cada cinco minutos, por exemplo com */5 * * * * no cron, com as quatro variáveis definidas. A primeira verificação fica em silêncio quando a página está saudável; cada mudança posterior, incluindo a recuperação de down para ok, publica uma vez.

Bom saber

TemaComportamento
Verificações sobrepostasCom skip_if_running ativado, um início é ignorado enquanto a execução anterior ainda está em andamento, e o agendamento registra isso em last_error. Defina como false apenas se a sobreposição for inofensiva.
Um agendamento que paraApós cinco inícios com falha seguidos, por exemplo porque os créditos acabaram, o agendamento se desativa sozinho e nenhuma nova execução aparece. Confira enabled e last_error com GET /v1/schedules/{id} de vez em quando, ou recarregue os créditos e defina enabled como true.
Alterando o intervaloPATCH /v1/schedules/{id} com um novo cron; o próximo início é contado a partir de agora.
Pausandoephemeral schedules pause ID e resume, ou enabled em um PATCH.
Mantenha a verificação somente leitura
Este fluxo de trabalho não tem conexões nem shell, e o acesso à web alcança um único domínio. Como é a execução que decide o que informar, trate a resposta dela como um sinal para investigar, não como um comando a ser cumprido automaticamente.
Prefere um callback?
Se você prefere receber um callback assinado em vez de consultar, inicie as execuções a partir do seu próprio agendador com POST /v1/runs, o mesmo fluxo de trabalho e um callback. O receptor é o de a receita de investigação de pagamento. Assim você abre mão da proteção contra sobreposição e da programação do Ephemeral, então reserve os agendamentos para o trabalho que você não precisa empurrar.
© 2026 EphemeralProduzido por erni.works
esc

Nada corresponde a “”.