Saltar al contenido principal

Tareas programadas (Cron)

Cron es el programador integrado del Gateway. Conserva los trabajos, activa el agente en el momento adecuado y puede entregar la salida de vuelta a un canal de chat o a un endpoint de webhook.

Inicio rápido

# Add a one-shot reminder
openclaw cron add \
  --name "Reminder" \
  --at "2026-02-01T16:00:00Z" \
  --session main \
  --system-event "Reminder: check the cron docs draft" \
  --wake now \
  --delete-after-run

# Check your jobs
openclaw cron list

# See run history
openclaw cron runs --id <job-id>

Cómo funciona cron

  • Cron se ejecuta dentro del proceso del Gateway (no dentro del modelo).
  • Los trabajos se conservan en ~/.openclaw/cron/jobs.json, por lo que los reinicios no pierden las programaciones.
  • Todas las ejecuciones de cron crean registros de tareas en segundo plano.
  • Los trabajos de una sola ejecución (--at) se eliminan automáticamente después de un éxito de forma predeterminada.
  • Las ejecuciones aisladas de cron cierran, en la medida de lo posible, las pestañas/procesos del navegador rastreados para su sesión cron:<jobId> cuando la ejecución se completa, para que la automatización desacoplada del navegador no deje procesos huérfanos.
  • Las ejecuciones aisladas de cron también protegen contra respuestas de confirmación obsoletas. Si el primer resultado es solo una actualización provisional de estado (on it, pulling everything together y pistas similares) y ninguna ejecución descendiente de subagente sigue siendo responsable de la respuesta final, OpenClaw vuelve a solicitar una vez el resultado real antes de entregarlo.
La conciliación de tareas para cron es propiedad del runtime: una tarea cron activa permanece activa mientras el runtime de cron siga rastreando ese trabajo como en ejecución, incluso si todavía existe una fila antigua de sesión hija. Una vez que el runtime deja de ser propietario del trabajo y expira el período de gracia de 5 minutos, el mantenimiento puede marcar la tarea como lost.

Tipos de programación

TipoIndicador de CLIDescripción
at--atMarca de tiempo de una sola ejecución (ISO 8601 o relativa como 20m)
every--everyIntervalo fijo
cron--cronExpresión cron de 5 campos o 6 campos con --tz opcional
Las marcas de tiempo sin zona horaria se tratan como UTC. Agrega --tz America/New_York para una programación en hora local de reloj. Las expresiones recurrentes al comienzo de cada hora se escalonan automáticamente hasta 5 minutos para reducir los picos de carga. Usa --exact para forzar una sincronización precisa o --stagger 30s para una ventana explícita.

El día del mes y el día de la semana usan lógica OR

Las expresiones cron son analizadas por croner. Cuando tanto los campos de día del mes como de día de la semana no son comodines, croner coincide cuando cualquiera de los campos coincide, no ambos. Este es el comportamiento estándar de Vixie cron.
# Intended: "9 AM on the 15th, only if it's a Monday"
# Actual:   "9 AM on every 15th, AND 9 AM on every Monday"
0 9 15 * 1
Esto se activa ~5–6 veces por mes en lugar de 0–1 vez por mes. OpenClaw usa aquí el comportamiento OR predeterminado de Croner. Para requerir ambas condiciones, usa el modificador de día de la semana + de Croner (0 9 15 * +1) o programa en un campo y valida el otro en el prompt o comando de tu trabajo.

Estilos de ejecución

EstiloValor de --sessionSe ejecuta enIdeal para
Sesión principalmainSiguiente turno de heartbeatRecordatorios, eventos del sistema
Aisladoisolatedcron:<jobId> dedicadoInformes, tareas en segundo plano
Sesión actualcurrentVinculada en el momento de creaciónTrabajo recurrente con contexto
Sesión personalizadasession:custom-idSesión nombrada persistenteFlujos de trabajo que se basan en el historial
Los trabajos de sesión principal encolan un evento del sistema y opcionalmente activan el heartbeat (--wake now o --wake next-heartbeat). Los trabajos aislados ejecutan un turno de agente dedicado con una sesión nueva. Las sesiones personalizadas (session:xxx) conservan el contexto entre ejecuciones, lo que permite flujos de trabajo como resúmenes diarios que se basan en resúmenes anteriores. Para los trabajos aislados, el desmontaje del runtime ahora incluye una limpieza del navegador en la medida de lo posible para esa sesión cron. Los fallos de limpieza se ignoran para que el resultado real de cron siga prevaleciendo. Cuando las ejecuciones aisladas de cron orquestan subagentes, la entrega también prefiere la salida final descendiente sobre el texto provisional obsoleto del padre. Si los descendientes todavía se están ejecutando, OpenClaw suprime esa actualización parcial del padre en lugar de anunciarla.

Opciones de payload para trabajos aislados

  • --message: texto del prompt (obligatorio para aislado)
  • --model / --thinking: reemplazos del modelo y nivel de razonamiento
  • --light-context: omitir la inyección de archivos de arranque del espacio de trabajo
  • --tools exec,read: restringir qué herramientas puede usar el trabajo
--model usa el modelo permitido seleccionado para ese trabajo. Si el modelo solicitado no está permitido, cron registra una advertencia y vuelve a la selección de modelo del agente/predeterminada del trabajo. Las cadenas de respaldo configuradas siguen aplicándose, pero un simple reemplazo de modelo sin una lista explícita de respaldo por trabajo ya no añade el primario del agente como un objetivo adicional de reintento oculto. La precedencia de selección de modelo para trabajos aislados es:
  1. Reemplazo de modelo del hook de Gmail (cuando la ejecución provino de Gmail y ese reemplazo está permitido)
  2. model del payload por trabajo
  3. Reemplazo de modelo de la sesión cron almacenada
  4. Selección de modelo del agente/predeterminada
El modo rápido también sigue la selección activa resuelta. Si la configuración del modelo seleccionado tiene params.fastMode, el cron aislado lo usa de forma predeterminada. Un reemplazo almacenado de fastMode en la sesión sigue teniendo prioridad sobre la configuración en cualquier dirección. Si una ejecución aislada encuentra una transferencia en vivo de cambio de modelo, cron reintenta con el proveedor/modelo cambiado y conserva esa selección activa antes de reintentar. Cuando el cambio también incluye un nuevo perfil de autenticación, cron también conserva ese reemplazo del perfil de autenticación. Los reintentos están acotados: después del intento inicial más 2 reintentos por cambio, cron aborta en lugar de entrar en un bucle infinito.

Entrega y salida

ModoQué sucede
announceEntrega un resumen al canal de destino (predeterminado para aislado)
webhookHace POST del payload del evento finalizado a una URL
noneSolo interno, sin entrega
Usa --announce --channel telegram --to "-1001234567890" para la entrega al canal. Para temas de foro de Telegram, usa -1001234567890:topic:123. Los destinos de Slack/Discord/Mattermost deben usar prefijos explícitos (channel:<id>, user:<id>). Para trabajos aislados propiedad de cron, el ejecutor es responsable de la ruta de entrega final. Se solicita al agente que devuelva un resumen en texto plano, y ese resumen luego se envía mediante announce, webhook o se mantiene interno para none. --no-deliver no devuelve la entrega al agente; mantiene la ejecución como interna. Si la tarea original indica explícitamente enviar un mensaje a algún destinatario externo, el agente debe indicar a quién/dónde debe ir ese mensaje en su salida en lugar de intentar enviarlo directamente. Las notificaciones de fallo siguen una ruta de destino separada:
  • cron.failureDestination establece un valor global predeterminado para las notificaciones de fallo.
  • job.delivery.failureDestination lo reemplaza por trabajo.
  • Si ninguno está configurado y el trabajo ya entrega mediante announce, las notificaciones de fallo ahora vuelven a ese destino principal de anuncio.
  • delivery.failureDestination solo es compatible con trabajos sessionTarget="isolated" a menos que el modo principal de entrega sea webhook.

Ejemplos de CLI

Recordatorio de una sola ejecución (sesión principal):
openclaw cron add \
  --name "Calendar check" \
  --at "20m" \
  --session main \
  --system-event "Next heartbeat: check calendar." \
  --wake now
Trabajo aislado recurrente con entrega:
openclaw cron add \
  --name "Morning brief" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize overnight updates." \
  --announce \
  --channel slack \
  --to "channel:C1234567890"
Trabajo aislado con reemplazo de modelo y nivel de razonamiento:
openclaw cron add \
  --name "Deep analysis" \
  --cron "0 6 * * 1" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Weekly deep analysis of project progress." \
  --model "opus" \
  --thinking high \
  --announce

Webhooks

Gateway puede exponer endpoints HTTP de webhook para desencadenadores externos. Habilítalos en la configuración:
{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}

Autenticación

Cada solicitud debe incluir el token del hook mediante un encabezado:
  • Authorization: Bearer <token> (recomendado)
  • x-openclaw-token: <token>
Los tokens en la cadena de consulta se rechazan.

POST /hooks/wake

Encola un evento del sistema para la sesión principal:
curl -X POST http://127.0.0.1:18789/hooks/wake \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"text":"New email received","mode":"now"}'
  • text (obligatorio): descripción del evento
  • mode (opcional): now (predeterminado) o next-heartbeat

POST /hooks/agent

Ejecuta un turno de agente aislado:
curl -X POST http://127.0.0.1:18789/hooks/agent \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.4-mini"}'
Campos: message (obligatorio), name, agentId, wakeMode, deliver, channel, to, model, thinking, timeoutSeconds.

Hooks mapeados (POST /hooks/<name>)

Los nombres de hook personalizados se resuelven mediante hooks.mappings en la configuración. Las asignaciones pueden transformar payloads arbitrarios en acciones wake o agent con plantillas o transformaciones de código.

Seguridad

  • Mantén los endpoints de hook detrás de loopback, tailnet o un proxy inverso de confianza.
  • Usa un token de hook dedicado; no reutilices tokens de autenticación del gateway.
  • Mantén hooks.path en una subruta dedicada; / se rechaza.
  • Establece hooks.allowedAgentIds para limitar el enrutamiento explícito de agentId.
  • Mantén hooks.allowRequestSessionKey=false a menos que necesites sesiones seleccionadas por el solicitante.
  • Si habilitas hooks.allowRequestSessionKey, establece también hooks.allowedSessionKeyPrefixes para restringir las formas permitidas de la clave de sesión.
  • Los payloads del hook se encapsulan con límites de seguridad de forma predeterminada.

Integración de Gmail PubSub

Conecta desencadenadores del buzón de Gmail a OpenClaw mediante Google PubSub. Requisitos previos: CLI de gcloud, gog (gogcli), hooks de OpenClaw habilitados, Tailscale para el endpoint público HTTPS.

Configuración con asistente (recomendada)

openclaw webhooks gmail setup --account openclaw@gmail.com
Esto escribe la configuración hooks.gmail, habilita el ajuste preestablecido de Gmail y usa Tailscale Funnel para el endpoint push.

Inicio automático del Gateway

Cuando hooks.enabled=true y hooks.gmail.account está configurado, el Gateway inicia gog gmail watch serve al arrancar y renueva automáticamente la suscripción. Establece OPENCLAW_SKIP_GMAIL_WATCHER=1 para excluirte.

Configuración manual de una sola vez

  1. Selecciona el proyecto de GCP que posee el cliente OAuth usado por gog:
gcloud auth login
gcloud config set project <project-id>
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
  1. Crea el tema y concede acceso push de Gmail:
gcloud pubsub topics create gog-gmail-watch
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \
  --member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
  --role=roles/pubsub.publisher
  1. Inicia la suscripción:
gog gmail watch start \
  --account openclaw@gmail.com \
  --label INBOX \
  --topic projects/<project-id>/topics/gog-gmail-watch

Reemplazo de modelo de Gmail

{
  hooks: {
    gmail: {
      model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
      thinking: "off",
    },
  },
}

Administrar trabajos

# List all jobs
openclaw cron list

# Edit a job
openclaw cron edit <jobId> --message "Updated prompt" --model "opus"

# Force run a job now
openclaw cron run <jobId>

# Run only if due
openclaw cron run <jobId> --due

# View run history
openclaw cron runs --id <jobId> --limit 50

# Delete a job
openclaw cron remove <jobId>

# Agent selection (multi-agent setups)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops
openclaw cron edit <jobId> --clear-agent
Nota sobre el reemplazo de modelo:
  • openclaw cron add|edit --model ... cambia el modelo seleccionado del trabajo.
  • Si el modelo está permitido, ese proveedor/modelo exacto llega a la ejecución del agente aislado.
  • Si no está permitido, cron muestra una advertencia y vuelve a la selección de modelo del agente/predeterminada del trabajo.
  • Las cadenas de respaldo configuradas siguen aplicándose, pero un simple reemplazo con --model sin una lista explícita de respaldo por trabajo ya no recurre al primario del agente como un objetivo adicional de reintento silencioso.

Configuración

{
  cron: {
    enabled: true,
    store: "~/.openclaw/cron/jobs.json",
    maxConcurrentRuns: 1,
    retry: {
      maxAttempts: 3,
      backoffMs: [60000, 120000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "server_error"],
    },
    webhookToken: "replace-with-dedicated-webhook-token",
    sessionRetention: "24h",
    runLog: { maxBytes: "2mb", keepLines: 2000 },
  },
}
Desactiva cron: cron.enabled: false o OPENCLAW_SKIP_CRON=1. Reintento de una sola ejecución: los errores transitorios (límite de velocidad, sobrecarga, red, error del servidor) se reintentan hasta 3 veces con retroceso exponencial. Los errores permanentes se desactivan de inmediato. Reintento recurrente: retroceso exponencial (de 30s a 60m) entre reintentos. El retroceso se restablece después de la siguiente ejecución exitosa. Mantenimiento: cron.sessionRetention (predeterminado 24h) elimina las entradas de sesión de ejecuciones aisladas. cron.runLog.maxBytes / cron.runLog.keepLines eliminan automáticamente los archivos de registro de ejecución.

Solución de problemas

Secuencia de comandos

openclaw status
openclaw gateway status
openclaw cron status
openclaw cron list
openclaw cron runs --id <jobId> --limit 20
openclaw system heartbeat last
openclaw logs --follow
openclaw doctor

Cron no se ejecuta

  • Verifica cron.enabled y la variable de entorno OPENCLAW_SKIP_CRON.
  • Confirma que el Gateway esté ejecutándose de forma continua.
  • Para programaciones cron, verifica la zona horaria (--tz) frente a la zona horaria del host.
  • reason: not-due en la salida de ejecución significa que la ejecución manual se comprobó con openclaw cron run <jobId> --due y que el trabajo aún no debía ejecutarse.

Cron se ejecutó pero no hubo entrega

  • El modo de entrega none significa que no se espera ningún mensaje externo.
  • Un destino de entrega faltante o no válido (channel/to) significa que se omitió la salida.
  • Los errores de autenticación del canal (unauthorized, Forbidden) significan que la entrega fue bloqueada por las credenciales.
  • Si la ejecución aislada devuelve solo el token silencioso (NO_REPLY / no_reply), OpenClaw suprime la entrega saliente directa y también la ruta de resumen en cola de respaldo, por lo que no se publica nada de vuelta en el chat.
  • Para trabajos aislados propiedad de cron, no esperes que el agente use la herramienta de mensajes como respaldo. El ejecutor es responsable de la entrega final; --no-deliver la mantiene interna en lugar de permitir un envío directo.

Problemas habituales con zonas horarias

  • Cron sin --tz usa la zona horaria del host del gateway.
  • Las programaciones at sin zona horaria se tratan como UTC.
  • activeHours de Heartbeat usa la resolución de zona horaria configurada.

Relacionado