Skip to content

Cron 是 OpenClaw Gateway 的内置调度器,负责持久化任务、在正确时间唤醒 agent 并将结果回传到聊天频道或 Webhook 端点。本页涵盖三种调度类型(一次性/固定间隔/cron 表达式)、四种执行模式(主 session/隔离/当前/自定义)、Webhook 触发配置、Gmail PubSub 集成及完整故障排查指南。

定时任务(Cron)

Cron 是 Gateway 的内置调度器。它持久化任务、在正确时间唤醒 agent,并可以将输出回传到聊天频道或 Webhook 端点。

快速开始

bash
# 添加一次性提醒
openclaw cron add \
  --name "Reminder" \
  --at "2026-02-01T16:00:00Z" \
  --session main \
  --system-event "提醒:检查 cron 文档草稿" \
  --wake now \
  --delete-after-run

# 查看任务列表
openclaw cron list

# 查看运行历史
openclaw cron runs --id <job-id>

Cron 工作原理

  • Cron 在 Gateway 进程内部运行(不在模型内部)。
  • 任务持久化在 ~/.openclaw/cron/jobs.json,重启不会丢失调度。
  • 所有 cron 执行都会创建后台任务记录。
  • 一次性任务(--at)默认在成功后自动删除。
  • 隔离 cron 运行在完成后会尽力关闭该 cron session 追踪的浏览器标签/进程,避免留下孤立进程。
  • 隔离 cron 运行还会防范过时的确认回复:如果第一条结果只是中间状态更新(如"正在处理"之类)且没有子代理继续负责最终答案,OpenClaw 会重新提示一次获取实际结果再进行交付。

Cron 的任务协调由运行时拥有:只要 cron 运行时仍追踪该任务,活跃 cron 任务就会保持存活。一旦运行时不再拥有该任务且 5 分钟宽限窗口过期,维护进程可将任务标记为 lost

调度类型

类型CLI 参数说明
at--at一次性时间戳(ISO 8601 或相对时间如 20m
every--every固定间隔
cron--cron5 字段或 6 字段 cron 表达式,可配合 --tz

不带时区的时间戳视为 UTC。使用 --tz America/New_York 可按本地时钟调度。

整点重复表达式会自动错开最多 5 分钟以减少负载峰值。使用 --exact 强制精确时间,或用 --stagger 30s 指定错开窗口。

执行方式

方式--session运行位置适合场景
主 sessionmain下一次心跳轮次提醒、系统事件
隔离isolated专用 cron:<jobId>报告、后台任务
当前 sessioncurrent创建时绑定上下文相关的周期工作
自定义 sessionsession:custom-id持久化命名 session需要积累历史的工作流

主 session 任务将系统事件加入队列,可选唤醒心跳(--wake now--wake next-heartbeat)。隔离任务用新 session 运行专用 agent 轮次。自定义 sessionsession:xxx)跨次运行保留上下文,适合每日站会等需要基于历史摘要的工作流。

隔离任务的运行时拆卸包含对该 cron session 的尽力浏览器清理。清理失败不会影响 cron 实际结果。

隔离 cron 运行编排子代理时,交付也优先使用最终子代理输出而非过时的父级临时文本。如果子代理仍在运行,OpenClaw 会暂不宣布父级的部分更新。

隔离任务的负载选项

  • --message:提示词文本(隔离任务必填)
  • --model / --thinking:模型和思考级别覆盖
  • --light-context:跳过 workspace bootstrap 文件注入
  • --tools exec,read:限制任务可用工具

--model 使用该任务允许的指定模型。如果请求的模型不被允许,cron 会记录警告并回退到任务的 agent/默认模型选择。已配置的回退链仍然适用,但不带显式回退列表的普通模型覆盖不会再把 agent 主模型附加为隐式额外重试目标。

隔离任务的模型选择优先级:

  1. Gmail hook 模型覆盖(当运行来自 Gmail 且该覆盖被允许时)
  2. 每任务 payload model
  3. 存储的 cron session 模型覆盖
  4. Agent/默认模型选择

Fast 模式也遵循解析后的实时选择。如果选中的模型配置有 params.fastMode,隔离 cron 默认使用它。存储的 session fastMode 覆盖仍然优先于任一方向的配置。

隔离运行遇到实时模型切换时,cron 会用切换后的提供商/模型重试,并在重试前持久化该实时选择。切换同时携带新 auth profile 时,cron 也会持久化该 auth profile 覆盖。重试有上限:初始尝试加 2 次切换重试后,cron 会中止而非无限循环。

交付与输出

模式行为
announce将摘要发送到目标频道(隔离任务默认)
webhookPOST 完成事件 payload 到 URL
none仅内部处理,不交付

使用 --announce --channel telegram --to "-1001234567890" 进行频道交付。Telegram 话题使用 -1001234567890:topic:123。Slack/Discord/Mattermost 目标应使用显式前缀(channel:<id>user:<id>)。

对于 cron 拥有的隔离任务,runner 拥有最终交付路径。Agent 被提示返回纯文本摘要,然后通过 announcewebhooknone(内部)发送。--no-deliver 不会把交付权还给 agent,而是将运行保持在内部。

如果任务明确要求向外部收件人发送消息,agent 应在输出中说明应该向谁/在哪里发送,而不是直接尝试发送。

失败通知走独立的目标路径:

  • cron.failureDestination 设置失败通知的全局默认目标。
  • job.delivery.failureDestination 对每个任务单独覆盖。
  • 如果两者都未设置,且任务已通过 announce 交付,失败通知会回退到该主 announce 目标。
  • delivery.failureDestination 只支持 sessionTarget="isolated" 任务,除非主交付模式是 webhook

CLI 示例

主 session 一次性提醒:

bash
openclaw cron add \
  --name "Calendar check" \
  --at "20m" \
  --session main \
  --system-event "下次心跳:检查日历。" \
  --wake now

带交付的周期隔离任务:

bash
openclaw cron add \
  --name "Morning brief" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "总结隔夜更新。" \
  --announce \
  --channel slack \
  --to "channel:C1234567890"

带模型和思考级别覆盖的隔离任务:

bash
openclaw cron add \
  --name "Deep analysis" \
  --cron "0 6 * * 1" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "对项目进度进行每周深度分析。" \
  --model "opus" \
  --thinking high \
  --announce

Webhooks

Gateway 可以暴露 HTTP Webhook 端点用于外部触发。在配置中启用:

json5
{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}

认证

每个请求必须通过 header 携带 hook token:

  • Authorization: Bearer <token>(推荐)
  • x-openclaw-token: <token>

查询字符串 token 会被拒绝。

POST /hooks/wake

为主 session 加入系统事件:

bash
curl -X POST http://127.0.0.1:18789/hooks/wake \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"text":"收到新邮件","mode":"now"}'
  • text(必填):事件描述
  • mode(可选):now(默认)或 next-heartbeat

POST /hooks/agent

运行隔离 agent 轮次:

bash
curl -X POST http://127.0.0.1:18789/hooks/agent \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"message":"总结收件箱","name":"Email","model":"openai/gpt-5.4-mini"}'

字段:message(必填)、nameagentIdwakeModedeliverchanneltomodelthinkingtimeoutSeconds

映射 Hook(POST /hooks/<name>)

自定义 hook 名称通过配置中的 hooks.mappings 解析。映射可以将任意 payload 通过模板或代码转换为 wakeagent 动作。

安全

  • 将 hook 端点限制在 loopback、tailnet 或可信反向代理后面。
  • 使用专用 hook token,不要复用 gateway auth token。
  • hooks.path 保持在专用子路径;/ 会被拒绝。
  • 设置 hooks.allowedAgentIds 限制显式 agentId 路由。
  • 保持 hooks.allowRequestSessionKey=false,除非需要调用方选择 session。
  • 如果启用了 hooks.allowRequestSessionKey,同时设置 hooks.allowedSessionKeyPrefixes 来约束允许的 session key 形状。
  • Hook payload 默认由安全边界包裹。

Gmail PubSub 集成

通过 Google PubSub 将 Gmail 收件箱触发器接入 OpenClaw。

前置条件gcloud CLI、gog(gogcli)、OpenClaw hooks 已启用、Tailscale 用于公网 HTTPS 端点。

向导配置(推荐)

bash
openclaw webhooks gmail setup --account openclaw@gmail.com

这会写入 hooks.gmail 配置,启用 Gmail 预设,并使用 Tailscale Funnel 作为 push 端点。

Gateway 自动启动

hooks.enabled=truehooks.gmail.account 已设置时,Gateway 会在启动时启动 gog gmail watch serve 并自动续订 watch。设置 OPENCLAW_SKIP_GMAIL_WATCHER=1 可退出。

手动一次性配置

  1. 选择拥有 gog 使用的 OAuth 客户端的 GCP 项目:
bash
gcloud auth login
gcloud config set project <project-id>
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
  1. 创建 topic 并授予 Gmail push 访问权限:
bash
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. 启动 watch:
bash
gog gmail watch start \
  --account openclaw@gmail.com \
  --label INBOX \
  --topic projects/<project-id>/topics/gog-gmail-watch

Gmail 模型覆盖

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

管理任务

bash
# 列出所有任务
openclaw cron list

# 编辑任务
openclaw cron edit <jobId> --message "更新后的提示词" --model "opus"

# 立即强制运行任务
openclaw cron run <jobId>

# 仅在到期时运行
openclaw cron run <jobId> --due

# 查看运行历史
openclaw cron runs --id <jobId> --limit 50

# 删除任务
openclaw cron remove <jobId>

# 指定 agent(多 agent 配置)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "检查运维队列" --agent ops
openclaw cron edit <jobId> --clear-agent

配置

json5
{
  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 },
  },
}

禁用 cron:cron.enabled: falseOPENCLAW_SKIP_CRON=1

一次性重试:临时错误(频率限制、过载、网络、服务器错误)最多重试 3 次,指数退避。永久性错误立即禁用。

周期任务重试:重试间隔指数退避(30s 到 60m)。下次成功运行后重置退避。

维护cron.sessionRetention(默认 24h)清理隔离运行的 session 条目。cron.runLog.maxBytes / cron.runLog.keepLines 自动清理运行日志文件。

故障排查

诊断命令梯

bash
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 未触发

  • 检查 cron.enabledOPENCLAW_SKIP_CRON 环境变量。
  • 确认 Gateway 持续运行。
  • 对于 cron 调度,验证时区(--tz)与宿主机时区的关系。
  • 运行输出中 reason: not-due 意味着用 openclaw cron run <jobId> --due 手动运行时任务还未到期。

Cron 已触发但没有交付

  • 交付模式为 none 说明不期望有外部消息。
  • 交付目标缺失/无效(channel/to)说明出站被跳过。
  • 频道认证错误(unauthorizedForbidden)说明交付被凭证阻止。
  • 如果隔离运行只返回静默 token(NO_REPLY / no_reply),OpenClaw 会同时抑制直接出站交付和回退的排队摘要路径,不会向聊天发任何内容。
  • 对于 cron 拥有的隔离任务,不要期望 agent 使用消息工具作为回退。runner 拥有最终交付;--no-deliver 保持内部处理而非允许直接发送。

时区陷阱

  • 不带 --tz 的 cron 使用 gateway 宿主机时区。
  • 不带时区的 at 调度视为 UTC。
  • 心跳的 activeHours 使用配置的时区解析。

常见问题

Q: 隔离任务和主 session 任务有什么区别?

A: 隔离任务在专用的 cron:<jobId> session 中运行,有独立上下文,互不干扰,适合报告、后台数据处理等任务。主 session 任务只是往心跳队列里加系统事件,轻量快速,适合提醒和状态触发。

Q: 如何让定时任务把结果发到 Telegram 群?

A: 使用 --announce --channel telegram --to "<chat_id>" 参数,或者在配置里设置 delivery.announce 目标。Telegram 话题频道使用 <chat_id>:topic:<topic_id> 格式。

Q: Cron 任务失败了会重试吗?

A: 会。一次性任务遇到临时错误(频率限制、过载、网络错误)最多重试 3 次,间隔指数退避(默认 60s/120s/300s)。永久性错误直接禁用不重试。

相关链接