OpenClaw automation delivery
Announce, webhook or none, how a current-session result is committed, the SSRF guard, target syntax, failure alerts and incidents, and pinning the output language
A job that ran perfectly and told no one is a job that did not run, as far as anyone can tell. OpenClaw’s delivery layer decides where a finished run sends its output, what counts as delivered, and how failures are reported without flooding the channel. Here are the three modes and the commit semantics for current-session jobs, the webhook guard, target syntax, the sharing rule between the agent’s own sends and the runner’s fallback, the failure-alert policy with its incidents and recovery notices, and the two rules that trip people, delivery failure versus execution failure and the reply language.
Modes and commits
- Announce fallback-delivers the final text to the target if the agent did not send it itself, webhook posts the finished event payload to a URL, and none performs no runner fallback; a successful primary webhook run with no non-blank summary skips the post and records an empty suppression reason, while execution errors still send the error event.
- With a public origin configured and the Control UI enabled, chat notifications carry an inspect link: command and script completions open the automation run, isolated agent announcements open the run’s session.
- For a current-session job the final assistant result is a first-class session completion: OpenClaw waits for active turns in the creation-bound conversation, verifies the same session generation still owns the key, and commits the result through the canonical transcript writer with job and run provenance and an idempotency key, so a retry cannot append it twice; WebChat receives the event immediately and the same result comes from history after a reconnect.
- If the bound conversation is an external channel, the normal durable send also happens, at most once, and a verified message-tool send suppresses the automatic resend but not the session commit; a conversation with no external route completes on the commit alone, and a route that cannot be resolved at run time leaves the result in the conversation and records a delivery error, not a turn failure.
Automation jobs do not infer a reply language from channel, locale, or previous messages.
Guards, targets, sharing
Every outbound automation webhook uses the strict SSRF guard: loopback, private, link-local and other special-use targets are refused by default for primary delivery, completion and failure destinations and failure-alert webhooks, and the only recommended exception is an exact hostname or IP entry in the webhook policy, with the private-network opt-in reserved for hosts where every configured webhook may reach trusted internal services. Targets follow channel syntax: a Telegram chat id with a topic suffix, Slack, Discord and Mattermost with channel or user prefixes, case-sensitive Matrix room ids. On hosts with several configured channels, isolated announce jobs must name a channel unless a provider-prefixed target or a preserved session route selects one, a best-effort flag accepts unresolved fallback delivery without failing the job, and a provider prefix must agree with an explicit channel so a Telegram id is never handed to WhatsApp as a phone number. Announcements retry transient failures only when nothing may have reached the recipient. For isolated jobs chat delivery is shared: with a chat route available the agent can use the message tool even with delivery disabled, and if it sends to the configured or current target the runner skips its fallback announce; a reminder created from an active chat stores that live target as its fallback route, implicit announce delivery validates and reroutes stale targets through channel allowlists, and DM pairing approvals are never fallback recipients.
Failure alerts
- Execution failures use one scheduler-owned policy: a job with an existing failure route is covered by default after two consecutive failures with a one-hour cooldown, repeated failures with the same cause form one incident that does not re-alert even after the cooldown or a restart, a changed cause or destination can alert again, and a later success sends one recovery notice and clears the incident; skipped runs and unknown outcomes do not establish recovery. Routes resolve from the job’s own alert object, then the job’s failure destination layered over the global policy, then the primary announce target, with per-job overrides for threshold, cooldown, channel, recipient, mode, account and whether skipped runs alert.
- A required completion-delivery failure is distinct from an execution failure: a run can record an ok execution status with a failed completion status, it does not increment the failure streak or backoff, it can alert through an alternate destination without waiting for the threshold, and repeated delivery failures form their own incident; chat notifications show normalised causes with the run start time in the user timezone, while raw commands, provider bodies and stack text stay in history. A provider rejecting an unsupported model records a model-not-found state that the doctor fix repairs by swapping to the provider’s declared successor when policy allows or clearing the override.
- The unconditional backstop: a time-based recurring job is auto-disabled after ten consecutive execution failures, repeated schedule-computation failures after three, the job records the reason, the owning agent gets a safe notification with the recovery command, and re-enabling clears the reason and streaks; disabled jobs are hidden from the default list, so use the all flag to find them.
OpenClaw automations is the guide this delivery layer belongs to, and OpenClaw hooks and webhooks the webhook side of the same outbound story.
Language and targets
Put the language rule in the scheduled message or template, for example to answer in Chinese while keeping URLs, code and product names unchanged, and verify template placeholders are filled before the job runs; mixed-language output means the rule was not explicit enough. OpenClaw on Telegram shows the topic target syntax in context, and OpenClaw streaming and chunking how a text-only Discord target receives the final text once rather than every streamed fragment.
On Diali
On Diali announce delivery to the channel you connected is the common case, failure alerts arrive on the same route after the second consecutive failure, and the reply language is whatever you write into the job’s message. Hosted OpenClaw on Diali is the assistant and Timezones in OpenClaw the zone the failure notices are timestamped in.
- Announce, webhook, none; empty summaries skip the post.
- Two failures, one hour, one incident, one recovery notice.
- Ten failures disable the job; say the language in the message.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
