定时任务 Automations:cron、提醒与 Webhook 触发
上一课的选型表把「让 Claw 在你没盯着的时候把事办了」拆成了几种机制;这一课把其中使用频率最高的 OpenClaw 定时任务(官方名 Automations) 拆开讲透。它是什么?一句话:OpenClaw 的内置调度器——任务持久化在共享 SQLite 状态库里,Gateway 到点唤醒 agent,结果可以投递到聊天渠道、webhook 端点,或者哪儿也不发。
命令行入口是 openclaw automations,openclaw cron 是同一组命令的别名——看到老教程写 openclaw cron 别慌,是同一个东西。全部示例基于 OpenClaw v2026.10.9。
学完你能做什么
- 用
--at建一次性提醒、用--cron/--every建循环任务,openclaw automations list里看得到,到点自动运行 - 把任务结果投递到你指定的聊天渠道(
--announce --channel --to)或 webhook 端点(--webhook) - 管理已建任务:查运行历史、临时禁用、改提示词、立即强制运行
- 打开入站 Webhook,让外部服务(CI、监控、脚本)通过 HTTP 主动唤醒 Claw
- 避开两个经典坑:cron 表达式日/星期的 OR 陷阱、三个互不相关的时区设置
你现在的困境
- 每天早上一睁眼,要自己翻十几个网站和群消息,才能拼出「昨晚发生了什么」
- 「下班前提醒我发周报」还是靠人脑记,AI 助手只在被问到时才有用,一走开就停摆
- 想让 CI 一跑完就让 AI 看一眼日志,但不知道怎么把外部事件「喂」给它
什么时候用这一招
当你需要:
- 固定节奏干活:每天早上 7 点汇总资讯、每周五提醒周报、每 15 分钟查一次队列深度
- 一次性提醒:20 分钟后提醒我、下周一早上叫我核对清单
- 外部事件触发:代码推送、构建完成、脚本跑完时唤醒 Claw 干活
而且不想:
- 自己搭 crontab + 脚本 + 通知管道那一整套
- 24 小时盯着聊天窗口等消息
💡 拿不准用哪个机制?
回到上一课的选型表:定时 = Automations(本课);精确一次性提醒 = Automations 的 --at;外部触发 = Webhooks(本课第 4 步);会话生命周期脚本 = Hooks;写进工作区的持久指令 = Standing Orders。见 高效工作流阶段导读。
🎒 开始前的准备
- 走完了 高效工作流阶段导读:Gateway 正在运行、至少连上一个模型(
/model status能报出当前模型) - 在 Gateway 所在机器上有终端权限——automations 命令需要正在运行的 Gateway,且所有变更操作(
add/create、edit、remove、run)需要operator.admin权限 - 想让结果发进飞书、企业微信、Telegram、Slack?先在 场景实战 接好至少一个渠道;不接也能学,用
--no-deliver或只看运行历史 - 一杯水 ☕——本课全是短命令,复制就能跑
核心思路
一个定时任务(job)= 调度(什么时候跑)+ 负载(跑什么)+ 投递(结果发到哪)。三个维度各有几个选项,先混个脸熟,下面逐步用:
五种调度(什么时候触发):
| 种类 | CLI 参数 | 含义 |
|---|---|---|
at | --at | 一次性时间点:ISO 8601 时间戳,或 20m 这样的相对时间 |
every | --every | 固定间隔:10m、1h、1d |
cron | --cron | 5/6 字段 cron 表达式,可配 --tz 时区 |
on-exit | --on-exit | 被监听的命令退出时触发一次 |
stream | --stream-command | 常驻命令的输出行攒成批次触发 |
四种负载(跑什么):
| 负载 | CLI 参数 | 含义 |
|---|---|---|
| 系统事件 | --system-event | 在 owning agent 主会话里触发一次普通回合(提醒类首选) |
| agent 消息 | --message | 一次完整的模型回合,让 Claw 真去干活 |
| 命令 | --command | 在 Gateway 主机上跑 shell 命令,不调模型 |
| 脚本 | --script | 无头 code-mode 脚本,能用 owning agent 的工具 |
四种执行会话(在哪跑):--session main(主会话,适合提醒)、isolated(每次全新会话,适合报告类循环任务)、current(绑定创建它的对话)、session:<id>(跨次积累上下文的持久会话)。
三种投递(结果去哪):--announce(发进聊天渠道)、--webhook(POST 到 HTTP 端点)、--no-deliver(不发,只留运行记录)。
💡 两个别名,别被绕晕
openclaw cron 是 openclaw automations 的别名;automations create 是 automations add 的别名。新任务支持位置参数写法:先调度、后提示词,比如 openclaw automations create "0 7 * * *" "Summarize overnight updates."。自然语言调度("every day at 9am")不支持,老实写 cron。
跟我做
第 1 步:建第一个 OpenClaw 定时任务(20 分钟后提醒你)
为什么:一次性提醒是最小的定时任务,30 秒能建好,用来确认整条链路(创建 → 存储 → 到点触发)是通的。
openclaw automations add \
--name "Calendar check" \
--at "20m" \
--session main \
--system-event "Check the calendar for upcoming events."各参数对号:--at "20m" 表示 20 分钟后跑一次(也可写 ISO 时间戳);--session main 在主会话触发;--system-event 是提醒内容。
你应该看到:命令执行成功,无报错。接着验证它存进去了:
openclaw automations list你应该看到:列表里出现名为 Calendar check 的任务和它的 job id——把这个 id 记下来,后面全用得上。
- 小检查:
openclaw automations list里能看到Calendar check
也可以直接写绝对时间。下面改自官方快速开始示例(只去掉了已废弃的 --wake now),--delete-after-run 表示成功跑完自动删掉任务,不留垃圾:
openclaw automations create "2027-02-01T16:00:00Z" \
--name "Reminder" \
--session main \
--system-event "Reminder: check the automations docs draft" \
--delete-after-run💡 网上老教程里的 --wake now 已经废弃
--wake now|next-heartbeat 这个参数如今只是「被接受但不做事」的兼容字段——任务到点会通过普通会话执行自动触发,不需要额外的 wake 步骤。定时行为完全由调度参数决定,见到它直接删掉即可。
第 2 步:建 cron 循环任务,把结果投递到聊天渠道
为什么:一次性提醒只能叫你一声;真正省时间的是「每天早上自动汇总并发给我」这类循环任务——cron 定节奏,投递参数决定结果落在哪。
openclaw automations create "0 7 * * *" \
"Summarize overnight updates. 用中文回复;链接、代码和产品名保持原样。" \
--name "Morning brief" \
--tz "Asia/Shanghai" \
--session isolated \
--announce \
--channel slack \
--to "channel:C1234567890"逐行拆开:
| 参数 | 作用 |
|---|---|
"0 7 * * *" | 位置参数一:cron 表达式,每天 07:00 |
"Summarize overnight updates. …" | 位置参数二:任务提示词。任务不会从渠道或历史消息推断回复语言,中文回复要写进提示词 |
--tz "Asia/Shanghai" | cron 求值时区。不写则用 Gateway 主机时区 |
--session isolated | 每次运行开全新会话,不污染主对话 |
--announce --channel slack --to "channel:C1234567890" | 结果投递到 Slack 频道。Slack/Discord/Mattermost 用 channel:<id>、user:<id> 前缀;Telegram 群用 -100… 开头的数字 id |
你应该看到:创建成功。add/create、list、show 都会预览解析后的投递路由——如果目的地解析不了,这里就会告诉你原因,不用等到第二天早上才发现没收到。
- 小检查:
openclaw automations show <job-id>能看到解析后的投递路由
三个补充说明:
- 目标格式因渠道而异:飞书、企业微信等国内 IM 的接入与目标写法见 场景实战(飞书接入、企业微信接入)。配置了多个渠道的主机上,isolated 任务必须给
--channel(除非--to带 provider 前缀或保留了会话路由)。 - 没接渠道也能学:CLI 建的 isolated 任务需要一个可解析的渠道路由、webhook 投递或
--no-deliver三者之一;练习时加--no-deliver,结果只进运行历史。 - 别让它轰炸聊天:定时检查类任务在提示词里约定「无事发生时只回
NO_REPLY」——整段最终回复是大写NO_REPLY时,投递会被静默跳过,执行记录照常写入历史。
想走 webhook 而不是聊天渠道?把投递参数换成 --webhook(它与 --announce/--channel/--to 互斥,不能同用):
openclaw automations create "0 18 * * 1-5" \
"Summarize today's deploys as JSON." \
--name "Deploy digest" \
--webhook "https://example.invalid/openclaw/cron"第 3 步:管理定时任务——运行历史、禁用与立即运行
为什么:任务建完不是一劳永逸——改提示词、临时停用、查「它到底跑没跑」,都是日常操作。全在 openclaw automations 一个命令族里:
openclaw automations list # 启用中的任务
openclaw automations list --all # 含已禁用的任务
openclaw automations get <job-id> # 单个任务的完整 JSON
openclaw automations show <job-id> # 单个任务 + 解析后的投递路由
openclaw automations runs <job-id> --limit 50 # 运行历史
openclaw automations edit <job-id> --message "Updated prompt" # 改提示词
openclaw automations disable <job-id> # 停用(不删除)
openclaw automations enable <job-id> # 重新启用
openclaw automations run <job-id> # 立即强制运行
openclaw automations remove <job-id> # 删除不想等 20 分钟验证第 1 步的提醒?强制运行立刻见效:
openclaw automations run <job-id>你应该看到:类似 { ok: true, enqueued: true, runId: "…" } 的输出——run 排入队列就返回,runId 用来查这一次的执行结果:
openclaw automations runs <job-id> --run-id <run-id>你应该看到:这条运行的记录,status 为 ok、error 或 skipped(payload 执行状态),外加整轮完成状态 completionStatus(succeeded / failed / unknown)。
- 小检查:
openclaw automations runs <job-id>里能看到刚才强制运行的记录
三个值得记住的行为:
- 手动运行不吃档期:强制
run不会消耗定时任务的下一个档期;被禁用的任务手动跑一次也不会自动恢复调度,要恢复用enable。 - 失败自动退避:循环任务连续出错按
30s → 1m → 5m → 15m → 60m退避重试,下次成功后归位;时间型循环任务连续失败 10 次会被自动禁用(用list --all找回,修好原因后enable)。 - 改模型用
--model:automations edit <job-id> --model "opus" --thinking high可给单个任务换模型/思考档位;模型不被允许时任务直接报验证错误,不会偷偷换回默认模型。
第 4 步:打开入站 Webhook,让外部服务唤醒 Claw
为什么:前三种触发都由时间驱动;「CI 一跑完就让 Claw 看日志」这种外部事件,要用方向相反的入站 Webhook——外部服务通过 HTTP 调 OpenClaw。它默认禁用,分三步打开。
1. 写进配置。把下面这段合并进 Gateway 配置文件(~/.openclaw/openclaw.json),token 换成一个长随机串——专用 token,不要复用 Gateway 认证 token 或密码;main 换成你要唤醒的 agent id:
{
hooks: {
enabled: true,
token: "<long-random-hook-token>",
path: "/hooks",
allowedAgentIds: ["main"],
allowRequestSessionKey: false,
},
}2. 校验并重启(Gateway 前台运行的话,重启那个前台进程):
openclaw config validate
openclaw gateway restart
openclaw logs --follow你应该看到:校验无报错,Gateway 重启后日志开始滚动。
3. 冒烟测试。另开一个终端,向本机 Gateway 发一条无害测试(token、agent id、端口按你的配置替换;默认端口 18789):
curl --include http://127.0.0.1:18789/hooks/agent \
-H 'Authorization: Bearer <long-random-hook-token>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: webhook-smoke-001' \
--data '{"message":"Summarize this test event: the sample import completed.","name":"Webhook smoke test","agentId":"main","deliver":false}'你应该看到:HTTP 200,响应体形如:
{ "ok": true, "runId": "<hook-request-run-id>" }在 openclaw logs --follow 里搜 hook agent run completed 和这个 runId,能看到执行结果。注意 200 只代表受理成功(拿到了会话执行名额),不代表模型跑完、工具成功或消息送达——本例 "deliver":false 就是故意不发消息。
- 小检查:curl 返回 200 和
runId,日志里能搜到hook agent run completed
三个端点,按需选用:
| 端点 | 作用 |
|---|---|
POST /hooks/wake | 向目标 agent 的主会话排一条受信通知(轻量「叫一声」) |
POST /hooks/agent | 提交一次完整 agent 回合(带 message,可指定模型/会话模式) |
POST /hooks/<name> | 经 hooks.mappings 映射的自定义路径,可把外部负载转成上面两种动作 |
认证规则:每个请求必须带 Authorization: Bearer <token>(推荐)或 x-openclaw-token: <token>;URL query 传 token 会被拒绝;所有端点只收 POST,正文用 Content-Type: application/json。
⚠️ Webhook 是暴露面,四条安全底线
- 端点留在 loopback、tailnet 或受信反向代理后面;远程调用用 HTTPS,只暴露需要的路径
- 用 hook 专用 token 和专用子路径(
/会被拒绝) - 收紧
hooks.allowedAgentIds,只放需要的 agent - 外部事件内容当数据看:agent hook 内容默认有安全包裹,但包裹不移除工具和 workspace 访问——不可信输入交给受限 agent 处理
检查点 ✅
openclaw automations list能看到你建的任务和 job id- 强制运行
openclaw automations run <job-id>返回了runId,runs里有这条记录 - 循环任务带了
--tz "Asia/Shanghai",list里的下次运行时间符合预期 - curl 冒烟测试返回 HTTP 200 和
runId,日志里搜到hook agent run completed - 能说出
0 9 15 * 1的真实含义(OR),并知道怎么改成 AND
踩坑提醒
❌ cron 日与星期同时写非通配,每月触发 5-6 次而不是 0-1 次
想表达「每月 15 号且是周一的 9 点」,写成:
# 想要:每月 15 号且是周一的 9 点
# 实际:每月 15 号的 9 点 + 每周一的 9 点,约每月 5-6 次
0 9 15 * 1原因:OpenClaw 用 croner 解析 cron,日(day-of-month)与星期(day-of-week)同为非通配时按标准 Vixie 行为取 OR,不是 AND。
正确做法:要 AND 用 + 前缀写星期——0 9 15 * +1;或者只用一个字段,把另一个条件写进任务提示词让 Claw 自己判断。
❌ 时间「对了」,时区不对
三套时区互不相关,最容易踩:
--at不带时区 → 按 UTC 解释(--at "2026-11-06T09:00:00"是北京时间 17 点)--cron不带--tz→ 按 Gateway 主机时区求值- 活动时段
--active-hours-*→ 有自己的--active-hours-timezone(user/local/ IANA),与 cron 的--tz独立
正确做法:国内部署最稳的习惯是 cron 一律显式 --tz "Asia/Shanghai";用 --at 时要么带时区偏移(+08:00),要么配 --tz。
❌ 任务到点没跑
按官方排错命令梯从上往下查:
openclaw status
openclaw gateway status
openclaw automations status
openclaw automations list
openclaw automations runs <job-id> --limit 20
openclaw automations show <job-id>
openclaw logs --follow
openclaw doctor常见原因对号:Gateway 没在持续运行;cron.enabled: false 或环境变量 OPENCLAW_SKIP_CRON=1 关了自动调度(两者都不挡手动 run);任务被自动禁用——list 默认不显示禁用任务,要 list --all 找回,修好原因后 enable;最后再核对 --tz 与主机时区是不是看错了。
❌ Webhook 返回 200,聊天里却没消息
200 只代表受理。排查顺序:
- 冒烟测试里
"deliver":false本来就故意不发消息,这是设计不是故障 - 想在同一个请求里拿到执行与投递结果:payload 加
"waitForCompletion": true,响应的completion里有status、delivered、deliverySuppressionReason - 渠道直投必须同时给
channel和to,只给一半会在派发前被400拒绝 - 日志里
status=ok却带deliveryError= 执行成功、投递失败,两者要分开看
进阶技巧(可选)
条件触发器:定时检查,有变化才唤醒。 给 every/cron/stream 调度挂一个 --trigger-script ./watch-pr-ci.js,脚本返回 { fire, message?, state? }——fire: false 就安静跳过,不发模型回合。状态上限 16 KB,单次评估 30 秒预算、最多 5 次工具调用。注意:强制 run 会绕过条件门直接执行;run --due 则尊重条件门。安全上要清楚:条件脚本默认带 owning agent 的完整工具策略(含 exec)无人值守运行,需要硬停时设 cron.triggers.enabled: false。实战拼装见 网页监控:页面一变就通知你。
/loop:聊天里一句话建循环。 owner-only 的 /loop [interval] <prompt> 在当前对话里建循环任务——/loop 5m check deploy status 固定节奏;不带间隔则自步调(1 分钟到 1 小时之间)。/loop status 查看、/loop stop [name] 停。命令细节见 聊天命令速成。
监控策略:别让后台任务半夜吵你。 给检查类任务加活动时段和让路开关:
openclaw automations add \
--name "Project monitor" \
--every 30m \
--session isolated \
--message "Check the job scratch for newly blocked work. Report changes that need attention; otherwise reply NO_REPLY." \
--active-hours-start 08:00 \
--active-hours-end 22:00 \
--active-hours-timezone user \
--idle-only \
--skip-if-scratch-empty \
--no-deliver--idle-only 让前台工作优先,--skip-if-scratch-empty 在任务便签明确为空时跳过模型回合。
定时任务 + 本地模型。 isolated 任务开跑前,调度器会先探测本地模型端点(Ollama 端点对应 /api/tags,vLLM / SGLang / LM Studio 等 OpenAI 兼容端点对应 /models)是否可达——探测只做 TCP 连通检查,不发 HTTP 请求。探测不到就把这次运行记为 skipped,等下个档期再试(结果按端点缓存 5 分钟,不会连环轰炸)。本地模型接入见 本地模型:Ollama、vLLM 与 ds4。
几个总开关。 cron.enabled: false 或 OPENCLAW_SKIP_CRON=1:停所有自动调度(手动 run 不受影响)。cron.skipMissedJobs: true:跳过 Gateway 停机期间错过的循环档期,避免重启后集中补跑一堆过期提醒(默认补跑;一次性 at 任务不受此开关影响)。启动环境变量 OPENCLAW_DISABLE_CRON_HOST_EXECUTION=1:硬禁命令/脚本负载、条件触发器、on-exit 和 Gateway 托管 stream——改启动环境后要重启 Gateway 才生效。
本课小结
✅ OpenClaw 定时任务 = 内置调度器 Automations:openclaw automations(openclaw cron 是别名),任务持久化在共享 SQLite 状态库,到点由 Gateway 唤醒。
✅ 一个任务三个维度:调度(--at / --every / --cron --tz / --on-exit / --stream-command)× 负载(--system-event / --message / --command / --script)× 投递(--announce --channel --to / --webhook / --no-deliver)。
✅ 执行会话四选一:main(提醒)、isolated(报告类,每次全新)、current(绑定创建对话)、session:<id>(跨次积累)。
✅ 入站 Webhook 默认禁用:hooks.enabled + 专用 token 打开;/hooks/wake、/hooks/agent、/hooks/<name> 三个端点,只收 POST + Bearer 认证,200 只代表受理。
✅ 两大经典坑:cron 日/星期同为非通配是 OR(AND 用 + 前缀);--at 无时区按 UTC、cron 无 --tz 用主机时区、活动时段另有时区——三套互不相关。
| 关键配置字段 | 推荐值 | 说明 |
|---|---|---|
--tz | "Asia/Shanghai"(国内) | cron 求值时区;也适用于无偏移的 --at 时间 |
--session | isolated(报告)/ main(提醒) | isolated 每次全新会话,不污染主对话 |
--announce --channel --to | 渠道 id + 目标 | Slack/Discord 用 channel:<id>;多渠道主机必给 --channel |
hooks.enabled / hooks.token | true / 长随机专用 token | 入站 Webhook 开关与认证,勿复用 Gateway 认证 |
cron.enabled | true | false 或 OPENCLAW_SKIP_CRON=1 停自动调度 |
cron.triggers.enabled | true(默认) | false 硬停条件脚本、脚本负载与 stream 调度 |
CLI 速查:openclaw automations list / get / show / runs / edit / enable / disable / run / remove,加 --help 看全量参数。完整命令表见 CLI 命令与配置速查。
下一课预告
定时任务解决「什么时候干」;下一课 浏览器控制:让 Claw 替你上网操作 给它一双上网的手,解决「拿什么干」——两课一拼,晨报和监控就是照抄的事。
你会学到:
web_search/x_search/web_fetch轻量三件套:搜资料、抓正文- 隔离的
openclaw托管浏览器:点按钮、填表单、截图,不碰你自己的浏览器 - 复用已登录 Chrome 会话的
userprofile - 组合拳预演:定时 + 上网 = 每日晨报、网页监控
相关教程
- 每日晨报:定时抓资讯发到你的 IM——本课 cron 循环 + 投递的直接应用
- 网页监控:页面一变就通知你——条件触发器的实战拼装
- GitHub 值班:PR 摘要与 issue 自动处理——入站 Webhook 唤醒 agent 的典型场景