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.
Run periodic tasks: clean expired data, sync records, generate reports. Your function fires automatically according to the schedule you configure.
Pattern: config.cron + isCron guard + secrets for external connections.
import { define, z } from "@jelou/functions";
export default define({
name: "cleanup-job",
description: "Cleans expired sessions and syncs records",
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: "only runs via cron" };
}
ctx.log("Running cleanup", { cron: ctx.trigger.cron });
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++;
}
ctx.log("Cleanup completed", { cleaned, total: staleRecords.length });
return { cleaned, checked: staleRecords.length };
},
});
jelou secrets set cleanup-job DATABASE_URL=https://db.example.com EXTERNAL_API_KEY=YOUR_API_KEY
Why it works this way
config.cron defines when it runs. You can have multiple schedules with different timezones.
- The guard
if (!ctx.isCron) prevents someone from running the cleanup via HTTP accidentally.
config.mcp: false — a maintenance task is not an AI tool.
ctx.trigger.cron tells you which schedule triggered the execution.