Saltar a contenido

Cron Jobs

El worker ejecuta tareas programadas via Cloudflare Cron Triggers.

Configuración

# wrangler.toml
[triggers]
crons = ["0 3 * * *"]  # Todos los días a las 3:00 AM UTC

Tarea: Auto-refresh de tokens

Renueva automáticamente los tokens OAuth que estén por vencer en los próximos 5 días.

flowchart TD
    CRON["⏰ Cron Trigger<br/>3:00 AM UTC diario"] --> A["Buscar tokens con<br/>expires_at < ahora + 5 días"]
    A --> B{¿Hay tokens<br/>por vencer?}
    B -->|No| C["Log: No tokens expiring"]
    B -->|Sí| D["Para cada token:"]
    D --> E["exchangeMPToken()<br/>grant_type: refresh_token"]
    E --> F{¿Éxito?}
    F -->|Sí| G["Actualizar token en DB<br/>Log: Refreshed"]
    F -->|No| H["Log error<br/>Continuar con siguiente"]
    G --> I{¿Más tokens?}
    H --> I
    I -->|Sí| D
    I -->|No| J["Fin"]

Tolerancia

El refresh se hace 5 días antes de la expiración. Si falla, hay 5 días para solucionarlo manualmente antes de que el token expire y las llamadas a MercadoPago dejen de funcionar.

Implementación

El handler scheduled se exporta junto con fetch en el worker:

export default {
  fetch: app.fetch,
  scheduled: async (
    controller: ScheduledController,
    env: CloudflareBindings,
    ctx: ExecutionContext,
  ) => {
    const db = createDb(env.webhook_db);
    await refreshExpiringTokens(db, env);
  },
} satisfies ExportedHandler<CloudflareBindings>;

La función refreshExpiringTokens usa exchangeMPToken() de lib/mercadopago.ts, la misma función centralizada que usan las rutas de OAuth para renovar tokens.

Monitoreo

Los logs del cron aparecen en Cloudflare Dashboard → Workers → Logs:

[Cron] No tokens expiring in 5 days

Cuando renueva:

[Cron] Refreshed token for 'mi-cliente', expires: 2025-09-01T14:00:00.000Z
[Cron] Refreshed token for 'otro-cliente', expires: 2025-09-02T10:30:00.000Z

Si un refresh falla:

[Cron] Failed to refresh 'otro-cliente': MercadoPago API error: 401

Si falla un refresh

El cron no se detiene si falla un cliente. Continúa con los demás y loguea el error. Si un token no se puede renovar (ej: refresh_token expirado), hay que re-hacer el flujo OAuth manualmente desde /oauth/login.

Testing local

Para testear el cron localmente con Miniflare:

curl http://localhost:5173/__scheduled