Appearance
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 | --cron | 5 字段或 6 字段 cron 表达式,可配合 --tz |
不带时区的时间戳视为 UTC。使用 --tz America/New_York 可按本地时钟调度。
整点重复表达式会自动错开最多 5 分钟以减少负载峰值。使用 --exact 强制精确时间,或用 --stagger 30s 指定错开窗口。
执行方式
| 方式 | --session 值 | 运行位置 | 适合场景 |
|---|---|---|---|
| 主 session | main | 下一次心跳轮次 | 提醒、系统事件 |
| 隔离 | isolated | 专用 cron:<jobId> | 报告、后台任务 |
| 当前 session | current | 创建时绑定 | 上下文相关的周期工作 |
| 自定义 session | session:custom-id | 持久化命名 session | 需要积累历史的工作流 |
主 session 任务将系统事件加入队列,可选唤醒心跳(--wake now 或 --wake next-heartbeat)。隔离任务用新 session 运行专用 agent 轮次。自定义 session(session:xxx)跨次运行保留上下文,适合每日站会等需要基于历史摘要的工作流。
隔离任务的运行时拆卸包含对该 cron session 的尽力浏览器清理。清理失败不会影响 cron 实际结果。
隔离 cron 运行编排子代理时,交付也优先使用最终子代理输出而非过时的父级临时文本。如果子代理仍在运行,OpenClaw 会暂不宣布父级的部分更新。
隔离任务的负载选项
--message:提示词文本(隔离任务必填)--model/--thinking:模型和思考级别覆盖--light-context:跳过 workspace bootstrap 文件注入--tools exec,read:限制任务可用工具
--model 使用该任务允许的指定模型。如果请求的模型不被允许,cron 会记录警告并回退到任务的 agent/默认模型选择。已配置的回退链仍然适用,但不带显式回退列表的普通模型覆盖不会再把 agent 主模型附加为隐式额外重试目标。
隔离任务的模型选择优先级:
- Gmail hook 模型覆盖(当运行来自 Gmail 且该覆盖被允许时)
- 每任务 payload
model - 存储的 cron session 模型覆盖
- Agent/默认模型选择
Fast 模式也遵循解析后的实时选择。如果选中的模型配置有 params.fastMode,隔离 cron 默认使用它。存储的 session fastMode 覆盖仍然优先于任一方向的配置。
隔离运行遇到实时模型切换时,cron 会用切换后的提供商/模型重试,并在重试前持久化该实时选择。切换同时携带新 auth profile 时,cron 也会持久化该 auth profile 覆盖。重试有上限:初始尝试加 2 次切换重试后,cron 会中止而非无限循环。
交付与输出
| 模式 | 行为 |
|---|---|
announce | 将摘要发送到目标频道(隔离任务默认) |
webhook | POST 完成事件 payload 到 URL |
none | 仅内部处理,不交付 |
使用 --announce --channel telegram --to "-1001234567890" 进行频道交付。Telegram 话题使用 -1001234567890:topic:123。Slack/Discord/Mattermost 目标应使用显式前缀(channel:<id>、user:<id>)。
对于 cron 拥有的隔离任务,runner 拥有最终交付路径。Agent 被提示返回纯文本摘要,然后通过 announce、webhook 或 none(内部)发送。--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 \
--announceWebhooks
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(必填)、name、agentId、wakeMode、deliver、channel、to、model、thinking、timeoutSeconds。
映射 Hook(POST /hooks/<name>)
自定义 hook 名称通过配置中的 hooks.mappings 解析。映射可以将任意 payload 通过模板或代码转换为 wake 或 agent 动作。
安全
- 将 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=true 且 hooks.gmail.account 已设置时,Gateway 会在启动时启动 gog gmail watch serve 并自动续订 watch。设置 OPENCLAW_SKIP_GMAIL_WATCHER=1 可退出。
手动一次性配置
- 选择拥有
gog使用的 OAuth 客户端的 GCP 项目:
bash
gcloud auth login
gcloud config set project <project-id>
gcloud services enable gmail.googleapis.com pubsub.googleapis.com- 创建 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- 启动 watch:
bash
gog gmail watch start \
--account openclaw@gmail.com \
--label INBOX \
--topic projects/<project-id>/topics/gog-gmail-watchGmail 模型覆盖
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: false 或 OPENCLAW_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 doctorCron 未触发
- 检查
cron.enabled和OPENCLAW_SKIP_CRON环境变量。 - 确认 Gateway 持续运行。
- 对于
cron调度,验证时区(--tz)与宿主机时区的关系。 - 运行输出中
reason: not-due意味着用openclaw cron run <jobId> --due手动运行时任务还未到期。
Cron 已触发但没有交付
- 交付模式为
none说明不期望有外部消息。 - 交付目标缺失/无效(
channel/to)说明出站被跳过。 - 频道认证错误(
unauthorized、Forbidden)说明交付被凭证阻止。 - 如果隔离运行只返回静默 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)。永久性错误直接禁用不重试。