openclaw automations CLI 管理自动化;openclaw cron 仍是相同命令的别名。
快速开始
1
添加一次性提醒
2
检查你的作业
3
查看运行历史
自动化如何工作
- 自动化在 Gateway 进程内部运行,而不是在模型内部运行。Gateway 必须处于运行状态,计划任务才会触发。
- 任务定义、运行时状态和运行历史会持久化在 OpenClaw 的共享 SQLite 状态数据库中,因此重启不会丢失计划任务。
- 每次自动化运行都会创建一条后台任务记录。
- 一次性任务(
--at)默认在成功后自动删除;传入--keep-after-run可保留它们。 - 每次运行的墙钟时间预算:设置后使用
--timeout-seconds。否则,隔离/分离式代理轮次任务会受调度器自身 60 分钟看门狗限制,底层代理轮次超时(agents.defaults.timeoutSeconds,默认 48 小时)不会生效;命令任务默认 10 分钟,脚本负载默认 5 分钟。 - Gateway 启动时,过期的隔离代理轮次任务会被重新调度,而不是立即重放,从而避免模型/工具引导工作占用频道连接窗口。
- 如果你通过系统 cron 或其他外部调度器驱动
openclaw agent,请为其添加强制终止升级机制,即使 CLI 已经处理了SIGTERM/SIGINT。基于 Gateway 的运行会请求 Gateway 中止已接受的运行;--local运行会收到相同的中止信号。对于 GNUtimeout,优先使用timeout -k 60 600 openclaw agent ...,而不是单纯的timeout 600 ...——如果进程无法及时排空,-k的值可作为后备机制。对于 systemd 单元,请使用带宽限窗口(TimeoutStopSec)的SIGTERM停止信号,然后再执行最终强制终止。如果原始 Gateway 运行仍处于活动状态时复用--run-id,系统会将重复运行报告为进行中,而不是启动第二次运行。
任务协调
任务协调
自动化任务协调首先由运行时负责,其次由持久化历史记录提供支持:只要自动化运行时仍将某个任务跟踪为运行中,活动自动化任务就会保持活动状态,即使旧的子会话记录仍然存在。运行时停止拥有该任务且 5 分钟宽限期结束后,维护检查会针对匹配的
cron:<jobId>:<startedAt> 运行,读取持久化的运行日志和任务状态。此处的终止结果会最终确定任务账本;否则,Gateway 所有的维护机制可以将任务标记为 lost。离线 CLI 审计可以从持久化历史中恢复,但其自身为空的进程内活动任务集合并不能证明 Gateway 所有的运行已经消失。计划类型
不带时区的时间戳会被视为 UTC。添加
--tz America/New_York 可将不带偏移的 --at 日期时间按该 IANA 时区解释,或按该 IANA 时区计算 cron 表达式。不带 --tz 的 cron 表达式使用 Gateway 主机时区。--tz 不能与 --every 或 --on-exit 一起使用。
每小时整点的重复表达式(分钟为 0 且小时字段为通配符)会自动错开最多 5 分钟,以减少负载峰值。使用 --exact 可强制精确时间,或使用 --stagger 30s 指定明确的窗口(仅适用于 cron 调度)。
心跳任务迁移
较早版本的心跳临时配置支持结构化的tasks: 块。升级后运行 openclaw doctor --fix,将每个条目转换为普通的、可编辑的主会话自动化作业。Doctor 会保留间隔和之前的上次运行时间,在移除该块之前创建作业,并在重新运行时安全地收敛相同的声明键。
这些迁移后的作业携带公开的 systemEvent 负载,因此 openclaw automations list、get、edit 和 remove,以及 automations agent 工具,都可以像管理其他作业一样管理它们(该工具仍接受旧版的 cron 名称作为兼容性别名)。它们的执行使用受保护的心跳任务唤醒机制:活动时段、最小间隔、洪泛控制和繁忙重试仍然适用,同时调度器负责管理每个任务独立的节奏。在同一合并窗口内到期的作业可以共享一次心跳 turn。在心跳活动时段之外到期的计划会被跳过,并在作业的下一次触发时机重试。
心跳临时配置现在仅用于监控说明文本。运行时心跳不会将 tasks: 文本解析为计划;请将新的重复性工作创建为自动化作业。
流来源
流计划会让一个由操作员编写的 argv 命令在 Gateway 下持续运行,并根据其 stdout 和 stderr 行触发作业。流计划由事件驱动,永远不会因时间到期,并且要求cron.triggers.enabled: true,因为该长生命周期命令与触发器脚本具有相同的无人值守信任级别。禁用或移除作业会停止进程;Gateway 关闭时会等待进程树拆除完成。快速失败会使用调度器内置的错误退避机制重启。连续五次运行时间短于 60 秒后,作业会进入错误状态,并使用常规的失败告警路径;手动重新启用作业即可清除重启上限。
mode: "line"(默认值)接受每一行。mode: "match" 仅接受与编译后的 match 正则表达式匹配的行。一个批次会在静默 batchMs 后关闭(默认 250 ms,限制在 50–5000 之间)或在达到 maxBatchBytes 时关闭(默认 16384,限制在 1024–65536 之间)。达到字节上限时,批次会以 [truncated] 结尾。匹配模式始终会将完整行与其完整文本进行比对,即使超过 maxBatchBytes 也是如此(只有传送出去的批次会被截断);在受限的原始输入上限处被切断的行只有前缀,因此会被视为不匹配,而不会让一个以行尾锚定的模式在截断处触发。该批次会附加到系统事件文本或 agent-turn 消息中。由于来源命令与负载命令会产生歧义的进程所有权,因此流调度不接受命令负载。
每个作业只保留一次负载触发和一个受限的待处理批次。当负载正在运行时,或内置的 30 秒触发间隔尚未过去时到达的行,会合并到该待处理批次中,而不是构建一个无限队列。一个串行化的所有者会将门控丢弃、负载错误和未运行的分发记录到 streamDroppedBatches 中;受限合并会增加 streamCoalescedBatches。失败的负载不会重试,因为它们可能不是幂等的。逻辑源身份在受监督的子进程重启之间保持稳定,但在来源被禁用、移除或替换时会轮换,因此来自已退役来源的排队批次即使在 A 到 B 再到 A 的编辑之后也无法触发。停止完成后,旧子进程的延迟回调不会再生效。V1 不包含原生 WebSocket 来源;可以用诸如 websocat wss://example.invalid/events 这样的 argv 命令进行桥接。
当流作业还具有 trigger.script 时,门控会在每个关闭的批次上运行一次。当前批次可通过深度冻结的 trigger.streamBatch 字符串获取,并与 trigger.state 并列存在。fire: false 会在持久化门控状态后丢弃该批次。fire: true 会保留现有触发消息语义,然后将该批次追加到最终负载中。流作业也可以改为使用不带条件门控的脚本负载;该脚本会通过相同的 trigger.streamBatch 值接收批次。将脚本负载与条件门控组合会被拒绝,因为两者都会占用持久化的 trigger.state 槽位。
动态节奏(pacing)
重复性作业可以设置pacing.min 和/或 pacing.max,其值为 15m 或 4h 等时长字符串;至少需要设置一个边界。对 automations add|edit 使用 --pacing-min 和 --pacing-max(--clear-pacing 会移除两个边界)。
在 agent-turn 运行期间,带 pacing 的作业可以使用 action: "next_check" 和 in: "30m" 调用 automations 工具。该提议仅适用于当前正在运行的作业,并从成功完成运行时开始计时。OpenClaw 会将其静默限制在已配置的边界内。
没有提议的 pacing 不会改变正常调度。失败、超时和跳过的运行会丢弃该提议,因此现有的重试和错误退避行为具有优先级。手动强制运行周期性作业属于带外操作,并会保留其待定的自然或 pacing 槽位。对于条件触发的作业,即使提议请求更早检查,内置的最小间隔仍然是下限。
/loop 聊天快捷方式
在聊天中,仅所有者可用的 /loop [interval] <prompt> 命令会创建一个绑定到该对话的周期性 agent-turn 作业。提供一个间隔,例如 5m,用于固定节奏;或者省略它,让 loop 在 1 分钟到 1 小时之间通过 next_check 自行节奏控制。使用 /loop status 列出绑定到对话的 loops,使用 /loop stop [name] 将其移除。
月内日期和星期几使用 OR 逻辑
Cron 表达式由 croner 解析。当月中的日期字段和星期字段都不是通配符时,croner 会在任一字段匹配时触发,而不是两者都匹配。这是标准的 Vixie cron 行为。+ 星期字段修饰符(0 9 15 * +1),或者只按一个字段进行调度,并在作业的 prompt 或命令中对另一个条件进行检查。
事件触发器(条件监视器)
事件触发器会将无头条件脚本添加到every、cron 或 stream 调度中。时间调度在到期时对其进行评估;流调度则会针对每个已关闭的批次进行评估。只有当脚本返回 fire: true 时,调度器才会运行正常负载:
{ fire, message?, state? }。之前的 JSON 状态以深度冻结的 trigger.state 形式提供;流门控还会接收当前批次作为 trigger.streamBatch。返回新的 state 值即可将其持久化。状态上限为 16 KB。当触发结果包含 message 时,调度器会在执行前将其追加到系统事件文本或代理轮次消息中。once: true 会在首次成功触发负载后禁用该任务。
fire: false 会持久化评估状态和计数器,然后重新调度,但不会创建运行历史。如果已触发的负载运行失败,返回的 state 不会 被持久化——下一次评估仍会看到之前的状态并可能再次触发,因此脚本应编写为只读检查,并将动作保留在负载中。触发器调度内置最小间隔为 30 秒。每次评估都有 30 秒的墙钟时间预算,最多可进行 5 次工具调用。
编写 watcher 时应围绕可操作状态,而不仅仅是成功状态:如果某个 watcher 在检查失败或超时时就悄然停止,它看起来会是健康的,但实际上已经坏了。将观察结果与 trigger.state 进行比较并返回新的状态以去重;不要依赖模型或进程内存。触发时,message 应保持自包含,因为它会成为已触发运行的完整事件上下文。
从本地脚本文件创建一个监视器(- 表示从 stdin 读取脚本):
载荷
每个作业都恰好携带一种载荷类型,由标志位决定:
另一种载荷类型
heartbeat 由系统拥有:Gateway 会为每个启用 heartbeat 的 agent 收敛出一个 heartbeat 监控作业(参见 Heartbeat)。它会出现在 automations list --all 中,但无法通过 CLI 或 API 创建或编辑。Heartbeat 配置会在启动时、配置重新加载时,或通过 openclaw doctor --fix 写入持久化的监控计划。当自动化被禁用时,监控器不会触发,也不会运行任何备用 heartbeat 定时器。
代理轮次选项
string
required
提示文本(孤立/当前/自定义会话作业必填)。
string
模型覆盖;必须解析为允许的模型,否则运行将因校验错误而失败。
string
每个作业的回退模型列表,例如
--fallbacks openai/gpt-5.6-sol,openrouter/meta-llama/llama-3.3-70b-instruct:free。对于不带回退的严格运行,请传入 --fallbacks ""。boolean
在
automations edit 中,移除每个作业的回退覆盖,使作业遵循已配置的回退优先级。不能与 --fallbacks 组合使用。boolean
在
automations edit 中,移除每个作业的模型覆盖,使作业遵循正常的自动化模型优先级(已存储的自动化会话覆盖,否则使用 agent/默认模型)。不能与 --model 组合使用。string
思考级别覆盖(
off|minimal|low|medium|high|xhigh|adaptive|max|ultra)。可用级别仍取决于所选模型和 agent 运行时。boolean
在
automations edit 中,移除每个作业的思考级别覆盖。不能与 --thinking 组合使用。boolean
跳过工作区引导文件注入。
string
限制作业可使用的工具,例如
--tools exec,read。--tools 的作业,会存储不受限制的 * 策略;automations edit --clear-tools 会恢复这一显式的不受限制策略。在显式工具策略存在之前创建的现有作业,会保留当前行为,直到其工具策略被显式编辑或作业被重新创建。
--model 会设置作业的主模型;它不会替换会话中的 /model 覆盖,因此已配置的回退链仍会叠加其上。无法解析或不被允许的模型会使运行以显式校验错误失败,而不会悄悄回退到默认值。如果某个作业有 --model 但没有显式或已配置的回退列表,OpenClaw 会传入一个空的回退覆盖,而不是悄悄把 agent 主模型追加为隐藏的重试目标。
孤立作业的模型选择优先级,从高到低:
- 每个作业载荷中的
model(显式配置;不允许的模型会使运行失败) - Gmail hook 模型覆盖(仅当运行来自 Gmail 且该覆盖被允许时)
- 用户选择的已存储自动化会话模型覆盖
- Agent/默认模型选择
fastMode、每个 agent 的 agents.entries.*.fastModeDefault、全局的 agents.defaults.fastModeDefault,然后是所选模型的 params.fastMode。自动模式使用模型的 params.fastAutoOnSeconds 截止时间,默认为 60 秒。
如果运行遇到实时模型切换交接,调度器会使用切换后的提供方/模型重试,并为当前运行持久化该选择(以及任何新的身份验证配置)。重试次数受到限制:在初始尝试加上 2 次切换重试之后,调度器会中止运行,而不是继续循环。
在孤立运行开始之前,OpenClaw 会检查配置了 api: "ollama" 和 api: "openai-completions" 且 baseUrl 为回环地址、私有网络或 .local 的提供方对应的可达本地端点。此预检会遍历作业已配置的回退链,只有在所有候选都不可达时才将运行标记为 skipped;--fallbacks "" 会让该遍历严格限定为仅主模型。某个端点宕机会将该运行记录为 skipped 并带有清晰的错误信息,而不是启动模型调用。该结果会按端点缓存 5 分钟(不是按作业或模型缓存),因此许多共享同一个失效本地 Ollama/vLLM/SGLang/LM Studio 服务器的到期作业,只需一次探测,而不会引发请求风暴。被跳过的预检运行不会增加执行错误退避;设置 failureAlert.includeSkipped 可选择接收重复的跳过告警。
命令载荷
命令载荷会在 Gateway 调度器内执行确定性脚本,而不会启动由模型支持的轮次。它们在 Gateway 主机上执行,捕获 stdout/stderr,将运行记录到作业的运行历史中,并复用与代理轮次作业相同的announce、webhook 和 none 投递模式。
命令载荷是面向操作员管理员的 Gateway 自动化接口,而不是 agent 的
tools.exec 调用。创建、更新、移除或手动运行自动化作业都需要 operator.admin;之后按计划运行的命令会在 Gateway 进程内执行,并作为由该管理员创建的自动化运行。Agent 执行策略(tools.exec.mode、审批提示、每个 agent 的工具允许列表)约束的是模型可见的执行工具,而不是命令载荷。--command <shell> 会存储为 argv: ["sh", "-lc", <shell>]。使用 --command-argv '["node","scripts/report.mjs"]' 可进行精确的 argv 执行,而无需 shell 解析。可选的 --command-env KEY=VALUE(可重复)、--command-input、--timeout-seconds(默认 10 分钟)、--no-output-timeout-seconds 和 --output-max-bytes 用于控制进程环境、stdin 和输出边界。
投递的文本源自进程输出:非空 stdout 优先;如果 stdout 为空而 stderr 非空,则投递 stderr;如果两者都存在,调度器会发送一个简短的 stdout:/stderr: 区块。退出代码为 0 时,运行记录为 ok;非零退出、信号中断、超时或无输出超时会记录为 error,并可能触发失败告警。仅打印 NO_REPLY 的命令会使用常规自动化静默标记抑制机制,不会向聊天发送任何内容。
脚本载荷
脚本载荷会以无头方式在与触发脚本相同的代码模式执行器中运行,而不会启动一次对话式代理轮次。在创建或运行它们之前,请启用cron.triggers.enabled;这个危险自动化开关同时涵盖触发脚本和脚本载荷。脚本作业只支持 main 和 isolated 会话目标。
--script <file|-> 可从文件或 stdin 读取 JavaScript。超时默认是 300 秒,上限为 900;工具预算默认是 50 次调用,上限为 200。这些载荷预算与更小的触发门评估预算是分开的。
脚本可以返回一个包含以下可选字段的对象:
notify:通过作业的announce、webhook或none投递模式发送的文本。若省略,则不发送任何内容。对于main作业,该文本会变成一个系统事件。wake:"now"会在入队notify(或一个紧凑的完成事件)后立即请求一次 heartbeat;"next-heartbeat"会将事件安排到下一次 heartbeat。state:JSON 状态,上限为 16 KB,且仅在成功运行后持久化。下一次运行会收到其冻结副本作为trigger.state,与触发脚本一致。由于该命名空间只有一个持久化拥有者,因此脚本载荷不能与同一作业上的条件触发器组合使用。nextCheck:例如"15m"这样的持续时间。它仅对启用了 pacing 的作业有效,并使用与代理轮次提议相同的 pacing 限制。
nextCheck,都属于正常的自动化运行错误:它们会进入运行历史,触发退避和失败告警处理,但不会持久化返回的状态。
执行样式
计划自动化中的 Codex apps
由 Codex 创建的自动化可以保留经过身份验证的创建者线程可用的 app ID 和权限上限。在执行时,OpenClaw 要求使用相同的已准备 Codex 配置和账户,然后根据当前 app 策略进一步收窄已存储的上限。已撤销的 app、账户/运行时更改以及交互式批准要求都会以安全失败方式终止,并显示恢复消息;它们绝不会回退到更广泛或不同的凭据。没有捕获 app 封装的旧作业会继续执行其常规的非 app 行为;仅当需要 Codex app 访问权限时,才重新创建或重新授权作业。请参阅 Native Codex plugins。
当创建请求携带会话上下文时,Agent-turn 作业默认使用创建它们的对话。没有会话键的调用方(包括未提供会话键的 CLI 和 API 调用方)会回退到
isolated。系统事件和心跳仍默认使用 main;命令和脚本负载仍默认使用 isolated。
主会话 vs 隔离会话 vs 自定义会话
主会话 vs 隔离会话 vs 自定义会话
主会话作业会将系统事件加入调度器拥有的运行通道,并可选择唤醒心跳(
--wake now 或 --wake next-heartbeat)。它们可以使用目标主会话最近一次投递的上下文来回复,但不会将例行自动化回合追加到人工聊天通道,也不会延长目标会话的每日/空闲重置新鲜度。隔离会话作业会使用全新的会话运行专用的 Agent 回合。自定义会话(session:xxx)会在多次运行之间持久化上下文,从而支持基于之前摘要构建每日站会等工作流。主会话自动化事件是自包含的系统事件提醒。它们不会自动包含默认的心跳提示或心跳监视器草稿;如果提醒应参考这些上下文,请在自动化事件文本中明确说明。隔离会话作业中“全新会话”的含义
隔离会话作业中“全新会话”的含义
每次运行都会使用新的记录/会话 ID。OpenClaw 会携带安全的偏好设置(思考/快速/详细设置、标签、用户明确选择的模型/身份验证覆盖项),但不会从旧的自动化会话记录中继承环境对话上下文:频道/群组路由、发送或排队策略、提权、来源或 ACP 运行时绑定。如果重复性作业应有意基于相同的对话上下文构建,请使用
current 或 session:<id>。无人值守运行契约
无人值守运行契约
隔离自动化和钩子 Agent 回合明确属于无人值守运行:没有人可以进行澄清或批准。最终回复必须是交付内容,而不是计划、确认或请求输入。如果没有任何需要处理的事项,Agent 应返回
HEARTBEAT_OK,并明确说明失败情况;重试和失败告警策略由调度器负责。对于受信任的计划作业,如果作业自身的指令明确要求提出问题或制定计划,则以作业指令为准;如果某个作业已不再需要,Agent 可以将其删除。外部钩子回合只会接收通用的无人值守契约;跨越外部内容边界时,它们不会接收该覆盖规则或自行删除指导。子 Agent 和 Discord 投递
子 Agent 和 Discord 投递
当隔离自动化运行编排子 Agent 时,投递会优先使用最终后代输出,而不是过时的父级中间文本。如果后代仍在运行,OpenClaw 会抑制该父级的部分更新,而不是发布它。对于仅文本的 Discord 通知目标,OpenClaw 只发送一次规范化的最终助手文本,而不会同时回放流式/中间文本和最终答案。媒体和结构化 Discord 负载仍会单独交付,以确保附件和组件不会丢失。
交付与输出
使用
--announce --channel telegram --to "-1001234567890" 进行频道交付。对于 Telegram 论坛主题,请使用 -1001234567890:topic:123;OpenClaw 也接受 Telegram 所有者提供的 -1001234567890:123 简写形式。直接 RPC/配置调用方可以将 delivery.threadId 作为字符串或数字传递。Slack/Discord/Mattermost 目标使用显式前缀(channel:<id>、user:<id>)。Matrix 房间 ID 区分大小写;请使用准确的房间 ID,或使用 Matrix 中的 room:!room:server 格式。
对于配置了多个频道的主机,使用 automations add|create 创建或使用 automations edit 修改的隔离 announce 作业必须设置 --channel <id>,除非带有提供方前缀的 --to 或保留的会话路由选择了频道。仅当无法解析的回退交付是可接受的时,才使用 --best-effort-deliver;它不会选择频道,并且交付失败不会导致作业失败。
当 announce 交付使用 channel: "last" 或省略 channel 时,诸如 telegram:123 这样的提供方前缀目标可以在调度程序回退到会话历史或单个已配置频道之前选择频道。只有已加载插件所公布的前缀才是提供方选择器。如果 delivery.channel 已明确指定,则目标前缀必须指向同一提供方;channel: "whatsapp" 搭配 to: "telegram:123" 会被拒绝,而不会让 WhatsApp 将 Telegram ID 解释为电话号码。目标类型和服务前缀(channel:<id>、user:<id>、imessage:<handle>、sms:<number>)仍然是由频道负责的目标语法,而不是提供方选择器。
对于隔离作业,聊天交付是共享的:如果有可用的聊天路由,即使使用 --no-deliver,代理也可以使用 message 工具。如果代理发送到了已配置/当前目标,OpenClaw 会跳过回退 announce。否则,announce、webhook 和 none 只控制运行器在代理轮次结束后如何处理最终回复。
当代理从活动聊天创建一个隔离提醒时,OpenClaw 会为回退 announce 路由存储保留的实时交付目标。内部会话键可能是小写;当当前聊天上下文可用时,不会根据这些键重建提供方交付目标。
隐式 announce 交付会使用已配置的频道允许列表来验证并重定向过时目标。DM 配对存储中的批准不是回退自动化接收者;当计划作业应主动发送到某个 DM 时,请设置 delivery.to 或配置频道的 allowFrom 条目。
失败通知
失败通知遵循单独的目标路径:cron.failureAlert上的目标字段(mode、channel、to、accountId)为失败通知设置全局默认值。已弃用的cron.failureDestination块会由openclaw doctor --fix合并到这些字段中。job.delivery.failureDestination会按作业覆盖该设置。- 如果两者都未设置,且作业已经通过
announce交付,则失败通知会回退到该主要 announce 目标。 - 仅当
sessionTarget="isolated"的作业,或主要交付模式为webhook时,才支持delivery.failureDestination。 failureAlert.includeSkipped: true会让作业或全局自动化提醒策略加入重复的跳过运行提醒。跳过的运行会使用单独的连续跳过计数器,因此不会影响执行错误退避。openclaw automations edit提供按作业设置提醒的选项:--failure-alert/--no-failure-alert、--failure-alert-after <n>、--failure-alert-channel、--failure-alert-to、--failure-alert-cooldown、--failure-alert-include-skipped/--failure-alert-exclude-skipped、--failure-alert-mode以及--failure-alert-account-id。
runAtMs 字段中读取同一时刻。
聊天通知会在可用时显示规范化的失败原因,并将原始命令、路径和提供方错误保留在自动化历史记录中。失败 webhook 会保留结构化的原始错误,以供诊断集成使用。
失败提醒默认选择加入,但调度程序还提供无条件的安全后备机制。基于时间的重复作业在连续执行失败 10 次后会自动禁用;成功运行会重置该连续计数。重复的计划计算失败在发生 3 次错误后会自动禁用。作业会将 state.autoDisabled.reason 记录为 consecutive-failures 或 schedule-errors,并向所属代理发送包含安全原因和恢复命令的通知。原始错误会保留在自动化历史记录中。修复原因后,运行 openclaw automations enable <jobId>;启用操作会清除记录的原因和失败计数。由于默认列表会隐藏已禁用的作业,请使用 openclaw automations list --all 检查这些作业。
输出语言
自动化作业不会根据频道、区域设置或之前的消息推断回复语言。请将语言规则放入计划消息或模板中:{{language}} 之类的占位符是否已填充。如果输出混杂多种语言,请明确说明规则,例如:“叙述性文本使用中文,技术术语保留英文。“
CLI 示例
- 一次性提醒
- 循环隔离作业
- 模型与思考覆盖
- Webhook 输出
- 命令输出
管理作业
sessions.list 中的持久 ID 调用 sessions.patch { key, archived: true, expectedSessionId })会禁用绑定到该会话的每个已启用自动化作业:其隔离的 cron:<jobId> 会话、session:<key> 目标,或投递/唤醒 sessionKey 通道。恢复会话需要使用相同的已观察身份,并且不会重新启用这些作业;请使用 openclaw automations enable <jobId>。在 Control UI 侧边栏中,拥有已启用绑定作业的会话会显示时钟徽章。
openclaw automations run <jobId> 在手动运行入队后返回。对于关闭钩子、维护脚本或其他必须阻塞直到排队运行完成的自动化,请使用 --wait;该选项会轮询返回的 runId(默认超时为 10m,轮询间隔为 2s),状态为 ok 时退出码为 0,状态为 error、skipped 或等待超时时退出码为非零值。
代理的 automations 工具从 automations(action: "list") 返回精简的作业摘要(id、name、enabled、nextRunAtMs、scheduleKind、lastRunStatus);如需获取一个完整的作业定义,请使用 automations(action: "get", jobId: "...")。直接的 Gateway 调用方可以向 cron.list 传递 compact: true;省略该参数则保留包含投递预览的完整响应。
openclaw automations create 是 openclaw automations add 的别名。新作业可以使用位置参数形式的计划("0 9 * * 1"、"every 1h"、"20m" 或 ISO 时间戳),后跟位置参数形式的代理提示词。在 automations add|create 或 automations edit 中使用 --webhook <url>,可将已完成运行的负载通过 POST 发送到 HTTP 端点;webhook 投递不能与聊天投递标志(--announce、--channel、--to、--thread-id、--account)结合使用。在 automations edit 中,--clear-channel、--clear-to、--clear-thread-id 和 --clear-account 可分别取消设置这些路由字段(每个参数都不能与对应的设置参数同时使用)——这与 --no-deliver 不同,后者只会禁用运行器的备用投递。
webhook URL 仍受上述严格出站策略的约束;如需使用本地或私有接收器,请配置 cron.webhookSsrfPolicy。
模型覆盖说明:
openclaw automations add|edit --model ...会更改作业所选的模型。- 如果模型获准使用,则该确切的提供商/模型会用于隔离代理运行。
- 如果模型不被允许或无法解析,调度程序会使该运行失败,并返回明确的验证错误。
- API
cron.update负载补丁可以将model: null设置为清除已存储的作业模型覆盖。 openclaw automations edit <job-id> --clear-model会从 CLI 清除该覆盖(效果与model: null补丁相同),且不能与--model同时使用。- 已配置的备用链仍会生效,因为自动化的
--model是作业的主要模型,而不是会话/model覆盖。 openclaw automations add|edit --fallbacks ...会设置负载中的fallbacks,替换该作业已配置的备用模型;--fallbacks ""会禁用备用模型,使运行严格执行。openclaw automations edit <job-id> --clear-fallbacks会清除每个作业的覆盖设置。- 如果没有显式或已配置的备用列表,单独使用
--model不会将代理主要模型作为静默的额外重试目标。
Webhook
Gateway 可以为外部触发器暴露 HTTP webhook 端点。在配置中启用:认证
每个请求都必须通过请求头包含 hook token:Authorization: Bearer <token>(推荐)x-openclaw-token: <token>
POST /hooks/wake
POST /hooks/wake
POST /hooks/agent
POST /hooks/agent
运行一次 agent 轮次。默认情况下,会话彼此隔离:字段:
message(必需)、name、agentId、sessionKey(需要 hooks.allowRequestSessionKey=true)、sessionMode(isolated 或 persistent)、idempotencyKey、wakeMode、deliver、channel、to、accountId、model、thinking、timeoutSeconds。仅当重复投递应复用之前的上下文时,才将 sessionMode 设置为 "persistent"。直接持久化 hook 需要显式的 sessionKey、hooks.allowRequestSessionKey: true,以及非空的 hooks.allowedSessionKeyPrefixes 允许列表。省略 sessionMode 或使用 "isolated" 可创建全新的运行会话。Hook 投递会在隔离运行计划执行之前绑定:- 同时省略
channel和to时,将仅运行并完成;结果会通过 hook 完成事件提供。 - 启用投递时,只提供
channel或to其中之一会使请求以400失败,并且不会安排运行。 - 公告投递需要具体的 channel;webhook hook 永远不会继承主会话的
lastchannel 或收件人。 - 设置
deliver: false会使运行仅完成,并忽略任何投递目的地。 - 同时提供具体的
channel和to会启用直接公告投递。 - 在多账户 channel 上,将
accountId与channel和to一起设置,以选择一个已配置且已启用的账户。未知、已禁用或无效的账户 ID 会返回400,并且不会安排运行。
200 响应可能最多需要 15 秒,并表示运行已进入其 agent 运行器。运行前失败时返回 { ok: false, error, runId },具体包括:400:投递坐标或账户选择无效;请修正请求后重试。409:目标会话已更改,或以其他方式拒绝新工作;解决会话冲突后重试。502:Gateway 或 cron 在进入运行器之前准备失败。503:运行器接收未能在 15 秒内完成。超时的排队工作会被取消,之后不会再启动。
映射 hook(POST /hooks/<name>)
映射 hook(POST /hooks/<name>)
自定义 hook 名称通过配置中的
hooks.mappings 解析。映射可以使用模板或代码转换,将任意载荷转换为 wake 或 agent 操作。映射的 agent 操作使用与 POST /hooks/agent 相同的 15 秒接收机制以及 200/400/409/502/503 响应契约。持久化映射 hook 需要稳定的映射 sessionKey 或 hooks.defaultSessionKey。由模板派生的键仍遵循上述请求键选择加入机制和前缀策略。Gmail PubSub 集成
通过 Google PubSub 将 Gmail 收件箱触发器连接到 OpenClaw。前置条件:
gcloud CLI、gog(gogcli)、已启用的 OpenClaw hooks、用于公共 HTTPS 端点的 Tailscale,以及可正常工作的沙箱后端。下面的示例使用默认的 Docker 后端;请先按照沙箱镜像与设置构建其镜像,或配置其他受支持的后端。配置受限的 Gmail 阅读器(推荐)
连接 Gmail transport 之前,请将专用的 reader 和 hook 策略合并到现有配置中。保留现有 agent 上的真实设置;下面的main 条目仅展示所需的 roster 形状。
openclaw agents list --bindings;替换每个占位符并验证每个 channel owner。
这种结构更安全的原因:
- 显式的
main绑定会保留现有 channel 所有权,而不会让非 Gmail 流量处于无所有者状态。当只有一个账户属于main时,请使用具体的accountId,而不是"*"。 agentId: "mail_reader"可使 Gmail 避开mainagent。allowedAgentIds会阻止此 hook 端点选择其他 agent。如果 Gateway 还提供其他 hook 工作流,也只能加入它们预期使用的 agent id。scope: "session"会为每封 Gmail 邮件提供独立的沙箱;workspaceAccess: "none"会使主机 agent 工作区无法进入该沙箱。allow: ["session_status"]是每个 agent 的绝对限制,因此全局tools.alsoAllow添加项无法泄漏到 reader 中。最小配置文件和显式 deny 列表使预期边界可审计。deliver: false会使完成结果保留在 hook 流程内。在验证 reader 后,如需向外部公告摘要,请设置deliver: true并添加明确的channel和to。除非你有意公开确切的协调工具,并将其与范围狭窄的tools.agentToAgent策略配套,否则请保持 agent-to-agent 交接处于禁用状态。
session_status,则每个 agent 的允许列表无法将其恢复。请确保继承的策略保留 session_status;有效工具集为空时,流程会在模型看到邮件之前中止。
如果你确实要将 Gmail 路由到功能更强大的 agent,请将其视为一项安全决策:保持外部内容包装处于启用状态,对运行进行沙箱隔离,并且只授予该工作流所需的工具。
验证阅读器模型身份验证
每个 agent 都有自己的身份验证存储。请为mail_reader 所选的提供商完成身份验证,或确保它能够使用受支持的共享环境/配置凭据,然后在连接 Gmail 之前验证实际生效的路由:
连接 Gmail 传输
hooks.gmail 传输设置、启用 Gmail 预设、保留上述受限映射,并默认使用 Tailscale Funnel 作为推送端点(--tailscale funnel|serve|off)。向导不会创建阅读器 agent 或会话密钥策略,因此请先应用受限配置。
验证阅读器边界
mail_reader,会话密钥以 hook:gmail: 开头,运行处于沙箱中,并且结果仅对邮件进行摘要。任何尝试访问链接、写入文件、执行 shell 命令、执行浏览器操作或注册 MCP 的行为,都应视为边界检查失败。
Gateway 自动启动
当hooks.enabled=true 且设置了 hooks.gmail.account 时,Gateway 会在启动时运行 gog gmail watch serve 并自动续订 watch。设置 OPENCLAW_SKIP_GMAIL_WATCHER=1 可选择退出。
手动一次性设置
1
选择 GCP 项目
选择拥有
gog 使用的 OAuth 客户端的 GCP 项目:2
创建 topic 并授予 Gmail 推送访问权限
3
启动 watch
Gmail 模型覆盖
配置
webhookToken 会在自动化 webhook POST 请求中以 Authorization: Bearer <token> 的形式发送。
Webhook URL 不得包含嵌入式用户名/密码凭据;当接收方支持 bearer 身份验证时,请使用
webhookToken。
webhookSsrfPolicy 适用于每个出站自动化 webhook,省略时将采用严格策略。
相比宽泛的 dangerouslyAllowPrivateNetwork 选择启用,建议优先使用范围更窄的
allowedHostnames 条目。
自动化作业、运行历史记录以及隔离的格式错误作业都存储在共享的 SQLite 状态数据库中。请使用 CLI 或 Gateway API 更改作业;cron.store 已弃用。
禁用自动化:cron.enabled: false 或 OPENCLAW_SKIP_CRON=1。
重试行为
重试行为
一次性重试:临时错误(速率限制、过载、网络、超时、服务器错误)会使用内置重试计划。永久性错误会立即禁用该作业。周期性重试:连续执行错误会按扩展后的计划退避(30s、60s、5m、15m、60m)。在下一次成功运行后,退避计时会重置。
维护
维护
cron.sessionRetention(默认为 24h,设置为 false 或 "0h" 时禁用)会清理隔离运行会话条目。运行历史记录会为每个作业保留最新的 2000 条终止行;丢失的行仍会保留 24 小时的清理期限。旧版存储迁移
旧版存储迁移
升级时,运行
openclaw doctor --fix,将历史的 ~/.openclaw/cron/jobs.json、jobs-state.json、jobs-quarantine.json 和 runs/*.jsonl 文件导入 SQLite,并为原文件添加 .migrated 后缀进行归档。格式错误的作业行仍可在 SQLite 中恢复,而有效作业会继续运行。故障排除
命令序列
自动化未触发
自动化未触发
- 检查
cron.enabled和OPENCLAW_SKIP_CRON环境变量。 - 确认网关持续运行。
- 对于
cron计划,验证时区(--tz)是否与主机时区一致。 - 如果运行输出中出现
reason: not-due,表示已通过openclaw automations run <jobId> --due检查手动运行,但任务尚未到执行时间。
任务已触发但未送达
任务已触发但未送达
- 送达模式为
none表示不会预期由运行器进行回退发送。如果聊天路由可用,代理仍可以通过message工具直接发送。 - 缺少或无效的送达目标(
channel/to)表示已跳过出站发送。 - 对于 Matrix,复制的任务或旧版任务如果将
delivery.to中的房间 ID 转换为小写,可能会失败,因为 Matrix 房间 ID 区分大小写。请将任务编辑为 Matrix 中对应的准确!room:server或room:!room:server值。 - 频道身份验证错误(
unauthorized、Forbidden)表示凭据阻止了送达。 - 如果隔离运行仅返回静默令牌(
NO_REPLY/no_reply),OpenClaw 会抑制直接出站送达和回退的排队摘要路径,因此不会向聊天中发回任何内容。 - 如果代理应自行向用户发送消息,请检查任务是否具有可用的路由(使用之前聊天中的
channel: "last",或使用明确的频道/目标)。
自动化或心跳似乎阻止了/new 风格的会话轮换
自动化或心跳似乎阻止了/new 风格的会话轮换
- 每日重置和空闲重置的新鲜度并非基于
updatedAt;请参阅会话管理。 - 自动化唤醒、心跳运行、执行通知和网关记录操作可能会更新会话行以用于路由/状态,但不会延长
sessionStartedAt或lastInteractionAt。 - 对于在这些字段存在之前创建的旧版记录,如果转录 JSONL 会话头仍然可用,OpenClaw 可以从中恢复
sessionStartedAt。对于没有lastInteractionAt的旧版空闲记录,会使用恢复的启动时间作为其空闲基准。
时区注意事项
时区注意事项
- 不带
--tz的 Cron 表达式使用网关主机的时区。 - 不带时区的
at计划将按 UTC 处理。 - 心跳
activeHours使用配置的时区解析结果。