投递
已完成运行将输出发送到哪里、运行或投递失败时会发生什么,以及如何固定回复语言。属于 Automations 指南的一部分。
投递与输出¶
| 模式 | 发生的情况 |
|---|---|
announce |
如果代理未发送,则将最终文本回退投递到目标 |
webhook |
将完成事件负载 POST 到 URL |
none |
无 runner 回退投递 |
成功的主 webhook 运行如果没有非空摘要,会故意跳过 POST 并记录 deliverySuppressionReason: "empty",与 announce 投递的可选输出契约一致。即使没有摘要,执行错误仍会发送错误事件。
主 webhook 在收到 HTTP 2xx 确认后记录投递。HTTP 拒绝会记录 未投递。如果请求可能已到达接收方,但其响应丢失或超时,投递保持 未知;传输层不会重试该模糊发送。必需投递也会使完成状态保持未知,而尽力投递可以成功完成而不声称已投递。
当配置了 gateway.publicOrigin 且启用了 Control UI 时,聊天通知会包含一个指向 Control UI 的 Inspect 链接。命令和脚本完成通知会打开自动化运行;隔离代理通知会打开该运行的会话。
对于使用 announce(默认)的 current 作业,最终助手结果是一等会话完成,而不是 WebChat 特有的出站消息。OpenClaw 会等待创建绑定对话中的活动轮次,验证同一会话代际仍拥有该键,并通过规范转录写入器提交结果,附带 cron 作业/运行来源和作业/运行幂等键。重试不会将同一结果追加两次。
当前会话结果使用与频道通知相同的静默回复处理。内部控制令牌不会进入对话历史,抑制说明文字会保留其附加媒体。
如果运行在等待对话期间被取消,它会停止等待,而不会中断活动轮次或追加结果。
WebChat 会立即收到已提交的 session.message 事件。刷新或重连后,相同的助手结果来自 chat.history;无需后续用户消息。只有在该转录/事件提交成功后,投递才算成功。
如果绑定对话是外部频道,OpenClaw 还会执行其常规的持久频道发送。该发送仍然最多发生一次,且必需的会话提交不会创建第二条外部消息。已验证的 message 工具发送会抑制自动频道重发,但不会抑制会话提交。只有当外部接收方交接(如需要)和规范会话提交都成功后,运行才会被报告为已投递。
当绑定对话没有外部频道路由——WebChat/Control UI 对话,或未配置频道插件的网关——仅会话提交即可完成投递,运行成功且不会尝试外部发送。如果对话确实指定了一个在运行时无法解析的外部路由,已提交的结果会保留在对话中,运行会将解析失败记录为其投递错误:这是投递失败,而不是轮次失败。
对于当前代理轮次作业,配置无关的外部频道不会改变此行为。显式的投递频道、接收方、账户或线程仍使用常规频道解析。如果该解析失败,报告会保留在对话中,运行会记录投递错误,即使无法选择任何外部频道。
从 WebChat 创建当前会话代理轮次作业时,使用 delivery: { mode: "announce" }(或省略 delivery)。该工具不会将内部 WebChat 对话坐标复制到外部 announce 路由。不要设置 delivery.channel: "webchat";显式频道仍必须通过常规已配置频道验证。条件触发器使用相同的投递规则。
Warning
每个出站自动化 webhook 都使用严格 SSRF 防护。回环、 私有/内部、链路本地以及其他特殊用途目标默认会被拒绝,适用于 主投递、完成和失败目标以及失败告警 webhook。
仅通过精确的主机名或 IP 豁免允许你信任的接收方:
仅当每个已配置的自动化 webhook 都可能访问受信任的私有网络服务时,才在 webhookSsrfPolicy 下使用 dangerouslyAllowPrivateNetwork: true。保持策略未设置会维持严格行为。
使用 --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 区分大小写;请使用 Matrix 中精确的房间 ID 或 room:!room:server 形式。
在 Control UI 的 Automations 编辑器中进行 announce 投递时,选择一个频道,并在 高级 下选择显式的 账户 ID,即可在 收件人 字段中看到已配置的对话目标。选择目标会保留你选择的账户,并且不会推断主题。这些已配置的建议仅适用于主 announce 目标;失败告警路由仍然独立。你仍然可以输入不在建议中的目标。
在配置了多个频道的主机上,使用 automations add|create 创建或使用 automations edit 修改的隔离 announce 作业必须设置 --channel <channel-plugin-id>,除非带提供商前缀的 --to 或保留的会话路由选择了频道。仅当可接受未解析的回退投递时,才使用 --best-effort-deliver;它不会选择频道,且投递失败不会使作业失败。
Channel announcements retry transient failures only when no payload may have reached the recipient. A successful retry records delivery without retaining the earlier attempt's error, including with best-effort delivery. Partial or ambiguous sends are not replayed by the announcement retry loop.
When announce delivery uses channel: "last" or omits channel, a provider-prefixed target such as telegram:123 can select the channel before the scheduler falls back to session history or a single configured channel. Only prefixes advertised by the loaded plugin are provider selectors. If delivery.channel is explicit, the target prefix must name the same provider; channel: "whatsapp" with to: "telegram:123" is rejected instead of letting WhatsApp interpret the Telegram ID as a phone number. Target-kind and service prefixes (channel:<id>, user:<id>, imessage:<handle>, sms:<number>) stay channel-owned target syntax, not provider selectors.
For isolated jobs, chat delivery is shared: if a chat route is available, the agent can use the message tool even with --no-deliver. If the agent sends to the configured/current target, OpenClaw skips the fallback announce. Otherwise announce, webhook, and none only control what the runner does with the final reply after the agent turn.
Scheduled message actions use the Gateway that owns the live run. Keep the
job's account, channel, target, and configured delivery route, but do not supply
per-call gatewayUrl or gatewayToken fields. Ordinary and standalone message
calls can still use those fields. To recover an existing trusted job whose
prompt or template supplies them, edit only that prompt or template to remove
the two fields, then run the same job again. A Gateway action reports
Scheduled message actions require the active bound Gateway. Remove per-call
gatewayUrl and gatewayToken fields and retry. until those fields are removed;
without a scheduler-host binding it reports Scheduled message actions require
an active bound Gateway. Run the job on its owning Gateway instead of copying
connection fields into the prompt. The next send then uses the live binding,
including current cancellation and tool-policy withdrawal.
When an agent creates an isolated reminder from an active chat, OpenClaw stores the preserved live delivery target for the fallback announce route. Internal session keys may be lowercase; provider delivery targets are not reconstructed from those keys when current chat context is available.
Implicit announce delivery uses configured channel allowlists to validate and reroute stale targets. DM pairing-store approvals are not fallback automation recipients; set delivery.to or configure the channel allowFrom entry when a scheduled job should proactively send to a DM.
故障通知¶
故障警报 Webhook 在请求可能已到达接收方但其响应丢失时保持 未知。显式 HTTP 拒绝或可证明发生在发送之前的故障会记录为 未投递,并允许应用内回退通知。未知结果不会触发该回退。
执行故障使用由调度器拥有的单一阈值和冷却策略。具有现有故障路由的任务在连续 2 次失败后默认适用,冷却时间为 1 小时。该路由可以是已解析的故障目标或任务的主要公告目标。没有此类路由的任务保持静默,除非按任务或全局 failureAlert 对象显式启用该策略。
相同原因导致的重复故障构成一个事件,不会发送重复警报,即使冷却过期或 Gateway 重启。原因或目标变化后,冷却结束可以发送新警报。成功运行会清除事件及其冷却,而不发送通知,因此下一次故障可以再次警报;恢复在自动化历史中保持可见。跳过的运行和未知投递结果不会建立恢复。成功的静默触发检查可以恢复触发故障,但不能证明先前失败的负载已恢复。
启动恢复根据保存的运行结果协调事件,而不发送历史通知。保存的成功运行会清除旧事件,即使其任务状态更新被中断,因此后续再次发生时可以再次警报。
故障通知路由按以下顺序解析:
- 任务
failureAlert对象中的路由字段。 job.delivery.failureDestination,叠加在全局cron.failureAlert的目标字段(mode、channel、to、accountId)之上。cron.failureDestination块不会直接读取;openclaw doctor --fix会将其合并到全局对象中。-
任务的主要公告目标。
-
job.failureAlert: false会禁用该任务的执行故障和必需投递故障警报。自动禁用安全通知仍然有效。 - 全局
cron.failureAlert.enabled: false会禁用继承的通知。按任务的failureAlert对象会显式重新启用该任务;enabled: true显式启用全局策略。 - 按任务的
failureAlert对象或任何全局cron.failureAlert对象都会启用并调整策略,即使任务没有现有路由。 delivery.bestEffort: true会抑制继承的/默认的执行故障警报。显式的按任务failureAlert仍然具有权威性。delivery.failureDestination仅在sessionTarget="isolated"任务上受支持,除非主要投递模式为webhook。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。
在 Control UI 中,自定义失败告警会显示已存储的阈值、冷却时间和模式覆盖。被省略的通道会显示中性的 last 选项,而不会存储它。将阈值或冷却时间留空,或者为告警模式选择 继承全局设置,即可使用 Gateway 的常规全局和路由默认值。冷却时间接受具有毫秒精度的小数秒,包括表示无冷却的 0;例如,1.001 秒会保留 1001 毫秒。编辑其他任务字段或克隆任务会保留其告警策略,包括跳过运行设置。
必需的完成投递失败不同于执行失败:一次运行可以记录 status: "ok" 且 completionStatus: "failed"。它不会增加执行失败连续计数或退避。投递失败告警可以通过已解析的备用失败目标进行通知,而无需等待 failureAlert.after。重复的投递失败也会形成一个事件。针对已变化失败的告警,包括执行告警之后的首次投递失败,会遵循共享的任务/全局 failureAlert.cooldownMs(默认 1 小时);被抑制的告警仍会将投递失败保留在运行历史中。跳过的运行和静默触发检查不会清除投递事件或其冷却;成功完成则会清除。调度器永远不会重试告警中已经失败的主路由。
聊天失败通知包含运行开始时间,使用代理配置的用户时区。当配置了 gateway.publicOrigin 且启用了 Control UI 时,它们还会包含指向自动化运行的 Inspect 链接。Webhook 消息文本保持稳定;集成可以从结构化的 runAtMs 字段读取同一时刻,并自行构造链接。
聊天通知会显示已知命令和脚本失败的规范化失败原因或允许列表中的生产者事实。任意命令、路径、提供商正文、密钥、投递错误、跳过原因、诊断信息以及堆栈/错误文本仍保留在自动化历史中。失败 Webhook 会保留结构化原始错误,供诊断集成使用。
所有者会话修复¶
修复默认开启。升级会改变你在聊天中告警的自有自动化上看到的内容:连续失败中的首次失败告警会变成创建该任务所在会话中的修复请求,而告警作为回退。具有 failureAlert: false 的任务两者都不会收到。
当从会话创建的任务(它具有所有者会话)达到其执行失败告警阈值,且告警本应发送到聊天(announce 模式)时,OpenClaw 会向该所有者会话发送修复请求,而不是发送告警。请求会指明任务名称,并包含其计划、名称、负载和最后错误;名称、负载和错误会被标记为不可信数据。命令任务以及 on-exit 或 stream 计划仅限操作员使用,并像以前一样告警。
会话会将该请求作为普通代理回合处理,就好像它收到了一条消息:它在该会话的 session 中运行,使用其转录、工作区和工具策略,并且回复会发送到会话自身的路由,包括其线程或主题。心跳设置不适用。瞬时故障不会收到回复,它可以在工作区中修复的问题(例如任务所遵循的辅助脚本或说明文件)会附带一行说明进行修复,否则它会向你索要它确切需要的内容。请求不携带你的发送者身份,因此所有者专用工具(例如自动化控制)仍不可用;更改任务本身发生在你的回复回合中。
每个失败连续计数最多获得一个修复请求,即使其原因后来发生变化。当任务没有所有者会话,或者它不会再运行时(例如已用完重试的一次性任务),告警会像以前一样发送。如果任务在请求之后再次失败,你会收到正常的失败告警,并注明已请求修复;连续计数中后续的告警遵循常规冷却。成功运行会静默清除连续计数。
脚本设置会在执行开始前,在插件重新加载后刷新已退役的工具。如果该恢复失败,告警会说明工具无法刷新且脚本未运行,然后指向自动化历史和插件状态。无法运行的监视器没有关于其所监视系统的新证据。
提供商对不支持模型的拒绝会在任务状态和运行历史中记录 model_not_found。失败通知会指向 openclaw doctor --fix 以处理提供商声明的退役,或更改/移除自动化的模型覆盖。已知退役的自动化模型路由会在另一次推理请求之前失败。当代理的模型策略允许时,Doctor 会用提供商声明的继任者替换覆盖。如果没有声明的继任者,它会清除覆盖,使任务继承代理默认值。如果固定覆盖的继任者被禁止,Doctor 会保留该引用并报告所需的策略更改。仅缺少账户目录条目或发现故障不会授权迁移。
调度器还提供安全兜底。基于时间的周期性任务在连续 10 次执行失败后自动禁用;成功运行会重置该连续计数。一个例外:具有 delivery.mode: "none" 且没有活动失败告警策略的任务,永远不会因其代理自身的 AUTOMATION_FAILED 报告而自动禁用,因为它没有可通知的对象。这些运行仍会计入 consecutiveErrors 和错误退避,并且其运行时错误仍会自动禁用它。在终止失败时,更丰富的自动禁用通知会替换常规阈值告警。重复的计划计算失败会在 3 次错误后自动禁用。任务将 state.autoDisabled.reason 记录为 consecutive-failures 或 schedule-errors,拥有该任务的代理会收到包含安全原因和恢复命令的通知。原始错误保留在自动化历史中。修复原因后,运行 openclaw automations enable <jobId>;启用会清除记录的原因和失败连续计数。由于默认列表会隐藏已禁用的任务,请使用 openclaw automations list --all 检查它们。
输出语言¶
自动化任务不会根据渠道、区域设置或之前的消息推断回复语言。请在计划消息或模板中写明语言规则:
openclaw automations edit <jobId> \
--message "Summarize the updates. Respond in Chinese; keep URLs, code, and product names unchanged."
对于模板文件,请在渲染后的提示中保留语言指令,并在任务运行前验证诸如 {{language}} 之类的占位符已填写。如果输出混合了多种语言,请明确规则,例如:“叙述性文本使用中文,技术术语保留英文。”
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw