Documentation Index
Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
Use this file to discover all available pages before exploring further.
Ejecuta tareas periódicas: limpiar datos expirados, sincronizar registros, generar reportes. Tu función se dispara automáticamente según el schedule que configures.
Patrón: config.cron + guard isCron + secrets para conexiones externas.
import { define, z } from "@jelou/functions";
export default define({
name: "cleanup-job",
description: "Limpia sesiones expiradas y sincroniza registros",
input: z.object({}),
config: {
cron: [
{ expression: "0 3 * * *", timezone: "UTC" },
{ expression: "0 15 * * 1-5", timezone: "America/Guayaquil" },
],
mcp: false,
},
handler: async (_input, ctx) => {
if (!ctx.isCron) {
return { skipped: true, reason: "solo se ejecuta por cron" };
}
ctx.log("Ejecutando limpieza", { cron: ctx.trigger.cron });
// Evitar duplicados con ctx.memory
if (ctx.memory.available) {
const yaEjecutado = await ctx.memory.get("limpieza_hoy", false);
if (yaEjecutado) {
ctx.log("Ya se ejecutó hoy, omitiendo");
return { skipped: true, reason: "ya ejecutado" };
}
}
const dbUrl = ctx.env.get("DATABASE_URL");
const apiKey = ctx.env.get("EXTERNAL_API_KEY");
const staleRecords = await fetch(`${dbUrl}/api/sessions?expired=true`)
.then((r) => r.json());
let cleaned = 0;
for (const record of staleRecords) {
await fetch(`${dbUrl}/api/sessions/${record.id}`, {
method: "DELETE",
headers: { Authorization: `Bearer ${apiKey}` },
});
cleaned++;
}
// Notificar al admin por WhatsApp
if (ctx.jelou.available && cleaned > 0) {
await ctx.jelou.send({
type: "text",
to: ctx.env.get("ADMIN_PHONE") || "",
text: `Limpieza completada: ${cleaned} registros eliminados.`,
});
}
// Marcar como ejecutado (expira en 20h)
if (ctx.memory.available) {
await ctx.memory.set("limpieza_hoy", true, 72000);
}
ctx.log("Limpieza completada", { cleaned, total: staleRecords.length });
return { cleaned, checked: staleRecords.length };
},
});
Configurar secrets
jelou secrets set cleanup-job DATABASE_URL=https://db.example.com EXTERNAL_API_KEY=YOUR_API_KEY
Por qué funciona así
config.cron define cuándo se ejecuta. Puedes tener múltiples schedules con distintas zonas horarias.
- El guard
if (!ctx.isCron) previene que alguien ejecute la limpieza por HTTP accidentalmente.
config.mcp: false — una tarea de mantenimiento no es un tool de IA.
ctx.trigger.cron te dice cuál schedule disparó la ejecución.