![[OpenClaw 文档]工具--自动化与任务](https://minio.imgdata.cn/cnesa/cnesa/2026/05/29/765544625aa111cd7ec16c796667c69f.png)
本文档汇总了 OpenClaw 官方文档站 工具 > 自动化与任务 子模块下的全部 2 篇内容,源自 docs.openclaw.ai/zh-CN。
📄 钩子
原文:https://docs.openclaw.ai/zh-CN/automation/hooks
钩子是在 Gateway 网关内部发生某些事件时运行的小脚本。它们可以从目录中发现,并可通过 openclaw hooks 检查。只有在你启用钩子,或配置了至少一个钩子条目、钩子包、旧版处理器或额外钩子目录之后,Gateway 网关才会加载内部钩子。
OpenClaw 中有两种钩子:
- 内部钩子(本页):当智能体事件触发时在 Gateway 网关内部运行,例如
/new、/reset、/stop或生命周期事件。 - 网络钩子:外部 HTTP 端点,可让其他系统触发 OpenClaw 中的工作。参见 网络钩子。
钩子也可以内置在插件中。openclaw hooks list 会同时显示独立钩子和插件管理的钩子。
快速开始
# List available hooks
openclaw hooks list
# Enable a hook
openclaw hooks enable session-memory
# Check hook status
openclaw hooks check
# Get detailed information
openclaw hooks info session-memory
事件类型
| 事件 | 触发时机 |
|---|---|
command:new |
发出 /new 命令 |
command:reset |
发出 /reset 命令 |
command:stop |
发出 /stop 命令 |
command |
任意命令事件(通用监听器) |
session:compact:before |
压缩开始总结历史之前 |
session:compact:after |
压缩完成之后 |
session:patch |
会话属性被修改时 |
agent:bootstrap |
工作区引导文件被注入之前 |
gateway:startup |
渠道启动且钩子加载之后 |
gateway:shutdown |
Gateway 网关关闭开始时 |
gateway:pre-restart |
预期的 Gateway 网关重启之前 |
message:received |
来自任意渠道的入站消息 |
message:transcribed |
音频转写完成之后 |
message:preprocessed |
媒体和链接预处理完成或被跳过之后 |
message:sent |
出站消息已送达 |
编写钩子
钩子结构
每个钩子都是一个包含两个文件的目录:
my-hook/
├── HOOK.md # Metadata + documentation
└── handler.ts # Handler implementation
HOOK.md 格式
---
name: my-hook
description: "Short description of what this hook does"
metadata:
{ "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }
---
# My Hook
Detailed documentation goes here.
元数据字段(metadata.openclaw):
| 字段 | 描述 |
|---|---|
emoji |
CLI 中显示的表情符号 |
events |
要监听的事件数组 |
export |
要使用的命名导出(默认为 "default") |
os |
要求的平台(例如 ["darwin", "linux"]) |
requires |
要求的 bins、anyBins、env 或 config 路径 |
always |
跳过资格检查(布尔值) |
install |
安装方法 |
处理器实现
const handler = async (event) => {
if (event.type !== "command" || event.action !== "new") {
return;
}
console.log(`[my-hook] New command triggered`);
// Your logic here
// Optionally send message to user
event.messages.push("Hook executed!");
};
export default handler;
每个事件都包含:type、action、sessionKey、timestamp、messages(推入以发送给用户)以及 context(事件特定数据)。智能体和工具插件钩子上下文还可以包含 trace,这是一个只读、兼容 W3C 的诊断跟踪上下文,插件可将其传入结构化日志以进行 OTEL 关联。
事件上下文要点
命令事件(command:new、command:reset):context.sessionEntry、context.previousSessionEntry、context.commandSource、context.workspaceDir、context.cfg。
消息事件(message:received):context.from、context.content、context.channelId、context.metadata(提供商特定数据,包括 senderId、senderName、guildId)。context.content 会优先使用命令式消息中的非空命令正文,然后回退到原始入站正文和通用正文;它不包含仅面向智能体的增强内容,例如线程历史或链接摘要。
消息事件(message:sent):context.to、context.content、context.success、context.channelId。
消息事件(message:transcribed):context.transcript、context.from、context.channelId、context.mediaPath。
消息事件(message:preprocessed):context.bodyForAgent(最终增强正文)、context.from、context.channelId。
引导事件(agent:bootstrap):context.bootstrapFiles(可变数组)、context.agentId。
会话补丁事件(session:patch):context.sessionEntry、context.patch(仅更改字段)、context.cfg。只有特权客户端可以触发补丁事件。
压缩事件:session:compact:before 包含 messageCount、tokenCount。session:compact:after 会添加 compactedCount、summaryLength、tokensBefore、tokensAfter。
command:stop 观察用户发出 /stop;它是取消/命令生命周期事件,
不是智能体最终化关口。需要检查自然最终答案并要求智能体再执行一次的插件,
应改用类型化插件钩子 before_agent_finalize。参见 插件钩子。
Gateway 网关生命周期事件:gateway:shutdown 包含 reason 和 restartExpectedMs,并在 Gateway 网关关闭开始时触发。gateway:pre-restart 包含相同上下文,但只会在关闭属于预期重启的一部分,且提供了有限的 restartExpectedMs 值时触发。在关闭期间,每个生命周期钩子的等待都是尽力而为且有界的,因此即使处理器卡住,关闭也会继续。
在 gateway:shutdown(或 gateway:pre-restart)事件与关闭序列其余部分之间,Gateway 网关还会为进程停止时仍处于活动状态的每个会话触发类型化的 session_end 插件钩子。普通 SIGTERM/SIGINT 停止时,事件的 reason 为 shutdown;当关闭是作为预期重启的一部分排程时,则为 restart。此排空过程有界,因此缓慢的 session_end 处理器无法阻塞进程退出;并且已经通过替换 / 重置 / 删除 / 压缩完成最终化的会话会被跳过,以避免重复触发。
钩子发现
钩子会按覆盖优先级递增的顺序从以下目录发现:
- 内置钩子:随 OpenClaw 发布
- 插件钩子:内置在已安装插件中的钩子
- 托管钩子:
~/.openclaw/hooks/(用户安装,跨工作区共享)。来自hooks.internal.load.extraDirs的额外目录共享此优先级。 - 工作区钩子:
<workspace>/hooks/(按智能体划分,默认禁用,直到显式启用)
工作区钩子可以添加新的钩子名称,但不能覆盖同名的内置钩子、托管钩子或插件提供的钩子。
在配置内部钩子之前,Gateway 网关会在启动时跳过内部钩子发现。使用 openclaw hooks enable <name> 启用内置或托管钩子,安装钩子包,或设置 hooks.internal.enabled=true 以选择加入。启用一个具名钩子时,Gateway 网关只会加载该钩子的处理器;hooks.internal.enabled=true、额外钩子目录和旧版处理器会选择加入广泛发现。
钩子包
钩子包是通过 package.json 中的 openclaw.hooks 导出钩子的 npm 包。使用以下命令安装:
openclaw plugins install <path-or-spec>
npm 规格仅限注册表(包名 + 可选精确版本或 dist-tag)。Git/URL/file 规格和 semver 范围会被拒绝。
内置钩子
| 钩子 | 事件 | 作用 |
|---|---|---|
| session-memory | command:new、command:reset |
将会话上下文保存到 <workspace>/memory/ |
| bootstrap-extra-files | agent:bootstrap |
从 glob 模式注入额外引导文件 |
| command-logger | command |
将所有命令记录到 ~/.openclaw/logs/commands.log |
| compaction-notifier | session:compact:before、session:compact:after |
在会话压缩开始/结束时发送可见的聊天通知 |
| boot-md | gateway:startup |
Gateway 网关启动时运行 BOOT.md |
启用任意内置钩子:
openclaw hooks enable <hook-name>
session-memory 详情
提取最近 15 条用户/助手消息,并使用主机本地日期保存到 <workspace>/memory/YYYY-MM-DD-HHMM.md。记忆捕获在后台运行,因此 /new 和 /reset 的确认不会被转录读取或可选的 slug 生成延迟。设置 hooks.internal.entries.session-memory.llmSlug: true 可使用已配置模型生成描述性文件名 slug。需要配置 workspace.dir。
bootstrap-extra-files 配置
{
"hooks": {
"internal": {
"entries": {
"bootstrap-extra-files": {
"enabled": true,
"paths": ["packages/*/AGENTS.md", "packages/*/TOOLS.md"]
}
}
}
}
}
路径相对于工作区解析。只加载已识别的引导基本文件名(AGENTS.md、SOUL.md、TOOLS.md、IDENTITY.md、USER.md、HEARTBEAT.md、BOOTSTRAP.md、MEMORY.md)。
command-logger 详情
将每个斜杠命令记录到 ~/.openclaw/logs/commands.log。
compaction-notifier 详情
当 OpenClaw 开始和完成压缩会话转录时,向当前对话发送简短状态消息。这会让聊天界面上的长轮次不那么令人困惑,因为用户可以看到助手正在总结上下文,并会在压缩后继续。
boot-md 详情
Gateway 网关启动时,从活动工作区运行 BOOT.md。
插件钩子
插件可以通过插件 SDK 注册类型化钩子以实现更深度的集成:
拦截工具调用、修改提示、控制消息流等。
当你需要 before_tool_call、before_agent_reply、
before_install 或其他进程内生命周期钩子时,请使用插件钩子。
完整插件钩子参考见 插件钩子。
配置
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}
按钩子设置的环境变量:
{
"hooks": {
"internal": {
"entries": {
"my-hook": {
"enabled": true,
"env": { "MY_CUSTOM_VAR": "value" }
}
}
}
}
}
额外钩子目录:
{
"hooks": {
"internal": {
"load": {
"extraDirs": ["/path/to/more/hooks"]
}
}
}
}
旧版 hooks.internal.handlers 数组配置格式仍然支持,用于向后兼容,但新的钩子应使用基于发现机制的系统。
CLI 参考
# List all hooks (add --eligible, --verbose, or --json)
openclaw hooks list
# Show detailed info about a hook
openclaw hooks info <hook-name>
# Show eligibility summary
openclaw hooks check
# Enable/disable
openclaw hooks enable <hook-name>
openclaw hooks disable <hook-name>
最佳实践
- 保持处理器快速。 钩子会在命令处理期间运行。使用
void processInBackground(event)以即发即忘的方式执行繁重工作。 - 优雅处理错误。 将有风险的操作包装在 try/catch 中;不要抛出异常,以便其他处理器可以运行。
- 尽早过滤事件。 如果事件类型/动作不相关,立即返回。
- 使用具体的事件键。 优先使用
"events": ["command:new"],而不是"events": ["command"],以减少开销。
故障排除
未发现钩子
# Verify directory structure
ls -la ~/.openclaw/hooks/my-hook/
# Should show: HOOK.md, handler.ts
# List all discovered hooks
openclaw hooks list
钩子不符合条件
openclaw hooks info my-hook
检查缺失的二进制文件(PATH)、环境变量、配置值或 OS 兼容性。
钩子未执行
- 确认钩子已启用:
openclaw hooks list - 重启你的 Gateway 网关进程,使钩子重新加载。
- 检查 Gateway 网关日志:
./scripts/clawlog.sh | grep hook
相关
- CLI 参考:hooks
- Webhook
- 插件钩子 — 进程内插件生命周期钩子
- 配置
📄 定时任务
原文:https://docs.openclaw.ai/zh-CN/automation/cron-jobs
Cron 是 Gateway 网关的内置调度器。它会持久化作业,在正确时间唤醒智能体,并可将输出送回聊天渠道或 webhook 端点。
快速开始
bash
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
bash
openclaw cron list
openclaw cron get <job-id>
openclaw cron show <job-id>
bash
openclaw cron runs --id <job-id>
cron 的工作原理
- Cron 在 Gateway 网关进程内部运行(不在模型内部)。
- 作业定义会持久化到
~/.openclaw/cron/jobs.json,因此重启不会丢失计划。 - 运行时执行状态会持久化到旁边的
~/.openclaw/cron/jobs-state.json。如果你在 git 中跟踪 cron 定义,请跟踪jobs.json,并将jobs-state.json加入 gitignore。 - 拆分后,旧版本 OpenClaw 可以读取
jobs.json,但可能会把作业视为全新作业,因为运行时字段现在位于jobs-state.json中。 - 当 Gateway 网关正在运行或已停止时编辑
jobs.json,OpenClaw 会将变更的计划字段与待处理运行时槽位元数据进行比较,并清除陈旧的nextRunAtMs值。纯格式化或仅键顺序重写会保留待处理槽位。 - 所有 cron 执行都会创建后台任务记录。
- 在 Gateway 网关启动时,逾期的隔离智能体轮次作业会被重新安排到渠道连接窗口之外,而不是立即重放,因此 Discord/Telegram 启动和原生命令设置在重启后仍能保持响应。
- 一次性作业(
--at)默认在成功后自动删除。 - 隔离 cron 运行完成时,会尽力关闭其
cron:<jobId>会话中跟踪的浏览器标签页/进程,因此分离的浏览器自动化不会留下孤立进程。 - 获得狭窄 cron 自清理授权的隔离 cron 运行,仍可以读取调度器状态、经过自过滤的当前作业列表以及该作业的运行历史,因此状态/Heartbeat 检查可以检查自身计划,而不会获得更广泛的 cron 修改权限。
- 隔离 cron 运行还会防范陈旧的确认回复。如果第一个结果只是临时状态更新(
on it、pulling everything together以及类似提示),并且没有后代子智能体运行仍负责最终答案,OpenClaw 会在交付前重新提示一次以获取实际结果。 - 隔离 cron 运行优先使用嵌入式运行中的结构化执行拒绝元数据,然后回退到已知的最终摘要/输出标记,例如
SYSTEM_RUN_DENIED和INVALID_REQUEST,因此被阻止的命令不会被报告为成功运行。 - 隔离 cron 运行还会将运行级智能体失败视为作业错误,即使没有生成回复载荷也是如此,因此模型/提供商失败会递增错误计数器并触发失败通知,而不是把作业清除为成功。
- 当隔离智能体轮次作业达到
timeoutSeconds时,cron 会中止底层智能体运行,并给它一个短暂的清理窗口。如果运行没有排空,由 Gateway 网关拥有的清理会在 cron 记录超时前强制清除该运行的会话所有权,因此排队的聊天工作不会被留在陈旧的处理中会话后面。 - 如果隔离智能体轮次在运行器启动前或首次模型调用前停滞,cron 会记录特定阶段的超时,例如
setup timed out before runner start或stalled before first model call (last phase: context-engine)。这些 watchdog 会在外部 CLI 进程实际启动前覆盖嵌入式提供商和 CLI 支持的提供商,并且与较长的timeoutSeconds值独立封顶,因此冷启动/凭证/上下文失败会快速暴露,而不是等待完整作业预算。
cron 的任务协调首先由运行时拥有,其次由持久历史支持:只要 cron 运行时仍跟踪该作业为正在运行,活动 cron 任务就会保持存活,即使旧的子会话行仍然存在。一旦运行时停止拥有该作业且 5 分钟宽限窗口到期,维护检查会查看持久化运行日志和作业状态,查找匹配的 cron:<jobId>:<startedAt> 运行。如果该持久历史显示终态结果,任务账本会据此完成;否则,由 Gateway 网关拥有的维护可以将任务标记为 lost。离线 CLI 审计可以从持久历史恢复,但它不会把自身空的进程内活动作业集当作由 Gateway 网关拥有的 cron 运行已消失的证据。
计划类型
| 类型 | CLI 标志 | 描述 |
|---|---|---|
at |
--at |
一次性时间戳(ISO 8601 或类似 20m 的相对时间) |
every |
--every |
固定间隔 |
cron |
--cron |
5 字段或 6 字段 cron 表达式,带可选 --tz |
不带时区的时间戳会被视为 UTC。添加 --tz America/New_York 可按本地墙钟时间调度。
整点循环表达式会自动错开最多 5 分钟,以减少负载峰值。使用 --exact 强制精确计时,或使用 --stagger 30s 指定显式窗口。
月中日期和星期使用 OR 逻辑
cron 表达式由 croner 解析。当月中日期字段和星期字段都不是通配符时,croner 会在任一字段匹配时匹配,而不是两个都匹配。这是标准 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
这会每月触发约 5-6 次,而不是每月 0-1 次。OpenClaw 在这里使用 Croner 的默认 OR 行为。要要求两个条件都满足,请使用 Croner 的 + 星期修饰符(0 9 15 * +1),或在一个字段上调度,并在作业的提示或命令中保护另一个条件。
执行风格
| 风格 | --session 值 |
运行位置 | 最适合 |
|---|---|---|---|
| 主会话 | main |
下一个 Heartbeat 轮次 | 提醒、系统事件 |
| 隔离 | isolated |
专用 cron:<jobId> |
报告、后台杂务 |
| 当前会话 | current |
创建时绑定 | 具备上下文感知的循环工作 |
| 自定义会话 | session:custom-id |
持久命名会话 | 基于历史构建的工作流 |
主会话作业会将系统事件加入队列,并可选择唤醒 Heartbeat(--wake now 或 --wake next-heartbeat)。这些系统事件不会延长目标会话的每日/空闲重置新鲜度。隔离作业会使用全新会话运行专用智能体轮次。自定义会话(session:xxx)会跨运行持久化上下文,从而支持每日站会等基于先前摘要构建的工作流。
对于隔离作业,“全新会话”是指每次运行都有新的 transcript/会话 ID。OpenClaw 可能会携带安全偏好,例如 thinking/fast/verbose 设置、标签,以及显式用户选择的模型/凭证覆盖,但它不会从较旧的 cron 行继承环境对话上下文:渠道/群组路由、发送或队列策略、权限提升、来源或 ACP 运行时绑定。当循环作业应有意基于同一对话上下文构建时,请使用 current 或 session:<id>。
对于隔离作业,运行时拆除现在包括对该 cron 会话的尽力浏览器清理。清理失败会被忽略,因此实际 cron 结果仍然优先。
隔离 cron 运行还会通过共享运行时清理路径释放为该作业创建的任何内置 MCP 运行时实例。这与主会话和自定义会话 MCP 客户端的拆除方式一致,因此隔离 cron 作业不会跨运行泄漏 stdio 子进程或长生命周期 MCP 连接。
当隔离 cron 运行编排子智能体时,交付也会优先使用最终后代输出,而不是陈旧的父级临时文本。如果后代仍在运行,OpenClaw 会抑制该部分父级更新,而不会公告它。
对于纯文本 Discord 公告目标,OpenClaw 会发送一次规范最终助手文本,而不是同时重放流式/中间文本载荷和最终答案。媒体和结构化 Discord 载荷仍会作为单独载荷交付,因此附件和组件不会被丢弃。
隔离作业的载荷选项
提示文本(隔离模式必需)。
模型覆盖;使用为该作业选择的允许模型。
Thinking 级别覆盖。
跳过工作区 bootstrap 文件注入。
限制作业可以使用哪些工具,例如 --tools exec,read。
--model 使用所选的允许模型作为该作业的主模型。它不同于聊天会话的 /model 覆盖:当作业主模型失败时,已配置的回退链仍然适用。如果请求的模型不被允许或无法解析,cron 会让运行失败,并给出明确的验证错误,而不是静默回退到作业的智能体/默认模型选择。
cron 作业也可以携带载荷级 fallbacks。如果存在,该列表会替换作业已配置的回退链。当你想要严格 cron 运行,仅尝试所选模型时,请在作业载荷/API 中使用 fallbacks: []。如果作业有 --model,但既没有载荷回退,也没有已配置回退,OpenClaw 会传递显式空回退覆盖,因此智能体主模型不会作为隐藏的额外重试目标追加进去。
隔离作业的模型选择优先级为:
- Gmail 钩子模型覆盖(当运行来自 Gmail 且该覆盖被允许时)
- 每作业载荷
model - 用户选择的已存储 cron 会话模型覆盖
- 智能体/默认模型选择
Fast 模式也会跟随解析后的实时选择。如果所选模型配置具有 params.fastMode,隔离 cron 默认会使用它。已存储会话的 fastMode 覆盖仍会在任一方向上优先于配置。
如果隔离运行遇到实时模型切换移交,cron 会使用切换后的提供商/模型重试,并在重试前为活动运行持久化该实时选择。当切换还携带新的凭证配置文件时,cron 也会为活动运行持久化该凭证配置文件覆盖。重试是有界的:在初始尝试加 2 次切换重试之后,cron 会中止,而不是无限循环。
在隔离的 cron 运行进入智能体运行器之前,OpenClaw 会检查已配置的 api: "ollama" 和 api: "openai-completions" 提供商中可访问的本地提供商端点,这些端点的 baseUrl 为 local loopback、私有网络或 .local。如果该端点已停机,运行会被记录为 skipped,并给出明确的提供商/模型错误,而不是启动模型调用。端点结果会缓存 5 分钟,因此许多使用同一个已停机本地 Ollama、vLLM、SGLang 或 LM Studio 服务器的到期作业会共享一次小型探测,而不是制造请求风暴。跳过的提供商预检运行不会增加执行错误退避;当你想收到重复跳过通知时,请启用 failureAlert.includeSkipped。
投递和输出
| 模式 | 会发生什么 |
|---|---|
announce |
如果智能体没有发送,则将最终文本作为兜底投递到目标 |
webhook |
将完成事件载荷 POST 到 URL |
none |
不进行运行器兜底投递 |
使用 --announce --channel telegram --to "-1001234567890" 进行渠道投递。对于 Telegram 论坛主题,请使用 -1001234567890:topic:123;直接 RPC/配置调用方也可以将 delivery.threadId 作为字符串或数字传入。Slack/Discord/Mattermost 目标应使用显式前缀(channel:<id>、user:<id>)。Matrix 房间 ID 区分大小写;请使用精确的房间 ID,或使用来自 Matrix 的 room:!room:server 形式。
当 announce 投递使用 channel: "last" 或省略 channel 时,带提供商前缀的目标(例如 telegram:123)可以在 cron 回退到会话历史或单个已配置渠道之前选择渠道。只有已加载插件声明的前缀才是提供商选择器。如果 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 投递会使用已配置的渠道 allowlist 来验证并重定向过期目标。私信配对存储批准不是兜底自动化收件人;当定时作业需要主动发送到私信时,请设置 delivery.to 或配置渠道 allowFrom 条目。
失败通知遵循单独的目标路径:
cron.failureDestination为失败通知设置全局默认值。job.delivery.failureDestination按作业覆盖该值。- 如果两者都未设置,并且作业已通过
announce投递,失败通知现在会回退到该主要 announce 目标。 delivery.failureDestination仅支持sessionTarget="isolated"作业,除非主要投递模式是webhook。failureAlert.includeSkipped: true会让作业或全局 cron 告警策略选择接收重复的跳过运行告警。跳过的运行会保留单独的连续跳过计数器,因此不会影响执行错误退避。
CLI 示例
bash
openclaw cron add \
--name "Calendar check" \
--at "20m" \
--session main \
--system-event "Next heartbeat: check calendar." \
--wake now
bash
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"
bash
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
Webhook
Gateway 网关 可以公开 HTTP webhook 端点,用于外部触发器。在配置中启用:
{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
},
}
身份验证
每个请求都必须通过标头包含 hook 令牌:
Authorization: Bearer <token>(推荐)x-openclaw-token: <token>
查询字符串令牌会被拒绝。
为主会话入队一个系统事件:
```bash
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"}'
```
<ParamField path="text" type="string" required>
事件描述。
</ParamField>
<ParamField path="mode" type="string" default="now">
`now` 或 `next-heartbeat`。
</ParamField>
运行一个隔离智能体轮次:
```bash
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"}'
```
字段:`message`(必填)、`name`、`agentId`、`wakeMode`、`deliver`、`channel`、`to`、`model`、`fallbacks`、`thinking`、`timeoutSeconds`。
自定义 hook 名称通过配置中的 hooks.mappings 解析。映射可以使用模板或代码转换,将任意载荷转换为 wake 或 agent 操作。
将 hook 端点放在 local loopback、tailnet 或可信反向代理之后。
- 使用专用 hook 令牌;不要复用 Gateway 网关 认证令牌。
- 将
hooks.path保持在专用子路径上;/会被拒绝。 - 设置
hooks.allowedAgentIds以限制显式agentId路由。 - 除非需要由调用方选择会话,否则保持
hooks.allowRequestSessionKey=false。 - 如果启用
hooks.allowRequestSessionKey,也要设置hooks.allowedSessionKeyPrefixes来约束允许的会话键形状。 - 默认情况下,hook 载荷会用安全边界包装。
Gmail PubSub 集成
通过 Google PubSub 将 Gmail 收件箱触发器接入 OpenClaw。
前置条件:gcloud CLI、gog(gogcli)、已启用的 OpenClaw hook、用于公共 HTTPS 端点的 Tailscale。
向导设置(推荐)
openclaw webhooks gmail setup --account openclaw@gmail.com
这会写入 hooks.gmail 配置,启用 Gmail 预设,并使用 Tailscale Funnel 作为推送端点。
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
```
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
bash
gog gmail watch start \
--account openclaw@gmail.com \
--label INBOX \
--topic projects/<project-id>/topics/gog-gmail-watch
Gmail 模型覆盖
{
hooks: {
gmail: {
model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
thinking: "off",
},
},
}
管理作业
# List all jobs
openclaw cron list
# Get one stored job as JSON
openclaw cron get <jobId>
# Show one job, including resolved delivery route
openclaw cron show <jobId>
# 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
模型覆盖说明:
openclaw cron add|edit --model ...会更改作业选择的模型。- 如果模型被允许,该精确的提供商/模型会进入隔离智能体运行。
- 如果不被允许或无法解析,cron 会以显式验证错误让该运行失败。
- 已配置的兜底链仍然适用,因为 cron
--model是作业主模型,而不是会话/model覆盖。 - 载荷
fallbacks会替换该作业已配置的兜底;fallbacks: []会禁用兜底并使运行变为严格模式。 - 没有显式或已配置兜底列表的普通
--model不会静默落到智能体主模型作为额外重试目标。
配置
{
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 },
},
}
maxConcurrentRuns 同时限制定时 cron 调度和隔离智能体轮次执行。隔离 cron 智能体轮次在内部使用队列的专用 cron-nested 执行通道,因此提高该值会让独立的 cron LLM 运行并行推进,而不是只启动它们的外层 cron 包装器。共享的非 cron nested 通道不会被此设置拓宽。
运行时状态 sidecar 源自 cron.store:例如 ~/clawd/cron/jobs.json 这样的 .json 存储会使用 ~/clawd/cron/jobs-state.json,而没有 .json 后缀的存储路径会追加 -state.json。
如果你手动编辑 jobs.json,请不要将 jobs-state.json 纳入源代码控制。OpenClaw 使用该 sidecar 存放待处理槽位、活跃标记、上次运行元数据,以及告诉调度器外部编辑的作业何时需要新的 nextRunAtMs 的调度身份。
禁用 cron:cron.enabled: false 或 OPENCLAW_SKIP_CRON=1。
一次性重试:瞬时错误(速率限制、过载、网络、服务器错误)最多重试 3 次,并使用指数退避。永久错误会立即禁用。
**周期性重试**:重试之间使用指数退避(30 秒到 60 分钟)。退避会在下一次成功运行后重置。
cron.sessionRetention(默认 24h)会清理隔离运行会话条目。cron.runLog.maxBytes / cron.runLog.keepLines 会自动清理运行日志文件。
故障排除
命令阶梯
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.enabled 和 OPENCLAW_SKIP_CRON 环境变量。
- 确认 Gateway 网关持续运行。
- 对于 cron 调度,请核对时区(--tz)与主机时区。
- 运行输出中的 reason: not-due 表示使用 openclaw cron run <jobId> --due 检查了手动运行,并且该任务尚未到期。
- 投递模式 none 表示不会期望 runner 回退发送。当聊天路由可用时,智能体仍可直接使用 message 工具发送。
- 投递目标缺失/无效(channel/to)表示已跳过出站发送。
- 对于 Matrix,复制的或旧版任务如果包含小写的 delivery.to 房间 ID,可能会失败,因为 Matrix 房间 ID 区分大小写。将任务编辑为 Matrix 中精确的 !room:server 或 room:!room:server 值。
- 渠道认证错误(unauthorized、Forbidden)表示投递被凭证阻止。
- 如果隔离运行只返回静默令牌(NO_REPLY / no_reply),OpenClaw 会抑制直接出站投递,也会抑制回退排队摘要路径,因此不会向聊天回发任何内容。
- 如果智能体应自行给用户发消息,请检查任务是否有可用路由(channel: "last" 且存在之前的聊天,或显式的渠道/目标)。
- 每日重置和空闲重置的新鲜度不基于 updatedAt;参见会话管理。
- Cron 唤醒、Heartbeat 运行、exec 通知和 Gateway 网关记账可能会为路由/Status 更新会话行,但它们不会延长 sessionStartedAt 或 lastInteractionAt。
- 对于在这些字段存在之前创建的旧版行,如果文件仍可用,OpenClaw 可以从 transcript JSONL 会话头中恢复 sessionStartedAt。没有 lastInteractionAt 的旧版空闲行会使用该恢复的开始时间作为其空闲基线。
- 未设置 --tz 的 Cron 使用 Gateway 网关主机时区。
- 没有时区的 at 调度会按 UTC 处理。
- Heartbeat activeHours 使用已配置的时区解析。