docs(cron): document explicit per-channel delivery targets for all platforms (#54630)

The cron delivery table only showed Discord/Telegram with explicit
target syntax and described Slack and every other platform as
home-channel-only. In fact the generic platform:<target> routing in
_resolve_single_delivery_target resolves explicit targets for every
platform: Slack (#channel / channel ID / channel:thread_ts), Matrix
(room/user IDs), Feishu (chat:thread), WhatsApp (JID / E.164), Signal
(group / E.164), SMS, Email, and Weixin all have dedicated explicit-
target branches in _parse_target_ref; the remaining platforms accept a
generic platform:<chat_id> passthrough.

Update the Delivery Model table (en + zh-Hans) to show the real
per-platform syntax, document #channel name resolution via the channel
directory, and note the Slack thread_ts nuance. Docs-only.
This commit is contained in:
Ben Barclay 2026-06-29 15:23:16 +10:00 committed by GitHub
parent 388268ecde
commit e1f4098b9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 36 deletions

View file

@ -224,30 +224,38 @@ This mirrors the gateway's behavior — without it, cron agents would fail on ra
## Delivery Model
Cron job results can be delivered to any supported platform:
Cron job results can be delivered to any supported platform.
A bare platform name (`slack`, `telegram`, …) delivers to that platform's configured **home channel**. To target a **specific** destination instead, append a target after a colon: `platform:<target>`. The target is resolved at fire time (not when the job is created), so a job can name a destination on a platform that isn't connected yet and start delivering once it comes online.
Most platforms also accept an optional thread/topic as a third segment: `platform:<chat_id>:<thread_id>`.
| Target | Syntax | Example |
|--------|--------|---------|
| Origin chat | `origin` | Deliver to the chat where the job was created |
| Local file | `local` | Save to `~/.hermes/cron/output/` |
| Telegram | `telegram` or `telegram:<chat_id>` | `telegram:-1001234567890` |
| Discord | `discord` or `discord:#channel` | `discord:#engineering` |
| Slack | `slack` | Deliver to Slack home channel |
| WhatsApp | `whatsapp` | Deliver to WhatsApp home |
| Signal | `signal` | Deliver to Signal |
| Matrix | `matrix` | Deliver to Matrix home room |
| Mattermost | `mattermost` | Deliver to Mattermost home |
| Email | `email` | Deliver via email |
| SMS | `sms` | Deliver via SMS |
| Home Assistant | `homeassistant` | Deliver to HA conversation |
| DingTalk | `dingtalk` | Deliver to DingTalk |
| Feishu | `feishu` | Deliver to Feishu |
| WeCom | `wecom` | Deliver to WeCom |
| Weixin | `weixin` | Deliver to Weixin (WeChat) |
| BlueBubbles | `bluebubbles` | Deliver to iMessage via BlueBubbles |
| QQ Bot | `qqbot` | Deliver to QQ (Tencent) via Official API v2 |
| Telegram | `telegram`, `telegram:<chat_id>`, `telegram:<chat_id>:<thread_id>`, `telegram:@username` | `telegram:-1001234567890:17585` |
| Discord | `discord`, `discord:#channel`, `discord:<channel_id>`, `discord:<channel_id>:<thread_id>` | `discord:#engineering` |
| Slack | `slack`, `slack:#channel`, `slack:<channel_id>`, `slack:<channel_id>:<thread_ts>` | `slack:#engineering` |
| Matrix | `matrix`, `matrix:<!room_id:server>`, `matrix:<@user:server>` | `matrix:!abc123:example.org` |
| Feishu | `feishu`, `feishu:<chat_id>`, `feishu:<chat_id>:<thread_id>` | `feishu:oc_abc123def` |
| WhatsApp | `whatsapp`, `whatsapp:<jid>`, `whatsapp:+<E.164>` | `whatsapp:123456@g.us` |
| Signal | `signal`, `signal:group:<id>`, `signal:+<E.164>` | `signal:group:aBcD==` |
| SMS | `sms`, `sms:+<E.164>` | `sms:+<E.164 number>` |
| Email | `email`, `email:<address>` | `email:alerts@example.com` |
| Weixin | `weixin`, `weixin:<wxid>` | `weixin:wxid_abc123` |
| Mattermost | `mattermost` or `mattermost:<channel_id>` | Bare name delivers to Mattermost home |
| Home Assistant | `homeassistant` or `homeassistant:<conversation>` | Bare name delivers to HA conversation |
| DingTalk | `dingtalk` or `dingtalk:<chat_id>` | Bare name delivers to DingTalk |
| WeCom | `wecom` or `wecom:<chat_id>` | Bare name delivers to WeCom |
| BlueBubbles | `bluebubbles` or `bluebubbles:<chat_guid>` | Bare name delivers to iMessage via BlueBubbles |
| QQ Bot | `qqbot` or `qqbot:<chat_id>` | Bare name delivers to QQ (Tencent) via Official API v2 |
For Telegram topics, use the format `telegram:<chat_id>:<thread_id>` (e.g., `telegram:-1001234567890:17585`).
Platforms in the first group have explicit, validated target syntax — named channels (`#channel`), topics/threads, room/user IDs, group IDs, or phone numbers. The remaining platforms accept the generic `platform:<chat_id>` form (the value after the colon is used verbatim as the destination ID); a bare platform name always delivers to the home channel.
**Named channels** (`slack:#engineering`, `discord:#engineering`, or a friendly name like `slack:engineering`) are resolved against the channel directory the gateway builds from connected adapters, so the gateway must have discovered the channel for name resolution to succeed; raw IDs (`slack:C0123ABCD45`) always work.
For **Telegram topics**, use `telegram:<chat_id>:<thread_id>` (e.g., `telegram:-1001234567890:17585`). For **Slack threads**, the third segment is the parent message's `thread_ts` (e.g., `slack:C0123ABCD45:1700000000.000100`), so it only applies when replying under an existing message.
### Response Wrapping

View file

@ -159,30 +159,38 @@ import requests, json
## 投递模型
Cron 任务结果可投递到任何受支持的平台:
Cron 任务结果可投递到任何受支持的平台。
裸平台名(`slack``telegram` 等)会投递到该平台配置的**主频道**。若要投递到**特定**目标,请在冒号后追加目标:`platform:<target>`。目标在任务触发时解析(而非创建时),因此任务可以指定一个尚未连接的平台目标,待其上线后即开始投递。
大多数平台还支持以第三段指定可选的话题/线程:`platform:<chat_id>:<thread_id>`
| 目标 | 语法 | 示例 |
|--------|--------|---------|
| 来源聊天 | `origin` | 投递到创建该任务的聊天 |
| 本地文件 | `local` | 保存到 `~/.hermes/cron/output/` |
| Telegram | `telegram``telegram:<chat_id>` | `telegram:-1001234567890` |
| Discord | `discord``discord:#channel` | `discord:#engineering` |
| Slack | `slack` | 投递到 Slack 主频道 |
| WhatsApp | `whatsapp` | 投递到 WhatsApp 主会话 |
| Signal | `signal` | 投递到 Signal |
| Matrix | `matrix` | 投递到 Matrix 主房间 |
| Mattermost | `mattermost` | 投递到 Mattermost 主频道 |
| Email | `email` | 通过邮件投递 |
| SMS | `sms` | 通过短信投递 |
| Home Assistant | `homeassistant` | 投递到 HA 对话 |
| DingTalk | `dingtalk` | 投递到钉钉 |
| Feishu | `feishu` | 投递到飞书 |
| WeCom | `wecom` | 投递到企业微信 |
| Weixin | `weixin` | 投递到微信WeChat |
| BlueBubbles | `bluebubbles` | 通过 BlueBubbles 投递到 iMessage |
| QQ Bot | `qqbot` | 通过官方 API v2 投递到 QQ腾讯 |
| Telegram | `telegram``telegram:<chat_id>``telegram:<chat_id>:<thread_id>``telegram:@username` | `telegram:-1001234567890:17585` |
| Discord | `discord``discord:#channel``discord:<channel_id>``discord:<channel_id>:<thread_id>` | `discord:#engineering` |
| Slack | `slack``slack:#channel``slack:<channel_id>``slack:<channel_id>:<thread_ts>` | `slack:#engineering` |
| Matrix | `matrix``matrix:<!room_id:server>``matrix:<@user:server>` | `matrix:!abc123:example.org` |
| Feishu | `feishu``feishu:<chat_id>``feishu:<chat_id>:<thread_id>` | `feishu:oc_abc123def` |
| WhatsApp | `whatsapp``whatsapp:<jid>``whatsapp:+<E.164>` | `whatsapp:123456@g.us` |
| Signal | `signal``signal:group:<id>``signal:+<E.164>` | `signal:group:aBcD==` |
| SMS | `sms``sms:+<E.164>` | `sms:+<E.164 号码>` |
| Email | `email``email:<address>` | `email:alerts@example.com` |
| Weixin | `weixin``weixin:<wxid>` | `weixin:wxid_abc123` |
| Mattermost | `mattermost``mattermost:<channel_id>` | 裸名投递到 Mattermost 主频道 |
| Home Assistant | `homeassistant``homeassistant:<conversation>` | 裸名投递到 HA 对话 |
| DingTalk | `dingtalk``dingtalk:<chat_id>` | 裸名投递到钉钉 |
| WeCom | `wecom``wecom:<chat_id>` | 裸名投递到企业微信 |
| BlueBubbles | `bluebubbles` `bluebubbles:<chat_guid>` | 裸名通过 BlueBubbles 投递到 iMessage |
| QQ Bot | `qqbot` `qqbot:<chat_id>` | 裸名通过官方 API v2 投递到 QQ腾讯 |
对于 Telegram 话题,使用格式 `telegram:<chat_id>:<thread_id>`(例如 `telegram:-1001234567890:17585`)。
第一组平台具有显式、经校验的目标语法——具名频道(`#channel`)、话题/线程、房间/用户 ID、群组 ID 或电话号码。其余平台接受通用的 `platform:<chat_id>` 形式(冒号后的值原样用作目标 ID裸平台名始终投递到主频道。
**具名频道**`slack:#engineering``discord:#engineering`,或像 `slack:engineering` 这样的友好名称)会根据 gateway 从已连接适配器构建的频道目录进行解析,因此 gateway 必须已发现该频道,名称解析才能成功;原始 ID`slack:C0123ABCD45`)则始终可用。
对于 **Telegram 话题**,使用 `telegram:<chat_id>:<thread_id>`(例如 `telegram:-1001234567890:17585`)。对于 **Slack 线程**,第三段是父消息的 `thread_ts`(例如 `slack:C0123ABCD45:1700000000.000100`),因此仅在回复某条已有消息下方时适用。
### 响应包装