Skip to main content
Uma execução diferida é uma invocação que você agenda para acontecer uma única vez no futuro: um lembrete em 24 horas, um follow-up de carrinho abandonado, uma pesquisa 2 dias após a compra.
Cron ou diferida?
  • Cron — repete em um horário fixo (todos os dias às 9:00). Definido no código.
  • Diferida — acontece uma vez, em um momento calculado em tempo de execução (24 horas depois deste pedido). Agendada pelo handler ou pela requisição HTTP.

Agendar pelo handler

ctx.jelou.schedule() agenda uma execução relativa a “agora”:
index.ts

Parâmetros

A duração aceita unidades compostas da maior para a menor: "1h30m" é válido, "30m1h" não.
Para follow-ups muito curtos use 5 segundos ou mais. Abaixo disso, a latência de rede pode deixar o momento agendado no passado e a plataforma rejeita.

Momento absoluto

ctx.jelou.scheduleAt() recebe uma data em vez de uma duração:
Lança erro se a data já passou ou não pode ser interpretada. Os outros campos funcionam como em schedule().

Evitar duplicados

Se o serviço que chama sua função fizer retentativa, idempotencyKey garante um único agendamento:
Reutilizar a mesma idempotencyKey com um payload diferente retorna erro 409.

Agendar por requisição HTTP

Qualquer cliente pode diferir uma chamada adicionando um header ao POST normal. Sem headers de agenda, a função executa imediatamente como sempre.
A resposta é 202 Accepted quando o agendamento é criado e 200 OK quando uma retentativa reutiliza um agendamento existente. O corpo não pode passar de 64 KB.

Receber o disparo

Na hora marcada, sua função recebe o payload original na rota indicada. Use ctx.isScheduledFire para distinguir o disparo de uma requisição normal:

Verificar antes de agir

Entre o agendamento e o disparo, a realidade pode mudar: o cliente já pagou, o template foi pausado, o usuário pediu descadastro. ctx.guard encadeia essas verificações e evita o envio se alguma falhar:
Se todas as verificações passam, .run() executa e o resultado é a resposta. Se alguma falha, a cadeia é interrompida e retorna { skipped: "<nome>" } sem executar o envio.
A cadeia termina com .run(handler), não com .then(). ctx.guard é uma cadeia nova em cada requisição.
Se o bot não viaja no payload, em um disparo diferido ctx.bot não está resolvido e ctx.templateRegistry fica sem canal associado. Inclua o botId no payload ao agendar e vincule com ctx.templateRegistry.for(botId). Veja templates do WhatsApp.

Consultar o que está agendado

ctx.jelou.findDeferred() lista as execuções pendentes da sua função:

Cancelar

ctx.jelou.cancelDefer() cancela em lote por audiência ou etiqueta. Exige exatamente um de subject, key ou keyPrefix:
raced contém as execuções que já estavam disparando quando o cancelamento chegou — para essas, a verificação com ctx.guard no handler é a última defesa. Escreva seus handlers de forma idempotente. Antes de um cancelamento amplo, previsualize o alcance com dryRun:
Não existe “reagendar”: um agendamento é imutável. Para mudar a hora, cancele e agende de novo.

Teste local

schedule, scheduleAt, findDeferred e cancelDefer funcionam apenas em uma função implantada. Localmente lançam erro porque não há credenciais de plataforma. Para exercitar o fluxo com jelou functions dev, ative a simulação:
Nesse modo os argumentos são validados, o agendamento é registrado nos logs e um resultado sintético é retornado — seu handler continua executando, mas nada real é agendado. Para testes unitários use createMockContext, cujo ctx.jelou registra as chamadas sem rede nem configuração.

Inspecionar pelo CLI

Veja a referência do CLI.

Limites

Agendamentos já disparados, cancelados ou falhos não contam no limite de ativos.

Problemas comuns

Consulte o status e o último erro do agendamento:
Se o status é failed, o campo de erro indica por que a entrega falhou. Se é cancelled, algo cancelou antes — revise suas chamadas a cancelDefer.

Cron

Tarefas recorrentes em horário fixo.

Mensageria

Enviar WhatsApp e validar templates.

Webhooks

Verificar assinaturas de serviços externos.

CLI

Comandos defer list e defer get.