MESSAGE_UNDELIVERED hook so operators can route the failure.
Off by default — existing deployments are unchanged until you opt in.
Quick Start
1
Turn the notice on
Set Start the gateway as usual — a permanently-undeliverable reply now sends a one-line notice and fires the hook.
notify_on_undelivered: true in the gateway: block of gateway.yaml.2
Customise the notice text
Add
undelivered_template to replace the built-in one-line note.How It Works
TheDeliveryRouter already parks a permanently-failed reply in the DLQ. With the flag on, it also best-effort sends a short notice on the same channel and fires the hook — both fully guarded so they can never mask the original failure.
A large or rich reply may fail while a one-line note still lands, so the notice is attempted even when the original send did not succeed. Whether the note reached the user is reported to the hook as notice_delivered.
Configuration Options
Both keys live under the top-levelgateway: block.
The built-in notice is
⚠️ Your request was processed but the reply couldn't be delivered. These knobs are read off the gateway config via getattr — the CLI path (start_with_config / from_config_file) stamps them from the validated gateway: block, so the opt-in actually reaches the router instead of silently defaulting to OFF.The MESSAGE_UNDELIVERED Hook
The hook fires the moment a reply is confirmed permanently undeliverable, so an operator can mirror, alert, or re-queue it without patching adapters.MessageUndeliveredInput payload fields:
Common Patterns
Mirror every undelivered reply to a home channel
Notice on, but no operator hook
Set onlynotify_on_undelivered when you just want the user to hear something and don’t yet handle the hook.
Best Practices
Keep it off unless silent loss is a problem
Keep it off unless silent loss is a problem
The default is OFF and byte-for-byte unchanged. Turn it on for user-facing bots where a silently dropped reply would confuse people.
Keep the template short
Keep the template short
The notice exists to slip through where a large/rich reply couldn’t. A one-line plain-text note is far more likely to land than the original.
Use the hook to re-queue, not to retry inline
Use the hook to re-queue, not to retry inline
The reply is already in the DLQ by the time the hook fires. Route it — mirror, alert, or re-queue — rather than assuming the notice guarantees delivery.
Check notice_delivered before you rely on it
Check notice_delivered before you rely on it
notice_delivered tells you whether even the one-line note reached the user. When it’s False, escalate through the operator channel.Related
Gateway Overview
Gateway configuration, channels, and multi-bot mode.
Inbound DLQ
Where permanently-failed messages are parked.
Dead Target Registry
Self-healing suppression of confirmed-dead targets.
Bot Lifecycle Hooks
All gateway/bot lifecycle hook events.

