¿Cron o diferida?
- Cron — se repite en un horario fijo (todos los días a las 9:00). Se define en el código.
- Diferida — ocurre una vez, en un momento calculado en tiempo de ejecución (24 horas después de este pedido). Se agenda desde el handler o desde la petición HTTP.
Agendar desde el handler
ctx.jelou.schedule() agenda una ejecución relativa a “ahora”:
index.ts
Parámetros
La duración acepta unidades compuestas de mayor a menor:
"1h30m" es válido, "30m1h" no.
Momento absoluto
ctx.jelou.scheduleAt() recibe una fecha en vez de una duración:
schedule().
Evitar duplicados
Si el servicio que llama a tu función reintenta,idempotencyKey garantiza una sola reserva:
idempotencyKey con un payload distinto devuelve un error 409.
Agendar desde una petición HTTP
Cualquier cliente puede diferir una llamada agregando una cabecera al POST normal. Sin cabeceras de agenda, la función se ejecuta de inmediato como siempre.
La respuesta es
202 Accepted cuando se crea la reserva y 200 OK cuando un reintento reutiliza una reserva existente. El cuerpo no puede superar 64 KB.
Recibir el disparo
Cuando llega el momento, tu función recibe elpayload original en la ruta que indicaste. Usa ctx.isScheduledFire para distinguir el disparo de una petición normal:
Verificar antes de actuar
Entre el momento en que agendas y el momento en que se dispara, la realidad pudo cambiar: el cliente ya pagó, la plantilla se pausó, el usuario se dio de baja.ctx.guard encadena esas verificaciones y evita el envío si alguna falla:
.run() y su resultado es la respuesta. Si alguna falla, la cadena se corta y devuelve { skipped: "<nombre>" } sin ejecutar el envío.
La cadena termina con
.run(handler), no con .then(). ctx.guard es una cadena nueva en cada petición.Consultar lo agendado
ctx.jelou.findDeferred() lista las ejecuciones pendientes de tu función:
Cancelar
ctx.jelou.cancelDefer() cancela en bloque por audiencia o etiqueta. Requiere exactamente uno de subject, key o keyPrefix:
raced contiene las ejecuciones que ya se estaban disparando cuando llegó la cancelación — para esas, la verificación con ctx.guard en el handler es la última defensa. Escribe tus handlers para que sean idempotentes.
Antes de una cancelación amplia, previsualiza el alcance con dryRun:
No existe “reprogramar”: una reserva es inmutable. Para cambiar la hora, cancela y agenda de nuevo.
Prueba local
schedule, scheduleAt, findDeferred y cancelDefer funcionan solo en una función desplegada. En local lanzan un error porque no hay credenciales de plataforma.
Para probar el flujo con jelou functions dev, activa la simulación:
createMockContext, cuyo ctx.jelou registra las llamadas sin red ni configuración.
Inspeccionar desde el CLI
Límites
Las reservas ya disparadas, canceladas o fallidas no cuentan contra el límite de activas.
Problemas comunes
- No se disparó
- Se envió aunque cancelé
- Error en local
- Se agendó dos veces
Consulta el estado y el último error de la reserva:Si el estado es
failed, el campo de error indica por qué falló la entrega. Si es cancelled, algo la canceló antes — revisa tus llamadas a cancelDefer.Cron
Tareas recurrentes en horario fijo.
Mensajería
Enviar WhatsApp y validar plantillas.
Webhooks
Verificar firmas de servicios externos.
CLI
Comandos
defer list y defer get.