chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
5cb65bba36
commit
6a065927f0
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 设置 Slack 或调试 Slack 套接字/HTTP 模式
|
||||
summary: Slack 设置和运行时行为(Socket Mode + HTTP 请求 URL)
|
||||
summary: Slack 设置和运行时行为(Socket 模式 + HTTP 请求 URL)
|
||||
title: Slack
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T22:49:25Z"
|
||||
generated_at: "2026-05-04T07:02:43Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 2be45f03511a64373b1f4316c59800eeeef8baccb4c00454b49999258b2e546b
|
||||
source_hash: d4a91fc1ae5f1e03f714308be54e164ef204809e74efabed8dc75c3035c14228
|
||||
source_path: channels/slack.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
可通过 Slack 应用集成在私信和频道中用于生产环境。默认模式是 Socket Mode;也支持 HTTP Request URLs。
|
||||
通过 Slack 应用集成,已可用于生产环境中的私信和渠道。默认模式是 Socket Mode;也支持 HTTP 请求 URL。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
@ -21,8 +21,8 @@ x-i18n:
|
||||
<Card title="斜杠命令" icon="terminal" href="/zh-CN/tools/slash-commands">
|
||||
原生命令行为和命令目录。
|
||||
</Card>
|
||||
<Card title="频道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨频道诊断和修复手册。
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断和修复操作手册。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -32,12 +32,12 @@ x-i18n:
|
||||
<Tab title="Socket Mode(默认)">
|
||||
<Steps>
|
||||
<Step title="创建新的 Slack 应用">
|
||||
在 Slack 应用设置中按下 **[创建新应用](https://api.slack.com/apps/new)** 按钮:
|
||||
在 Slack 应用设置中点击 **[创建新应用](https://api.slack.com/apps/new)** 按钮:
|
||||
|
||||
- 选择 **from a manifest**,并为你的应用选择一个工作区
|
||||
- 粘贴下面的[示例清单](#manifest-and-scope-checklist),然后继续创建
|
||||
- 生成带有 `connections:write` 的 **App-Level Token**(`xapp-...`)
|
||||
- 安装应用,并复制显示的 **Bot Token**(`xoxb-...`)
|
||||
- 选择 **从清单创建**,并为你的应用选择一个工作区
|
||||
- 粘贴下方的 [示例清单](#manifest-and-scope-checklist),然后继续创建
|
||||
- 生成具有 `connections:write` 权限的 **应用级令牌**(`xapp-...`)
|
||||
- 安装应用,并复制显示的 **Bot 令牌**(`xoxb-...`)
|
||||
|
||||
</Step>
|
||||
|
||||
@ -64,7 +64,7 @@ openclaw config patch --file ./slack.socket.patch.json5 --dry-run
|
||||
openclaw config patch --file ./slack.socket.patch.json5
|
||||
```
|
||||
|
||||
Env 回退方式(仅默认账号):
|
||||
环境变量回退(仅默认账号):
|
||||
|
||||
```bash
|
||||
SLACK_APP_TOKEN=xapp-...
|
||||
@ -84,15 +84,15 @@ openclaw gateway
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="HTTP Request URLs">
|
||||
<Tab title="HTTP 请求 URL">
|
||||
<Steps>
|
||||
<Step title="创建新的 Slack 应用">
|
||||
在 Slack 应用设置中按下 **[创建新应用](https://api.slack.com/apps/new)** 按钮:
|
||||
在 Slack 应用设置中点击 **[创建新应用](https://api.slack.com/apps/new)** 按钮:
|
||||
|
||||
- 选择 **from a manifest**,并为你的应用选择一个工作区
|
||||
- 粘贴[示例清单](#manifest-and-scope-checklist),并在创建前更新 URL
|
||||
- 保存用于请求验证的 **Signing Secret**
|
||||
- 安装应用,并复制显示的 **Bot Token**(`xoxb-...`)
|
||||
- 选择 **从清单创建**,并为你的应用选择一个工作区
|
||||
- 粘贴 [示例清单](#manifest-and-scope-checklist),并在创建前更新 URL
|
||||
- 保存用于请求验证的 **签名密钥**
|
||||
- 安装应用,并复制显示的 **Bot 令牌**(`xoxb-...`)
|
||||
|
||||
</Step>
|
||||
|
||||
@ -121,9 +121,9 @@ openclaw config patch --file ./slack.http.patch.json5
|
||||
```
|
||||
|
||||
<Note>
|
||||
为多账号 HTTP 使用唯一的 webhook 路径
|
||||
为多账号 HTTP 使用唯一 webhook 路径
|
||||
|
||||
给每个账号分配不同的 `webhookPath`(默认 `/slack/events`),避免注册冲突。
|
||||
为每个账号指定不同的 `webhookPath`(默认 `/slack/events`),以避免注册冲突。
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
@ -142,7 +142,7 @@ openclaw gateway
|
||||
|
||||
## Socket Mode 传输调优
|
||||
|
||||
默认情况下,OpenClaw 会将 Socket Mode 的 Slack SDK 客户端 pong 超时设置为 15 秒。仅当你需要针对工作区或主机进行特定调优时,才覆盖传输设置:
|
||||
对于 Socket Mode,OpenClaw 默认将 Slack SDK 客户端 pong 超时设为 15 秒。仅在需要针对工作区或主机进行特定调优时,才覆盖传输设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -159,11 +159,11 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
仅对记录 Slack websocket pong/server-ping 超时,或运行在已知存在事件循环饥饿的主机上的 Socket Mode 工作区使用此项。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍是应用状态,不是传输活跃性信号。
|
||||
仅当 Socket Mode 工作区记录 Slack WebSocket pong/server-ping 超时,或运行在已知存在事件循环饥饿问题的主机上时,才使用此配置。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍然是应用状态,而不是传输存活信号。
|
||||
|
||||
## 清单和权限范围检查清单
|
||||
## 清单和作用域核对清单
|
||||
|
||||
基础 Slack 应用清单对 Socket Mode 和 HTTP Request URLs 相同。只有 `settings` 块(以及斜杠命令的 `url`)不同。
|
||||
Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只有 `settings` 块(以及斜杠命令的 `url`)不同。
|
||||
|
||||
基础清单(Socket Mode 默认):
|
||||
|
||||
@ -240,7 +240,7 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
对于 **HTTP Request URLs 模式**,将 `settings` 替换为 HTTP 变体,并为每个斜杠命令添加 `url`。需要公开 URL:
|
||||
对于 **HTTP 请求 URL 模式**,将 `settings` 替换为 HTTP 变体,并为每个斜杠命令添加 `url`。需要公共 URL:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -284,19 +284,19 @@ openclaw gateway
|
||||
|
||||
### 其他清单设置
|
||||
|
||||
展示扩展上述默认设置的不同功能。
|
||||
启用不同功能来扩展上述默认设置。
|
||||
|
||||
默认清单会启用 Slack App Home **Home** 标签,并订阅 `app_home_opened`。当工作区成员打开 Home 标签时,OpenClaw 会使用 `views.publish` 发布安全的默认 Home 视图;不会包含会话负载或私有配置。**Messages** 标签仍会为 Slack 私信启用。
|
||||
默认清单启用 Slack 应用首页的 **首页** 标签页,并订阅 `app_home_opened`。当工作区成员打开首页标签页时,OpenClaw 会通过 `views.publish` 发布一个安全的默认首页视图;其中不包含任何对话载荷或私有配置。**消息** 标签页仍为 Slack 私信启用。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="可选原生斜杠命令">
|
||||
<Accordion title="可选的原生斜杠命令">
|
||||
|
||||
可以使用多个[原生斜杠命令](#commands-and-slash-behavior)来替代单个已配置命令,但需注意:
|
||||
可以使用多个 [原生斜杠命令](#commands-and-slash-behavior),而不是单个已配置命令;但有一些细节:
|
||||
|
||||
- 使用 `/agentstatus` 而不是 `/status`,因为 `/status` 命令已被保留。
|
||||
- 请使用 `/agentstatus` 而不是 `/status`,因为 `/status` 命令已保留。
|
||||
- 一次最多只能提供 25 个斜杠命令。
|
||||
|
||||
将你现有的 `features.slash_commands` 部分替换为[可用命令](/zh-CN/tools/slash-commands#command-list)的一个子集:
|
||||
将现有的 `features.slash_commands` 部分替换为 [可用命令](/zh-CN/tools/slash-commands#command-list) 的一个子集:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Socket Mode(默认)">
|
||||
@ -422,8 +422,8 @@ openclaw gateway
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="HTTP Request URLs">
|
||||
使用与上方 Socket Mode 相同的 `slash_commands` 列表,并向每个条目添加 `"url": "https://gateway-host.example.com/slack/events"`。示例:
|
||||
<Tab title="HTTP 请求 URL">
|
||||
使用与上方 Socket Mode 相同的 `slash_commands` 列表,并为每个条目添加 `"url": "https://gateway-host.example.com/slack/events"`。示例:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -443,20 +443,20 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
在列表中的每个命令上重复该 `url` 值。
|
||||
对列表中的每个命令重复使用该 `url` 值。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="可选作者身份作用域(写操作)">
|
||||
如果你希望传出消息使用当前智能体身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` 机器人作用域。
|
||||
<Accordion title="可选作者身份作用域(写入操作)">
|
||||
如果你希望外发消息使用当前智能体身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` bot 作用域。
|
||||
|
||||
如果你使用表情图标,Slack 预期使用 `:emoji_name:` 语法。
|
||||
如果你使用表情图标,Slack 需要 `:emoji_name:` 语法。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="可选用户令牌作用域(读操作)">
|
||||
如果你配置了 `channels.slack.userToken`,典型的读取作用域包括:
|
||||
<Accordion title="可选用户令牌作用域(读取操作)">
|
||||
如果你配置了 `channels.slack.userToken`,典型读取作用域为:
|
||||
|
||||
- `channels:history`, `groups:history`, `im:history`, `mpim:history`
|
||||
- `channels:read`, `groups:read`, `im:read`, `mpim:read`
|
||||
@ -475,23 +475,23 @@ openclaw gateway
|
||||
- HTTP 模式需要 `botToken` + `signingSecret`。
|
||||
- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文
|
||||
字符串或 SecretRef 对象。
|
||||
- 配置令牌会覆盖环境变量回退值。
|
||||
- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` 环境变量回退仅适用于默认账号。
|
||||
- `userToken`(`xoxp-...`)仅能通过配置设置(没有环境变量回退),并且默认采用只读行为(`userTokenReadOnly: true`)。
|
||||
- 配置令牌会覆盖环境变量回退。
|
||||
- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` 环境变量回退仅适用于默认账户。
|
||||
- `userToken`(`xoxp-...`)只能通过配置提供(没有环境变量回退),并默认采用只读行为(`userTokenReadOnly: true`)。
|
||||
|
||||
Status 快照行为:
|
||||
|
||||
- Slack 账号检查会按凭证跟踪 `*Source` 和 `*Status`
|
||||
- Slack 账户检查会跟踪每个凭据的 `*Source` 和 `*Status`
|
||||
字段(`botToken`、`appToken`、`signingSecret`、`userToken`)。
|
||||
- Status 为 `available`、`configured_unavailable` 或 `missing`。
|
||||
- `configured_unavailable` 表示账号已通过 SecretRef
|
||||
或其他非内联密钥来源配置,但当前命令/运行时路径
|
||||
- `configured_unavailable` 表示账户通过 SecretRef
|
||||
或其他非内联密钥来源进行了配置,但当前命令/运行时路径
|
||||
无法解析实际值。
|
||||
- 在 HTTP 模式下会包含 `signingSecretStatus`;在 Socket Mode 下,
|
||||
所需组合是 `botTokenStatus` + `appTokenStatus`。
|
||||
- 在 HTTP 模式下,会包含 `signingSecretStatus`;在 Socket Mode 下,
|
||||
必需组合为 `botTokenStatus` + `appTokenStatus`。
|
||||
|
||||
<Tip>
|
||||
对于操作/目录读取,配置用户令牌后可以优先使用用户令牌。对于写入,仍优先使用机器人令牌;仅当 `userTokenReadOnly: false` 且机器人令牌不可用时,才允许用户令牌写入。
|
||||
对于操作/目录读取,配置后可以优先使用用户令牌。对于写入,仍优先使用 bot 令牌;只有当 `userTokenReadOnly: false` 且 bot 令牌不可用时,才允许用户令牌写入。
|
||||
</Tip>
|
||||
|
||||
## 操作和门控
|
||||
@ -500,7 +500,7 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
|
||||
当前 Slack 工具中可用的操作组:
|
||||
|
||||
| 组 | 默认值 |
|
||||
| 组 | 默认值 |
|
||||
| ---------- | ------- |
|
||||
| messages | 启用 |
|
||||
| reactions | 启用 |
|
||||
@ -508,13 +508,13 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
| memberInfo | 启用 |
|
||||
| emojiList | 启用 |
|
||||
|
||||
当前 Slack 消息操作包括 `send`、`upload-file`、`download-file`、`read`、`edit`、`delete`、`pin`、`unpin`、`list-pins`、`member-info` 和 `emoji-list`。`download-file` 接受入站文件占位符中显示的 Slack 文件 ID,并为图片返回图片预览,或为其他文件类型返回本地文件元数据。
|
||||
当前 Slack 消息操作包括 `send`、`upload-file`、`download-file`、`read`、`edit`、`delete`、`pin`、`unpin`、`list-pins`、`member-info` 和 `emoji-list`。`download-file` 接受入站文件占位符中显示的 Slack 文件 ID,并对图片返回图片预览,或对其他文件类型返回本地文件元数据。
|
||||
|
||||
## 访问控制和路由
|
||||
|
||||
<Tabs>
|
||||
<Tab title="私信策略">
|
||||
`channels.slack.dmPolicy` 控制私信访问。`channels.slack.allowFrom` 是规范的私信允许列表。
|
||||
`channels.slack.dmPolicy` 控制私信访问。`channels.slack.allowFrom` 是规范私信允许列表。
|
||||
|
||||
- `pairing`(默认)
|
||||
- `allowlist`
|
||||
@ -526,16 +526,16 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `dm.enabled`(默认 true)
|
||||
- `channels.slack.allowFrom`
|
||||
- `dm.allowFrom`(旧版)
|
||||
- `dm.groupEnabled`(群组私信默认 false)
|
||||
- `dm.groupEnabled`(群组私信默认为 false)
|
||||
- `dm.groupChannels`(可选 MPIM 允许列表)
|
||||
|
||||
多账号优先级:
|
||||
多账户优先级:
|
||||
|
||||
- `channels.slack.accounts.default.allowFrom` 仅适用于 `default` 账号。
|
||||
- 具名账号在自己的 `allowFrom` 未设置时继承 `channels.slack.allowFrom`。
|
||||
- 具名账号不会继承 `channels.slack.accounts.default.allowFrom`。
|
||||
- `channels.slack.accounts.default.allowFrom` 仅适用于 `default` 账户。
|
||||
- 命名账户在自己的 `allowFrom` 未设置时继承 `channels.slack.allowFrom`。
|
||||
- 命名账户不会继承 `channels.slack.accounts.default.allowFrom`。
|
||||
|
||||
旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom` 仍会为兼容性读取。`openclaw doctor --fix` 会在不改变访问权限的前提下,将它们迁移到 `dmPolicy` 和 `allowFrom`。
|
||||
为兼容性,旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom` 仍会读取。`openclaw doctor --fix` 会在不改变访问权限的情况下,将它们迁移到 `dmPolicy` 和 `allowFrom`。
|
||||
|
||||
私信中的配对使用 `openclaw pairing approve slack <code>`。
|
||||
|
||||
@ -548,22 +548,22 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `allowlist`
|
||||
- `disabled`
|
||||
|
||||
渠道允许列表位于 `channels.slack.channels` 下,并且配置键**必须使用稳定的 Slack 渠道 ID**(例如 `C12345678`)。
|
||||
渠道允许列表位于 `channels.slack.channels` 下,并且配置键名**必须使用稳定的 Slack 渠道 ID**(例如 `C12345678`)。
|
||||
|
||||
运行时注意事项:如果 `channels.slack` 完全缺失(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录警告(即使设置了 `channels.defaults.groupPolicy`)。
|
||||
运行时注意事项:如果完全缺少 `channels.slack`(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录一条警告(即使已设置 `channels.defaults.groupPolicy`)。
|
||||
|
||||
名称/ID 解析:
|
||||
|
||||
- 渠道允许列表条目和私信允许列表条目会在启动时解析,前提是令牌访问允许
|
||||
- 未解析的渠道名称条目会保留为已配置状态,但默认在路由中忽略
|
||||
- 入站授权和渠道路由默认优先使用 ID;直接用户名/别名匹配需要 `channels.slack.dangerouslyAllowNameMatching: true`
|
||||
- 当令牌访问允许时,渠道允许列表条目和私信允许列表条目会在启动时解析
|
||||
- 未解析的渠道名称条目会按配置保留,但默认会在路由时被忽略
|
||||
- 入站授权和渠道路由默认以 ID 优先;直接用户名/slug 匹配需要 `channels.slack.dangerouslyAllowNameMatching: true`
|
||||
|
||||
<Warning>
|
||||
基于名称的键(`#channel-name` 或 `channel-name`)在 `groupPolicy: "allowlist"` 下**不会**匹配。渠道查找默认优先使用 ID,因此基于名称的键永远无法成功路由,该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,后者不需要渠道键参与路由,因此基于名称的键看起来可以工作。
|
||||
在 `groupPolicy: "allowlist"` 下,基于名称的键(`#channel-name` 或 `channel-name`)**不会**匹配。渠道查找默认以 ID 优先,因此基于名称的键永远无法成功路由,并且该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,后者不需要渠道键即可路由,而基于名称的键看起来也能工作。
|
||||
|
||||
始终使用 Slack 渠道 ID 作为键。查找方式:在 Slack 中右键点击渠道 → **Copy link** — ID(`C...`)会出现在 URL 末尾。
|
||||
始终使用 Slack 渠道 ID 作为键。查找方式:在 Slack 中右键点击渠道 → **复制链接** — ID(`C...`)会显示在 URL 末尾。
|
||||
|
||||
正确:
|
||||
正确示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -578,7 +578,7 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
}
|
||||
```
|
||||
|
||||
错误(在 `groupPolicy: "allowlist"` 下会被静默阻止):
|
||||
不正确(在 `groupPolicy: "allowlist"` 下会被静默阻止):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -596,28 +596,28 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及和渠道用户">
|
||||
渠道消息默认受提及门控。
|
||||
<Tab title="Mentions and channel users">
|
||||
渠道消息默认需要提及才会处理。
|
||||
|
||||
提及来源:
|
||||
|
||||
- 显式应用提及(`<@botId>`)
|
||||
- 当机器人用户是 Slack 用户组成员时的 Slack 用户组提及(`<!subteam^S...>`);需要 `usergroups:read`
|
||||
- Slack 用户组提及(`<!subteam^S...>`),当机器人用户是该用户组成员时生效;需要 `usergroups:read`
|
||||
- 提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复机器人线程行为(当 `thread.requireExplicitMention` 为 `true` 时禁用)
|
||||
|
||||
按渠道控制项(`channels.slack.channels.<id>`;名称只能通过启动解析或 `dangerouslyAllowNameMatching` 使用):
|
||||
每个渠道的控制项(`channels.slack.channels.<id>`;名称仅通过启动解析或 `dangerouslyAllowNameMatching` 使用):
|
||||
|
||||
- `requireMention`
|
||||
- `users`(允许列表)
|
||||
- `allowBots`
|
||||
- `skills`
|
||||
- `systemPrompt`
|
||||
- `tools`, `toolsBySender`
|
||||
- `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:` 或 `"*"` 通配符
|
||||
(旧版无前缀键仍只映射到 `id:`)
|
||||
- `tools`、`toolsBySender`
|
||||
- `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:`,或 `"*"` 通配符
|
||||
(旧版无前缀键仍仅映射到 `id:`)
|
||||
|
||||
对渠道和私有渠道来说,`allowBots` 是保守的:只有当发送机器人被明确列在该房间的 `users` 允许列表中,或 `channels.slack.allowFrom` 中至少一个显式 Slack 所有者 ID 当前是房间成员时,才接受机器人发送的房间消息。通配符和显示名称所有者条目不满足所有者存在性要求。所有者存在性使用 Slack `conversations.members`;请确保应用具备对应房间类型的匹配读取作用域(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查询失败,OpenClaw 会丢弃机器人发送的房间消息。
|
||||
`allowBots` 对渠道和私有渠道采取保守策略:只有当发送消息的机器人被显式列入该房间的 `users` 允许列表,或来自 `channels.slack.allowFrom` 的至少一个显式 Slack 所有者 ID 当前是房间成员时,才会接受机器人发出的房间消息。通配符和显示名称所有者条目不满足所有者在场条件。所有者在场使用 Slack `conversations.members`;确保应用拥有匹配房间类型的读取范围(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查询失败,OpenClaw 会丢弃机器人发出的房间消息。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@ -625,18 +625,18 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
## 线程、会话和回复标签
|
||||
|
||||
- 私信路由为 `direct`;渠道路由为 `channel`;MPIM 路由为 `group`。
|
||||
- Slack 路由绑定接受原始对等方 ID,以及 `channel:C12345678`、`user:U12345678` 和 `<@U12345678>` 等 Slack 目标形式。
|
||||
- 使用默认 `session.dmScope=main` 时,Slack 私信会折叠到智能体主会话。
|
||||
- Slack 路由绑定接受原始对端 ID,以及 `channel:C12345678`、`user:U12345678` 和 `<@U12345678>` 等 Slack 目标形式。
|
||||
- 使用默认 `session.dmScope=main` 时,Slack 私信会合并到智能体主会话。
|
||||
- 渠道会话:`agent:<agentId>:slack:channel:<channelId>`。
|
||||
- 线程回复在适用时可以创建线程会话后缀(`:thread:<threadTs>`)。
|
||||
- 适用时,线程回复可以创建线程会话后缀(`:thread:<threadTs>`)。
|
||||
- `channels.slack.thread.historyScope` 默认值为 `thread`;`thread.inheritParent` 默认值为 `false`。
|
||||
- `channels.slack.thread.initialHistoryLimit` 控制新线程会话启动时获取多少条现有线程消息(默认 `20`;设置为 `0` 可禁用)。
|
||||
- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,抑制隐式线程提及,使机器人只响应线程内的显式 `@bot` 提及,即使机器人已经参与过该线程。没有此设置时,在机器人已参与线程中的回复会绕过 `requireMention` 门控。
|
||||
- `channels.slack.thread.initialHistoryLimit` 控制新线程会话启动时获取多少条现有线程消息(默认 `20`;设为 `0` 可禁用)。
|
||||
- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,抑制隐式线程提及,使机器人只响应线程内显式的 `@bot` 提及,即使机器人已经参与过该线程。否则,机器人已参与线程中的回复会绕过 `requireMention` 门控。
|
||||
|
||||
回复线程控制项:
|
||||
|
||||
- `channels.slack.replyToMode`: `off|first|all|batched`(默认 `off`)
|
||||
- `channels.slack.replyToModeByChatType`:按 `direct|group|channel` 设置
|
||||
- `channels.slack.replyToMode`:`off|first|all|batched`(默认 `off`)
|
||||
- `channels.slack.replyToModeByChatType`:按 `direct|group|channel` 分别设置
|
||||
- 直接聊天的旧版回退:`channels.slack.dm.replyToMode`
|
||||
|
||||
支持手动回复标签:
|
||||
@ -645,23 +645,23 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `[[reply_to:<id>]]`
|
||||
|
||||
<Note>
|
||||
`replyToMode="off"` 会禁用 Slack 中的**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这不同于 Telegram,在 Telegram 中,显式标签在 `"off"` 模式下仍会被遵循。Slack 线程会在渠道中隐藏消息,而 Telegram 回复会以内联形式保持可见。
|
||||
`replyToMode="off"` 会禁用 Slack 中的**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这与 Telegram 不同,Telegram 在 `"off"` 模式下仍会遵循显式标签。Slack 线程会将消息从渠道中隐藏,而 Telegram 回复会以内联形式保持可见。
|
||||
</Note>
|
||||
|
||||
## 确认回应
|
||||
## 确认反应
|
||||
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情。
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号。
|
||||
|
||||
解析顺序:
|
||||
|
||||
- `channels.slack.accounts.<accountId>.ackReaction`
|
||||
- `channels.slack.ackReaction`
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份表情回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
- 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
注意事项:
|
||||
|
||||
- Slack 预期使用短代码(例如 `"eyes"`)。
|
||||
- Slack 期望使用短代码(例如 `"eyes"`)。
|
||||
- 使用 `""` 可为 Slack 账号或全局禁用该反应。
|
||||
|
||||
## 文本流式传输
|
||||
@ -672,18 +672,37 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `partial`(默认):用最新的部分输出替换预览文本。
|
||||
- `block`:追加分块预览更新。
|
||||
- `progress`:生成时显示进度状态文本,然后发送最终文本。
|
||||
- `streaming.preview.toolProgress`:当草稿预览处于活动状态时,将工具/进度更新路由到同一个已编辑的预览消息中(默认值:`true`)。设置为 `false` 可保留单独的工具/进度消息。
|
||||
- `streaming.preview.toolProgress`:当草稿预览处于活动状态时,将工具/进度更新路由到同一条已编辑的预览消息中(默认:`true`)。设为 `false` 可保留单独的工具/进度消息。
|
||||
- `streaming.preview.commandText` / `streaming.progress.commandText`:设为 `status` 可隐藏原始命令/执行文本,同时保留紧凑的工具进度行(默认:`raw`)。
|
||||
|
||||
当 `channels.slack.streaming.mode` 为 `partial` 时,`channels.slack.streaming.nativeTransport` 控制 Slack 原生文本流式传输(默认值:`true`)。
|
||||
隐藏原始命令/执行文本,同时保留紧凑的进度行:
|
||||
|
||||
- 必须有可用的回复线程,才能显示原生文本流式传输和 Slack 助手线程状态。线程选择仍遵循 `replyToMode`。
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"slack": {
|
||||
"streaming": {
|
||||
"mode": "progress",
|
||||
"progress": {
|
||||
"toolProgress": true,
|
||||
"commandText": "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`channels.slack.streaming.nativeTransport` 在 `channels.slack.streaming.mode` 为 `partial` 时控制 Slack 原生文本流式传输(默认:`true`)。
|
||||
|
||||
- 必须有可用的回复线程,原生文本流式传输和 Slack 助手线程状态才会显示。线程选择仍遵循 `replyToMode`。
|
||||
- 当原生流式传输不可用或不存在回复线程时,渠道、群聊和顶层私信根仍可使用普通草稿预览。
|
||||
- 顶层 Slack 私信默认保持在线程之外,因此不会显示 Slack 的线程样式原生流/状态预览;OpenClaw 会改为在私信中发布并编辑草稿预览。
|
||||
- 顶层 Slack 私信默认保持在线程外,因此不会显示 Slack 线程样式的原生流/状态预览;OpenClaw 会改为在私信中发布并编辑草稿预览。
|
||||
- 媒体和非文本载荷会回退到普通投递。
|
||||
- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/块最终消息只有在能够就地编辑预览时才会刷新。
|
||||
- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/分块最终消息仅在可以就地编辑预览时刷新。
|
||||
- 如果流式传输在回复中途失败,OpenClaw 会对剩余载荷回退到普通投递。
|
||||
|
||||
使用草稿预览而不是 Slack 原生文本流式传输:
|
||||
使用草稿预览,而不是 Slack 原生文本流式传输:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -704,9 +723,9 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- 布尔值 `channels.slack.streaming` 会自动迁移到 `channels.slack.streaming.mode` 和 `channels.slack.streaming.nativeTransport`。
|
||||
- 旧版 `channels.slack.nativeStreaming` 会自动迁移到 `channels.slack.streaming.nativeTransport`。
|
||||
|
||||
## 输入状态反应回退
|
||||
## 输入反应回退
|
||||
|
||||
`typingReaction` 会在 OpenClaw 处理回复时,为入站 Slack 消息添加一个临时反应,并在运行完成后移除它。这在线程回复之外最有用,因为线程回复使用默认的 “is typing...” 状态指示器。
|
||||
`typingReaction` 会在 OpenClaw 处理回复期间,为入站 Slack 消息添加一个临时表情回应,并在运行结束时移除它。这在线程回复之外最有用;线程回复会使用默认的“正在输入...”状态指示器。
|
||||
|
||||
解析顺序:
|
||||
|
||||
@ -716,15 +735,15 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
注意事项:
|
||||
|
||||
- Slack 需要短代码(例如 `"hourglass_flowing_sand"`)。
|
||||
- 反应是尽力而为的;在回复或失败路径完成后,会自动尝试清理。
|
||||
- 该表情回应是尽力而为的,并且会在回复或失败路径完成后自动尝试清理。
|
||||
|
||||
## 媒体、分块和投递
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="入站附件">
|
||||
Slack 文件附件会从 Slack 托管的私有 URL 下载(基于令牌认证的请求流程),并在抓取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以用 `download-file` 获取原始文件。
|
||||
Slack 文件附件会从 Slack 托管的私有 URL 下载(令牌认证请求流),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以使用 `download-file` 获取原始文件。
|
||||
|
||||
下载使用有界的空闲超时和总超时。如果 Slack 文件检索停滞或失败,OpenClaw 会继续处理消息,并回退到文件占位符。
|
||||
下载使用有界空闲超时和总超时。如果 Slack 文件检索停滞或失败,OpenClaw 会继续处理消息,并回退到文件占位符。
|
||||
|
||||
运行时入站大小上限默认为 `20MB`,除非被 `channels.slack.mediaMaxMb` 覆盖。
|
||||
|
||||
@ -732,26 +751,26 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
|
||||
<Accordion title="出站文本和文件">
|
||||
- 文本分块使用 `channels.slack.textChunkLimit`(默认 4000)
|
||||
- `channels.slack.chunkMode="newline"` 启用段落优先拆分
|
||||
- `channels.slack.chunkMode="newline"` 启用优先按段落拆分
|
||||
- 文件发送使用 Slack 上传 API,并且可以包含线程回复(`thread_ts`)
|
||||
- 配置后,出站媒体上限遵循 `channels.slack.mediaMaxMb`;否则渠道发送会使用媒体管线中的 MIME 类型默认值
|
||||
- 配置后,出站媒体上限遵循 `channels.slack.mediaMaxMb`;否则渠道发送会使用媒体流水线中的 MIME 类型默认值
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="投递目标">
|
||||
首选的显式目标:
|
||||
首选显式目标:
|
||||
|
||||
- `user:<id>` 用于私信
|
||||
- `channel:<id>` 用于渠道
|
||||
|
||||
纯文本/分块的 Slack 私信可以直接发布到用户 ID;文件上传和线程发送会先通过 Slack 会话 API 打开私信,因为这些路径需要具体的会话 ID。
|
||||
仅文本/区块的 Slack 私信可以直接发布到用户 ID;文件上传和线程发送会先通过 Slack conversation API 打开私信,因为这些路径需要具体的 conversation ID。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 命令和斜杠行为
|
||||
|
||||
斜杠命令在 Slack 中表现为单个配置命令或多个原生命令。配置 `channels.slack.slashCommand` 以更改命令默认值:
|
||||
斜杠命令在 Slack 中可以表现为单个已配置命令,也可以表现为多个原生命令。配置 `channels.slack.slashCommand` 可更改命令默认值:
|
||||
|
||||
- `enabled: false`
|
||||
- `name: "openclaw"`
|
||||
@ -770,9 +789,9 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
/help
|
||||
```
|
||||
|
||||
原生参数菜单使用自适应渲染策略,在分派所选选项值之前显示确认模态框:
|
||||
原生参数菜单使用自适应渲染策略,会在分派所选选项值前显示确认模态框:
|
||||
|
||||
- 最多 5 个选项:按钮块
|
||||
- 最多 5 个选项:按钮区块
|
||||
- 6-100 个选项:静态选择菜单
|
||||
- 超过 100 个选项:当交互选项处理器可用时,使用带异步选项过滤的外部选择
|
||||
- 超出 Slack 限制:编码后的选项值回退为按钮
|
||||
@ -781,11 +800,11 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
/think
|
||||
```
|
||||
|
||||
斜杠会话使用 `agent:<agentId>:slack:slash:<userId>` 这样的隔离键,并且仍会使用 `CommandTargetSessionKey` 将命令执行路由到目标会话会话。
|
||||
斜杠会话使用类似 `agent:<agentId>:slack:slash:<userId>` 的隔离键,并且仍使用 `CommandTargetSessionKey` 将命令执行路由到目标 conversation 会话。
|
||||
|
||||
## 交互式回复
|
||||
|
||||
Slack 可以渲染智能体编写的交互式回复控件,但此功能默认禁用。
|
||||
Slack 可以渲染由智能体编写的交互式回复控件,但此功能默认禁用。
|
||||
|
||||
全局启用:
|
||||
|
||||
@ -819,30 +838,29 @@ Slack 可以渲染智能体编写的交互式回复控件,但此功能默认
|
||||
}
|
||||
```
|
||||
|
||||
启用后,智能体可以发出仅限 Slack 的回复指令:
|
||||
启用后,智能体可以发出仅适用于 Slack 的回复指令:
|
||||
|
||||
- `[[slack_buttons: Approve:approve, Reject:reject]]`
|
||||
- `[[slack_select: Choose a target | Canary:canary, Production:production]]`
|
||||
|
||||
这些指令会编译为 Slack Block Kit,并通过现有 Slack 交互事件路径把点击或选择路由回来。
|
||||
这些指令会编译为 Slack Block Kit,并通过现有 Slack 交互事件路径将点击或选择路由回来。
|
||||
|
||||
注意:
|
||||
注意事项:
|
||||
|
||||
- 这是 Slack 专用 UI。其他渠道不会把 Slack Block Kit 指令转换为自己的按钮系统。
|
||||
- 交互回调值是 OpenClaw 生成的不透明令牌,而不是智能体编写的原始值。
|
||||
- 如果生成的交互块会超过 Slack Block Kit 限制,OpenClaw 会回退为原始文本回复,而不是发送无效的 blocks 载荷。
|
||||
- 这是 Slack 专属 UI。其他渠道不会将 Slack Block Kit 指令转换为自己的按钮系统。
|
||||
- 交互式回调值是 OpenClaw 生成的不透明令牌,而不是智能体编写的原始值。
|
||||
- 如果生成的交互区块会超出 Slack Block Kit 限制,OpenClaw 会回退为原始文本回复,而不是发送无效的 blocks 载荷。
|
||||
|
||||
## Slack 中的 Exec 审批
|
||||
## Slack 中的执行审批
|
||||
|
||||
Slack 可以充当带有交互式按钮和交互的原生审批客户端,而不是回退到 Web UI 或终端。
|
||||
Slack 可以作为带有交互式按钮和交互的原生审批客户端,而不是回退到 Web 界面或终端。
|
||||
|
||||
- Exec 审批使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。
|
||||
- 当请求已经到达 Slack 且审批 id 类型为 `plugin:` 时,插件审批仍可通过同一 Slack 原生按钮界面完成。
|
||||
- 执行审批使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。
|
||||
- 当请求已经落在 Slack 中且审批 ID 类型为 `plugin:` 时,插件审批仍可以通过同一个 Slack 原生按钮界面解析。
|
||||
- 审批者授权仍会强制执行:只有被识别为审批者的用户才能通过 Slack 批准或拒绝请求。
|
||||
|
||||
这使用与其他渠道相同的共享审批按钮界面。当你的 Slack 应用设置中启用 `interactivity` 后,审批提示会直接在会话中渲染为 Block Kit 按钮。
|
||||
当这些按钮存在时,它们就是主要审批体验;OpenClaw
|
||||
只有在工具结果说明聊天审批不可用,或手动审批是唯一路径时,
|
||||
这使用与其他渠道相同的共享审批按钮界面。当你的 Slack 应用设置中启用 `interactivity` 时,审批提示会直接在 conversation 中渲染为 Block Kit 按钮。
|
||||
当这些按钮存在时,它们是主要审批体验;只有在工具结果表明聊天审批不可用或手动审批是唯一路径时,OpenClaw
|
||||
才应包含手动 `/approve` 命令。
|
||||
|
||||
配置路径:
|
||||
@ -852,10 +870,10 @@ Slack 可以充当带有交互式按钮和交互的原生审批客户端,而
|
||||
- `channels.slack.execApprovals.target`(`dm` | `channel` | `both`,默认:`dm`)
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
当 `enabled` 未设置或为 `"auto"` 且至少能解析出一个审批者时,Slack 会自动启用原生 Exec 审批。设置 `enabled: false` 可显式禁用 Slack 作为原生审批客户端。
|
||||
当能够解析审批者时,设置 `enabled: true` 可强制开启原生审批。
|
||||
当 `enabled` 未设置或为 `"auto"` 且至少解析出一个审批者时,Slack 会自动启用原生执行审批。设置 `enabled: false` 可明确禁用 Slack 作为原生审批客户端。
|
||||
设置 `enabled: true` 可在解析出审批者时强制启用原生审批。
|
||||
|
||||
没有显式 Slack Exec 审批配置时的默认行为:
|
||||
没有显式 Slack 执行审批配置时的默认行为:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -865,8 +883,7 @@ Slack 可以充当带有交互式按钮和交互的原生审批客户端,而
|
||||
}
|
||||
```
|
||||
|
||||
只有当你想覆盖审批者、添加过滤器,或
|
||||
选择启用来源聊天投递时,才需要显式 Slack 原生配置:
|
||||
只有在你想覆盖审批者、添加过滤器或选择启用来源聊天投递时,才需要显式 Slack 原生配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -882,34 +899,32 @@ Slack 可以充当带有交互式按钮和交互的原生审批客户端,而
|
||||
}
|
||||
```
|
||||
|
||||
共享 `approvals.exec` 转发是独立的。只有当 Exec 审批提示也必须
|
||||
路由到其他聊天或显式的带外目标时才使用它。共享 `approvals.plugin` 转发也是
|
||||
独立的;当这些请求已经到达 Slack 时,Slack 原生按钮仍然可以完成插件审批。
|
||||
共享 `approvals.exec` 转发是独立的。只有在执行审批提示还必须路由到其他聊天或显式带外目标时才使用它。共享 `approvals.plugin` 转发也是独立的;当这些请求已经落在 Slack 中时,Slack 原生按钮仍可以解析插件审批。
|
||||
|
||||
同一聊天中的 `/approve` 也适用于已经支持命令的 Slack 渠道和私信。完整的审批转发模型见 [Exec 审批](/zh-CN/tools/exec-approvals)。
|
||||
同一聊天中的 `/approve` 也适用于已支持命令的 Slack 渠道和私信。请参阅[执行审批](/zh-CN/tools/exec-approvals),了解完整的审批转发模型。
|
||||
|
||||
## 事件和运行行为
|
||||
|
||||
- 消息编辑/删除会映射为系统事件。
|
||||
- 线程广播(“同时发送到渠道”的线程回复)会作为普通用户消息处理。
|
||||
- 反应添加/移除事件会映射为系统事件。
|
||||
- 成员加入/离开、渠道创建/重命名,以及置顶添加/移除事件会映射为系统事件。
|
||||
- 启用 `configWrites` 后,`channel_id_changed` 可以迁移渠道配置键。
|
||||
- 渠道主题/用途元数据会被视为不受信任的上下文,并且可以注入到路由上下文中。
|
||||
- 线程发起者和初始线程历史上下文种子会在适用时按已配置的发送者允许列表过滤。
|
||||
- 块操作和模态框交互会发出带有丰富载荷字段的结构化 `Slack interaction: ...` 系统事件:
|
||||
- 块操作:选定值、标签、选择器值,以及 `workflow_*` 元数据
|
||||
- 模态框 `view_submission` 和 `view_closed` 事件,包含已路由的渠道元数据和表单输入
|
||||
- 表情回应添加/移除事件会映射为系统事件。
|
||||
- 成员加入/离开、渠道创建/重命名以及置顶添加/移除事件会映射为系统事件。
|
||||
- 启用 `configWrites` 时,`channel_id_changed` 可以迁移渠道配置键。
|
||||
- 渠道主题/用途元数据会被视为不受信任的上下文,并可注入到路由上下文中。
|
||||
- 线程起始消息和初始线程历史上下文种子填充会在适用时按已配置的发送者允许列表过滤。
|
||||
- 区块操作和模态交互会发出结构化的 `Slack interaction: ...` 系统事件,并带有丰富的载荷字段:
|
||||
- 区块操作:所选值、标签、选择器值以及 `workflow_*` 元数据
|
||||
- 模态 `view_submission` 和 `view_closed` 事件,包含已路由的渠道元数据和表单输入
|
||||
|
||||
## 配置参考
|
||||
|
||||
主要参考:[配置参考 - Slack](/zh-CN/gateway/config-channels#slack)。
|
||||
|
||||
<Accordion title="高信号 Slack 字段">
|
||||
<Accordion title="高价值 Slack 字段">
|
||||
|
||||
- 模式/认证:`mode`、`botToken`、`appToken`、`signingSecret`、`webhookPath`、`accounts.*`
|
||||
- 模式/身份验证:`mode`、`botToken`、`appToken`、`signingSecret`、`webhookPath`、`accounts.*`
|
||||
- 私信访问:`dm.enabled`、`dmPolicy`、`allowFrom`(旧版:`dm.policy`、`dm.allowFrom`)、`dm.groupEnabled`、`dm.groupChannels`
|
||||
- 兼容性开关:`dangerouslyAllowNameMatching`(紧急破窗;除非需要,否则保持关闭)
|
||||
- 兼容性开关:`dangerouslyAllowNameMatching`(应急;除非需要,否则保持关闭)
|
||||
- 渠道访问:`groupPolicy`、`channels.*`、`channels.*.users`、`channels.*.requireMention`
|
||||
- 线程/历史:`replyToMode`、`replyToModeByChatType`、`thread.*`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
- 投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`streaming`、`streaming.nativeTransport`、`streaming.preview.toolProgress`
|
||||
@ -924,11 +939,11 @@ Slack 可以充当带有交互式按钮和交互的原生审批客户端,而
|
||||
按顺序检查:
|
||||
|
||||
- `groupPolicy`
|
||||
- 渠道允许列表(`channels.slack.channels`)——**键必须是渠道 ID**(`C12345678`),而不是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为默认情况下渠道路由以 ID 优先。查找 ID:在 Slack 中右键点击渠道 → **Copy link**——URL 末尾的 `C...` 值就是渠道 ID。
|
||||
- 渠道允许列表(`channels.slack.channels`):**键必须是渠道 ID**(`C12345678`),而不是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为默认情况下渠道路由会优先使用 ID。要查找 ID:在 Slack 中右键点击渠道 → **复制链接**;URL 末尾的 `C...` 值就是渠道 ID。
|
||||
- `requireMention`
|
||||
- 每个渠道的 `users` 允许列表
|
||||
- 每渠道 `users` 允许列表
|
||||
|
||||
有用的命令:
|
||||
常用命令:
|
||||
|
||||
```bash
|
||||
openclaw channels status --probe
|
||||
@ -943,10 +958,10 @@ openclaw doctor
|
||||
|
||||
- `channels.slack.dm.enabled`
|
||||
- `channels.slack.dmPolicy`(或旧版 `channels.slack.dm.policy`)
|
||||
- 配对审批 / 允许列表条目
|
||||
- 配对审批/允许列表条目
|
||||
- Slack Assistant 私信事件:提到 `drop message_changed` 的详细日志
|
||||
通常表示 Slack 发送了编辑后的 Assistant 线程事件,但消息元数据中没有
|
||||
可恢复的人类发送者
|
||||
通常表示 Slack 发送了一个已编辑的 Assistant 线程事件,
|
||||
且消息元数据中没有可恢复的人类发送者
|
||||
|
||||
```bash
|
||||
openclaw pairing list slack
|
||||
@ -954,52 +969,52 @@ openclaw pairing list slack
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Socket 模式未连接">
|
||||
在 Slack 应用设置中验证 bot + app 令牌和 Socket Mode 启用状态。
|
||||
<Accordion title="Socket Mode 未连接">
|
||||
在 Slack 应用设置中验证机器人和应用令牌,以及 Socket Mode 启用状态。
|
||||
|
||||
如果 `openclaw channels status --probe --json` 显示 `botTokenStatus` 或
|
||||
`appTokenStatus: "configured_unavailable"`,说明 Slack 账户已配置,
|
||||
但当前运行时无法解析基于 SecretRef 的值。
|
||||
但当前运行时无法解析由 SecretRef 支持的值。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="HTTP 模式未收到事件">
|
||||
<Accordion title="HTTP 模式未接收事件">
|
||||
验证:
|
||||
|
||||
- 签名密钥
|
||||
- webhook 路径
|
||||
- Slack Request URL(Events + Interactivity + Slash Commands)
|
||||
- 每个 HTTP 账户使用唯一的 `webhookPath`
|
||||
- Slack 请求 URL(事件 + 交互性 + 斜杠命令)
|
||||
- 每个 HTTP 账户唯一的 `webhookPath`
|
||||
|
||||
如果账户快照中出现 `signingSecretStatus: "configured_unavailable"`,
|
||||
说明 HTTP 账户已配置,但当前运行时无法解析基于 SecretRef 的签名密钥。
|
||||
说明 HTTP 账户已配置,但当前运行时无法解析由 SecretRef 支持的签名密钥。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生/斜杠命令未触发">
|
||||
确认你的意图是:
|
||||
验证你的预期是:
|
||||
|
||||
- 原生命令模式(`channels.slack.commands.native: true`),并且 Slack 中注册了匹配的斜杠命令
|
||||
- 或单个斜杠命令模式(`channels.slack.slashCommand.enabled: true`)
|
||||
- 原生命令模式(`channels.slack.commands.native: true`),并在 Slack 中注册了匹配的斜杠命令
|
||||
- 或单斜杠命令模式(`channels.slack.slashCommand.enabled: true`)
|
||||
|
||||
也请检查 `commands.useAccessGroups` 和渠道/用户允许列表。
|
||||
另请检查 `commands.useAccessGroups` 和渠道/用户允许列表。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 附件视觉参考
|
||||
|
||||
当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体轮次中。图像文件可以通过媒体理解路径传递,或直接传递给具备视觉能力的回复模型;其他文件会保留为可下载的文件上下文,而不是作为图像输入处理。
|
||||
当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体回合。图像文件可以通过媒体理解路径传递,或直接传递给具备视觉能力的回复模型;其他文件会保留为可下载的文件上下文,而不是作为图像输入处理。
|
||||
|
||||
### 支持的媒体类型
|
||||
|
||||
| 媒体类型 | 来源 | 当前行为 | 备注 |
|
||||
| ------------------------------ | -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| JPEG / PNG / GIF / WebP 图像 | Slack 文件 URL | 下载并附加到该轮对话中,以便支持视觉的处理 | 单文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) |
|
||||
| PDF 文件 | Slack 文件 URL | 下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站不会自动将 PDF 转换为图像视觉输入 |
|
||||
| 其他文件 | Slack 文件 URL | 尽可能下载并作为文件上下文暴露 | 二进制文件不会被视为图像输入 |
|
||||
| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,根消息文件可以作为上下文补全 | 仅包含文件的起始消息会使用附件占位符 |
|
||||
| 多图像消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理限制为每条消息最多八个文件 |
|
||||
| 媒体类型 | 来源 | 当前行为 | 备注 |
|
||||
| ------------------------------ | -------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
| JPEG / PNG / GIF / WebP 图像 | Slack 文件 URL | 已下载并附加到该轮次,以便支持视觉的处理 | 单文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) |
|
||||
| PDF 文件 | Slack 文件 URL | 已下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站不会自动将 PDF 转换为图像视觉输入 |
|
||||
| 其他文件 | Slack 文件 URL | 可行时下载并作为文件上下文暴露 | 二进制文件不会被视为图像输入 |
|
||||
| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,根消息文件可以作为上下文补齐 | 仅包含文件的起始消息使用附件占位符 |
|
||||
| 多图像消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理限制为每条消息最多八个文件 |
|
||||
|
||||
### 入站流水线
|
||||
|
||||
@ -1007,48 +1022,48 @@ openclaw pairing list slack
|
||||
|
||||
1. OpenClaw 使用机器人令牌(`xoxb-...`)从 Slack 的私有 URL 下载文件。
|
||||
2. 下载成功后,文件会写入媒体存储。
|
||||
3. 下载的媒体路径和内容类型会添加到入站上下文中。
|
||||
3. 下载的媒体路径和内容类型会添加到入站上下文。
|
||||
4. 支持图像的模型/工具路径可以使用该上下文中的图像附件。
|
||||
5. 非图像文件仍会作为文件元数据或媒体引用提供给能够处理它们的工具。
|
||||
5. 非图像文件仍会作为文件元数据或媒体引用,供能够处理它们的工具使用。
|
||||
|
||||
### 线程根附件继承
|
||||
|
||||
当消息到达某个线程中时(具有 `thread_ts` 父级):
|
||||
当消息到达某个线程中(具有 `thread_ts` 父级)时:
|
||||
|
||||
- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件补全为线程起始上下文。
|
||||
- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件补齐为线程起始消息上下文。
|
||||
- 直接回复附件优先于根消息附件。
|
||||
- 仅包含文件且没有文本的根消息会用附件占位符表示,这样后备逻辑仍可包含其文件。
|
||||
- 只有文件且没有文本的根消息会用附件占位符表示,这样回退仍能包含其文件。
|
||||
|
||||
### 多附件处理
|
||||
|
||||
当单条 Slack 消息包含多个文件附件时:
|
||||
|
||||
- 每个附件都会通过媒体流水线独立处理。
|
||||
- 下载的媒体引用会聚合到消息上下文中。
|
||||
- 已下载的媒体引用会聚合到消息上下文中。
|
||||
- 处理顺序遵循事件载荷中的 Slack 文件顺序。
|
||||
- 一个附件下载失败不会阻塞其他附件。
|
||||
- 某个附件下载失败不会阻塞其他附件。
|
||||
|
||||
### 大小、下载和模型限制
|
||||
|
||||
- **大小上限**:默认每个文件 20 MB。可通过 `channels.slack.mediaMaxMb` 配置。
|
||||
- **下载失败**:Slack 无法提供的文件、过期 URL、不可访问文件、超大文件以及 Slack 认证/登录 HTML 响应会被跳过,而不是报告为不支持的格式。
|
||||
- **视觉模型**:图像分析会在当前回复模型支持视觉时使用它,否则使用 `agents.defaults.imageModel` 配置的图像模型。
|
||||
- **下载失败**:Slack 无法提供的文件、过期 URL、无法访问的文件、超大文件以及 Slack 凭证/登录 HTML 响应会被跳过,而不是报告为不支持的格式。
|
||||
- **视觉模型**:图像分析会使用支持视觉的当前回复模型,或使用在 `agents.defaults.imageModel` 配置的图像模型。
|
||||
|
||||
### 已知限制
|
||||
|
||||
| 场景 | 当前行为 | 解决方法 |
|
||||
| -------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| 过期的 Slack 文件 URL | 文件被跳过;不显示错误 | 在 Slack 中重新上传文件 |
|
||||
| 未配置视觉模型 | 图像附件会存储为媒体引用,但不会作为图像分析 | 配置 `agents.defaults.imageModel` 或使用支持视觉的回复模型 |
|
||||
| 非常大的图像(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,可增大 `channels.slack.mediaMaxMb` |
|
||||
| 转发/共享附件 | 文本以及 Slack 托管的图像/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 |
|
||||
| PDF 附件 | 存储为文件/媒体上下文,不会自动通过图像视觉路由 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具进行 PDF 分析 |
|
||||
| 场景 | 当前行为 | 解决方法 |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
|
||||
| 过期的 Slack 文件 URL | 文件被跳过;不会显示错误 | 在 Slack 中重新上传文件 |
|
||||
| 未配置视觉模型 | 图像附件会存储为媒体引用,但不会作为图像分析 | 配置 `agents.defaults.imageModel` 或使用支持视觉的回复模型 |
|
||||
| 非常大的图像(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,增大 `channels.slack.mediaMaxMb` |
|
||||
| 转发/共享的附件 | 文本以及由 Slack 托管的图像/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 |
|
||||
| PDF 附件 | 存储为文件/媒体上下文,不会自动通过图像视觉处理 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具分析 PDF |
|
||||
|
||||
### 相关文档
|
||||
|
||||
- [媒体理解流水线](/zh-CN/nodes/media-understanding)
|
||||
- [PDF 工具](/zh-CN/tools/pdf)
|
||||
- 史诗任务:[#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用
|
||||
- Epic:[#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用
|
||||
- 回归测试:[#51353](https://github.com/openclaw/openclaw/issues/51353)
|
||||
- 实时验证:[#51354](https://github.com/openclaw/openclaw/issues/51354)
|
||||
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 开发 Telegram 功能或网络钩子
|
||||
summary: Telegram 机器人支持状态、功能和配置
|
||||
summary: Telegram 机器人支持状态、能力和配置
|
||||
title: Telegram
|
||||
x-i18n:
|
||||
generated_at: "2026-05-04T06:12:14Z"
|
||||
generated_at: "2026-05-04T07:02:42Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c7f49db5f3fe8fd724e53a2ae3d226446f248bf9d021fcc01c1cf816649381d2
|
||||
source_hash: 6ef1b019a6a0e261b33972b5edffaedd29310b1333d112bade2e79e9d56887c6
|
||||
source_path: channels/telegram.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
生产级支持通过 grammY 处理机器人私信和群组。默认模式是长轮询;webhook 模式为可选。
|
||||
可用于 bot 私信和群组的生产就绪方案,基于 grammY。长轮询是默认模式;webhook 模式可选。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
@ -29,8 +29,8 @@ x-i18n:
|
||||
## 快速设置
|
||||
|
||||
<Steps>
|
||||
<Step title="在 BotFather 中创建机器人 token">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认句柄正是 `@BotFather`)。
|
||||
<Step title="在 BotFather 中创建 bot token">
|
||||
打开 Telegram,并与 **@BotFather** 聊天(确认句柄确实是 `@BotFather`)。
|
||||
|
||||
运行 `/newbot`,按提示操作,并保存 token。
|
||||
|
||||
@ -51,8 +51,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
环境变量后备:`TELEGRAM_BOT_TOKEN=...`(仅默认账号)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置或环境变量中配置 token,然后启动 Gateway 网关。
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账户)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置 token,然后启动 Gateway 网关。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -64,44 +64,44 @@ openclaw pairing list telegram
|
||||
openclaw pairing approve telegram <CODE>
|
||||
```
|
||||
|
||||
配对码会在 1 小时后过期。
|
||||
配对码在 1 小时后过期。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="将机器人添加到群组">
|
||||
将机器人添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy` 以匹配你的访问模型。
|
||||
<Step title="将 bot 添加到群组">
|
||||
将 bot 添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy`,使其与你的访问模型匹配。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
Token 解析顺序会感知账号。实践中,配置值优先于环境变量后备,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账号。
|
||||
token 解析顺序会感知账户。实际使用中,配置值优先于环境变量回退,且 `TELEGRAM_BOT_TOKEN` 只适用于默认账户。
|
||||
</Note>
|
||||
|
||||
## Telegram 端设置
|
||||
## Telegram 侧设置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私模式和群组可见性">
|
||||
Telegram 机器人默认使用**隐私模式**,这会限制它们接收的群组消息。
|
||||
Telegram bot 默认启用**隐私模式**,这会限制它们能接收哪些群组消息。
|
||||
|
||||
如果机器人必须看到所有群组消息,可以:
|
||||
如果 bot 必须看到所有群组消息,可以:
|
||||
|
||||
- 通过 `/setprivacy` 禁用隐私模式,或
|
||||
- 将机器人设为群组管理员。
|
||||
- 将 bot 设为群组管理员。
|
||||
|
||||
切换隐私模式时,请在每个群组中移除并重新添加机器人,以便 Telegram 应用更改。
|
||||
切换隐私模式时,请在每个群组中移除并重新添加 bot,以便 Telegram 应用该变更。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组权限">
|
||||
管理员状态在 Telegram 群组设置中控制。
|
||||
|
||||
管理员机器人会接收所有群组消息,这对常驻群组行为很有用。
|
||||
管理员 bot 会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="有用的 BotFather 开关">
|
||||
|
||||
- `/setjoingroups` 用于允许或拒绝添加到群组
|
||||
- `/setjoingroups` 用于允许/拒绝添加到群组
|
||||
- `/setprivacy` 用于群组可见性行为
|
||||
|
||||
</Accordion>
|
||||
@ -114,31 +114,31 @@ Token 解析顺序会感知账号。实践中,配置值优先于环境变量
|
||||
`channels.telegram.dmPolicy` 控制直接消息访问:
|
||||
|
||||
- `pairing`(默认)
|
||||
- `allowlist`(需要 `allowFrom` 中至少有一个发送者 ID)
|
||||
- `open`(需要 `allowFrom` 包含 `"*"`)
|
||||
- `allowlist`(要求 `allowFrom` 中至少有一个发送者 ID)
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到机器人用户名的 Telegram 账号都能指挥机器人。仅对有意公开且工具被严格限制的机器人使用它;单所有者机器人应使用带数字用户 ID 的 `allowlist`。
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到 bot 用户名的 Telegram 账户都能指挥这个 bot。仅在有意公开且工具受到严格限制的 bot 中使用;单所有者 bot 应使用 `allowlist` 并配置数字用户 ID。
|
||||
|
||||
`channels.telegram.allowFrom` 接受数字 Telegram 用户 ID。`telegram:` / `tg:` 前缀会被接受并规范化。
|
||||
在多账号配置中,限制性的顶层 `channels.telegram.allowFrom` 会被视为安全边界:账号级 `allowFrom: ["*"]` 条目不会让该账号公开,除非合并后的有效账号允许列表仍包含显式通配符。
|
||||
`dmPolicy: "allowlist"` 搭配空 `allowFrom` 会阻止所有私信,并会被配置校验拒绝。
|
||||
设置流程只会要求数字用户 ID。
|
||||
如果你已升级,且你的配置包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人 token)。
|
||||
如果你之前依赖配对存储允许列表文件,`openclaw doctor --fix` 可以在允许列表流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
在多账户配置中,限制性的顶层 `channels.telegram.allowFrom` 会被视为安全边界:账户级 `allowFrom: ["*"]` 条目不会让该账户公开,除非合并后的有效账户 allowlist 仍然包含显式通配符。
|
||||
`dmPolicy: "allowlist"` 搭配空 `allowFrom` 会阻止所有私信,并会被配置验证拒绝。
|
||||
设置只会要求提供数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` allowlist 条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram bot token)。
|
||||
如果你以前依赖配对存储 allowlist 文件,`openclaw doctor --fix` 可以在 allowlist 流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
|
||||
对单所有者机器人,优先使用 `dmPolicy: "allowlist"` 并配置显式数字 `allowFrom` ID,让访问策略在配置中保持持久(而不是依赖先前的配对批准)。
|
||||
对于单所有者 bot,优先使用 `dmPolicy: "allowlist"` 并配置显式数字 `allowFrom` ID,使访问策略持久保存在配置中(而不是依赖以前的配对批准)。
|
||||
|
||||
常见误解:私信配对批准并不意味着“这个发送者在所有地方都已获授权”。
|
||||
配对授予私信访问权限。如果尚无命令所有者,第一次获批配对还会设置 `commands.ownerAllowFrom`,让仅所有者命令和 exec 批准拥有显式操作员账号。
|
||||
群组发送者授权仍来自显式配置允许列表。
|
||||
如果你希望“我授权一次后,私信和群组命令都可用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
常见混淆:私信配对批准并不意味着“这个发送者在所有地方都已授权”。
|
||||
配对授予私信访问权限。如果尚不存在命令所有者,第一次批准的配对还会设置 `commands.ownerAllowFrom`,使仅所有者命令和执行批准拥有显式操作员账户。
|
||||
群组发送者授权仍来自显式配置 allowlist。
|
||||
如果你希望“我授权一次,私信和群组命令都可用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,请确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
|
||||
### 查找你的 Telegram 用户 ID
|
||||
|
||||
更安全(无需第三方机器人):
|
||||
更安全(无第三方 bot):
|
||||
|
||||
1. 给你的机器人发私信。
|
||||
1. 给你的 bot 发送私信。
|
||||
2. 运行 `openclaw logs --follow`。
|
||||
3. 读取 `from.id`。
|
||||
|
||||
@ -152,14 +152,14 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略和允许列表">
|
||||
两项控制会一起生效:
|
||||
<Tab title="群组策略和 allowlist">
|
||||
两个控制项会共同生效:
|
||||
|
||||
1. **允许哪些群组**(`channels.telegram.groups`)
|
||||
- 没有 `groups` 配置:
|
||||
- 使用 `groupPolicy: "open"`:任何群组都可以通过群组 ID 检查
|
||||
- 使用 `groupPolicy: "allowlist"`(默认):群组会被阻止,直到你添加 `groups` 条目(或 `"*"`)
|
||||
- 已配置 `groups`:作为允许列表(显式 ID 或 `"*"`)
|
||||
- 已配置 `groups`:作为 allowlist 生效(显式 ID 或 `"*"`)
|
||||
|
||||
2. **群组中允许哪些发送者**(`channels.telegram.groupPolicy`)
|
||||
- `open`
|
||||
@ -168,15 +168,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
`groupAllowFrom` 用于群组发送者过滤。如果未设置,Telegram 会回退到 `allowFrom`。
|
||||
`groupAllowFrom` 条目应为数字 Telegram 用户 ID(`telegram:` / `tg:` 前缀会被规范化)。
|
||||
不要把 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 属于 `channels.telegram.groups`。
|
||||
不要将 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 应放在 `channels.telegram.groups` 下。
|
||||
非数字条目会在发送者授权中被忽略。
|
||||
安全边界(`2026.2.25+`):群组发送者认证**不会**继承私信配对存储批准。
|
||||
配对仅适用于私信。对于群组,请设置 `groupAllowFrom` 或每群组/每话题的 `allowFrom`。
|
||||
安全边界(`2026.2.25+`):群组发送者身份验证**不会**继承私信配对存储批准。
|
||||
配对保持仅用于私信。对于群组,请设置 `groupAllowFrom` 或按群组/按话题设置 `allowFrom`。
|
||||
如果未设置 `groupAllowFrom`,Telegram 会回退到配置中的 `allowFrom`,而不是配对存储。
|
||||
单所有者机器人的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果完全缺少 `channels.telegram`,运行时会默认故障关闭为 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
单所有者 bot 的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时注意事项:如果完全缺少 `channels.telegram`,运行时默认会故障关闭为 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
|
||||
示例:允许一个特定群组中的任何成员:
|
||||
示例:允许某个特定群组中的任何成员:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -193,7 +193,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
示例:只允许一个特定群组中的特定用户:
|
||||
示例:仅允许某个特定群组内的特定用户:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -211,23 +211,23 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
```
|
||||
|
||||
<Warning>
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组允许列表。
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组 allowlist。
|
||||
|
||||
- 将类似 `-1001234567890` 的负数 Telegram 群组或超级群组聊天 ID 放在 `channels.telegram.groups` 下。
|
||||
- 当你想限制已允许群组中的哪些人可以触发机器人时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望已允许群组中的任何成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
- 当你想限制允许群组内哪些人可以触发 bot 时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望允许群组中的任何成员都能与 bot 对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及行为">
|
||||
群组回复默认需要提及。
|
||||
群组回复默认要求提及。
|
||||
|
||||
提及可以来自:
|
||||
|
||||
- 原生 `@botusername` 提及,或
|
||||
- 以下位置的提及模式:
|
||||
- 以下位置中的提及模式:
|
||||
- `agents.list[].groupChat.mentionPatterns`
|
||||
- `messages.groupChat.mentionPatterns`
|
||||
|
||||
@ -236,7 +236,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `/activation always`
|
||||
- `/activation mention`
|
||||
|
||||
这些只会更新会话状态。使用配置以实现持久化。
|
||||
这些只会更新会话状态。使用配置来持久化。
|
||||
|
||||
持久化配置示例:
|
||||
|
||||
@ -255,7 +255,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
获取群组聊天 ID:
|
||||
|
||||
- 将群组消息转发给 `@userinfobot` / `@getidsbot`
|
||||
- 或从 `openclaw logs --follow` 读取 `chat.id`
|
||||
- 或从 `openclaw logs --follow` 中读取 `chat.id`
|
||||
- 或检查 Bot API `getUpdates`
|
||||
|
||||
</Tab>
|
||||
@ -265,12 +265,12 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
- Telegram 由 Gateway 网关进程拥有。
|
||||
- 路由是确定性的:Telegram 入站会回复到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会规范化为共享渠道信封,并带有回复元数据和媒体占位符。
|
||||
- 入站消息会规范化为共享渠道信封,并包含回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会追加 `:topic:<threadId>` 以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会保留线程 ID 用于回复,但默认让私信保持在扁平会话上。当你有意希望进行私信话题会话隔离时,请配置 `channels.telegram.dm.threadReplies: "inbound"`、`channels.telegram.direct.<chatId>.threadReplies: "inbound"`、`requireTopic: true`,或匹配的话题配置。
|
||||
- 长轮询使用 grammY runner,并按聊天/按线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 长轮询在每个 Gateway 网关进程内部受保护,因此同一时间只有一个活动 poller 可以使用一个机器人 token。如果你仍看到 `getUpdates` 409 冲突,可能是另一个 OpenClaw Gateway 网关、脚本或外部 poller 正在使用同一个 token。
|
||||
- 默认情况下,如果 120 秒内没有完成的 `getUpdates` 存活信号,会触发长轮询 watchdog 重启。仅当你的部署在长时间运行工作期间仍出现误判的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会为回复保留线程 ID,但默认让私信保持扁平会话。当你确实想要私信话题会话隔离时,请配置 `channels.telegram.dm.threadReplies: "inbound"`、`channels.telegram.direct.<chatId>.threadReplies: "inbound"`、`requireTopic: true`,或匹配的话题配置。
|
||||
- 长轮询使用 grammY runner,并按聊天/线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 每个 Gateway 网关进程内部都会保护长轮询,因此同一时间只能有一个活跃轮询器使用一个 bot token。如果你仍然看到 `getUpdates` 409 冲突,很可能是另一个 OpenClaw Gateway 网关、脚本或外部轮询器正在使用同一个 token。
|
||||
- 长轮询看门狗默认会在 120 秒内没有完成 `getUpdates` 活性检查后触发重启。仅当你的部署在长时间运行工作期间仍然出现误判的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账户覆盖。
|
||||
- Telegram Bot API 不支持已读回执(`sendReadReceipts` 不适用)。
|
||||
|
||||
## 功能参考
|
||||
@ -285,11 +285,12 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
要求:
|
||||
|
||||
- `channels.telegram.streaming` 为 `off | partial | block | progress`(默认:`partial`)
|
||||
- `progress` 会保留一个可编辑的 Status 草稿,并用工具进度更新它,直到最终交付
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑预览消息(默认:预览流式传输启用时为 `true`)
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔 `streaming` 值;运行 `openclaw doctor --fix` 可将它们迁移到 `channels.telegram.streaming.mode`
|
||||
- `progress` 会保留一条可编辑的状态草稿,并用工具进度更新它,直到最终送达
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑的预览消息(默认:预览流式传输启用时为 `true`)
|
||||
- `streaming.preview.commandText` 控制这些工具进度行中的命令/执行细节:`raw`(默认,保留已发布行为)或 `status`(仅工具标签)
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔型 `streaming` 值;运行 `openclaw doctor --fix` 可将它们迁移到 `channels.telegram.streaming.mode`
|
||||
|
||||
工具进度预览更新是在工具运行时显示的简短 Status 行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持启用这些更新,以匹配 `v2026.4.22` 及之后发布的 OpenClaw 行为。若要保留答案文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
工具进度预览更新是在工具运行时显示的短状态行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持启用这些更新,以匹配 `v2026.4.22` 及更高版本中已发布的 OpenClaw 行为。若要为回答文本保留已编辑预览,但隐藏工具进度行,请设置:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -306,49 +307,84 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
使用 `streaming.mode: "off"` 只适用于你想要仅最终结果投递的场景:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立的 Status 消息发送。审批提示、媒体载荷和错误仍会通过正常的最终投递路径路由。当你只想保留回答预览编辑,同时隐藏工具进度 Status 行时,请使用 `streaming.preview.toolProgress: false`。
|
||||
若要保持工具进度可见但隐藏命令/执行文本,请设置:
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"streaming": {
|
||||
"mode": "partial",
|
||||
"preview": {
|
||||
"commandText": "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
对于进度草稿模式,请把相同的命令文本策略放在 `streaming.progress` 下:
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"streaming": {
|
||||
"mode": "progress",
|
||||
"progress": {
|
||||
"toolProgress": true,
|
||||
"commandText": "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
仅当你希望只交付最终消息时,才使用 `streaming.mode: "off"`:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立 Status 消息发送。审批提示、媒体载荷和错误仍会通过正常的最终交付路径路由。当你只想保留答案预览编辑,同时隐藏工具进度 Status 行时,请使用 `streaming.preview.toolProgress: false`。
|
||||
|
||||
<Note>
|
||||
Telegram 选定引用回复是例外。当 `replyToMode` 为 `"first"`、`"all"` 或 `"batched"`,且入站消息包含选定引用文本时,OpenClaw 会通过 Telegram 原生引用回复路径发送最终回答,而不是编辑回答预览,因此 `streaming.preview.toolProgress` 无法为该轮显示短 Status 行。没有选定引用文本的当前消息回复仍会保留预览流式传输。当工具进度可见性比原生引用回复更重要时,请设置 `replyToMode: "off"`;或者设置 `streaming.preview.toolProgress: false` 来确认这一取舍。
|
||||
Telegram 选中文本引用回复是例外。当 `replyToMode` 为 `"first"`、`"all"` 或 `"batched"`,且入站消息包含选中的引用文本时,OpenClaw 会通过 Telegram 原生引用回复路径发送最终答案,而不是编辑答案预览,因此 `streaming.preview.toolProgress` 无法为该轮显示简短 Status 行。没有选中文本引用的当前消息回复仍会保留预览流式传输。当工具进度可见性比原生引用回复更重要时,请设置 `replyToMode: "off"`;或者设置 `streaming.preview.toolProgress: false` 以确认接受该权衡。
|
||||
</Note>
|
||||
|
||||
对于纯文本回复:
|
||||
|
||||
- 简短私信/群组/话题预览:OpenClaw 会保留同一条预览消息并在原处执行最终编辑,除非预览出现后发送过可见的非预览消息
|
||||
- 预览后跟随可见的非预览输出:OpenClaw 会把完成后的回复作为新的最终消息发送,并清理较早的预览,因此最终回答会出现在中间输出之后
|
||||
- 简短私信/群组/topic 预览:OpenClaw 会保留同一条预览消息,并在原位置执行最终编辑,除非预览出现后发送过一条可见的非预览消息
|
||||
- 预览后跟随可见非预览输出:OpenClaw 会把完成后的回复作为新的最终消息发送,并清理较早的预览,因此最终答案会出现在中间输出之后
|
||||
- 超过约一分钟的预览:OpenClaw 会把完成后的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳会反映完成时间,而不是预览创建时间
|
||||
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到正常最终投递,然后清理预览消息。
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到正常的最终交付,然后清理预览消息。
|
||||
|
||||
预览流式传输与分块流式传输是分开的。当为 Telegram 明确启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
预览流式传输独立于分块流式传输。当 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
|
||||
仅限 Telegram 的推理流:
|
||||
|
||||
- `/reasoning stream` 会在生成期间将推理发送到实时预览
|
||||
- 推理预览会在最终投递后删除;当推理应保持可见时,请使用 `/reasoning on`
|
||||
- 最终回答发送时不包含推理文本
|
||||
- `/reasoning stream` 会在生成期间把推理发送到实时预览
|
||||
- 推理预览会在最终交付后删除;当推理应保持可见时,请使用 `/reasoning on`
|
||||
- 最终答案会在不包含推理文本的情况下发送
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Formatting and HTML fallback">
|
||||
<Accordion title="格式化和 HTML 回退">
|
||||
出站文本使用 Telegram `parse_mode: "HTML"`。
|
||||
|
||||
- 类 Markdown 文本会渲染为 Telegram 安全的 HTML。
|
||||
- 原始模型 HTML 会被转义,以减少 Telegram 解析失败。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会按纯文本重试。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会以纯文本重试。
|
||||
|
||||
链接预览默认启用,可使用 `channels.telegram.linkPreview: false` 禁用。
|
||||
链接预览默认启用,可通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Native commands and custom commands">
|
||||
<Accordion title="原生命令和自定义命令">
|
||||
Telegram 命令菜单注册会在启动时通过 `setMyCommands` 处理。
|
||||
|
||||
原生命令默认值:
|
||||
|
||||
- `commands.native: "auto"` 会为 Telegram 启用原生命令
|
||||
|
||||
添加自定义命令菜单项:
|
||||
添加自定义命令菜单条目:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -365,24 +401,24 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
规则:
|
||||
|
||||
- 名称会被规范化(去掉开头的 `/`,转为小写)
|
||||
- 名称会被规范化(移除开头的 `/`,转为小写)
|
||||
- 有效模式:`a-z`、`0-9`、`_`,长度 `1..32`
|
||||
- 自定义命令不能覆盖原生命令
|
||||
- 冲突/重复项会被跳过并记录日志
|
||||
|
||||
说明:
|
||||
|
||||
- 自定义命令只是菜单项;它们不会自动实现行为
|
||||
- 插件/Skills 命令即使未显示在 Telegram 菜单中,输入时仍可生效
|
||||
- 自定义命令只是菜单条目;它们不会自动实现行为
|
||||
- 插件/skill 命令即使未显示在 Telegram 菜单中,在输入时仍可工作
|
||||
|
||||
如果原生命令被禁用,内置命令会被移除。自定义/插件命令在已配置时仍可能注册。
|
||||
如果禁用原生命令,内置命令会被移除。自定义/插件命令在配置后仍可注册。
|
||||
|
||||
常见设置失败:
|
||||
|
||||
- `setMyCommands failed` 搭配 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;请减少插件/Skills/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接 Bot API curl 命令可用,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 因 `404: Not Found` 失败时,可能表示 `channels.telegram.apiRoot` 被设置成完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根路径,`openclaw doctor --fix` 会移除意外尾随的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了配置的机器人 token。请用当前 BotFather token 更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 搭配网络/fetch 错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
- `setMyCommands failed` 带有 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;请减少插件/skill/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接 Bot API curl 命令可以工作,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 失败并显示 `404: Not Found` 时,可能表示 `channels.telegram.apiRoot` 被设置为完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根地址,并且 `openclaw doctor --fix` 会移除意外尾随的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了已配置的 bot 令牌。请使用当前 BotFather 令牌更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 带有网络/fetch 错误,通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
|
||||
### 设备配对命令(`device-pair` 插件)
|
||||
|
||||
@ -392,19 +428,19 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
2. 在 iOS 应用中粘贴代码
|
||||
3. `/pair pending` 列出待处理请求(包括角色/作用域)
|
||||
4. 批准请求:
|
||||
- `/pair approve <requestId>` 用于显式批准
|
||||
- `/pair approve` 用于只有一个待处理请求的情况
|
||||
- `/pair approve <requestId>` 用于明确批准
|
||||
- 只有一个待处理请求时使用 `/pair approve`
|
||||
- `/pair approve latest` 用于最近的请求
|
||||
|
||||
设置代码携带一个短期有效的 bootstrap token。内置 bootstrap 交接会将主节点 token 保持在 `scopes: []`;任何被交接的 operator token 都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write`。Bootstrap 作用域检查带有角色前缀,因此该 operator 允许列表只满足 operator 请求;非 operator 角色仍需要其自身角色前缀下的作用域。
|
||||
设置代码携带一个短生命周期的 bootstrap 令牌。内置 bootstrap 移交会把主节点令牌保留在 `scopes: []`;任何移交的操作员令牌都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write` 内。Bootstrap 作用域检查带有角色前缀,因此该操作员允许列表只满足操作员请求;非操作员角色仍需要其自身角色前缀下的作用域。
|
||||
|
||||
如果设备使用已更改的认证详情(例如角色/作用域/公钥)重试,先前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
如果设备使用变更后的认证详情(例如角色/作用域/公钥)重试,之前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
|
||||
更多详情:[配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inline buttons">
|
||||
<Accordion title="内联按钮">
|
||||
配置内联键盘作用域:
|
||||
|
||||
```json5
|
||||
@ -445,7 +481,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `all`
|
||||
- `allowlist`(默认)
|
||||
|
||||
旧版 `capabilities: ["inlineButtons"]` 会映射到 `inlineButtons: "all"`。
|
||||
旧版 `capabilities: ["inlineButtons"]` 映射到 `inlineButtons: "all"`。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -470,16 +506,16 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram message actions for agents and automation">
|
||||
<Accordion title="面向智能体和自动化的 Telegram 消息操作">
|
||||
Telegram 工具操作包括:
|
||||
|
||||
- `sendMessage`(`to`、`content`、可选 `mediaUrl`、`replyToMessageId`、`messageThreadId`)
|
||||
- `sendMessage`(`to`、`content`,可选 `mediaUrl`、`replyToMessageId`、`messageThreadId`)
|
||||
- `react`(`chatId`、`messageId`、`emoji`)
|
||||
- `deleteMessage`(`chatId`、`messageId`)
|
||||
- `editMessage`(`chatId`、`messageId`、`content`)
|
||||
- `createForumTopic`(`chatId`、`name`、可选 `iconColor`、`iconCustomEmojiId`)
|
||||
- `createForumTopic`(`chatId`、`name`,可选 `iconColor`、`iconCustomEmojiId`)
|
||||
|
||||
渠道消息操作会暴露符合人体工程学的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
渠道消息操作会公开符合人体工学的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
|
||||
门控控制:
|
||||
|
||||
@ -488,15 +524,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.actions.reactions`
|
||||
- `channels.telegram.actions.sticker`(默认:禁用)
|
||||
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用活动配置/密钥快照(启动/重载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,并且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用活动配置/密钥快照(启动/重新加载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
|
||||
反应移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Reply threading tags">
|
||||
Telegram 支持在生成输出中使用显式回复线程标签:
|
||||
<Accordion title="回复线程标签">
|
||||
Telegram 支持在生成的输出中使用显式回复线程标签:
|
||||
|
||||
- `[[reply_to_current]]` 回复触发消息
|
||||
- `[[reply_to:<id>]]` 回复特定 Telegram 消息 ID
|
||||
@ -507,29 +543,29 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `first`
|
||||
- `all`
|
||||
|
||||
当回复线程启用且原始 Telegram 文本或说明文字可用时,OpenClaw 会自动包含原生 Telegram 引用摘录。Telegram 将原生引用文本限制在 1024 个 UTF-16 code unit,因此较长消息会从开头引用;如果 Telegram 拒绝引用,则回退为普通回复。
|
||||
当启用回复线程且原始 Telegram 文本或说明可用时,OpenClaw 会自动包含一段原生 Telegram 引用摘录。Telegram 将原生引用文本限制为 1024 个 UTF-16 码元,因此更长的消息会从开头引用;如果 Telegram 拒绝该引用,则回退到普通回复。
|
||||
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会生效。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Forum topics and thread behavior">
|
||||
<Accordion title="论坛 topic 和线程行为">
|
||||
论坛超级群组:
|
||||
|
||||
- 话题会话键会追加 `:topic:<threadId>`
|
||||
- 回复和输入状态会以话题线程为目标
|
||||
- 话题配置路径:
|
||||
- topic 会话键会附加 `:topic:<threadId>`
|
||||
- 回复和正在输入状态会定向到 topic 线程
|
||||
- topic 配置路径:
|
||||
`channels.telegram.groups.<chatId>.topics.<threadId>`
|
||||
|
||||
通用话题(`threadId=1`)特殊情况:
|
||||
通用 topic(`threadId=1`)特例:
|
||||
|
||||
- 消息发送会省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入状态操作仍包含 `message_thread_id`
|
||||
- 发送消息会省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 正在输入操作仍包含 `message_thread_id`
|
||||
|
||||
话题继承:话题条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅限话题,不会从群组默认值继承。
|
||||
Topic 继承:topic 条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅限 topic,不会从群组默认值继承。
|
||||
|
||||
**按话题智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同的智能体。这会让每个话题拥有自己的隔离工作区、记忆和会话。示例:
|
||||
**按 topic 路由智能体**:每个 topic 都可以通过在 topic 配置中设置 `agentId` 路由到不同的智能体。这会给每个 topic 提供各自隔离的工作区、记忆和会话。示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -549,24 +585,25 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
然后每个话题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
然后每个 topic 都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定固定 ACP harness 会话(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的带话题限定 ID)。当前作用域限定为群组/超级群组中的论坛话题。参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
**持久 ACP topic 绑定**:论坛 topic 可以通过顶层类型化 ACP 绑定固定 ACP harness 会话(`bindings[]` 带有 `type: "acp"` 和 `match.channel: "telegram"`、`peer.kind: "group"`,以及类似 `-1001234567890:topic:42` 的 topic 限定 ID)。当前作用域限于群组/超级群组中的论坛 topic。请参阅 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
|
||||
**从聊天生成线程绑定的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在话题内固定生成确认。要求 `channels.telegram.threadBindings.spawnSessions` 保持启用(默认:`true`)。
|
||||
**从聊天生成线程绑定 ACP**:`/acp spawn <agent> --thread here|auto` 会把当前 topic 绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在 topic 内置顶生成确认消息。需要保持启用 `channels.telegram.threadBindings.spawnSessions`(默认:`true`)。
|
||||
|
||||
模板上下文会暴露 `MessageThreadId` 和 `IsForum`。带 `message_thread_id` 的私信聊天默认会在扁平会话上保留私信路由和回复元数据;只有在配置了 `threadReplies: "inbound"`、`threadReplies: "always"`、`requireTopic: true` 或匹配的话题配置时,才会使用线程感知的会话键。使用顶层 `channels.telegram.dm.threadReplies` 作为账户默认值,或使用 `direct.<chatId>.threadReplies` 配置单个私信。
|
||||
模板上下文暴露 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天默认在扁平会话中保留私信路由和回复元数据;只有在配置了 `threadReplies: "inbound"`、`threadReplies: "always"`、`requireTopic: true` 或匹配的话题配置时,它们才会使用感知线程的会话键。使用顶层 `channels.telegram.dm.threadReplies` 设置账号默认值,或使用 `direct.<chatId>.threadReplies` 设置某个私信。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Audio, video, and stickers">
|
||||
<Accordion title="音频、视频和贴纸">
|
||||
### 音频消息
|
||||
|
||||
Telegram 会区分语音消息和音频文件。
|
||||
Telegram 区分语音留言和音频文件。
|
||||
|
||||
- 默认:音频文件行为
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 可强制作为语音消息发送
|
||||
- 入站语音消息转录会在智能体上下文中被框定为机器生成的、不受信任文本;提及检测仍使用原始转录,因此受提及门控的语音消息会继续工作。
|
||||
- 在智能体回复中添加标签 `[[audio_as_voice]]` 可强制作为语音留言发送
|
||||
- 入站语音留言转写会在智能体上下文中被框定为机器生成的、
|
||||
不可信文本;提及检测仍使用原始转写,因此受提及门控的语音消息会继续工作。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -582,7 +619,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
### 视频消息
|
||||
|
||||
Telegram 会区分视频文件和视频便笺。
|
||||
Telegram 区分视频文件和视频留言。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -596,14 +633,14 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
视频便笺不支持字幕;提供的消息文本会单独发送。
|
||||
视频留言不支持说明文字;提供的消息文本会单独发送。
|
||||
|
||||
### 贴纸
|
||||
|
||||
入站贴纸处理:
|
||||
|
||||
- 静态 WEBP:下载并处理(占位符 `<media:sticker>`)
|
||||
- 动画 TGS:跳过
|
||||
- 动态 TGS:跳过
|
||||
- 视频 WEBM:跳过
|
||||
|
||||
贴纸上下文字段:
|
||||
@ -645,7 +682,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
搜索缓存的贴纸:
|
||||
搜索已缓存的贴纸:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -659,7 +696,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回应通知">
|
||||
Telegram 回应会以 `message_reaction` 更新到达(与消息载荷分开)。
|
||||
Telegram 回应会作为 `message_reaction` 更新到达(与消息负载分离)。
|
||||
|
||||
启用后,OpenClaw 会将如下系统事件加入队列:
|
||||
|
||||
@ -670,19 +707,19 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.reactionNotifications`:`off | own | all`(默认:`own`)
|
||||
- `channels.telegram.reactionLevel`:`off | ack | minimal | extensive`(默认:`minimal`)
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- `own` 表示仅用户对机器人发送消息的回应(通过已发送消息缓存尽力判断)。
|
||||
- 回应事件仍会遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- `own` 表示仅用户对机器人已发送消息的回应(通过已发送消息缓存尽力而为)。
|
||||
- 回应事件仍遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- Telegram 不会在回应更新中提供线程 ID。
|
||||
- 非论坛群组会路由到群聊会话
|
||||
- 论坛群组会路由到群组通用主题会话(`:topic:1`),而不是确切的原始主题
|
||||
- 非论坛群组路由到群组聊天会话
|
||||
- 论坛群组路由到群组通用话题会话(`:topic:1`),而不是精确的来源话题
|
||||
|
||||
轮询/webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Ack 回应">
|
||||
<Accordion title="确认回应">
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认 emoji。
|
||||
|
||||
解析顺序:
|
||||
@ -692,9 +729,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- Telegram 需要 Unicode emoji(例如 "👀")。
|
||||
- Telegram 期望 unicode emoji(例如 "👀")。
|
||||
- 使用 `""` 可为某个渠道或账号禁用回应。
|
||||
|
||||
</Accordion>
|
||||
@ -722,29 +759,29 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="长轮询与 webhook">
|
||||
默认使用长轮询。要使用 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选项为 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
默认是长轮询。对于 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公网入口,可以在本地端口前放置反向代理,或有意设置 `webhookHost: "0.0.0.0"`。
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公开入口,要么在本地端口前放置反向代理,要么有意设置 `webhookHost: "0.0.0.0"`。
|
||||
|
||||
webhook 模式会先验证请求防护、Telegram secret token 和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按主题机器人通道异步处理该更新,因此较慢的智能体轮次不会占住 Telegram 的投递 ACK。
|
||||
webhook 模式会先校验请求防护、Telegram 密钥令牌和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按话题机器人通道异步处理该更新,因此较慢的智能体轮次不会阻塞 Telegram 的投递 ACK。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="限制、重试和 CLI 目标">
|
||||
- `channels.telegram.textChunkLimit` 默认值为 4000。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度拆分前优先使用段落边界(空行)。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度拆分之前优先选择段落边界(空行)。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制入站和出站 Telegram 媒体大小。
|
||||
- `channels.telegram.mediaGroupFlushMs`(默认 500)控制 Telegram 相册/媒体组在 OpenClaw 将其作为一条入站消息分发前缓冲多久。如果相册部分到达较晚,可以增大该值;如果要降低相册回复延迟,可以减小该值。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时(如果未设置,则使用 grammY 默认值)。机器人客户端会将低于 60 秒出站文本/输入状态请求防护的配置值钳制在该防护以内,避免 grammY 在 OpenClaw 的传输防护和回退运行前中止可见回复投递。长轮询仍使用 45 秒 `getUpdates` 请求防护,因此空闲轮询不会被无限期遗弃。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认为 `120000`;仅在误报轮询停滞重启时,才在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 会禁用。
|
||||
- 回复/引用/转发的补充上下文目前按接收原样传递。
|
||||
- Telegram 允许列表主要用于控制谁能触发智能体,而不是完整的补充上下文删减边界。
|
||||
- `channels.telegram.mediaGroupFlushMs`(默认 500)控制 Telegram 相册/媒体组在 OpenClaw 将其作为一条入站消息派发前缓冲多久。如果相册片段到达较晚,请增大它;如果要减少相册回复延迟,请减小它。
|
||||
- `channels.telegram.timeoutSeconds` 覆盖 Telegram API 客户端超时(如果未设置,则使用 grammY 默认值)。机器人客户端会将低于 60 秒出站文本/输入状态请求防护的配置值钳制住,因此 grammY 不会在 OpenClaw 的传输防护和回退运行之前中止可见回复投递。长轮询仍使用 45 秒的 `getUpdates` 请求防护,因此空闲轮询不会被无限期遗弃。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在轮询停滞重启出现误报时,在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 表示禁用。
|
||||
- 回复/引用/转发的补充上下文目前会按收到的形式传递。
|
||||
- Telegram allowlist 主要控制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制项:
|
||||
- `channels.telegram.dmHistoryLimit`
|
||||
- `channels.telegram.dms["<user_id>"].historyLimit`
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助函数(CLI/工具/操作)中可恢复的出站 API 错误。入站最终回复投递也会对 Telegram 预连接失败使用有界安全发送重试,但不会重试可能重复可见消息的模糊发送后网络信封。
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送助手(CLI/工具/操作)中的可恢复出站 API 错误。入站最终回复投递也会对 Telegram 预连接失败使用有界的安全发送重试,但不会重试可能重复可见消息的模糊发送后网络信封。
|
||||
|
||||
CLI 发送目标可以是数字聊天 ID 或用户名:
|
||||
|
||||
@ -753,7 +790,7 @@ openclaw message send --channel telegram --target 123456789 --message "hi"
|
||||
openclaw message send --channel telegram --target @name --message "hi"
|
||||
```
|
||||
|
||||
Telegram 投票使用 `openclaw message poll`,并支持论坛主题:
|
||||
Telegram 投票使用 `openclaw message poll`,并支持论坛话题:
|
||||
|
||||
```bash
|
||||
openclaw message poll --channel telegram --target 123456789 \
|
||||
@ -768,52 +805,52 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
- `--poll-duration-seconds`(5-600)
|
||||
- `--poll-anonymous`
|
||||
- `--poll-public`
|
||||
- `--thread-id` 用于论坛主题(或使用 `:topic:` 目标)
|
||||
- 用于论坛话题的 `--thread-id`(或使用 `:topic:` 目标)
|
||||
|
||||
Telegram 发送还支持:
|
||||
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 区块的 `--presentation` 来发送内联键盘
|
||||
- 当机器人可以在该聊天中置顶时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求置顶投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带 `buttons` 块的 `--presentation` 创建内联键盘
|
||||
- 在机器人可以固定该聊天中的消息时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求固定投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动态媒体上传
|
||||
|
||||
操作门控:
|
||||
|
||||
- `channels.telegram.actions.sendMessage=false` 会禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,但保留常规发送启用
|
||||
- `channels.telegram.actions.sendMessage=false` 禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 禁用 Telegram 投票创建,同时保持常规发送启用
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram 中的执行审批">
|
||||
Telegram 支持在审批者私信中进行执行审批,并且可以选择在原始聊天或主题中发布提示。审批者必须是数字 Telegram 用户 ID。
|
||||
<Accordion title="Telegram 中的 exec 审批">
|
||||
Telegram 支持在审批者私信中进行 exec 审批,也可以选择在来源聊天或话题中发布提示。审批者必须是数字 Telegram 用户 ID。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.telegram.execApprovals.enabled`(当至少一个审批者可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.enabled`(至少有一个审批者可解析时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到来自 `commands.ownerAllowFrom` 的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.target`:`dm`(默认)| `channel` | `both`
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以与机器人对话,以及机器人将普通回复发送到哪里。它们不会让某人成为执行审批者。当尚不存在命令所有者时,第一个获批的私信配对会引导设置 `commands.ownerAllowFrom`,因此单所有者设置仍可正常工作,无需在 `execApprovals.approvers` 下重复 ID。
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以与机器人对话,以及它将普通回复发送到哪里。它们不会让某人成为 exec 审批者。当尚不存在命令所有者时,首次获批的私信配对会引导生成 `commands.ownerAllowFrom`,因此单所有者设置无需在 `execApprovals.approvers` 下重复 ID 也能正常工作。
|
||||
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组/主题中启用 `channel` 或 `both`。当提示落在论坛主题中时,OpenClaw 会为审批提示和后续消息保留该主题。执行审批默认在 30 分钟后过期。
|
||||
渠道投递会在聊天中显示命令文本;仅在可信的群组/话题中启用 `channel` 或 `both`。当提示落在论坛话题中时,OpenClaw 会为审批提示和后续消息保留该话题。exec 审批默认在 30 分钟后过期。
|
||||
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标界面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过执行审批解析。
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过 exec 审批解析。
|
||||
|
||||
请参阅[执行审批](/zh-CN/tools/exec-approvals)。
|
||||
参见 [Exec 审批](/zh-CN/tools/exec-approvals)。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 错误回复控制
|
||||
|
||||
当智能体遇到投递或提供商错误时,Telegram 可以回复错误文本,也可以抑制该错误。两个配置键控制此行为:
|
||||
当智能体遇到投递错误或提供商错误时,Telegram 可以回复错误文本,也可以将其抑制。两个配置键控制此行为:
|
||||
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送一条友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | 对同一聊天发送错误回复的最小间隔时间。防止在故障期间出现错误刷屏。 |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送一条友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | 向同一聊天发送错误回复之间的最短时间。防止服务中断期间出现错误刷屏。 |
|
||||
|
||||
支持按账号、按群组和按主题覆盖(继承方式与其他 Telegram 配置键相同)。
|
||||
支持按账号、按群组和按话题覆盖(继承方式与其他 Telegram 配置键相同)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -834,7 +871,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="机器人不回应非提及群组消息">
|
||||
<Accordion title="机器人不响应非提及群组消息">
|
||||
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完整可见性。
|
||||
- BotFather:`/setprivacy` -> Disable
|
||||
@ -847,9 +884,9 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
<Accordion title="机器人完全看不到群组消息">
|
||||
|
||||
- 当 `channels.telegram.groups` 存在时,群组必须被列出(或包含 `"*"`)
|
||||
- 当 `channels.telegram.groups` 存在时,必须列出群组(或包含 `"*"`)
|
||||
- 验证机器人在群组中的成员身份
|
||||
- 查看日志:使用 `openclaw logs --follow` 查看跳过原因
|
||||
- 查看日志:`openclaw logs --follow` 以了解跳过原因
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -857,33 +894,33 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
- 授权你的发送者身份(配对和/或数字 `allowFrom`)
|
||||
- 即使群组策略为 `open`,命令授权仍然适用
|
||||
- 出现 `setMyCommands failed` 且带有 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- 出现带有 `BOT_COMMANDS_TOO_MUCH` 的 `setMyCommands failed` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生命令菜单
|
||||
- `deleteMyCommands` / `setMyCommands` 启动调用和 `sendChatAction` 输入状态调用都有边界,并会在请求超时时通过 Telegram 的传输回退重试一次。持续的网络/fetch 错误通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性存在问题
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="启动报告未授权 token">
|
||||
|
||||
- `getMe returned 401` 是已配置 bot token 的 Telegram 身份验证失败。
|
||||
- 在 BotFather 中重新复制或重新生成 bot token,然后为默认账号更新 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是身份验证失败;将其视为“没有 webhook 存在”只会把同一个错误 token 失败推迟到后续 API 调用。
|
||||
- `getMe returned 401` 是已配置机器人 token 的 Telegram 认证失败。
|
||||
- 在 BotFather 中重新复制或重新生成机器人 token,然后为默认账户更新 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是认证失败;将其视为“没有 webhook 存在”只会把同一个错误 token 失败推迟到后续 API 调用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Polling or network instability">
|
||||
<Accordion title="轮询或网络不稳定">
|
||||
|
||||
- Node 22+ + 自定义 fetch/proxy 可能在 AbortSignal 类型不匹配时触发立即中止行为。
|
||||
- 某些主机会先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站可能导致间歇性 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些错误作为可恢复的网络错误重试。
|
||||
- 在轮询启动期间,OpenClaw 会为 grammY 复用启动时成功的 `getMe` 探测,因此 runner 不需要在第一次 `getUpdates` 前再执行第二次 `getMe`。
|
||||
- 如果 `deleteWebhook` 在轮询启动期间因瞬时网络错误失败,OpenClaw 会继续进入长轮询,而不是再进行一次轮询前的控制平面调用。仍处于活动状态的 webhook 会表现为 `getUpdates` 冲突;随后 OpenClaw 会重建 Telegram 传输并重试 webhook 清理。
|
||||
- 如果 Telegram 套接字按较短的固定周期回收,请检查是否设置了较低的 `channels.telegram.timeoutSeconds`;bot 客户端会将低于出站和 `getUpdates` 请求保护值的配置值钳制到保护值以上,但旧版本在该值低于这些保护值时可能会中止每一次轮询或回复。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成长轮询存活信号后重启轮询并重建 Telegram 传输。
|
||||
- 当正在运行的轮询账号在启动宽限期后仍未完成 `getUpdates`、正在运行的 webhook 账号在启动宽限期后仍未完成 `setWebhook`,或上一次成功的轮询传输活动已过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 只有当长时间运行的 `getUpdates` 调用是健康的,但你的主机仍报告误报的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的 proxy、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 的 Bot API 传输也会遵循进程 proxy 环境变量,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果服务环境中通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管 proxy,且没有标准 proxy 环境变量,Telegram 也会将该 URL 用于 Bot API 传输。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,请通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
- Node 22+ 加自定义 fetch/代理时,如果 AbortSignal 类型不匹配,可能触发立即中止行为。
|
||||
- 某些主机会先把 `api.telegram.org` 解析到 IPv6;损坏的 IPv6 出站可能导致间歇性 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些作为可恢复网络错误进行重试。
|
||||
- 在轮询启动期间,OpenClaw 会为 grammY 复用成功的启动 `getMe` 探测,因此运行器不需要在第一次 `getUpdates` 前再执行第二次 `getMe`。
|
||||
- 如果在轮询启动期间 `deleteWebhook` 因瞬时网络错误而失败,OpenClaw 会继续进入长轮询,而不是再发起一次预轮询控制面调用。仍然活跃的 webhook 会表现为 `getUpdates` 冲突;随后 OpenClaw 会重建 Telegram 传输并重试 webhook 清理。
|
||||
- 如果 Telegram socket 按较短的固定周期回收,请检查是否设置了较低的 `channels.telegram.timeoutSeconds`;机器人客户端会将低于出站和 `getUpdates` 请求保护阈值的配置值夹紧,但旧版本在该值低于这些保护阈值时,可能会中止每次轮询或回复。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成长轮询存活性检查后重启轮询并重建 Telegram 传输。
|
||||
- 当正在运行的轮询账户在启动宽限期后尚未完成 `getUpdates`、正在运行的 webhook 账户在启动宽限期后尚未完成 `setWebhook`,或最后一次成功的轮询传输活动已过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 只有在长时间运行的 `getUpdates` 调用健康,但你的主机仍报告误报的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 还会遵循用于 Bot API 传输的进程代理环境变量,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果在服务环境中通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管代理,且没有标准代理环境变量,Telegram 也会将该 URL 用于 Bot API 传输。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -891,8 +928,8 @@ channels:
|
||||
proxy: socks5://<user>:<password>@proxy-host:1080
|
||||
```
|
||||
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)。Telegram DNS 结果顺序依次遵循 `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER`、`channels.telegram.network.dnsResultOrder`,然后是进程默认值,例如 `NODE_OPTIONS=--dns-result-order=ipv4first`;如果都不适用,Node 22+ 会回退到 `ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确在仅 IPv4 行为下效果更好,请强制选择地址族:
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)。Telegram DNS 结果顺序依次遵循 `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER`、`channels.telegram.network.dnsResultOrder`,再到进程默认值,例如 `NODE_OPTIONS=--dns-result-order=ipv4first`;如果都不适用,Node 22+ 会回退到 `ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确使用仅 IPv4 行为效果更好,请强制选择地址族:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -901,7 +938,7 @@ channels:
|
||||
autoSelectFamily: false
|
||||
```
|
||||
|
||||
- 默认情况下,Telegram 媒体下载已允许 RFC 2544 基准测试范围的应答(`198.18.0.0/15`)。如果可信的 fake-IP 或透明 proxy 在媒体下载期间将 `api.telegram.org` 重写为其他 private/internal/special-use 地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
- 默认情况下,Telegram 媒体下载已经允许 RFC 2544 基准测试范围地址(`198.18.0.0/15`)。如果可信的假 IP 或透明代理在媒体下载期间将 `api.telegram.org` 重写为其他私有/内部/特殊用途地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -910,18 +947,20 @@ channels:
|
||||
dangerouslyAllowPrivateNetwork: true
|
||||
```
|
||||
|
||||
- 同一项也可以按账号配置在 `channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`。
|
||||
- 如果你的 proxy 将 Telegram 媒体主机解析到 `198.18.x.x`,请先保持 dangerous 标志关闭。Telegram 媒体默认已允许 RFC 2544 基准测试范围。
|
||||
- 同样的选择启用项也可按账户配置在
|
||||
`channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`。
|
||||
- 如果你的代理将 Telegram 媒体主机解析到 `198.18.x.x`,先保持危险标志关闭。默认情况下,Telegram 媒体已经允许 RFC 2544 基准测试范围。
|
||||
|
||||
<Warning>
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram 媒体 SSRF 保护。仅在可信、由运营方控制的 proxy 环境中使用,例如 Clash、Mihomo 或 Surge fake-IP 路由,并且它们会合成 RFC 2544 基准测试范围之外的 private 或 special-use 应答。普通公共互联网 Telegram 访问应保持关闭。
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram
|
||||
媒体 SSRF 防护。仅在可信、由操作方控制的代理环境中使用,例如 Clash、Mihomo 或 Surge 假 IP 路由,并且这些环境会合成 RFC 2544 基准测试范围之外的私有或特殊用途答案。正常公共互联网 Telegram 访问请保持关闭。
|
||||
</Warning>
|
||||
|
||||
- 环境覆盖(临时):
|
||||
- `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1`
|
||||
- `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1`
|
||||
- `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`
|
||||
- 验证 DNS 应答:
|
||||
- 验证 DNS 答案:
|
||||
|
||||
```bash
|
||||
dig +short api.telegram.org A
|
||||
@ -937,9 +976,9 @@ dig +short api.telegram.org AAAA
|
||||
|
||||
主要参考:[配置参考 - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
|
||||
<Accordion title="High-signal Telegram fields">
|
||||
<Accordion title="高信号 Telegram 字段">
|
||||
|
||||
- 启动/身份验证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向常规文件;符号链接会被拒绝)
|
||||
- 启动/认证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向普通文件;符号链接会被拒绝)
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`、`groups.*.topics.*`、顶层 `bindings[]`(`type: "acp"`)
|
||||
- exec 审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- 命令/菜单:`commands.native`、`commands.nativeSkills`、`customCommands`
|
||||
@ -947,7 +986,7 @@ dig +short api.telegram.org AAAA
|
||||
- 流式传输:`streaming`(预览)、`streaming.preview.toolProgress`、`blockStreaming`
|
||||
- 格式化/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 媒体/网络:`mediaMaxMb`、`mediaGroupFlushMs`、`timeoutSeconds`、`pollingStallThresholdMs`、`retry`、`network.autoSelectFamily`、`network.dangerouslyAllowPrivateNetwork`、`proxy`
|
||||
- 自定义 API 根路径:`apiRoot`(仅 Bot API 根路径;不要包含 `/bot<TOKEN>`)
|
||||
- 自定义 API 根地址:`apiRoot`(仅 Bot API 根地址;不要包含 `/bot<TOKEN>`)
|
||||
- webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 操作/能力:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- reactions:`reactionNotifications`、`reactionLevel`
|
||||
@ -957,28 +996,28 @@ dig +short api.telegram.org AAAA
|
||||
</Accordion>
|
||||
|
||||
<Note>
|
||||
多账号优先级:当配置了两个或更多账号 ID 时,设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`)以显式指定默认路由。否则 OpenClaw 会回退到第一个规范化账号 ID,并且 `openclaw doctor` 会发出警告。命名账号会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
多账户优先级:配置两个或更多账户 ID 时,设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`)以明确默认路由。否则,OpenClaw 会回退到第一个规范化账户 ID,并且 `openclaw doctor` 会发出警告。命名账户会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
</Note>
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Pairing" icon="link" href="/zh-CN/channels/pairing">
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
将 Telegram 用户与 Gateway 网关配对。
|
||||
</Card>
|
||||
<Card title="Groups" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题 allowlist 行为。
|
||||
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和主题允许列表行为。
|
||||
</Card>
|
||||
<Card title="Channel routing" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
将入站消息路由到智能体。
|
||||
</Card>
|
||||
<Card title="Security" icon="shield" href="/zh-CN/gateway/security">
|
||||
<Card title="安全" icon="shield" href="/zh-CN/gateway/security">
|
||||
威胁模型和加固。
|
||||
</Card>
|
||||
<Card title="Multi-agent routing" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
将群组和话题映射到智能体。
|
||||
<Card title="多智能体路由" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
将群组和主题映射到智能体。
|
||||
</Card>
|
||||
<Card title="Troubleshooting" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
<Card title="故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -2,28 +2,28 @@
|
||||
read_when:
|
||||
- 解释流式传输或分块在渠道中的工作方式
|
||||
- 更改分块流式传输或渠道分块行为
|
||||
- 调试重复/过早的分块回复或渠道预览流式传输
|
||||
- 调试重复/过早的块回复或渠道预览流式传输
|
||||
summary: 流式传输 + 分块行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输和分块
|
||||
x-i18n:
|
||||
generated_at: "2026-05-04T06:12:31Z"
|
||||
generated_at: "2026-05-04T07:02:56Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: fcb41ceb5602ab42c3fd41a59de62cc965ea61fdbc058c052fb93689a9c5299b
|
||||
source_hash: ff7b6cd8127255352fe16fb746469e9828e7d5aea183d3799ab10cc768515bd1
|
||||
source_path: concepts/streaming.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有两个独立的流式传输层:
|
||||
|
||||
- **分块流式传输(渠道):** 在助手写入时发出完成的 **块**。这些是普通渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成期间更新临时 **预览消息**。
|
||||
- **分块流式传输(渠道):** 在助手写入时发出已完成的 **块**。这些是普通渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成期间更新临时的 **预览消息**。
|
||||
|
||||
目前还没有对渠道消息的 **真正 token 增量流式传输**。预览流式传输基于消息(发送 + 编辑/追加)。
|
||||
目前渠道消息没有 **真正的 token 增量流式传输**。预览流式传输基于消息(发送 + 编辑/追加)。
|
||||
|
||||
## 分块流式传输(渠道消息)
|
||||
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的块发送输出。
|
||||
分块流式传输会在助手输出可用时,以较粗的分块发送输出。
|
||||
|
||||
```
|
||||
Model output
|
||||
@ -37,74 +37,73 @@ Model output
|
||||
|
||||
图例:
|
||||
|
||||
- `text_delta/events`:模型流事件(对于非流式模型可能较稀疏)。
|
||||
- `chunker`:应用最小/最大边界 + 断点偏好的 `EmbeddedBlockChunker`。
|
||||
- `text_delta/events`:模型流事件(对于非流式传输模型可能较稀疏)。
|
||||
- `chunker`:`EmbeddedBlockChunker`,应用最小/最大边界 + 断点偏好。
|
||||
- `channel send`:实际出站消息(块回复)。
|
||||
|
||||
**控制项:**
|
||||
|
||||
- `agents.defaults.blockStreamingDefault`:`"on"`/`"off"`(默认关闭)。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及按账号的变体),用于按渠道强制设为 `"on"`/`"off"`。
|
||||
- 渠道覆盖项:`*.blockStreaming`(以及按账号的变体),用于按渠道强制设为 `"on"`/`"off"`。
|
||||
- `agents.defaults.blockStreamingBreak`:`"text_end"` 或 `"message_end"`。
|
||||
- `agents.defaults.blockStreamingChunk`:`{ minChars, maxChars, breakPreference? }`。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(发送前合并流式块)。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(发送前合并已流式传输的块)。
|
||||
- 渠道硬上限:`*.textChunkLimit`(例如 `channels.whatsapp.textChunkLimit`)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会在按长度分块前按空行(段落边界)拆分)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会在按长度分块前先按空行(段落边界)拆分)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),会拆分过高的回复以避免 UI 裁切。
|
||||
|
||||
**边界语义:**
|
||||
|
||||
- `text_end`:在 chunker 发出块后立即流式传输块;每个 `text_end` 都刷新。
|
||||
- `message_end`:等到助手消息完成,然后刷新已缓冲的输出。
|
||||
- `text_end`:只要分块器发出块就流式传输;在每个 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息完成,然后刷新缓冲的输出。
|
||||
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用 chunker,因此它可以在末尾发出多个块。
|
||||
如果缓冲文本超过 `maxChars`,`message_end` 仍会使用分块器,因此它可以在末尾发出多个分块。
|
||||
|
||||
### 使用分块流式传输交付媒体
|
||||
### 使用分块流式传输进行媒体递送
|
||||
|
||||
`MEDIA:` 指令是普通交付元数据。当分块流式传输提前发送媒体块时,OpenClaw 会记住本轮交付。如果最终助手载荷重复相同媒体 URL,最终交付会剔除重复媒体,而不是再次发送附件。
|
||||
`MEDIA:` 指令是普通的递送元数据。当分块流式传输提前发送媒体块时,OpenClaw 会记住该轮次的递送。如果最终助手载荷重复了相同的媒体 URL,最终递送会移除重复媒体,而不是再次发送附件。
|
||||
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已流式传输的媒体周围添加了不同文本,OpenClaw 仍会发送新文本,同时保持媒体只交付一次。这可以防止在 Telegram 等渠道上出现重复语音消息或文件,例如当智能体在流式传输期间发出 `MEDIA:`,而提供商也在完成的回复中包含它时。
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已流式传输的媒体周围添加了不同文本,OpenClaw 仍会发送新文本,同时保持媒体只递送一次。这可以防止在 Telegram 等渠道上出现重复语音备注或文件,例如智能体在流式传输期间发出 `MEDIA:`,而提供商也在完成的回复中包含它时。
|
||||
|
||||
## 分块算法(低/高边界)
|
||||
|
||||
块分块由 `EmbeddedBlockChunker` 实现:
|
||||
|
||||
- **低边界:** 在缓冲区 >= `minChars` 之前不发出(除非强制)。
|
||||
- **低边界:** 缓冲区 >= `minChars` 前不发出(除非强制)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果强制,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬断点。
|
||||
- **代码围栏:** 永不在围栏内拆分;当在 `maxChars` 处强制拆分时,关闭 + 重新打开围栏以保持 Markdown 有效。
|
||||
- **代码围栏:** 永不在围栏内部拆分;当在 `maxChars` 处强制拆分时,会关闭 + 重新打开围栏以保持 Markdown 有效。
|
||||
|
||||
`maxChars` 会被钳制到渠道 `textChunkLimit`,因此你无法超过每个渠道的上限。
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此你无法超过每个渠道的上限。
|
||||
|
||||
## 合并(合并流式块)
|
||||
## 合并(合并已流式传输的块)
|
||||
|
||||
启用分块流式传输后,OpenClaw 可以在发送前 **合并连续的块分片**。这会减少“单行刷屏”,同时仍提供渐进式输出。
|
||||
启用分块流式传输时,OpenClaw 可以在发送前 **合并连续的块分块**。这可以减少“单行刷屏”,同时仍提供渐进式输出。
|
||||
|
||||
- 合并会等待 **空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超过时会刷新。
|
||||
- `minChars` 会阻止过小片段发送,直到累积足够文本(最终刷新总会发送剩余文本)。
|
||||
- 连接符派生自 `blockStreamingChunk.breakPreference`
|
||||
(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 使用渠道覆盖(包括按账号配置)。
|
||||
- 除非覆盖,否则 Signal/Slack/Discord 的默认合并 `minChars` 会提升到 1500。
|
||||
- `minChars` 会防止过小片段在累积足够文本前发送(最终刷新始终会发送剩余文本)。
|
||||
- 连接符派生自 `blockStreamingChunk.breakPreference`(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 使用渠道覆盖项(包括按账号配置)。
|
||||
- 除非覆盖,Signal/Slack/Discord 的默认合并 `minChars` 会提升到 1500。
|
||||
|
||||
## 块之间的类人节奏
|
||||
## 块之间的拟人化节奏
|
||||
|
||||
启用分块流式传输后,你可以在块回复之间添加 **随机暂停**(第一个块之后)。这会让多气泡回复感觉更自然。
|
||||
启用分块流式传输时,你可以在块回复之间(第一个块之后)添加 **随机暂停**。这会让多气泡回复感觉更自然。
|
||||
|
||||
- 配置:`agents.defaults.humanDelay`(可通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 配置:`agents.defaults.humanDelay`(通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 模式:`off`(默认)、`natural`(800–2500ms)、`custom`(`minMs`/`maxMs`)。
|
||||
- 仅适用于 **块回复**,不适用于最终回复或工具摘要。
|
||||
|
||||
## “流式传输分块还是全部内容”
|
||||
## “流式传输分块或全部内容”
|
||||
|
||||
这映射为:
|
||||
这对应于:
|
||||
|
||||
- **流式传输分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要 `*.blockStreaming: true`。
|
||||
- **在末尾流式传输全部内容:** `blockStreamingBreak: "message_end"`(刷新一次,如果非常长则可能有多个分块)。
|
||||
- **无分块流式传输:** `blockStreamingDefault: "off"`(仅最终回复)。
|
||||
- **在末尾流式传输全部内容:** `blockStreamingBreak: "message_end"`(刷新一次,如果非常长则可能刷新多个分块)。
|
||||
- **不进行分块流式传输:** `blockStreamingDefault: "off"`(仅最终回复)。
|
||||
|
||||
**渠道注意事项:** 除非显式将 `*.blockStreaming` 设为 `true`,否则分块流式传输 **关闭**。渠道可以在没有块回复的情况下流式传输实时预览(`channels.<channel>.streaming`)。
|
||||
**渠道注意事项:** 除非明确将 `*.blockStreaming` 设为 `true`,否则分块流式传输为 **关闭**。渠道可以在没有块回复的情况下流式传输实时预览(`channels.<channel>.streaming`)。
|
||||
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置。
|
||||
|
||||
@ -116,29 +115,29 @@ Model output
|
||||
|
||||
- `off`:禁用预览流式传输。
|
||||
- `partial`:单个预览,会被最新文本替换。
|
||||
- `block`:预览以分块/追加步骤更新。
|
||||
- `progress`:生成期间显示进度/Status 预览,完成时给出最终答案。
|
||||
- `block`:以分块/追加步骤更新预览。
|
||||
- `progress`:生成期间显示进度/状态预览,完成时给出最终答案。
|
||||
|
||||
`streaming.mode: "block"` 是一种适用于 Discord 和 Telegram 等支持编辑渠道的预览流式传输模式。它不会在那里启用渠道块交付。当你想要普通块回复时,请使用 `streaming.block.enabled` 或旧版 `blockStreaming` 渠道键。Microsoft Teams 是例外:它没有草稿预览块传输,因此 `streaming.mode: "block"` 会映射到 Teams 块交付,而不是原生 partial/progress 流式传输。
|
||||
`streaming.mode: "block"` 是一种预览流式传输模式,适用于 Discord 和 Telegram 等支持编辑的渠道。它不会在那里启用渠道块递送。需要普通块回复时,请使用 `streaming.block.enabled` 或旧版 `blockStreaming` 渠道键。Microsoft Teams 是例外:它没有草稿预览块传输,因此 `streaming.mode: "block"` 会映射到 Teams 块递送,而不是原生 partial/progress 流式传输。
|
||||
|
||||
### 渠道映射
|
||||
|
||||
| 渠道 | `off` | `partial` | `block` | `progress` |
|
||||
| ---------- | ----- | --------- | ------- | ---------------- |
|
||||
| Telegram | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Discord | ✅ | ✅ | ✅ | 可编辑进度草稿 |
|
||||
| Telegram | ✅ | ✅ | ✅ | 可编辑的进度草稿 |
|
||||
| Discord | ✅ | ✅ | ✅ | 可编辑的进度草稿 |
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
| MS Teams | ✅ | ✅ | ✅ | 原生进度流 |
|
||||
|
||||
仅 Slack:
|
||||
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程 Status 需要回复线程目标。顶层私信不会显示那种线程式预览,但它们仍可以使用 Slack 草稿预览帖子和编辑。
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 会切换 Slack 原生流式传输 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态需要一个回复线程目标。顶级私信不会显示这种线程式预览,但它们仍可使用 Slack 草稿预览帖子和编辑。
|
||||
|
||||
旧版键迁移:
|
||||
旧键迁移:
|
||||
|
||||
- Telegram:旧版 `streamMode` 和标量/布尔 `streaming` 值会被 doctor/config 兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Telegram:旧版 `streamMode` 和标量/布尔 `streaming` 值会被 Doctor/配置兼容路径检测并迁移到 `streaming.mode`。
|
||||
- Discord:`streamMode` + 布尔 `streaming` 会自动迁移到 `streaming` 枚举。
|
||||
- Slack:`streamMode` 会自动迁移到 `streaming.mode`;布尔 `streaming` 会自动迁移到 `streaming.mode` 加 `streaming.nativeTransport`;旧版 `nativeStreaming` 会自动迁移到 `streaming.nativeTransport`。
|
||||
|
||||
@ -146,52 +145,52 @@ Model output
|
||||
|
||||
Telegram:
|
||||
|
||||
- 在私信和群组/话题中使用 `sendMessage` + `editMessageText` 预览更新。
|
||||
- 当预览已可见约一分钟时,会发送新的最终消息,而不是就地编辑,然后清理预览,使 Telegram 的时间戳反映回复完成时间。
|
||||
- 当 Telegram 分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理写入临时预览,该预览会在最终交付后删除。
|
||||
- 在私信和群组/主题中使用 `sendMessage` + `editMessageText` 预览更新。
|
||||
- 当预览已可见约一分钟时,会发送新的最终消息,而不是就地编辑,然后清理预览,以便 Telegram 的时间戳反映回复完成时间。
|
||||
- 当明确启用 Telegram 分块流式传输时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理写入临时预览,该预览会在最终递送后删除。
|
||||
|
||||
Discord:
|
||||
|
||||
- 使用发送 + 编辑预览消息。
|
||||
- `block` 模式使用草稿分块(`draftChunk`)。
|
||||
- 当 Discord 分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览,而不刷新新草稿,然后使用正常交付。
|
||||
- 当明确启用 Discord 分块流式传输时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理预览且不刷新新的草稿,然后使用普通递送。
|
||||
|
||||
Slack:
|
||||
|
||||
- 当可用时,`partial` 可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- 可用时,`partial` 可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `block` 使用追加式草稿预览。
|
||||
- `progress` 使用 Status 预览文本,然后给出最终答案。
|
||||
- 没有回复线程的顶层私信会使用草稿预览帖子和编辑,而不是 Slack 原生流式传输。
|
||||
- 原生和草稿预览流式传输会抑制该轮的块回复,因此 Slack 回复只通过一条交付路径流式传输。
|
||||
- 最终媒体/错误载荷和进度最终结果不会创建一次性草稿消息;只有可编辑预览的文本/块最终结果会刷新待处理草稿文本。
|
||||
- `progress` 使用状态预览文本,然后给出最终答案。
|
||||
- 没有回复线程的顶级私信会使用草稿预览帖子和编辑,而不是 Slack 原生流式传输。
|
||||
- 原生和草稿预览流式传输会抑制该轮次的块回复,因此 Slack 回复只通过一个递送路径进行流式传输。
|
||||
- 最终媒体/错误载荷和进度最终结果不会创建一次性草稿消息;只有能够编辑预览的文本/块最终结果才会刷新待处理草稿文本。
|
||||
|
||||
Mattermost:
|
||||
|
||||
- 将思考、工具活动和部分回复文本流式传输到单个草稿预览帖子中,并在最终答案可安全发送时就地完成。
|
||||
- 如果预览帖子已被删除,或在完成时不可用,则回退为发送新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常交付前取消待处理预览更新,而不是刷新临时预览帖子。
|
||||
- 将思考、工具活动和部分回复文本流式传输到单个草稿预览帖子中,在最终答案可以安全发送时就地完成。
|
||||
- 如果预览帖子已被删除或在完成时不可用,则回退为发送新的最终帖子。
|
||||
- 最终媒体/错误载荷会在普通递送前取消待处理预览更新,而不是刷新临时预览帖子。
|
||||
|
||||
Matrix:
|
||||
|
||||
- 当最终文本可复用预览事件时,草稿预览会就地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终结果会在正常交付前取消待处理预览更新;已经可见的陈旧预览会被撤回。
|
||||
- 当最终文本可以复用预览事件时,草稿预览会就地完成。
|
||||
- 仅媒体、错误和回复目标不匹配的最终结果会在普通递送前取消待处理预览更新;已可见的过期预览会被撤回。
|
||||
|
||||
### 工具进度预览更新
|
||||
|
||||
预览流式传输还可以包含 **工具进度** 更新,即类似“搜索网络”、“读取文件”或“调用工具”的短 Status 行,它们会在工具运行期间出现在同一条预览消息中,先于最终回复。这让多步骤工具轮次在第一个思考预览和最终答案之间保持视觉上的活跃,而不是沉默。
|
||||
预览流式传输还可以包含 **工具进度** 更新,即“正在搜索网页”、“正在读取文件”或“正在调用工具”等短状态行,它们会在工具运行时、最终回复之前显示在同一条预览消息中。这会让多步骤工具轮次在第一个思考预览和最终答案之间保持视觉上的活跃,而不是静默。
|
||||
|
||||
支持的界面:
|
||||
支持的表面:
|
||||
|
||||
- **Discord**、**Slack**、**Telegram** 和 **Matrix** 在预览流式传输处于活动状态时,默认会将工具进度流式传输到实时预览编辑中。Microsoft Teams 在个人聊天中使用其原生进度流。
|
||||
- Telegram 自 `v2026.4.22` 起已启用工具进度预览更新;保持启用会保留该已发布行为。
|
||||
- **Mattermost** 已经将工具活动折叠进其单个草稿预览帖子(见上文)。
|
||||
- 工具进度编辑遵循当前的预览流式传输模式;当预览流式传输为 `off`,或当分块流式传输已接管消息时,它们会被跳过。在 Telegram 上,`streaming.mode: "off"` 表示仅最终结果:通用进度闲聊也会被抑制,而不是作为独立 Status 消息交付,同时审批提示、媒体载荷和错误仍会正常路由。
|
||||
- 若要保留预览流式传输但隐藏工具进度行,请将该渠道的 `streaming.preview.toolProgress` 设为 `false`。若要完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
- Telegram 选中文本引用回复是一个例外:当 `replyToMode` 不是 `"off"` 且存在选中的引用文本时,OpenClaw 会跳过该轮的答案预览流,因此工具进度预览行无法渲染。没有选中引用文本的当前消息回复仍会保留预览流式传输。详情请参阅 [Telegram 渠道文档](/zh-CN/channels/telegram)。
|
||||
- 默认情况下,当预览流式传输处于活动状态时,**Discord**、**Slack**、**Telegram** 和 **Matrix** 会将工具进度流式传输到实时预览编辑中。Microsoft Teams 在个人聊天中使用其原生进度流。
|
||||
- Telegram 自 `v2026.4.22` 起已发布并启用了工具进度预览更新;保持启用可保留该已发布行为。
|
||||
- **Mattermost** 已经将工具活动折叠到其单个草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑遵循活动的预览流式传输模式;当预览流式传输为 `off` 或分块流式传输已接管消息时会跳过。在 Telegram 上,`streaming.mode: "off"` 表示仅最终结果:通用进度闲聊也会被抑制,而不是作为独立状态消息递送;审批提示、媒体载荷和错误仍会正常路由。
|
||||
- 若要保留预览流式传输但隐藏工具进度行,请将该渠道的 `streaming.preview.toolProgress` 设为 `false`。若要在隐藏命令/执行文本的同时保持工具进度行可见,请将 `streaming.preview.commandText` 设为 `"status"`,或将 `streaming.progress.commandText` 设为 `"status"`;默认值为 `"raw"`,以保留已发布行为。此策略由使用 OpenClaw 紧凑进度渲染器的草稿/进度渠道共享,包括 Discord、Matrix、Microsoft Teams、Mattermost、Slack 草稿预览和 Telegram。若要完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
- Telegram 选定引用回复是一个例外:当 `replyToMode` 不是 `"off"` 且存在选定引用文本时,OpenClaw 会跳过该轮次的答案预览流,因此无法渲染工具进度预览行。没有选定引用文本的当前消息回复仍会保留预览流式传输。详情请参阅 [Telegram 渠道文档](/zh-CN/channels/telegram)。
|
||||
|
||||
示例:
|
||||
保持进度行可见,但隐藏原始 command/exec 文本:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -200,7 +199,8 @@ Matrix:
|
||||
"streaming": {
|
||||
"mode": "partial",
|
||||
"preview": {
|
||||
"toolProgress": false
|
||||
"toolProgress": true,
|
||||
"commandText": "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,9 +208,27 @@ Matrix:
|
||||
}
|
||||
```
|
||||
|
||||
## 相关内容
|
||||
在另一个紧凑进度渠道键下使用相同结构,例如 `channels.discord`、`channels.matrix`、`channels.msteams`、`channels.mattermost`,或 Slack 草稿预览。对于进度草稿模式,将相同策略放在 `streaming.progress` 下:
|
||||
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"streaming": {
|
||||
"mode": "progress",
|
||||
"progress": {
|
||||
"toolProgress": true,
|
||||
"commandText": "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 相关
|
||||
|
||||
- [进度草稿](/zh-CN/concepts/progress-drafts) — 在长轮次期间更新的可见进行中消息
|
||||
- [消息](/zh-CN/concepts/messages) — 消息生命周期和投递
|
||||
- [重试](/zh-CN/concepts/retry) — 投递失败时的重试行为
|
||||
- [渠道](/zh-CN/channels) — 每个渠道的流式传输支持
|
||||
- [渠道](/zh-CN/channels) — 按渠道的流式传输支持
|
||||
|
||||
Loading…
Reference in New Issue
Block a user