Docs: add zh-CN translations

This commit is contained in:
Josh Palmer
2026-02-01 22:47:44 +01:00
parent e70984745b
commit 149dc7c4e7
298 changed files with 53861 additions and 0 deletions

View File

@@ -0,0 +1,271 @@
---
read_when:
- 设置 BlueBubbles 渠道
- 排查 webhook 配对问题
- 在 macOS 上配置 iMessage
summary: 通过 BlueBubbles macOS 服务器集成 iMessageREST 发送/接收、输入状态、回应、配对、高级操作)。
title: BlueBubbles
x-i18n:
generated_at: "2026-02-01T19:41:18Z"
model: claude-opus-4-5
provider: pi
source_hash: ac9a9d71f3bbc661da6cb2897ea32d290bbd16b35925250601cfff53bc85de8c
source_path: channels/bluebubbles.md
workflow: 14
---
# BlueBubblesmacOS REST
状态:内置插件,通过 HTTP 与 BlueBubbles macOS 服务器通信。**推荐用于 iMessage 集成**,因为相比旧版 imsg 渠道,其 API 更丰富且更易于设置。
## 概述
- 通过 BlueBubbles 辅助应用在 macOS 上运行([bluebubbles.app](https://bluebubbles.app))。
- 推荐/已测试macOS Sequoia (15)。macOS Tahoe (26) 可用;编辑功能目前在 Tahoe 上不可用,群组图标更新可能报告成功但不会同步。
- OpenClaw 通过其 REST API 与之通信(`GET /api/v1/ping``POST /message/text``POST /chat/:id/*`)。
- 收到的消息通过 webhooks 到达;发出的回复、输入指示器、已读回执和 tapback 回应均为 REST 调用。
- 附件和贴纸作为入站媒体被接收(在可能的情况下呈现给智能体)。
- 配对/允许列表与其他渠道的工作方式相同(`/start/pairing` 等),使用 `channels.bluebubbles.allowFrom` + 配对码。
- 回应作为系统事件呈现,与 Slack/Telegram 相同,因此智能体可以在回复前"提及"它们。
- 高级功能:编辑、撤回、回复线程、消息特效、群组管理。
## 快速开始
1. 在你的 Mac 上安装 BlueBubbles 服务器(按照 [bluebubbles.app/install](https://bluebubbles.app/install) 的说明操作)。
2. 在 BlueBubbles 配置中,启用 Web API 并设置密码。
3. 运行 `openclaw onboard` 并选择 BlueBubbles或手动配置
```json5
{
channels: {
bluebubbles: {
enabled: true,
serverUrl: "http://192.168.1.100:1234",
password: "example-password",
webhookPath: "/bluebubbles-webhook",
},
},
}
```
4. 将 BlueBubbles webhooks 指向你的 Gateway示例`https://your-gateway-host:3000/bluebubbles-webhook?password=<password>`)。
5. 启动 Gateway它将注册 webhook 处理器并开始配对。
## 上手引导
BlueBubbles 可在交互式设置向导中使用:
```
openclaw onboard
```
向导会提示输入:
- **服务器 URL**必填BlueBubbles 服务器地址(例如 `http://192.168.1.100:1234`
- **密码**(必填):来自 BlueBubbles 服务器设置的 API 密码
- **Webhook 路径**(可选):默认为 `/bluebubbles-webhook`
- **私聊策略**:配对、允许列表、开放或禁用
- **允许列表**:电话号码、邮箱或聊天目标
你也可以通过 CLI 添加 BlueBubbles
```
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
```
## 访问控制(私聊 + 群组)
私聊:
- 默认:`channels.bluebubbles.dmPolicy = "pairing"`。
- 未知发送者会收到配对码;消息在批准前会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list bluebubbles`
- `openclaw pairing approve bluebubbles <CODE>`
- 配对是默认的令牌交换方式。详情:[配对](/start/pairing)
群组:
- `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(默认:`allowlist`)。
- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 控制谁可以在群组中触发。
### 提及门控(群组)
BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 行为一致:
- 使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)检测提及。
- 当群组启用 `requireMention` 时,智能体仅在被提及时回复。
- 来自授权发送者的控制命令会绕过提及门控。
按群组配置:
```json5
{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true }, // 所有群组的默认值
"iMessage;-;chat123": { requireMention: false }, // 针对特定群组的覆盖
},
},
},
}
```
### 命令门控
- 控制命令(例如 `/config`、`/model`)需要授权。
- 使用 `allowFrom` 和 `groupAllowFrom` 来确定命令授权。
- 授权发送者即使在群组中未提及也可以运行控制命令。
## 输入状态 + 已读回执
- **输入指示器**:在生成回复前和生成过程中自动发送。
- **已读回执**:由 `channels.bluebubbles.sendReadReceipts` 控制(默认:`true`)。
- **输入指示器**OpenClaw 发送输入开始事件BlueBubbles 在发送或超时时自动清除输入状态(通过 DELETE 手动停止不可靠)。
```json5
{
channels: {
bluebubbles: {
sendReadReceipts: false, // 禁用已读回执
},
},
}
```
## 高级操作
在配置中启用后BlueBubbles 支持高级消息操作:
```json5
{
channels: {
bluebubbles: {
actions: {
reactions: true, // tapback 回应默认true
edit: true, // 编辑已发送消息macOS 13+macOS 26 Tahoe 上不可用)
unsend: true, // 撤回消息macOS 13+
reply: true, // 按消息 GUID 回复线程
sendWithEffect: true, // 消息特效slam、loud 等)
renameGroup: true, // 重命名群聊
setGroupIcon: true, // 设置群聊图标/头像macOS 26 Tahoe 上不稳定)
addParticipant: true, // 向群组添加参与者
removeParticipant: true, // 从群组移除参与者
leaveGroup: true, // 离开群聊
sendAttachment: true, // 发送附件/媒体
},
},
},
}
```
可用操作:
- **react**:添加/移除 tapback 回应(`messageId`、`emoji`、`remove`
- **edit**:编辑已发送的消息(`messageId`、`text`
- **unsend**:撤回消息(`messageId`
- **reply**:回复特定消息(`messageId`、`text`、`to`
- **sendWithEffect**:使用 iMessage 特效发送(`text`、`to`、`effectId`
- **renameGroup**:重命名群聊(`chatGuid`、`displayName`
- **setGroupIcon**:设置群聊图标/头像(`chatGuid`、`media`)——在 macOS 26 Tahoe 上不稳定API 可能返回成功但图标不会同步)。
- **addParticipant**:向群组添加成员(`chatGuid`、`address`
- **removeParticipant**:从群组移除成员(`chatGuid`、`address`
- **leaveGroup**:离开群聊(`chatGuid`
- **sendAttachment**:发送媒体/文件(`to`、`buffer`、`filename`、`asVoice`
- 语音备忘录:设置 `asVoice: true` 并使用 **MP3** 或 **CAF** 音频以 iMessage 语音消息形式发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。
### 消息 ID短格式与完整格式
OpenClaw 可能会呈现*短*消息 ID例如 `1`、`2`)以节省 token。
- `MessageSid` / `ReplyToId` 可以是短 ID。
- `MessageSidFull` / `ReplyToIdFull` 包含提供商的完整 ID。
- 短 ID 存储在内存中;它们可能在重启或缓存清除后过期。
- 操作接受短格式或完整格式的 `messageId`,但如果短 ID 不再可用则会报错。
对于持久化自动化和存储,请使用完整 ID
- 模板:`{{MessageSidFull}}`、`{{ReplyToIdFull}}`
- 上下文:入站负载中的 `MessageSidFull` / `ReplyToIdFull`
模板变量请参阅[配置](/gateway/configuration)。
## 分块流式传输
控制回复是作为单条消息发送还是分块流式传输:
```json5
{
channels: {
bluebubbles: {
blockStreaming: true, // 启用分块流式传输(默认行为)
},
},
}
```
## 媒体 + 限制
- 入站附件会被下载并存储在媒体缓存中。
- 媒体上限通过 `channels.bluebubbles.mediaMaxMb` 设置默认8 MB
- 出站文本按 `channels.bluebubbles.textChunkLimit` 进行分块默认4000 字符)。
## 配置参考
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.bluebubbles.enabled`:启用/禁用渠道。
- `channels.bluebubbles.serverUrl`BlueBubbles REST API 基础 URL。
- `channels.bluebubbles.password`API 密码。
- `channels.bluebubbles.webhookPath`Webhook 端点路径(默认:`/bluebubbles-webhook`)。
- `channels.bluebubbles.dmPolicy``pairing | allowlist | open | disabled`(默认:`pairing`)。
- `channels.bluebubbles.allowFrom`私聊允许列表句柄、邮箱、E.164 号码、`chat_id:*`、`chat_guid:*`)。
- `channels.bluebubbles.groupPolicy``open | allowlist | disabled`(默认:`allowlist`)。
- `channels.bluebubbles.groupAllowFrom`:群组发送者允许列表。
- `channels.bluebubbles.groups`:按群组配置(`requireMention` 等)。
- `channels.bluebubbles.sendReadReceipts`:发送已读回执(默认:`true`)。
- `channels.bluebubbles.blockStreaming`:启用分块流式传输(默认:`true`)。
- `channels.bluebubbles.textChunkLimit`出站分块大小字符数默认4000
- `channels.bluebubbles.chunkMode``length`(默认)仅在超过 `textChunkLimit` 时分割;`newline` 在空行(段落边界)处分割,然后再进行长度分块。
- `channels.bluebubbles.mediaMaxMb`入站媒体上限MB默认8
- `channels.bluebubbles.historyLimit`用于上下文的最大群组消息数0 表示禁用)。
- `channels.bluebubbles.dmHistoryLimit`:私聊历史限制。
- `channels.bluebubbles.actions`:启用/禁用特定操作。
- `channels.bluebubbles.accounts`:多账户配置。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)。
- `messages.responsePrefix`。
## 寻址/投递目标
推荐使用 `chat_guid` 以实现稳定路由:
- `chat_guid:iMessage;-;+15555550123`(群组推荐使用)
- `chat_id:123`
- `chat_identifier:...`
- 直接句柄:`+15555550123`、`user@example.com`
- 如果直接句柄没有现有的私聊会话OpenClaw 将通过 `POST /api/v1/chat/new` 创建一个。这需要启用 BlueBubbles Private API。
## 安全
- Webhook 请求通过将 `guid`/`password` 查询参数或请求头与 `channels.bluebubbles.password` 比较来进行认证。来自 `localhost` 的请求也会被接受。
- 请保密 API 密码和 webhook 端点(将其视为凭证)。
- localhost 信任意味着同主机的反向代理可能会无意间绕过密码。如果你为 Gateway 设置了代理,请在代理层要求认证并配置 `gateway.trustedProxies`。参见 [Gateway 安全](/gateway/security#reverse-proxy-configuration)。
- 如果将 BlueBubbles 服务器暴露到局域网外部,请启用 HTTPS + 防火墙规则。
## 故障排除
- 如果输入/已读事件停止工作,请检查 BlueBubbles webhook 日志并验证 Gateway 路径是否与 `channels.bluebubbles.webhookPath` 匹配。
- 配对码在一小时后过期;使用 `openclaw pairing list bluebubbles` 和 `openclaw pairing approve bluebubbles <code>`。
- 回应功能需要 BlueBubbles private API`POST /api/v1/message/react`);请确保服务器版本已暴露该接口。
- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26Tahoe由于 private API 变更,编辑功能目前不可用。
- 群组图标更新在 macOS 26Tahoe上可能不稳定API 可能返回成功但新图标不会同步。
- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知不可用的操作。如果编辑功能在 macOS 26Tahoe上仍然显示请手动通过 `channels.bluebubbles.actions.edit=false` 禁用。
- 查看状态/健康信息:`openclaw status --all` 或 `openclaw status --deep`。
通用渠道工作流参考请参阅[渠道](/channels)和[插件](/plugins)指南。

View File

@@ -0,0 +1,463 @@
---
read_when:
- 开发 Discord 渠道功能
summary: Discord 机器人支持状态、功能和配置
title: Discord
x-i18n:
generated_at: "2026-02-01T19:19:25Z"
model: claude-opus-4-5
provider: pi
source_hash: 44e44e855481a81557d9c205bacaa82efef528f8dba59a2c39c26aeb4f420c62
source_path: channels/discord.md
workflow: 14
---
# DiscordBot API
状态:已可用于通过官方 Discord 机器人网关进行私信和服务器文字频道通信。
## 快速设置(新手)
1. 创建一个 Discord 机器人并复制机器人 token。
2. 在 Discord 应用设置中,启用 **Message Content Intent**(如果你计划使用允许列表或名称查找,还需启用 **Server Members Intent**)。
3. 为 OpenClaw 设置 token
- 环境变量:`DISCORD_BOT_TOKEN=...`
- 或配置:`channels.discord.token: "..."`
- 如果两者都设置了,配置优先(环境变量回退仅用于默认账户)。
4. 邀请机器人到你的服务器并赋予消息权限(如果只想用私信可以创建一个私人服务器)。
5. 启动 Gateway。
6. 私信访问默认需要配对;首次联系时批准配对码即可。
最小配置:
```json5
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
```
## 目标
- 通过 Discord 私信或服务器频道与 OpenClaw 对话。
- 私聊合并到智能体的主会话(默认 `agent:main:main`);服务器频道作为 `agent:<agentId>:discord:channel:<channelId>` 保持隔离(显示名称使用 `discord:<guildSlug>#<channelSlug>`)。
- 群组私信默认被忽略;通过 `channels.discord.dm.groupEnabled` 启用,可选通过 `channels.discord.dm.groupChannels` 限制。
- 保持路由确定性:回复始终发回消息到达的渠道。
## 工作原理
1. 创建 Discord 应用 → Bot启用所需的 intent私信 + 服务器消息 + 消息内容),获取机器人 token。
2. 邀请机器人到你的服务器,赋予在你需要使用的地方读取/发送消息所需的权限。
3. 使用 `channels.discord.token` 配置 OpenClaw或使用 `DISCORD_BOT_TOKEN` 作为回退)。
4. 运行 Gateway当 token 可用(配置优先,环境变量回退)且 `channels.discord.enabled` 不为 `false` 时,它会自动启动 Discord 渠道。
- 如果你偏好使用环境变量,设置 `DISCORD_BOT_TOKEN`(配置块是可选的)。
5. 私聊:投递时使用 `user:<id>`(或 `<@id>` 提及);所有回合都进入共享的 `main` 会话。裸数字 ID 具有歧义性,会被拒绝。
6. 服务器频道:投递时使用 `channel:<channelId>`。默认需要提及,可按服务器或按频道设置。
7. 私聊:默认通过 `channels.discord.dm.policy`(默认:`"pairing"`进行安全保护。未知发送者会收到配对码1 小时后过期);通过 `openclaw pairing approve discord <code>` 批准。
- 要保持旧的"对任何人开放"行为:设置 `channels.discord.dm.policy="open"``channels.discord.dm.allowFrom=["*"]`
- 要硬性限制允许列表:设置 `channels.discord.dm.policy="allowlist"` 并在 `channels.discord.dm.allowFrom` 中列出发送者。
- 要忽略所有私信:设置 `channels.discord.dm.enabled=false``channels.discord.dm.policy="disabled"`
8. 群组私信默认被忽略;通过 `channels.discord.dm.groupEnabled` 启用,可选通过 `channels.discord.dm.groupChannels` 限制。
9. 可选的服务器规则:设置 `channels.discord.guilds`,以服务器 ID推荐或 slug 为键,包含按频道的规则。
10. 可选的原生命令:`commands.native` 默认为 `"auto"`Discord/Telegram 开启Slack 关闭)。通过 `channels.discord.commands.native: true|false|"auto"` 覆盖;`false` 会清除之前注册的命令。文本命令由 `commands.text` 控制,必须作为独立的 `/...` 消息发送。使用 `commands.useAccessGroups: false` 可绕过命令的访问组检查。
- 完整命令列表 + 配置:[斜杠命令](/tools/slash-commands)
11. 可选的服务器上下文历史:设置 `channels.discord.historyLimit`(默认 20回退到 `messages.groupChat.historyLimit`)以在回复提及时包含最近 N 条服务器消息作为上下文。设置 `0` 可禁用。
12. 回应:智能体可以通过 `discord` 工具触发回应(由 `channels.discord.actions.*` 控制)。
- 回应移除语义:参见 [/tools/reactions](/tools/reactions)。
- `discord` 工具仅在当前渠道为 Discord 时暴露。
13. 原生命令使用隔离的会话键(`agent:<agentId>:discord:slash:<userId>`)而非共享的 `main` 会话。
注意:名称 → ID 解析使用服务器成员搜索,需要 Server Members Intent如果机器人无法搜索成员请使用 ID 或 `<@id>` 提及。
注意Slug 为小写且空格替换为 `-`。频道名称的 slug 不包含前导 `#`
注意:服务器上下文 `[from:]` 行包含 `author.tag` + `id`,方便进行可直接 ping 的回复。
## 配置写入
默认情况下Discord 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { discord: { configWrites: false } },
}
```
## 如何创建自己的机器人
这是在服务器guild频道`#help`)中运行 OpenClaw 的"Discord 开发者门户"设置。
### 1) 创建 Discord 应用 + 机器人用户
1. Discord 开发者门户 → **Applications****New Application**
2. 在你的应用中:
- **Bot** → **Add Bot**
- 复制 **Bot Token**(这就是你放入 `DISCORD_BOT_TOKEN` 的值)
### 2) 启用 OpenClaw 所需的网关 intent
Discord 会阻止"特权 intent",除非你明确启用。
**Bot****Privileged Gateway Intents** 中,启用:
- **Message Content Intent**(在大多数服务器中读取消息文本所必需;没有它你会看到"Used disallowed intents"或机器人会连接但不响应消息)
- **Server Members Intent**(推荐;某些成员/用户查找和服务器中的允许列表匹配所必需)
通常你**不**需要 **Presence Intent**
### 3) 生成邀请 URLOAuth2 URL 生成器)
在你的应用中:**OAuth2** → **URL Generator**
**Scopes**
-`bot`
-`applications.commands`(原生命令所必需)
**Bot Permissions**(最小基线)
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Add Reactions可选但推荐
- ✅ Use External Emojis / Stickers可选仅在你需要时
除非你在调试且完全信任机器人,否则避免使用 **Administrator**
复制生成的 URL打开它选择你的服务器安装机器人。
### 4) 获取 ID服务器/用户/频道)
Discord 到处使用数字 IDOpenClaw 配置推荐使用 ID。
1. Discord桌面/网页)→ **用户设置****高级** → 启用 **开发者模式**
2. 右键点击:
- 服务器名称 → **复制服务器 ID**guild id
- 频道(例如 `#help`)→ **复制频道 ID**
- 你的用户 → **复制用户 ID**
### 5) 配置 OpenClaw
#### Token
通过环境变量设置机器人 token推荐用于服务器
- `DISCORD_BOT_TOKEN=...`
或通过配置:
```json5
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
```
多账户支持:使用 `channels.discord.accounts`,每个账户配置独立的 token 和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
#### 允许列表 + 频道路由
示例"单服务器,只允许我,只允许 #help"
```json5
{
channels: {
discord: {
enabled: true,
dm: { enabled: false },
guilds: {
YOUR_GUILD_ID: {
users: ["YOUR_USER_ID"],
requireMention: true,
channels: {
help: { allow: true, requireMention: true },
},
},
},
retry: {
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1,
},
},
},
}
```
注意事项:
- `requireMention: true` 表示机器人仅在被提及时回复(推荐用于共享频道)。
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)对服务器消息也算作提及。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 如果存在 `channels`,任何未列出的频道默认被拒绝。
- 使用 `"*"` 频道条目来应用所有频道的默认值;明确的频道条目会覆盖通配符。
- 帖子继承父频道配置(允许列表、`requireMention`、技能、提示等),除非你明确添加帖子频道 ID。
- 机器人发送的消息默认被忽略;设置 `channels.discord.allowBots=true` 可允许它们(自己的消息仍然被过滤)。
- 警告:如果你允许回复其他机器人(`channels.discord.allowBots=true`),请使用 `requireMention``channels.discord.guilds.*.channels.<id>.users` 允许列表和/或在 `AGENTS.md``SOUL.md` 中设置明确的防护规则来防止机器人之间的回复循环。
### 6) 验证是否正常工作
1. 启动 Gateway。
2. 在你的服务器频道中,发送:`@Krill hello`(或你的机器人名称)。
3. 如果没有响应:查看下方**故障排除**。
### 故障排除
- 首先:运行 `openclaw doctor``openclaw channels status --probe`(可操作的警告 + 快速审计)。
- **"Used disallowed intents"**:在开发者门户中启用 **Message Content Intent**(以及可能的 **Server Members Intent**),然后重启 Gateway。
- **机器人连接但在服务器频道中从不回复**
- 缺少 **Message Content Intent**,或
- 机器人缺少频道权限View/Send/Read History
- 你的配置要求提及但你没有提及它,或
- 你的服务器/频道允许列表拒绝了该频道/用户。
- **`requireMention: false` 但仍然没有回复**
- `channels.discord.groupPolicy` 默认为 **allowlist**;将其设置为 `"open"` 或在 `channels.discord.guilds` 下添加服务器条目(可选在 `channels.discord.guilds.<id>.channels` 下列出频道以进行限制)。
- 如果你只设置了 `DISCORD_BOT_TOKEN` 且从未创建 `channels.discord` 部分,运行时默认将 `groupPolicy` 设为 `open`。添加 `channels.discord.groupPolicy``channels.defaults.groupPolicy` 或服务器/频道允许列表来锁定它。
- `requireMention` 必须位于 `channels.discord.guilds`(或特定频道)下。顶层的 `channels.discord.requireMention` 会被忽略。
- **权限审计**`channels status --probe`)仅检查数字频道 ID。如果你使用 slug/名称作为 `channels.discord.guilds.*.channels` 的键,审计无法验证权限。
- **私信不工作**`channels.discord.dm.enabled=false``channels.discord.dm.policy="disabled"`,或你尚未被批准(`channels.discord.dm.policy="pairing"`)。
## 功能与限制
- 私信和服务器文字频道(帖子被视为独立频道;不支持语音)。
- 输入指示尽力发送;消息分块使用 `channels.discord.textChunkLimit`(默认 2000并按行数分割较长回复`channels.discord.maxLinesPerMessage`,默认 17
- 可选的换行分块:设置 `channels.discord.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 支持文件上传,上限为配置的 `channels.discord.mediaMaxMb`(默认 8 MB
- 服务器回复默认需要提及门控,以避免嘈杂的机器人。
- 当消息引用另一条消息时,会注入回复上下文(引用内容 + ID
- 原生回复线程**默认关闭**;通过 `channels.discord.replyToMode` 和回复标签启用。
## 重试策略
出站 Discord API 调用在速率限制429时使用 Discord 的 `retry_after`(如可用)进行重试,采用指数退避和抖动。通过 `channels.discord.retry` 配置。参见[重试策略](/concepts/retry)。
## 配置
```json5
{
channels: {
discord: {
enabled: true,
token: "abc.123",
groupPolicy: "allowlist",
guilds: {
"*": {
channels: {
general: { allow: true },
},
},
},
mediaMaxMb: 8,
actions: {
reactions: true,
stickers: true,
emojiUploads: true,
stickerUploads: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
channels: true,
voiceStatus: true,
events: true,
moderation: false,
},
replyToMode: "off",
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["123456789012345678", "steipete"],
groupEnabled: false,
groupChannels: ["openclaw-dm"],
},
guilds: {
"*": { requireMention: true },
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
reactionNotifications: "own",
users: ["987654321098765432", "steipete"],
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["search", "docs"],
systemPrompt: "Keep answers short.",
},
},
},
},
},
},
}
```
确认回应由 `messages.ackReaction` + `messages.ackReactionScope` 全局控制。使用 `messages.removeAckAfterReply` 在机器人回复后清除确认回应。
- `dm.enabled`:设置 `false` 可忽略所有私信(默认 `true`)。
- `dm.policy`:私信访问控制(推荐 `pairing`)。`"open"` 需要 `dm.allowFrom=["*"]`
- `dm.allowFrom`:私信允许列表(用户 ID 或名称)。用于 `dm.policy="allowlist"``dm.policy="open"` 验证。向导接受用户名并在机器人可以搜索成员时将其解析为 ID。
- `dm.groupEnabled`:启用群组私信(默认 `false`)。
- `dm.groupChannels`:群组私信频道 ID 或 slug 的可选允许列表。
- `groupPolicy`:控制服务器频道处理方式(`open|disabled|allowlist``allowlist` 需要频道允许列表。
- `guilds`:按服务器 ID推荐或 slug 为键的按服务器规则。
- `guilds."*"`:当没有明确条目时应用的默认按服务器设置。
- `guilds.<id>.slug`:用于显示名称的可选友好 slug。
- `guilds.<id>.users`可选的按服务器用户允许列表ID 或名称)。
- `guilds.<id>.tools`:可选的按服务器工具策略覆盖(`allow`/`deny`/`alsoAllow`),在频道覆盖缺失时使用。
- `guilds.<id>.toolsBySender`:可选的按发送者工具策略覆盖(服务器级别,在频道覆盖缺失时应用;支持 `"*"` 通配符)。
- `guilds.<id>.channels.<channel>.allow`:当 `groupPolicy="allowlist"` 时允许/拒绝频道。
- `guilds.<id>.channels.<channel>.requireMention`:频道的提及门控。
- `guilds.<id>.channels.<channel>.tools`:可选的按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `guilds.<id>.channels.<channel>.toolsBySender`:可选的频道内按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `guilds.<id>.channels.<channel>.users`:可选的按频道用户允许列表。
- `guilds.<id>.channels.<channel>.skills`:技能过滤器(省略 = 所有技能,空 = 无)。
- `guilds.<id>.channels.<channel>.systemPrompt`:频道的额外系统提示(与频道主题合并)。
- `guilds.<id>.channels.<channel>.enabled`:设置 `false` 可禁用频道。
- `guilds.<id>.channels`:频道规则(键为频道 slug 或 ID
- `guilds.<id>.requireMention`:按服务器的提及要求(可按频道覆盖)。
- `guilds.<id>.reactionNotifications`:回应系统事件模式(`off``own``all``allowlist`)。
- `textChunkLimit`出站文本分块大小字符。默认2000。
- `chunkMode``length`(默认)仅在超过 `textChunkLimit` 时分割;`newline` 在按长度分块之前按空行(段落边界)分割。
- `maxLinesPerMessage`每条消息的软最大行数。默认17。
- `mediaMaxMb`:限制保存到磁盘的入站媒体大小。
- `historyLimit`:回复提及时包含的最近服务器消息数作为上下文(默认 20回退到 `messages.groupChat.historyLimit``0` 禁用)。
- `dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`dms["<user_id>"].historyLimit`
- `retry`:出站 Discord API 调用的重试策略attempts、minDelayMs、maxDelayMs、jitter
- `pluralkit`:解析 PluralKit 代理消息,使系统成员显示为不同的发送者。
- `actions`:按操作的工具门控;省略则允许所有(设置 `false` 可禁用)。
- `reactions`(涵盖添加回应 + 读取回应)
- `stickers``emojiUploads``stickerUploads``polls``permissions``messages``threads``pins``search`
- `memberInfo``roleInfo``channelInfo``voiceStatus``events`
- `channels`(创建/编辑/删除频道 + 分类 + 权限)
- `roles`(角色添加/移除,默认 `false`
- `moderation`(超时/踢出/封禁,默认 `false`
回应通知使用 `guilds.<id>.reactionNotifications`
- `off`:无回应事件。
- `own`:机器人自己消息上的回应(默认)。
- `all`:所有消息上的所有回应。
- `allowlist`:来自 `guilds.<id>.users` 的用户在所有消息上的回应(空列表则禁用)。
### PluralKitPK支持
启用 PK 查找,使代理消息解析为底层的系统 + 成员。启用后OpenClaw 使用成员身份进行允许列表匹配,并将发送者标记为 `Member (PK:System)` 以避免意外的 Discord ping。
```json5
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // 可选;私有系统需要
},
},
},
}
```
允许列表注意事项(启用 PK 时):
-`dm.allowFrom``guilds.<id>.users` 或按频道的 `users` 中使用 `pk:<memberId>`
- 成员显示名称也通过名称/slug 匹配。
- 查找使用**原始** Discord 消息 ID代理前的消息因此 PK API 仅在其 30 分钟窗口内解析它。
- 如果 PK 查找失败(例如没有 token 的私有系统),代理消息被视为机器人消息并被丢弃,除非设置 `channels.discord.allowBots=true`
### 工具操作默认值
| 操作组 | 默认值 | 说明 |
| -------------- | ------ | ------------------------------- |
| reactions | 启用 | 添加回应 + 列出回应 + emojiList |
| stickers | 启用 | 发送贴纸 |
| emojiUploads | 启用 | 上传表情 |
| stickerUploads | 启用 | 上传贴纸 |
| polls | 启用 | 创建投票 |
| permissions | 启用 | 频道权限快照 |
| messages | 启用 | 读取/发送/编辑/删除 |
| threads | 启用 | 创建/列出/回复 |
| pins | 启用 | 置顶/取消置顶/列出 |
| search | 启用 | 消息搜索(预览功能) |
| memberInfo | 启用 | 成员信息 |
| roleInfo | 启用 | 角色列表 |
| channelInfo | 启用 | 频道信息 + 列表 |
| channels | 启用 | 频道/分类管理 |
| voiceStatus | 启用 | 语音状态查询 |
| events | 启用 | 列出/创建计划事件 |
| roles | 禁用 | 角色添加/移除 |
| moderation | 禁用 | 超时/踢出/封禁 |
- `replyToMode``off`(默认)、`first``all`。仅在模型输出包含回复标签时生效。
## 回复标签
要请求线程回复,模型可以在输出中包含一个标签:
- `[[reply_to_current]]` — 回复触发的 Discord 消息。
- `[[reply_to:<id>]]` — 回复上下文/历史中的特定消息 ID。
当前消息 ID 以 `[message_id: …]` 附加到提示中;历史条目已包含 ID。
行为由 `channels.discord.replyToMode` 控制:
- `off`:忽略标签。
- `first`:仅第一个出站分块/附件作为回复。
- `all`:每个出站分块/附件都作为回复。
允许列表匹配注意事项:
- `allowFrom`/`users`/`groupChannels` 接受 ID、名称、标签或 `<@id>` 格式的提及。
- 支持 `discord:`/`user:`(用户)和 `channel:`(群组私信)等前缀。
- 使用 `*` 允许任何发送者/频道。
- 当存在 `guilds.<id>.channels` 时,未列出的频道默认被拒绝。
- 当省略 `guilds.<id>.channels` 时,允许列表中服务器的所有频道都被允许。
- 要**不允许任何频道**,设置 `channels.discord.groupPolicy: "disabled"`(或保持空的允许列表)。
- 配置向导接受 `Guild/Channel` 名称(公共 + 私有)并在可能时将其解析为 ID。
- 启动时OpenClaw 将允许列表中的频道/用户名称解析为 ID当机器人可以搜索成员时并记录映射未解析的条目保持原样。
原生命令注意事项:
- 注册的命令与 OpenClaw 的聊天命令一致。
- 原生命令遵循与私信/服务器消息相同的允许列表(`channels.discord.dm.allowFrom``channels.discord.guilds`、按频道规则)。
- 斜杠命令在 Discord UI 中可能对不在允许列表中的用户仍然可见OpenClaw 在执行时强制执行允许列表并回复"未授权"。
## 工具操作
智能体可以调用 `discord` 执行以下操作:
- `react` / `reactions`(添加或列出回应)
- `sticker``poll``permissions`
- `readMessages``sendMessage``editMessage``deleteMessage`
- 读取/搜索/置顶工具的负载包含标准化的 `timestampMs`UTC 纪元毫秒)和 `timestampUtc`,同时保留原始 Discord `timestamp`
- `threadCreate``threadList``threadReply`
- `pinMessage``unpinMessage``listPins`
- `searchMessages``memberInfo``roleInfo``roleAdd``roleRemove``emojiList`
- `channelInfo``channelList``voiceStatus``eventList``eventCreate`
- `timeout``kick``ban`
Discord 消息 ID 在注入的上下文中呈现(`[discord message id: …]` 和历史行),方便智能体定位它们。
表情可以是 unicode例如 `✅`)或自定义表情语法如 `<:party_blob:1234567890>`
## 安全与运维
- 将机器人 token 视为密码;在受管主机上推荐使用 `DISCORD_BOT_TOKEN` 环境变量或锁定配置文件权限。
- 仅授予机器人所需的权限(通常是读取/发送消息)。
- 如果机器人卡住或被速率限制,在确认没有其他进程占用 Discord 会话后重启 Gateway`openclaw gateway --force`)。

View File

@@ -0,0 +1,257 @@
---
read_when:
- 开发 Google Chat 渠道功能
summary: Google Chat 应用支持状态、功能和配置
title: Google Chat
x-i18n:
generated_at: "2026-02-01T19:20:03Z"
model: claude-opus-4-5
provider: pi
source_hash: 3b2bb116cdd12614c3d5afddd0879e9deb05c3606e3a2385cbc07f23552b357e
source_path: channels/googlechat.md
workflow: 14
---
# Google ChatChat API
状态:已可通过 Google Chat API webhook仅 HTTP用于私信和空间。
## 快速设置(新手)
1. 创建一个 Google Cloud 项目并启用 **Google Chat API**
- 前往:[Google Chat API 凭据](https://console.cloud.google.com/apis/api/chat.googleapis.com/credentials)
- 如果尚未启用,请启用该 API。
2. 创建**服务账户**
- 点击 **Create Credentials** > **Service Account**
- 随意命名(例如 `openclaw-chat`)。
- 权限留空(点击 **Continue**)。
- 有权访问的主体留空(点击 **Done**)。
3. 创建并下载 **JSON 密钥**
- 在服务账户列表中,点击你刚创建的那个。
- 进入 **Keys** 标签页。
- 点击 **Add Key** > **Create new key**
- 选择 **JSON** 并点击 **Create**
4. 将下载的 JSON 文件存储在你的 Gateway 主机上(例如 `~/.openclaw/googlechat-service-account.json`)。
5. 在 [Google Cloud Console Chat 配置](https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat) 中创建 Google Chat 应用:
- 填写 **Application info**
- **App name**:(例如 `OpenClaw`
- **Avatar URL**:(例如 `https://openclaw.ai/logo.png`
- **Description**:(例如 `Personal AI Assistant`
- 启用 **Interactive features**
-**Functionality** 下,勾选 **Join spaces and group conversations**
-**Connection settings** 下,选择 **HTTP endpoint URL**
-**Triggers** 下,选择 **Use a common HTTP endpoint URL for all triggers** 并将其设置为你的 Gateway 公共 URL 后跟 `/googlechat`
- _提示运行 `openclaw status` 可查找你的 Gateway 公共 URL。_
-**Visibility** 下,勾选 **Make this Chat app available to specific people and groups in &lt;Your Domain&gt;**
- 在文本框中输入你的邮箱地址(例如 `user@example.com`)。
- 点击底部的 **Save**
6. **启用应用状态**
- 保存后,**刷新页面**。
- 查找 **App status** 部分(通常在保存后位于顶部或底部附近)。
- 将状态更改为 **Live - available to users**
- 再次点击 **Save**
7. 使用服务账户路径 + webhook audience 配置 OpenClaw
- 环境变量:`GOOGLE_CHAT_SERVICE_ACCOUNT_FILE=/path/to/service-account.json`
- 或配置:`channels.googlechat.serviceAccountFile: "/path/to/service-account.json"`
8. 设置 webhook audience 类型 + 值(与你的 Chat 应用配置匹配)。
9. 启动 Gateway。Google Chat 将向你的 webhook 路径发送 POST 请求。
## 添加到 Google Chat
Gateway 运行且你的邮箱已添加到可见性列表后:
1. 前往 [Google Chat](https://chat.google.com/)。
2. 点击 **Direct Messages** 旁边的 **+**(加号)图标。
3. 在搜索栏中(通常用于添加人员的地方),输入你在 Google Cloud Console 中配置的 **App name**
- **注意**:机器人*不会*出现在"Marketplace"浏览列表中,因为它是私有应用。你必须按名称搜索。
4. 从结果中选择你的机器人。
5. 点击 **Add****Chat** 开始一对一对话。
6. 发送"Hello"来触发助手!
## 公共 URL仅 Webhook
Google Chat webhook 需要公共 HTTPS 端点。为安全起见,**仅将 `/googlechat` 路径暴露**到互联网。将 OpenClaw 仪表板和其他敏感端点保持在私有网络上。
### 方案 ATailscale Funnel推荐
使用 Tailscale Serve 用于私有仪表板Funnel 用于公共 webhook 路径。这样 `/` 保持私有,仅暴露 `/googlechat`
1. **检查你的 Gateway 绑定在哪个地址上:**
```bash
ss -tlnp | grep 18789
```
注意 IP 地址(例如 `127.0.0.1`、`0.0.0.0` 或你的 Tailscale IP 如 `100.x.x.x`)。
2. **仅将仪表板暴露给 tailnet端口 8443**
```bash
# 如果绑定到 localhost127.0.0.1 或 0.0.0.0
tailscale serve --bg --https 8443 http://127.0.0.1:18789
# 如果仅绑定到 Tailscale IP例如 100.106.161.80
tailscale serve --bg --https 8443 http://100.106.161.80:18789
```
3. **仅公开暴露 webhook 路径:**
```bash
# 如果绑定到 localhost127.0.0.1 或 0.0.0.0
tailscale funnel --bg --set-path /googlechat http://127.0.0.1:18789/googlechat
# 如果仅绑定到 Tailscale IP例如 100.106.161.80
tailscale funnel --bg --set-path /googlechat http://100.106.161.80:18789/googlechat
```
4. **为节点授权 Funnel 访问:**
如果出现提示,请访问输出中显示的授权 URL在你的 tailnet 策略中为此节点启用 Funnel。
5. **验证配置:**
```bash
tailscale serve status
tailscale funnel status
```
你的公共 webhook URL 将是:
`https://<node-name>.<tailnet>.ts.net/googlechat`
你的私有仪表板仅限 tailnet 访问:
`https://<node-name>.<tailnet>.ts.net:8443/`
在 Google Chat 应用配置中使用公共 URL不带 `:8443`)。
> 注意:此配置在重启后持续有效。要在之后移除,运行 `tailscale funnel reset` 和 `tailscale serve reset`。
### 方案 B反向代理Caddy
如果你使用像 Caddy 这样的反向代理,仅代理特定路径:
```caddy
your-domain.com {
reverse_proxy /googlechat* localhost:18789
}
```
使用此配置,对 `your-domain.com/` 的任何请求将被忽略或返回 404而 `your-domain.com/googlechat` 安全地路由到 OpenClaw。
### 方案 CCloudflare Tunnel
配置你的隧道入口规则,仅路由 webhook 路径:
- **路径**`/googlechat` -> `http://localhost:18789/googlechat`
- **默认规则**HTTP 404Not Found
## 工作原理
1. Google Chat 向 Gateway 发送 webhook POST 请求。每个请求包含一个 `Authorization: Bearer <token>` 头。
2. OpenClaw 根据配置的 `audienceType` + `audience` 验证 token
- `audienceType: "app-url"` → audience 是你的 HTTPS webhook URL。
- `audienceType: "project-number"` → audience 是 Cloud 项目编号。
3. 消息按空间路由:
- 私信使用会话键 `agent:<agentId>:googlechat:dm:<spaceId>`。
- 空间使用会话键 `agent:<agentId>:googlechat:group:<spaceId>`。
4. 私信访问默认需要配对。未知发送者会收到配对码;通过以下方式批准:
- `openclaw pairing approve googlechat <code>`
5. 群组空间默认需要 @提及。如果提及检测需要应用的用户名,请使用 `botUser`。
## 目标
使用以下标识符进行投递和允许列表:
- 私信:`users/<userId>` 或 `users/<email>`(接受邮箱地址)。
- 空间:`spaces/<spaceId>`。
## 配置要点
```json5
{
channels: {
googlechat: {
enabled: true,
serviceAccountFile: "/path/to/service-account.json",
audienceType: "app-url",
audience: "https://gateway.example.com/googlechat",
webhookPath: "/googlechat",
botUser: "users/1234567890", // 可选;辅助提及检测
dm: {
policy: "pairing",
allowFrom: ["users/1234567890", "name@example.com"],
},
groupPolicy: "allowlist",
groups: {
"spaces/AAAA": {
allow: true,
requireMention: true,
users: ["users/1234567890"],
systemPrompt: "Short answers only.",
},
},
actions: { reactions: true },
typingIndicator: "message",
mediaMaxMb: 20,
},
},
}
```
注意事项:
- 服务账户凭据也可以通过 `serviceAccount`JSON 字符串)内联传递。
- 如果未设置 `webhookPath`,默认 webhook 路径为 `/googlechat`。
- 当 `actions.reactions` 启用时,可通过 `reactions` 工具和 `channels action` 使用回应功能。
- `typingIndicator` 支持 `none`、`message`(默认)和 `reaction`reaction 需要用户 OAuth
- 附件通过 Chat API 下载并存储在媒体管道中(大小由 `mediaMaxMb` 限制)。
## 故障排除
### 405 Method Not Allowed
如果 Google Cloud Logs Explorer 显示如下错误:
```
status code: 405, reason phrase: HTTP error response: HTTP/1.1 405 Method Not Allowed
```
这意味着 webhook 处理器未注册。常见原因:
1. **渠道未配置**:配置中缺少 `channels.googlechat` 部分。通过以下方式验证:
```bash
openclaw config get channels.googlechat
```
如果返回"Config path not found",添加配置(参见[配置要点](#配置要点))。
2. **插件未启用**:检查插件状态:
```bash
openclaw plugins list | grep googlechat
```
如果显示"disabled",在配置中添加 `plugins.entries.googlechat.enabled: true`。
3. **Gateway 未重启**:添加配置后,重启 Gateway
```bash
openclaw gateway restart
```
验证渠道是否正在运行:
```bash
openclaw channels status
# 应显示Google Chat default: enabled, configured, ...
```
### 其他问题
- 检查 `openclaw channels status --probe` 查看认证错误或缺失的 audience 配置。
- 如果没有消息到达,确认 Chat 应用的 webhook URL + 事件订阅。
- 如果提及门控阻止了回复,将 `botUser` 设置为应用的用户资源名称并验证 `requireMention`。
- 发送测试消息时使用 `openclaw logs --follow` 查看请求是否到达 Gateway。
相关文档:
- [Gateway 配置](/gateway/configuration)
- [安全](/gateway/security)
- [回应](/tools/reactions)

View File

@@ -0,0 +1,38 @@
---
read_when:
- 开发 Telegram 或 grammY 相关功能
summary: 通过 grammY 集成 Telegram Bot API 及设置说明
title: grammY
x-i18n:
generated_at: "2026-02-01T19:20:16Z"
model: claude-opus-4-5
provider: pi
source_hash: ea7ef23e6d77801f4ef5fc56685ef4470f79f5aecab448d644a72cbab53521b7
source_path: channels/grammy.md
workflow: 14
---
# grammY 集成Telegram Bot API
# 为什么选择 grammY
- TypeScript 优先的 Bot API 客户端,内置长轮询 + webhook 辅助工具、中间件、错误处理、速率限制器。
- 比手动编写 fetch + FormData 更简洁的媒体辅助工具;支持所有 Bot API 方法。
- 可扩展:通过自定义 fetch 支持代理,会话中间件(可选),类型安全的上下文。
# 已交付的功能
- **单一客户端路径:** 基于 fetch 的实现已移除grammY 现在是唯一的 Telegram 客户端(发送 + Gateway默认启用 grammY throttler。
- **Gateway** `monitorTelegramProvider` 构建一个 grammY `Bot`,接入提及/允许列表门控、通过 `getFile`/`download` 下载媒体,并通过 `sendMessage/sendPhoto/sendVideo/sendAudio/sendDocument` 投递回复。支持通过 `webhookCallback` 进行长轮询或 webhook。
- **代理:** 可选的 `channels.telegram.proxy` 通过 grammY 的 `client.baseFetch` 使用 `undici.ProxyAgent`
- **Webhook 支持:** `webhook-set.ts` 封装了 `setWebhook/deleteWebhook``webhook.ts` 托管回调并支持健康检查 + 优雅关闭。当设置了 `channels.telegram.webhookUrl` + `channels.telegram.webhookSecret` 时 Gateway 启用 webhook 模式(否则使用长轮询)。
- **会话:** 私聊合并到智能体主会话(`agent:<agentId>:<mainKey>`);群组使用 `agent:<agentId>:telegram:group:<chatId>`;回复路由回同一渠道。
- **配置选项:** `channels.telegram.botToken``channels.telegram.dmPolicy``channels.telegram.groups`(允许列表 + 提及默认值)、`channels.telegram.allowFrom``channels.telegram.groupAllowFrom``channels.telegram.groupPolicy``channels.telegram.mediaMaxMb``channels.telegram.linkPreview``channels.telegram.proxy``channels.telegram.webhookSecret``channels.telegram.webhookUrl`
- **草稿流式传输:** 可选的 `channels.telegram.streamMode` 在私有话题聊天中使用 `sendMessageDraft`Bot API 9.3+)。这与渠道分块流式传输是分开的。
- **测试:** grammY mock 覆盖了私信 + 群组提及门控和出站发送;欢迎更多媒体/webhook 测试用例。
待讨论问题
- 如果遇到 Bot API 429 错误,考虑使用可选的 grammY 插件throttler
- 添加更多结构化的媒体测试(贴纸、语音消息)。
- 使 webhook 监听端口可配置(目前固定为 8787除非通过 Gateway 接入)。

View File

@@ -0,0 +1,302 @@
---
read_when:
- 设置 iMessage 支持
- 调试 iMessage 收发
summary: 通过 imsg基于 stdio 的 JSON-RPC实现 iMessage 支持、设置和 chat_id 路由
title: iMessage
x-i18n:
generated_at: "2026-02-01T19:21:07Z"
model: claude-opus-4-5
provider: pi
source_hash: bc19756a42ead80a0845f18c4830c3f1f40948f69b2b016a4026598cfb8fef0d
source_path: channels/imessage.md
workflow: 14
---
# iMessageimsg
状态:外部 CLI 集成。Gateway 启动 `imsg rpc`(基于 stdio 的 JSON-RPC
## 快速设置(新手)
1. 确保此 Mac 上的"信息"已登录。
2. 安装 `imsg`
- `brew install steipete/tap/imsg`
3. 配置 OpenClaw 的 `channels.imessage.cliPath``channels.imessage.dbPath`
4. 启动 Gateway 并批准所有 macOS 提示(自动化 + 完全磁盘访问权限)。
最小配置:
```json5
{
channels: {
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
dbPath: "/Users/<you>/Library/Messages/chat.db",
},
},
}
```
## 它是什么
- 在 macOS 上由 `imsg` 支持的 iMessage 渠道。
- 确定性路由:回复始终发回 iMessage。
- 私信共享智能体的主会话;群组是隔离的(`agent:<agentId>:imessage:group:<chat_id>`)。
- 如果多参与者线程以 `is_group=false` 到达,你仍然可以通过 `chat_id` 使用 `channels.imessage.groups` 来隔离它(参见下方"类群组线程")。
## 配置写入
默认情况下iMessage 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { imessage: { configWrites: false } },
}
```
## 要求
- macOS 且"信息"已登录。
- OpenClaw + `imsg` 需要完全磁盘访问权限(访问 Messages 数据库)。
- 发送时需要自动化权限。
- `channels.imessage.cliPath` 可以指向任何代理 stdin/stdout 的命令(例如,通过 SSH 连接到另一台 Mac 并运行 `imsg rpc` 的包装脚本)。
## 设置(快速路径)
1. 确保此 Mac 上的"信息"已登录。
2. 配置 iMessage 并启动 Gateway。
### 专用机器人 macOS 用户(用于隔离身份)
如果你希望机器人从一个**独立的 iMessage 身份**发送消息(并保持你的个人"信息"整洁),请使用专用的 Apple ID + 专用的 macOS 用户。
1. 创建一个专用的 Apple ID例如`my-cool-bot@icloud.com`)。
- Apple 可能需要手机号码进行验证/双重认证。
2. 创建一个 macOS 用户(例如:`openclawhome`)并登录。
3. 在该 macOS 用户中打开"信息"并使用机器人 Apple ID 登录 iMessage。
4. 启用远程登录(系统设置 → 通用 → 共享 → 远程登录)。
5. 安装 `imsg`
- `brew install steipete/tap/imsg`
6. 设置 SSH 使 `ssh <bot-macos-user>@localhost true` 无需密码即可工作。
7.`channels.imessage.accounts.bot.cliPath` 指向一个以机器人用户身份运行 `imsg` 的 SSH 包装脚本。
首次运行注意事项:发送/接收可能需要在*机器人 macOS 用户*中进行 GUI 审批(自动化 + 完全磁盘访问权限)。如果 `imsg rpc` 看起来卡住或退出,请登录该用户(屏幕共享很有帮助),运行一次 `imsg chats --limit 1` / `imsg send ...`,批准提示,然后重试。
示例包装脚本(`chmod +x`)。将 `<bot-macos-user>` 替换为你的实际 macOS 用户名:
```bash
#!/usr/bin/env bash
set -euo pipefail
# 先运行一次交互式 SSH 以接受主机密钥:
# ssh <bot-macos-user>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <bot-macos-user>@localhost \
"/usr/local/bin/imsg" "$@"
```
示例配置:
```json5
{
channels: {
imessage: {
enabled: true,
accounts: {
bot: {
name: "Bot",
enabled: true,
cliPath: "/path/to/imsg-bot",
dbPath: "/Users/<bot-macos-user>/Library/Messages/chat.db",
},
},
},
},
}
```
对于单账户设置,使用扁平选项(`channels.imessage.cliPath``channels.imessage.dbPath`)而非 `accounts` 映射。
### 远程/SSH 变体(可选)
如果你想在另一台 Mac 上使用 iMessage`channels.imessage.cliPath` 设置为通过 SSH 在远程 macOS 主机上运行 `imsg` 的包装脚本。OpenClaw 只需要 stdio。
示例包装脚本:
```bash
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
```
**远程附件:**`cliPath` 通过 SSH 指向远程主机时Messages 数据库中的附件路径引用的是远程机器上的文件。OpenClaw 可以通过设置 `channels.imessage.remoteHost` 自动通过 SCP 获取这些文件:
```json5
{
channels: {
imessage: {
cliPath: "~/imsg-ssh", // 到远程 Mac 的 SSH 包装脚本
remoteHost: "user@gateway-host", // 用于 SCP 文件传输
includeAttachments: true,
},
},
}
```
如果未设置 `remoteHost`OpenClaw 会尝试通过解析你包装脚本中的 SSH 命令来自动检测。建议显式配置以确保可靠性。
#### 通过 Tailscale 连接远程 Mac示例
如果 Gateway 运行在 Linux 主机/虚拟机上但 iMessage 必须运行在 Mac 上Tailscale 是最简单的桥接方案Gateway 通过 tailnet 与 Mac 通信,通过 SSH 运行 `imsg`,并通过 SCP 传回附件。
架构:
```
┌──────────────────────────────┐ SSH (imsg rpc) ┌──────────────────────────┐
│ Gateway 主机Linux/VM │──────────────────────────────────▶│ 装有 Messages + imsg 的 Mac │
│ - openclaw gateway │ SCP附件 │ - Messages 已登录 │
│ - channels.imessage.cliPath │◀──────────────────────────────────│ - 远程登录已启用 │
└──────────────────────────────┘ └──────────────────────────┘
│ Tailscale tailnet主机名或 100.x.y.z
user@gateway-host
```
具体配置示例Tailscale 主机名):
```json5
{
channels: {
imessage: {
enabled: true,
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "bot@mac-mini.tailnet-1234.ts.net",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
```
示例包装脚本(`~/.openclaw/scripts/imsg-ssh`
```bash
#!/usr/bin/env bash
exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
```
注意事项:
- 确保 Mac 已登录"信息",且远程登录已启用。
- 使用 SSH 密钥使 `ssh bot@mac-mini.tailnet-1234.ts.net` 无需提示即可工作。
- `remoteHost` 应与 SSH 目标匹配,以便 SCP 可以获取附件。
多账户支持:使用 `channels.imessage.accounts`,每个账户配置独立选项和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。不要提交 `~/.openclaw/openclaw.json`(它通常包含 token
## 访问控制(私信 + 群组)
私信:
- 默认:`channels.imessage.dmPolicy = "pairing"`
- 未知发送者会收到配对码;在批准之前消息会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list imessage`
- `openclaw pairing approve imessage <CODE>`
- 配对是 iMessage 私信的默认令牌交换方式。详情:[配对](/start/pairing)
群组:
- `channels.imessage.groupPolicy = open | allowlist | disabled`
- 当设置为 `allowlist` 时,`channels.imessage.groupAllowFrom` 控制谁可以在群组中触发。
- 提及门控使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`),因为 iMessage 没有原生提及元数据。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
## 工作原理(行为)
- `imsg` 流式传输消息事件Gateway 将其标准化为共享的渠道信封。
- 回复始终路由回同一个 chat id 或用户名。
## 类群组线程(`is_group=false`
一些 iMessage 线程可能有多个参与者,但由于"信息"存储聊天标识符的方式,仍然以 `is_group=false` 到达。
如果你在 `channels.imessage.groups` 下显式配置了一个 `chat_id`OpenClaw 会将该线程视为"群组",用于:
- 会话隔离(独立的 `agent:<agentId>:imessage:group:<chat_id>` 会话键)
- 群组允许列表/提及门控行为
示例:
```json5
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"42": { requireMention: false },
},
},
},
}
```
当你想为特定线程使用隔离的个性/模型时很有用(参见[多智能体路由](/concepts/multi-agent))。有关文件系统隔离,请参阅[沙箱](/gateway/sandboxing)。
## 媒体 + 限制
- 通过 `channels.imessage.includeAttachments` 可选接收附件。
- 媒体上限通过 `channels.imessage.mediaMaxMb` 设置。
## 限制
- 出站文本按 `channels.imessage.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.imessage.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 媒体上传上限由 `channels.imessage.mediaMaxMb` 限制(默认 16
## 寻址 / 投递目标
推荐使用 `chat_id` 进行稳定路由:
- `chat_id:123`(推荐)
- `chat_guid:...`
- `chat_identifier:...`
- 直接用户名:`imessage:+1555` / `sms:+1555` / `user@example.com`
列出聊天:
```
imsg chats --limit 20
```
## 配置参考iMessage
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.imessage.enabled`:启用/禁用渠道启动。
- `channels.imessage.cliPath``imsg` 的路径。
- `channels.imessage.dbPath`Messages 数据库路径。
- `channels.imessage.remoteHost`:当 `cliPath` 指向远程 Mac 时用于 SCP 附件传输的 SSH 主机(例如 `user@gateway-host`)。未设置时从 SSH 包装脚本自动检测。
- `channels.imessage.service``imessage | sms | auto`
- `channels.imessage.region`SMS 区域。
- `channels.imessage.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.imessage.allowFrom`私信允许列表用户名、邮箱、E.164 号码或 `chat_id:*`)。`open` 需要 `"*"`。iMessage 没有用户名;使用用户名或聊天目标。
- `channels.imessage.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.imessage.groupAllowFrom`:群组发送者允许列表。
- `channels.imessage.historyLimit` / `channels.imessage.accounts.*.historyLimit`包含为上下文的最大群组消息数0 禁用)。
- `channels.imessage.dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`channels.imessage.dms["<handle>"].historyLimit`
- `channels.imessage.groups`:按群组默认值 + 允许列表(使用 `"*"` 设置全局默认值)。
- `channels.imessage.includeAttachments`:将附件接收到上下文中。
- `channels.imessage.mediaMaxMb`:入站/出站媒体上限MB
- `channels.imessage.textChunkLimit`:出站分块大小(字符)。
- `channels.imessage.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)。
- `messages.responsePrefix`

View File

@@ -0,0 +1,50 @@
---
read_when:
- 你想为 OpenClaw 选择一个聊天渠道
- 你需要快速了解支持的消息平台
summary: OpenClaw 可连接的消息平台
title: 聊天渠道
x-i18n:
generated_at: "2026-02-01T19:21:22Z"
model: claude-opus-4-5
provider: pi
source_hash: 2632863def6dee97e0fa8b931762f0969174fd4fb22303a00dcd46527fe4a141
source_path: channels/index.md
workflow: 14
---
# 聊天渠道
OpenClaw 可以在你已经使用的任何聊天应用上与你对话。每个渠道通过 Gateway 连接。所有渠道都支持文本;媒体和回应功能因渠道而异。
## 支持的渠道
- [WhatsApp](/channels/whatsapp) — 最受欢迎;使用 Baileys 并需要二维码配对。
- [Telegram](/channels/telegram) — 通过 grammY 使用 Bot API支持群组。
- [Discord](/channels/discord) — Discord Bot API + Gateway支持服务器、频道和私信。
- [Slack](/channels/slack) — Bolt SDK工作区应用。
- [Google Chat](/channels/googlechat) — 通过 HTTP webhook 使用 Google Chat API 应用。
- [Mattermost](/channels/mattermost) — Bot API + WebSocket频道、群组、私信插件需单独安装
- [Signal](/channels/signal) — signal-cli注重隐私。
- [BlueBubbles](/channels/bluebubbles) — **推荐用于 iMessage**;使用 BlueBubbles macOS 服务器 REST API功能完整编辑、撤回、特效、回应、群组管理——编辑功能在 macOS 26 Tahoe 上目前不可用)。
- [iMessage](/channels/imessage) — 仅限 macOS通过 imsg 原生集成(旧版,新设置建议使用 BlueBubbles
- [Microsoft Teams](/channels/msteams) — Bot Framework企业支持插件需单独安装
- [LINE](/channels/line) — LINE Messaging API 机器人(插件,需单独安装)。
- [Nextcloud Talk](/channels/nextcloud-talk) — 通过 Nextcloud Talk 的自托管聊天(插件,需单独安装)。
- [Matrix](/channels/matrix) — Matrix 协议(插件,需单独安装)。
- [Nostr](/channels/nostr) — 通过 NIP-04 的去中心化私信(插件,需单独安装)。
- [Tlon](/channels/tlon) — 基于 Urbit 的通讯工具(插件,需单独安装)。
- [Twitch](/channels/twitch) — 通过 IRC 连接的 Twitch 聊天(插件,需单独安装)。
- [Zalo](/channels/zalo) — Zalo Bot API越南流行的通讯工具插件需单独安装
- [Zalo Personal](/channels/zalouser) — 通过二维码登录的 Zalo 个人账户(插件,需单独安装)。
- [WebChat](/web/webchat) — 通过 WebSocket 的 Gateway WebChat UI。
## 注意事项
- 渠道可以同时运行;配置多个渠道后 OpenClaw 会按聊天路由。
- 最快的设置通常是 **Telegram**(简单的 bot token。WhatsApp 需要二维码配对并在磁盘上存储更多状态。
- 群组行为因渠道而异;参见[群组](/concepts/groups)。
- 私信配对和允许列表出于安全考虑强制执行;参见[安全](/gateway/security)。
- Telegram 内部实现:[grammY 说明](/channels/grammy)。
- 故障排除:[渠道故障排除](/channels/troubleshooting)。
- 模型提供商单独文档化;参见[模型提供商](/providers/models)。

180
docs/zh-CN/channels/line.md Normal file
View File

@@ -0,0 +1,180 @@
---
read_when:
- 你想将 OpenClaw 连接到 LINE
- 你需要 LINE webhook + 凭据设置
- 你需要 LINE 特定的消息选项
summary: LINE Messaging API 插件设置、配置和使用
title: LINE
x-i18n:
generated_at: "2026-02-01T19:21:38Z"
model: claude-opus-4-5
provider: pi
source_hash: 8fbac126786f95b9454f3cc61906c2798393a8d7914e787d3755c020c7ab2da6
source_path: channels/line.md
workflow: 14
---
# LINE插件
LINE 通过 LINE Messaging API 连接到 OpenClaw。插件作为 Gateway 上的 webhook 接收器运行,使用你的频道访问 token + 频道密钥进行认证。
状态通过插件支持。支持私信、群聊、媒体、位置、Flex 消息、模板消息和快速回复。不支持回应和线程。
## 需要插件
安装 LINE 插件:
```bash
openclaw plugins install @openclaw/line
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/line
```
## 设置
1. 创建 LINE Developers 账户并打开控制台:
https://developers.line.biz/console/
2. 创建(或选择)一个 Provider 并添加一个 **Messaging API** 频道。
3. 从频道设置中复制 **Channel access token****Channel secret**
4. 在 Messaging API 设置中启用 **Use webhook**
5. 将 webhook URL 设置为你的 Gateway 端点(需要 HTTPS
```
https://gateway-host/line/webhook
```
Gateway 响应 LINE 的 webhook 验证GET和入站事件POST。如果你需要自定义路径请设置 `channels.line.webhookPath``channels.line.accounts.<id>.webhookPath` 并相应更新 URL。
## 配置
最小配置:
```json5
{
channels: {
line: {
enabled: true,
channelAccessToken: "LINE_CHANNEL_ACCESS_TOKEN",
channelSecret: "LINE_CHANNEL_SECRET",
dmPolicy: "pairing",
},
},
}
```
环境变量(仅默认账户):
- `LINE_CHANNEL_ACCESS_TOKEN`
- `LINE_CHANNEL_SECRET`
Token/密钥文件:
```json5
{
channels: {
line: {
tokenFile: "/path/to/line-token.txt",
secretFile: "/path/to/line-secret.txt",
},
},
}
```
多账户:
```json5
{
channels: {
line: {
accounts: {
marketing: {
channelAccessToken: "...",
channelSecret: "...",
webhookPath: "/line/marketing",
},
},
},
},
}
```
## 访问控制
私信默认需要配对。未知发送者会收到配对码,在批准之前其消息会被忽略。
```bash
openclaw pairing list line
openclaw pairing approve line <CODE>
```
允许列表和策略:
- `channels.line.dmPolicy``pairing | allowlist | open | disabled`
- `channels.line.allowFrom`:私信的允许 LINE 用户 ID 列表
- `channels.line.groupPolicy``allowlist | open | disabled`
- `channels.line.groupAllowFrom`:群组的允许 LINE 用户 ID 列表
- 按群组覆盖:`channels.line.groups.<groupId>.allowFrom`
LINE ID 区分大小写。有效的 ID 格式如下:
- 用户:`U` + 32 位十六进制字符
- 群组:`C` + 32 位十六进制字符
- 房间:`R` + 32 位十六进制字符
## 消息行为
- 文本在 5000 字符处分块。
- Markdown 格式会被去除;代码块和表格在可能时会转换为 Flex 卡片。
- 流式响应会被缓冲;智能体工作时 LINE 接收完整分块并显示加载动画。
- 媒体下载上限由 `channels.line.mediaMaxMb` 限制(默认 10
## 渠道数据(富消息)
使用 `channelData.line` 发送快速回复、位置、Flex 卡片或模板消息。
```json5
{
text: "Here you go",
channelData: {
line: {
quickReplies: ["Status", "Help"],
location: {
title: "Office",
address: "123 Main St",
latitude: 35.681236,
longitude: 139.767125,
},
flexMessage: {
altText: "Status card",
contents: {
/* Flex 负载 */
},
},
templateMessage: {
type: "confirm",
text: "Proceed?",
confirmLabel: "Yes",
confirmData: "yes",
cancelLabel: "No",
cancelData: "no",
},
},
},
}
```
LINE 插件还附带一个 `/card` 命令用于 Flex 消息预设:
```
/card info "Welcome" "Thanks for joining!"
```
## 故障排除
- **Webhook 验证失败:** 确保 webhook URL 为 HTTPS 且 `channelSecret` 与 LINE 控制台匹配。
- **没有入站事件:** 确认 webhook 路径与 `channels.line.webhookPath` 匹配且 Gateway 可从 LINE 访问。
- **媒体下载错误:** 如果媒体超过默认限制,请增大 `channels.line.mediaMaxMb`

View File

@@ -0,0 +1,63 @@
---
read_when:
- 添加或修改渠道位置解析
- 在智能体提示或工具中使用位置上下文字段
summary: 入站渠道位置解析Telegram + WhatsApp及上下文字段
title: 渠道位置解析
x-i18n:
generated_at: "2026-02-01T19:21:46Z"
model: claude-opus-4-5
provider: pi
source_hash: 5602ef105c3da7e47497bfed8fc343dd8d7f3c019ff7e423a08b25092c5a1837
source_path: channels/location.md
workflow: 14
---
# 渠道位置解析
OpenClaw 将聊天渠道中分享的位置标准化为:
- 附加到入站消息体的可读文本,以及
- 自动回复上下文负载中的结构化字段。
目前支持:
- **Telegram**(位置图钉 + 地点 + 实时位置)
- **WhatsApp**locationMessage + liveLocationMessage
- **Matrix**`m.location` 配合 `geo_uri`
## 文本格式
位置以友好的行格式呈现,不带括号:
- 图钉:
- `📍 48.858844, 2.294351 ±12m`
- 命名地点:
- `📍 Eiffel Tower — Champ de Mars, Paris (48.858844, 2.294351 ±12m)`
- 实时分享:
- `🛰 Live location: 48.858844, 2.294351 ±12m`
如果渠道包含标题/评论,会附加在下一行:
```
📍 48.858844, 2.294351 ±12m
Meet here
```
## 上下文字段
当存在位置信息时,以下字段会被添加到 `ctx` 中:
- `LocationLat`(数字)
- `LocationLon`(数字)
- `LocationAccuracy`(数字,米;可选)
- `LocationName`(字符串;可选)
- `LocationAddress`(字符串;可选)
- `LocationSource``pin | place | live`
- `LocationIsLive`(布尔值)
## 渠道说明
- **Telegram**:地点映射到 `LocationName/LocationAddress`;实时位置使用 `live_period`
- **WhatsApp**`locationMessage.comment``liveLocationMessage.caption` 作为标题行附加。
- **Matrix**`geo_uri` 解析为图钉位置;忽略海拔高度,`LocationIsLive` 始终为 false。

View File

@@ -0,0 +1,221 @@
---
read_when:
- 开发 Matrix 渠道功能
summary: Matrix 支持状态、功能和配置
title: Matrix
x-i18n:
generated_at: "2026-02-01T19:22:24Z"
model: claude-opus-4-5
provider: pi
source_hash: b276b5263593c766e7be6549abbb27927177e7b51cfd297b4825965372513ee4
source_path: channels/matrix.md
workflow: 14
---
# Matrix插件
Matrix 是一个开放、去中心化的消息协议。OpenClaw 作为 Matrix **用户**连接到任何主服务器,因此你需要为机器人创建一个 Matrix 账户。登录后你可以直接私信机器人或邀请它加入房间Matrix 的"群组"。Beeper 也是一个可用的客户端选项,但它需要启用端到端加密。
状态:通过插件支持(@vector-im/matrix-bot-sdk。支持私信、房间、线程、媒体、回应、投票发送 + poll-start 转为文本)、位置和端到端加密(需要加密支持)。
## 需要插件
Matrix 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/matrix
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/matrix
```
如果你在配置/上手引导期间选择了 Matrix 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 设置
1. 安装 Matrix 插件:
- 从 npm`openclaw plugins install @openclaw/matrix`
- 从本地检出:`openclaw plugins install ./extensions/matrix`
2. 在主服务器上创建 Matrix 账户:
- 在 [https://matrix.org/ecosystem/hosting/](https://matrix.org/ecosystem/hosting/) 浏览托管选项
- 或自行托管。
3. 获取机器人账户的访问 token
- 在你的主服务器上使用 Matrix 登录 API 配合 `curl`
```bash
curl --request POST \
--url https://matrix.example.org/_matrix/client/v3/login \
--header 'Content-Type: application/json' \
--data '{
"type": "m.login.password",
"identifier": {
"type": "m.id.user",
"user": "your-user-name"
},
"password": "your-password"
}'
```
- 将 `matrix.example.org` 替换为你的主服务器 URL。
- 或设置 `channels.matrix.userId` + `channels.matrix.password`OpenClaw 调用相同的登录端点,将访问 token 存储在 `~/.openclaw/credentials/matrix/credentials.json` 中,并在下次启动时重用。
4. 配置凭据:
- 环境变量:`MATRIX_HOMESERVER`、`MATRIX_ACCESS_TOKEN`(或 `MATRIX_USER_ID` + `MATRIX_PASSWORD`
- 或配置:`channels.matrix.*`
- 如果两者都设置了,配置优先。
- 使用访问 token 时:用户 ID 通过 `/whoami` 自动获取。
- 设置时,`channels.matrix.userId` 应为完整的 Matrix ID例如`@bot:example.org`)。
5. 重启 Gateway或完成上手引导
6. 从任何 Matrix 客户端Element、Beeper 等;参见 https://matrix.org/ecosystem/clients/与机器人开始私信或邀请它加入房间。Beeper 需要端到端加密,因此请设置 `channels.matrix.encryption: true` 并验证设备。
最小配置(访问 token用户 ID 自动获取):
```json5
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
dm: { policy: "pairing" },
},
},
}
```
端到端加密配置(启用端到端加密):
```json5
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
encryption: true,
dm: { policy: "pairing" },
},
},
}
```
## 加密(端到端加密)
端到端加密通过 Rust 加密 SDK **支持**。
通过 `channels.matrix.encryption: true` 启用:
- 如果加密模块加载成功,加密房间会自动解密。
- 向加密房间发送时,出站媒体会被加密。
- 首次连接时OpenClaw 会从你的其他会话请求设备验证。
- 在另一个 Matrix 客户端Element 等)中验证设备以启用密钥共享。
- 如果加密模块无法加载端到端加密将被禁用且加密房间无法解密OpenClaw 会记录警告。
- 如果你看到缺少加密模块的错误(例如 `@matrix-org/matrix-sdk-crypto-nodejs-*`),请允许 `@matrix-org/matrix-sdk-crypto-nodejs` 的构建脚本并运行 `pnpm rebuild @matrix-org/matrix-sdk-crypto-nodejs` 或通过 `node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js` 获取二进制文件。
加密状态按账户 + 访问 token 存储在 `~/.openclaw/matrix/accounts/<account>/<homeserver>__<user>/<token-hash>/crypto/`SQLite 数据库)。同步状态存储在同一目录下的 `bot-storage.json` 中。如果访问 token设备发生变化会创建新的存储机器人必须重新验证才能在加密房间中使用。
**设备验证:**
启用端到端加密后,机器人会在启动时从你的其他会话请求验证。打开 Element或其他客户端并批准验证请求以建立信任。验证完成后机器人可以解密加密房间中的消息。
## 路由模型
- 回复始终发回 Matrix。
- 私信共享智能体的主会话;房间映射到群组会话。
## 访问控制(私信)
- 默认:`channels.matrix.dm.policy = "pairing"`。未知发送者会收到配对码。
- 通过以下方式批准:
- `openclaw pairing list matrix`
- `openclaw pairing approve matrix <CODE>`
- 公开私信:`channels.matrix.dm.policy="open"` 加上 `channels.matrix.dm.allowFrom=["*"]`。
- `channels.matrix.dm.allowFrom` 接受用户 ID 或显示名称。向导在目录搜索可用时会将显示名称解析为用户 ID。
## 房间(群组)
- 默认:`channels.matrix.groupPolicy = "allowlist"`(提及门控)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。
- 使用 `channels.matrix.groups` 允许列表中的房间(房间 ID、别名或名称
```json5
{
channels: {
matrix: {
groupPolicy: "allowlist",
groups: {
"!roomId:example.org": { allow: true },
"#alias:example.org": { allow: true },
},
groupAllowFrom: ["@owner:example.org"],
},
},
}
```
- `requireMention: false` 启用该房间的自动回复。
- `groups."*"` 可以设置跨房间的提及门控默认值。
- `groupAllowFrom` 限制哪些发送者可以在房间中触发机器人(可选)。
- 按房间的 `users` 允许列表可以进一步限制特定房间内的发送者。
- 配置向导会提示输入房间允许列表(房间 ID、别名或名称并在可能时解析名称。
- 启动时OpenClaw 将允许列表中的房间/用户名称解析为 ID 并记录映射;未解析的条目保持原样。
- 邀请默认自动加入;通过 `channels.matrix.autoJoin` 和 `channels.matrix.autoJoinAllowlist` 控制。
- 要**不允许任何房间**,设置 `channels.matrix.groupPolicy: "disabled"`(或保持空的允许列表)。
- 旧版键:`channels.matrix.rooms`(与 `groups` 结构相同)。
## 线程
- 支持回复线程。
- `channels.matrix.threadReplies` 控制回复是否保持在线程中:
- `off`、`inbound`(默认)、`always`
- `channels.matrix.replyToMode` 控制不在线程中回复时的 reply-to 元数据:
- `off`(默认)、`first`、`all`
## 功能
| 功能 | 状态 |
| ---------- | ---------------------------------------------------------- |
| 私信 | ✅ 支持 |
| 房间 | ✅ 支持 |
| 线程 | ✅ 支持 |
| 媒体 | ✅ 支持 |
| 端到端加密 | ✅ 支持(需要加密模块) |
| 回应 | ✅ 支持(通过工具发送/读取) |
| 投票 | ✅ 支持发送;入站 poll start 转换为文本(响应/结束被忽略) |
| 位置 | ✅ 支持geo URI忽略海拔 |
| 原生命令 | ✅ 支持 |
## 配置参考Matrix
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.matrix.enabled`:启用/禁用渠道启动。
- `channels.matrix.homeserver`:主服务器 URL。
- `channels.matrix.userId`Matrix 用户 ID使用访问 token 时可选)。
- `channels.matrix.accessToken`:访问 token。
- `channels.matrix.password`登录密码token 会被存储)。
- `channels.matrix.deviceName`:设备显示名称。
- `channels.matrix.encryption`启用端到端加密默认false
- `channels.matrix.initialSyncLimit`:初始同步限制。
- `channels.matrix.threadReplies``off | inbound | always`默认inbound
- `channels.matrix.textChunkLimit`:出站文本分块大小(字符)。
- `channels.matrix.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.matrix.dm.policy``pairing | allowlist | open | disabled`默认pairing
- `channels.matrix.dm.allowFrom`:私信允许列表(用户 ID 或显示名称)。`open` 需要 `"*"`。向导在可能时将名称解析为 ID。
- `channels.matrix.groupPolicy``allowlist | open | disabled`默认allowlist
- `channels.matrix.groupAllowFrom`:群组消息的允许发送者列表。
- `channels.matrix.allowlistOnly`:强制对私信 + 房间执行允许列表规则。
- `channels.matrix.groups`:群组允许列表 + 按房间设置映射。
- `channels.matrix.rooms`:旧版群组允许列表/配置。
- `channels.matrix.replyToMode`:线程/标签的 reply-to 模式。
- `channels.matrix.mediaMaxMb`:入站/出站媒体上限MB
- `channels.matrix.autoJoin`:邀请处理(`always | allowlist | off`默认always
- `channels.matrix.autoJoinAllowlist`:自动加入的允许房间 ID/别名。
- `channels.matrix.actions`按操作的工具门控reactions/messages/pins/memberInfo/channelInfo

View File

@@ -0,0 +1,142 @@
---
read_when:
- 设置 Mattermost
- 调试 Mattermost 路由
summary: Mattermost 机器人设置和 OpenClaw 配置
title: Mattermost
x-i18n:
generated_at: "2026-02-01T19:22:40Z"
model: claude-opus-4-5
provider: pi
source_hash: 57fabe5eb0efbcb885f4178b317b2fa99a41daf609e3a471de2b44db9def4ad7
source_path: channels/mattermost.md
workflow: 14
---
# Mattermost插件
状态通过插件支持bot token + WebSocket 事件。支持频道、群组和私信。Mattermost 是一个可自托管的团队消息平台;有关产品详情和下载请访问官方网站 [mattermost.com](https://mattermost.com)。
## 需要插件
Mattermost 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/mattermost
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/mattermost
```
如果你在配置/上手引导期间选择了 Mattermost 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置
1. 安装 Mattermost 插件。
2. 创建一个 Mattermost 机器人账户并复制 **bot token**
3. 复制 Mattermost **基础 URL**(例如 `https://chat.example.com`)。
4. 配置 OpenClaw 并启动 Gateway。
最小配置:
```json5
{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
},
},
}
```
## 环境变量(默认账户)
如果你偏好使用环境变量,请在 Gateway 主机上设置:
- `MATTERMOST_BOT_TOKEN=...`
- `MATTERMOST_URL=https://chat.example.com`
环境变量仅适用于**默认**账户(`default`)。其他账户必须使用配置值。
## 聊天模式
Mattermost 自动响应私信。频道行为由 `chatmode` 控制:
- `oncall`(默认):仅在频道中被 @提及时响应
- `onmessage`:响应频道中的每条消息。
- `onchar`:当消息以触发前缀开头时响应。
配置示例:
```json5
{
channels: {
mattermost: {
chatmode: "onchar",
oncharPrefixes: [">", "!"],
},
},
}
```
注意事项:
- `onchar` 模式仍然响应明确的 @提及
- `channels.mattermost.requireMention` 对旧版配置仍然有效,但推荐使用 `chatmode`
## 访问控制(私信)
- 默认:`channels.mattermost.dmPolicy = "pairing"`(未知发送者会收到配对码)。
- 通过以下方式批准:
- `openclaw pairing list mattermost`
- `openclaw pairing approve mattermost <CODE>`
- 公开私信:`channels.mattermost.dmPolicy="open"` 加上 `channels.mattermost.allowFrom=["*"]`
## 频道(群组)
- 默认:`channels.mattermost.groupPolicy = "allowlist"`(提及门控)。
- 使用 `channels.mattermost.groupAllowFrom` 允许列表发送者(用户 ID 或 `@username`)。
- 开放频道:`channels.mattermost.groupPolicy="open"`(提及门控)。
## 出站投递目标
`openclaw message send` 或定时任务/webhook 中使用以下目标格式:
- `channel:<id>` 用于频道
- `user:<id>` 用于私信
- `@username` 用于私信(通过 Mattermost API 解析)
裸 ID 被视为频道。
## 多账户
Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账户:
```json5
{
channels: {
mattermost: {
accounts: {
default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" },
alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" },
},
},
},
}
```
## 故障排除
- 频道中没有回复确保机器人已加入频道并提及它oncall 模式使用触发前缀onchar 模式),或设置 `chatmode: "onmessage"`
- 认证错误:检查 bot token、基础 URL 以及账户是否已启用。
- 多账户问题:环境变量仅适用于 `default` 账户。

View File

@@ -0,0 +1,770 @@
---
read_when:
- 开发 Microsoft Teams 渠道功能
summary: Microsoft Teams 机器人支持状态、功能和配置
title: Microsoft Teams
x-i18n:
generated_at: "2026-02-01T19:26:12Z"
model: claude-opus-4-5
provider: pi
source_hash: 3d5641c578086f7569f42276d4ef2462200b9927ca3f505e6ee26806103eaa60
source_path: channels/msteams.md
workflow: 14
---
# Microsoft Teams插件
> "进入此处者,放弃一切希望。"
更新时间2026-01-21
状态:支持文本 + 私信附件;频道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见[在群聊中发送文件](#在群聊中发送文件))。投票通过 Adaptive Cards 发送。
## 需要插件
Microsoft Teams 作为插件发布,不包含在核心安装中。
**破坏性变更2026.1.15** Microsoft Teams 已从核心中移出。如果你使用它,必须安装插件。
原因说明:保持核心安装更轻量,并让 Microsoft Teams 依赖项可以独立更新。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/msteams
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/msteams
```
如果你在配置/上手引导期间选择了 Teams 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Microsoft Teams 插件。
2. 创建一个 **Azure Bot**App ID + 客户端密钥 + 租户 ID
3. 使用这些凭据配置 OpenClaw。
4. 通过公共 URL 或隧道暴露 `/api/messages`(默认端口 3978
5. 安装 Teams 应用包并启动 Gateway。
最小配置:
```json5
{
channels: {
msteams: {
enabled: true,
appId: "<APP_ID>",
appPassword: "<APP_PASSWORD>",
tenantId: "<TENANT_ID>",
webhook: { port: 3978, path: "/api/messages" },
},
},
}
```
注意:群聊默认被阻止(`channels.msteams.groupPolicy: "allowlist"`)。要允许群组回复,请设置 `channels.msteams.groupAllowFrom`(或使用 `groupPolicy: "open"` 允许任何成员,提及门控)。
## 目标
- 通过 Teams 私信、群聊或频道与 OpenClaw 对话。
- 保持路由确定性:回复始终发回消息到达的渠道。
- 默认使用安全的渠道行为(除非另行配置,否则需要提及)。
## 配置写入
默认情况下Microsoft Teams 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { msteams: { configWrites: false } },
}
```
## 访问控制(私信 + 群组)
**私信访问**
- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在批准前会被忽略。
- `channels.msteams.allowFrom` 接受 AAD 对象 ID、UPN 或显示名称。当凭据允许时,向导通过 Microsoft Graph 将名称解析为 ID。
**群组访问**
- 默认:`channels.msteams.groupPolicy = "allowlist"`(被阻止,除非你添加 `groupAllowFrom`)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。
- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群聊/频道中触发(回退到 `channels.msteams.allowFrom`)。
- 设置 `groupPolicy: "open"` 可允许任何成员(默认仍需提及门控)。
- 要**不允许任何频道**,设置 `channels.msteams.groupPolicy: "disabled"`
示例:
```json5
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["user@org.com"],
},
},
}
```
**团队 + 频道允许列表**
- 通过在 `channels.msteams.teams` 下列出团队和频道来限定群组/频道回复范围。
- 键可以是团队 ID 或名称;频道键可以是会话 ID 或名称。
-`groupPolicy="allowlist"` 且存在团队允许列表时,仅接受列出的团队/频道(提及门控)。
- 配置向导接受 `Team/Channel` 条目并为你存储。
- 启动时OpenClaw 将团队/频道和用户允许列表名称解析为 ID当 Graph 权限允许时)并记录映射;未解析的条目保持原样。
示例:
```json5
{
channels: {
msteams: {
groupPolicy: "allowlist",
teams: {
"My Team": {
channels: {
General: { requireMention: true },
},
},
},
},
},
}
```
## 工作原理
1. 安装 Microsoft Teams 插件。
2. 创建一个 **Azure Bot**App ID + 密钥 + 租户 ID
3. 构建一个引用该机器人并包含下方 RSC 权限的 **Teams 应用包**
4. 将 Teams 应用上传/安装到团队(或私人范围用于私信)。
5.`~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams` 并启动 Gateway。
6. Gateway 默认在 `/api/messages` 上监听 Bot Framework webhook 流量。
## Azure Bot 设置(前提条件)
在配置 OpenClaw 之前,你需要创建一个 Azure Bot 资源。
### 步骤 1创建 Azure Bot
1. 前往[创建 Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)
2. 填写 **Basics** 标签页:
| 字段 | 值 |
| ------------------ | --------------------------------------------------- |
| **Bot handle** | 你的机器人名称,例如 `openclaw-msteams`(必须唯一) |
| **Subscription** | 选择你的 Azure 订阅 |
| **Resource group** | 新建或使用现有的 |
| **Pricing tier** | **Free** 用于开发/测试 |
| **Type of App** | **Single Tenant**(推荐 - 见下方说明) |
| **Creation type** | **Create new Microsoft App ID** |
> **弃用通知:** 2025-07-31 之后已弃用创建新的多租户机器人。新机器人请使用 **Single Tenant**。
3. 点击 **Review + create****Create**(等待约 1-2 分钟)
### 步骤 2获取凭据
1. 前往你的 Azure Bot 资源 → **Configuration**
2. 复制 **Microsoft App ID** → 这是你的 `appId`
3. 点击 **Manage Password** → 进入应用注册
4.**Certificates & secrets****New client secret** → 复制 **Value** → 这是你的 `appPassword`
5. 进入 **Overview** → 复制 **Directory (tenant) ID** → 这是你的 `tenantId`
### 步骤 3配置消息端点
1. 在 Azure Bot → **Configuration**
2.**Messaging endpoint** 设置为你的 webhook URL
- 生产环境:`https://your-domain.com/api/messages`
- 本地开发:使用隧道(参见下方[本地开发](#本地开发隧道)
### 步骤 4启用 Teams 频道
1. 在 Azure Bot → **Channels**
2. 点击 **Microsoft Teams** → Configure → Save
3. 接受服务条款
## 本地开发(隧道)
Teams 无法访问 `localhost`。本地开发请使用隧道:
**方案 Angrok**
```bash
ngrok http 3978
# 复制 https URL例如 https://abc123.ngrok.io
# 将消息端点设置为https://abc123.ngrok.io/api/messages
```
**方案 BTailscale Funnel**
```bash
tailscale funnel 3978
# 使用你的 Tailscale funnel URL 作为消息端点
```
## Teams 开发者门户(替代方案)
除了手动创建清单 ZIP 外,你可以使用 [Teams 开发者门户](https://dev.teams.microsoft.com/apps)
1. 点击 **+ New app**
2. 填写基本信息(名称、描述、开发者信息)
3. 进入 **App features****Bot**
4. 选择 **Enter a bot ID manually** 并粘贴你的 Azure Bot App ID
5. 勾选范围:**Personal**、**Team**、**Group Chat**
6. 点击 **Distribute****Download app package**
7. 在 Teams 中:**Apps** → **Manage your apps****Upload a custom app** → 选择 ZIP
这通常比手动编辑 JSON 清单更简单。
## 测试机器人
**方案 AAzure Web Chat先验证 webhook**
1. 在 Azure 门户 → 你的 Azure Bot 资源 → **Test in Web Chat**
2. 发送一条消息 - 你应该看到回复
3. 这确认了你的 webhook 端点在 Teams 设置之前可以正常工作
**方案 BTeams安装应用后**
1. 安装 Teams 应用(旁加载或组织目录)
2. 在 Teams 中找到机器人并发送私信
3. 检查 Gateway 日志中的传入活动
## 设置(最小纯文本)
1. **安装 Microsoft Teams 插件**
- 从 npm`openclaw plugins install @openclaw/msteams`
- 从本地检出:`openclaw plugins install ./extensions/msteams`
2. **机器人注册**
- 创建 Azure Bot见上方并记录
- App ID
- 客户端密钥App password
- 租户 ID单租户
3. **Teams 应用清单**
- 包含一个 `bot` 条目,其中 `botId = <App ID>`
- 范围:`personal``team``groupChat`
- `supportsFiles: true`(个人范围文件处理所必需)。
- 添加 RSC 权限(见下方)。
- 创建图标:`outline.png`32x32`color.png`192x192
- 将三个文件打包在一起:`manifest.json``outline.png``color.png`
4. **配置 OpenClaw**
```json
{
"msteams": {
"enabled": true,
"appId": "<APP_ID>",
"appPassword": "<APP_PASSWORD>",
"tenantId": "<TENANT_ID>",
"webhook": { "port": 3978, "path": "/api/messages" }
}
}
```
你也可以使用环境变量替代配置键:
- `MSTEAMS_APP_ID`
- `MSTEAMS_APP_PASSWORD`
- `MSTEAMS_TENANT_ID`
5. **机器人端点**
- 将 Azure Bot 消息端点设置为:
- `https://<host>:3978/api/messages`(或你选择的路径/端口)。
6. **运行 Gateway**
- 当插件已安装且 `msteams` 配置存在凭据时Teams 渠道会自动启动。
## 历史上下文
- `channels.msteams.historyLimit` 控制多少条最近的频道/群组消息被包含在提示中。
- 回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户回合数)限制。按用户覆盖:`channels.msteams.dms["<user_id>"].historyLimit`。
## 当前 Teams RSC 权限(清单)
以下是我们 Teams 应用清单中**现有的 resourceSpecific 权限**。它们仅在安装了应用的团队/聊天中适用。
**频道(团队范围):**
- `ChannelMessage.Read.Group`Application- 无需 @提及即可接收所有频道消息
- `ChannelMessage.Send.Group`Application
- `Member.Read.Group`Application
- `Owner.Read.Group`Application
- `ChannelSettings.Read.Group`Application
- `TeamMember.Read.Group`Application
- `TeamSettings.Read.Group`Application
**群聊:**
- `ChatMessage.Read.Chat`Application- 无需 @提及即可接收所有群聊消息
## 示例 Teams 清单(已脱敏)
包含必需字段的最小有效示例。请替换 ID 和 URL。
```json
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json",
"manifestVersion": "1.23",
"version": "1.0.0",
"id": "00000000-0000-0000-0000-000000000000",
"name": { "short": "OpenClaw" },
"developer": {
"name": "Your Org",
"websiteUrl": "https://example.com",
"privacyUrl": "https://example.com/privacy",
"termsOfUseUrl": "https://example.com/terms"
},
"description": { "short": "OpenClaw in Teams", "full": "OpenClaw in Teams" },
"icons": { "outline": "outline.png", "color": "color.png" },
"accentColor": "#5B6DEF",
"bots": [
{
"botId": "11111111-1111-1111-1111-111111111111",
"scopes": ["personal", "team", "groupChat"],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": true
}
],
"webApplicationInfo": {
"id": "11111111-1111-1111-1111-111111111111"
},
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "ChannelMessage.Read.Group", "type": "Application" },
{ "name": "ChannelMessage.Send.Group", "type": "Application" },
{ "name": "Member.Read.Group", "type": "Application" },
{ "name": "Owner.Read.Group", "type": "Application" },
{ "name": "ChannelSettings.Read.Group", "type": "Application" },
{ "name": "TeamMember.Read.Group", "type": "Application" },
{ "name": "TeamSettings.Read.Group", "type": "Application" },
{ "name": "ChatMessage.Read.Chat", "type": "Application" }
]
}
}
}
```
### 清单注意事项(必需字段)
- `bots[].botId` **必须**与 Azure Bot App ID 匹配。
- `webApplicationInfo.id` **必须**与 Azure Bot App ID 匹配。
- `bots[].scopes` 必须包含你计划使用的范围(`personal`、`team`、`groupChat`)。
- `bots[].supportsFiles: true` 是个人范围文件处理所必需的。
- `authorization.permissions.resourceSpecific` 必须包含频道读取/发送权限(如果你需要频道流量)。
### 更新现有应用
要更新已安装的 Teams 应用(例如添加 RSC 权限):
1. 使用新设置更新 `manifest.json`
2. **递增 `version` 字段**(例如 `1.0.0` → `1.1.0`
3. **重新打包**清单和图标(`manifest.json`、`outline.png`、`color.png`
4. 上传新的 zip
- **方案 ATeams 管理中心):** Teams 管理中心 → Teams apps → Manage apps → 找到你的应用 → Upload new version
- **方案 B旁加载** 在 Teams 中 → Apps → Manage your apps → Upload a custom app
5. **对于团队频道:** 在每个团队中重新安装应用以使新权限生效
6. **完全退出并重新启动 Teams**(不只是关闭窗口)以清除缓存的应用元数据
## 功能:仅 RSC vs Graph
### 仅使用 **Teams RSC**(已安装应用,无 Graph API 权限)
可用:
- 读取频道消息**文本**内容。
- 发送频道消息**文本**内容。
- 接收**个人(私信)**文件附件。
不可用:
- 频道/群组**图片或文件内容**(负载仅包含 HTML 占位符)。
- 下载存储在 SharePoint/OneDrive 中的附件。
- 读取消息历史(超出实时 webhook 事件范围)。
### 使用 **Teams RSC + Microsoft Graph Application 权限**
新增:
- 下载托管内容(粘贴到消息中的图片)。
- 下载存储在 SharePoint/OneDrive 中的文件附件。
- 通过 Graph 读取频道/聊天消息历史。
### RSC vs Graph API
| 功能 | RSC 权限 | Graph API |
| -------------- | ------------------ | --------------------------- |
| **实时消息** | 是(通过 webhook | 否(仅轮询) |
| **历史消息** | 否 | 是(可查询历史) |
| **设置复杂度** | 仅需应用清单 | 需要管理员同意 + token 流程 |
| **离线可用** | 否(必须运行中) | 是(可随时查询) |
**总结:** RSC 用于实时监听Graph API 用于历史访问。要补上离线期间错过的消息,你需要具有 `ChannelMessage.Read.All` 的 Graph API需要管理员同意
## 启用 Graph 的媒体 + 历史(频道所必需)
如果你需要**频道**中的图片/文件或想获取**消息历史**,必须启用 Microsoft Graph 权限并授予管理员同意。
1. 在 Entra IDAzure AD**应用注册**中,添加 Microsoft Graph **Application 权限**
- `ChannelMessage.Read.All`(频道附件 + 历史)
- `Chat.Read.All` 或 `ChatMessage.Read.All`(群聊)
2. 为租户**授予管理员同意**。
3. 递增 Teams 应用**清单版本**,重新上传,并在 **Teams 中重新安装应用**。
4. **完全退出并重新启动 Teams** 以清除缓存的应用元数据。
## 已知限制
### Webhook 超时
Teams 通过 HTTP webhook 投递消息。如果处理时间过长(例如 LLM 响应缓慢),你可能会看到:
- Gateway 超时
- Teams 重试消息(导致重复)
- 回复丢失
OpenClaw 通过快速返回并主动发送回复来处理此问题,但非常慢的响应仍可能导致问题。
### 格式
Teams markdown 比 Slack 或 Discord 更有限:
- 基本格式有效:**粗体**、_斜体_、`代码`、链接
- 复杂 markdown表格、嵌套列表可能无法正确渲染
- 支持 Adaptive Cards 用于投票和任意卡片发送(见下方)
## 配置
关键设置(共享渠道模式请参见 `/gateway/configuration`
- `channels.msteams.enabled`:启用/禁用渠道。
- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:机器人凭据。
- `channels.msteams.webhook.port`(默认 `3978`
- `channels.msteams.webhook.path`(默认 `/api/messages`
- `channels.msteams.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.msteams.allowFrom`私信允许列表AAD 对象 ID、UPN 或显示名称)。当 Graph 访问可用时,向导在设置期间将名称解析为 ID。
- `channels.msteams.textChunkLimit`:出站文本分块大小。
- `channels.msteams.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.msteams.mediaAllowHosts`:入站附件主机允许列表(默认为 Microsoft/Teams 域名)。
- `channels.msteams.requireMention`:在频道/群组中需要 @提及(默认 true
- `channels.msteams.replyStyle``thread | top-level`(参见[回复样式:线程 vs 帖子](#回复样式线程-vs-帖子))。
- `channels.msteams.teams.<teamId>.replyStyle`:按团队覆盖。
- `channels.msteams.teams.<teamId>.requireMention`:按团队覆盖。
- `channels.msteams.teams.<teamId>.tools`:按团队默认工具策略覆盖(`allow`/`deny`/`alsoAllow`),在频道覆盖缺失时使用。
- `channels.msteams.teams.<teamId>.toolsBySender`:按团队按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`:按频道覆盖。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`:按频道覆盖。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`:按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `channels.msteams.teams.<teamId>.channels.<conversationId>.toolsBySender`:按频道按发送者工具策略覆盖(支持 `"*"` 通配符)。
- `channels.msteams.sharePointSiteId`:用于群聊/频道文件上传的 SharePoint 站点 ID参见[在群聊中发送文件](#在群聊中发送文件))。
## 路由与会话
- 会话键遵循标准智能体格式(参见 [/concepts/session](/concepts/session)
- 私信共享主会话(`agent:<agentId>:<mainKey>`)。
- 频道/群组消息使用会话 ID
- `agent:<agentId>:msteams:channel:<conversationId>`
- `agent:<agentId>:msteams:group:<conversationId>`
## 回复样式:线程 vs 帖子
Teams 最近在相同的底层数据模型上引入了两种频道 UI 样式:
| 样式 | 描述 | 推荐的 `replyStyle` |
| ----------------------- | ------------------------------ | ------------------- |
| **Posts**(经典) | 消息显示为卡片,下方有线程回复 | `thread`(默认) |
| **Threads**(类 Slack | 消息线性排列,更像 Slack | `top-level` |
**问题:** Teams API 不暴露频道使用哪种 UI 样式。如果你使用了错误的 `replyStyle`
- 在 Threads 样式的频道中使用 `thread` → 回复嵌套显示不自然
- 在 Posts 样式的频道中使用 `top-level` → 回复显示为独立的顶级帖子而非在线程中
**解决方案:** 根据频道的设置方式按频道配置 `replyStyle`
```json
{
"msteams": {
"replyStyle": "thread",
"teams": {
"19:abc...@thread.tacv2": {
"channels": {
"19:xyz...@thread.tacv2": {
"replyStyle": "top-level"
}
}
}
}
}
}
```
## 附件与图片
**当前限制:**
- **私信:** 图片和文件附件通过 Teams bot 文件 API 可用。
- **频道/群组:** 附件存储在 M365 存储SharePoint/OneDrive中。Webhook 负载仅包含 HTML 占位符,而非实际文件字节。**需要 Graph API 权限**才能下载频道附件。
没有 Graph 权限时包含图片的频道消息将仅作为纯文本接收机器人无法访问图片内容。默认情况下OpenClaw 仅从 Microsoft/Teams 主机名下载媒体。通过 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任何主机)。
## 在群聊中发送文件
机器人可以使用 FileConsentCard 流程在私信中发送文件(内置)。然而,**在群聊/频道中发送文件**需要额外设置:
| 场景 | 文件发送方式 | 所需设置 |
| -------------------- | --------------------------------------- | ------------------------------------ |
| **私信** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 |
| **群聊/频道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 |
| **图片(任何场景)** | Base64 编码内联 | 开箱即用 |
### 为什么群聊需要 SharePoint
机器人没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点对应用程序标识不可用)。要在群聊/频道中发送文件,机器人上传到 **SharePoint 站点**并创建共享链接。
### 设置
1. 在 Entra IDAzure AD→ 应用注册中**添加 Graph API 权限**
- `Sites.ReadWrite.All`Application- 上传文件到 SharePoint
- `Chat.Read.All`Application- 可选,启用按用户共享链接
2. 为租户**授予管理员同意**。
3. **获取你的 SharePoint 站点 ID**
```bash
# 通过 Graph Explorer 或使用有效 token 的 curl
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
# 示例:对于 "contoso.sharepoint.com/sites/BotFiles" 的站点
curl -H "Authorization: Bearer $TOKEN" \
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
# 响应包含:"id": "contoso.sharepoint.com,guid1,guid2"
```
4. **配置 OpenClaw**
```json5
{
channels: {
msteams: {
// ... 其他配置 ...
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2",
},
},
}
```
### 共享行为
| 权限 | 共享行为 |
| --------------------------------------- | ------------------------------------------ |
| 仅 `Sites.ReadWrite.All` | 组织范围共享链接(组织中的任何人都可访问) |
| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(仅聊天成员可访问) |
按用户共享更安全,因为只有聊天参与者可以访问文件。如果缺少 `Chat.Read.All` 权限,机器人回退到组织范围共享。
### 回退行为
| 场景 | 结果 |
| --------------------------------------- | ------------------------------------------ |
| 群聊 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint发送共享链接 |
| 群聊 + 文件 + 未配置 `sharePointSiteId` | 尝试 OneDrive 上传(可能失败),仅发送文本 |
| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint |
| 任何场景 + 图片 | Base64 编码内联(无需 SharePoint |
### 文件存储位置
上传的文件存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹。
## 投票Adaptive Cards
OpenClaw 通过 Adaptive Cards 发送 Teams 投票(没有原生 Teams 投票 API
- CLI`openclaw message poll --channel msteams --target conversation:<id> ...`
- 投票由 Gateway 记录在 `~/.openclaw/msteams-polls.json` 中。
- Gateway 必须保持在线以记录投票。
- 投票尚不会自动发布结果摘要(如需要请查看存储文件)。
## Adaptive Cards任意
使用 `message` 工具或 CLI 向 Teams 用户或会话发送任意 Adaptive Card JSON。
`card` 参数接受 Adaptive Card JSON 对象。提供 `card` 时,消息文本是可选的。
**智能体工具:**
```json
{
"action": "send",
"channel": "msteams",
"target": "user:<id>",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello!" }]
}
}
```
**CLI**
```bash
openclaw message send --channel msteams \
--target "conversation:19:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
```
卡片 schema 和示例请参见 [Adaptive Cards 文档](https://adaptivecards.io/)。目标格式详情请参见下方[目标格式](#目标格式)。
## 目标格式
Microsoft Teams 目标使用前缀区分用户和会话:
| 目标类型 | 格式 | 示例 |
| ----------------- | -------------------------------- | ------------------------------------------------- |
| 用户(按 ID | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
| 用户(按名称) | `user:<display-name>` | `user:John Smith`(需要 Graph API |
| 群组/频道 | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
| 群组/频道(原始) | `<conversation-id>` | `19:abc123...@thread.tacv2`(如果包含 `@thread` |
**CLI 示例:**
```bash
# 按 ID 发送给用户
openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# 按显示名称发送给用户(触发 Graph API 查找)
openclaw message send --channel msteams --target "user:John Smith" --message "Hello"
# 发送到群聊或频道
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
# 向会话发送 Adaptive Card
openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
```
**智能体工具示例:**
```json
{
"action": "send",
"channel": "msteams",
"target": "user:John Smith",
"message": "Hello!"
}
```
```json
{
"action": "send",
"channel": "msteams",
"target": "conversation:19:abc...@thread.tacv2",
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [{ "type": "TextBlock", "text": "Hello" }]
}
}
```
注意:不带 `user:` 前缀时,名称默认解析为群组/团队。通过显示名称定位人员时请始终使用 `user:`。
## 主动消息
- 主动消息仅在用户**已交互后**才可能,因为我们在那个时候存储会话引用。
- `dmPolicy` 和允许列表门控请参见 `/gateway/configuration`。
## 团队和频道 ID常见陷阱
Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请从 URL 路径中提取 ID
**团队 URL**
```
https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=...
└────────────────────────────┘
团队 IDURL 解码此部分)
```
**频道 URL**
```
https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=...
└─────────────────────────┘
频道 IDURL 解码此部分)
```
**用于配置:**
- 团队 ID = `/team/` 后的路径段URL 解码后,例如 `19:Bk4j...@thread.tacv2`
- 频道 ID = `/channel/` 后的路径段URL 解码后)
- **忽略** `groupId` 查询参数
## 私有频道
机器人在私有频道中的支持有限:
| 功能 | 标准频道 | 私有频道 |
| ------------------- | -------- | ---------------- |
| 机器人安装 | 是 | 有限 |
| 实时消息webhook | 是 | 可能不可用 |
| RSC 权限 | 是 | 行为可能不同 |
| @提及 | 是 | 如果机器人可访问 |
| Graph API 历史 | 是 | 是(需要权限) |
**私有频道不可用时的变通方案:**
1. 使用标准频道进行机器人交互
2. 使用私信 - 用户始终可以直接给机器人发消息
3. 使用 Graph API 进行历史访问(需要 `ChannelMessage.Read.All`
## 故障排除
### 常见问题
- **频道中图片不显示:** Graph 权限或管理员同意缺失。重新安装 Teams 应用并完全退出/重新打开 Teams。
- **频道中没有响应:** 默认需要提及;设置 `channels.msteams.requireMention=false` 或按团队/频道配置。
- **版本不匹配Teams 仍显示旧清单):** 移除并重新添加应用,完全退出 Teams 以刷新。
- **Webhook 返回 401 Unauthorized** 在没有 Azure JWT 的情况下手动测试时这是预期的 - 表示端点可达但认证失败。使用 Azure Web Chat 进行正确测试。
### 清单上传错误
- **"Icon file cannot be empty"** 清单引用了 0 字节的图标文件。创建有效的 PNG 图标(`outline.png` 32x32`color.png` 192x192
- **"webApplicationInfo.Id already in use"** 应用仍安装在其他团队/聊天中。先找到并卸载它,或等待 5-10 分钟传播。
- **上传时显示"Something went wrong"** 改为通过 https://admin.teams.microsoft.com 上传,打开浏览器 DevToolsF12→ Network 标签页,检查响应体中的实际错误。
- **旁加载失败:** 尝试"Upload an app to your org's app catalog"而非"Upload a custom app" - 这通常可以绕过旁加载限制。
### RSC 权限不生效
1. 验证 `webApplicationInfo.id` 与你的机器人 App ID 完全匹配
2. 重新上传应用并在团队/聊天中重新安装
3. 检查你的组织管理员是否阻止了 RSC 权限
4. 确认你使用了正确的范围:`ChannelMessage.Read.Group` 用于团队,`ChatMessage.Read.Chat` 用于群聊
## 参考
- [创建 Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot 设置指南
- [Teams 开发者门户](https://dev.teams.microsoft.com/apps) - 创建/管理 Teams 应用
- [Teams 应用清单 schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema)
- [使用 RSC 接收频道消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc)
- [RSC 权限参考](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent)
- [Teams bot 文件处理](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4)(频道/群组需要 Graph
- [主动消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages)

View File

@@ -0,0 +1,141 @@
---
read_when:
- 开发 Nextcloud Talk 渠道功能
summary: Nextcloud Talk 支持状态、功能和配置
title: Nextcloud Talk
x-i18n:
generated_at: "2026-02-01T19:26:32Z"
model: claude-opus-4-5
provider: pi
source_hash: 21b7b9756c4356a76dc0f14c10e44ed74a284cf3badf87e2df75eb88d8a90c31
source_path: channels/nextcloud-talk.md
workflow: 14
---
# Nextcloud Talk插件
状态通过插件支持webhook 机器人)。支持私信、房间、回应和 markdown 消息。
## 需要插件
Nextcloud Talk 作为插件发布,不包含在核心安装中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/nextcloud-talk
```
本地检出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/nextcloud-talk
```
如果你在配置/上手引导期间选择了 Nextcloud Talk 并检测到 git 检出OpenClaw 会自动提供本地安装路径。
详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Nextcloud Talk 插件。
2. 在你的 Nextcloud 服务器上创建一个机器人:
```bash
./occ talk:bot:install "OpenClaw" "<shared-secret>" "<webhook-url>" --feature reaction
```
3. 在目标房间设置中启用该机器人。
4. 配置 OpenClaw
- 配置:`channels.nextcloud-talk.baseUrl` + `channels.nextcloud-talk.botSecret`
- 或环境变量:`NEXTCLOUD_TALK_BOT_SECRET`(仅默认账户)
5. 重启 Gateway或完成上手引导
最小配置:
```json5
{
channels: {
"nextcloud-talk": {
enabled: true,
baseUrl: "https://cloud.example.com",
botSecret: "shared-secret",
dmPolicy: "pairing",
},
},
}
```
## 注意事项
- 机器人无法主动发起私信。用户必须先给机器人发消息。
- Webhook URL 必须能被 Gateway 访问;如果在代理后面,请设置 `webhookPublicUrl`。
- 机器人 API 不支持媒体上传;媒体以 URL 形式发送。
- Webhook 负载不区分私信和房间;设置 `apiUser` + `apiPassword` 以启用房间类型查询(否则私信会被视为房间)。
## 访问控制(私信)
- 默认:`channels.nextcloud-talk.dmPolicy = "pairing"`。未知发送者会收到配对码。
- 通过以下方式批准:
- `openclaw pairing list nextcloud-talk`
- `openclaw pairing approve nextcloud-talk <CODE>`
- 公开私信:`channels.nextcloud-talk.dmPolicy="open"` 加上 `channels.nextcloud-talk.allowFrom=["*"]`。
## 房间(群组)
- 默认:`channels.nextcloud-talk.groupPolicy = "allowlist"`(提及门控)。
- 使用 `channels.nextcloud-talk.rooms` 允许列表中的房间:
```json5
{
channels: {
"nextcloud-talk": {
rooms: {
"room-token": { requireMention: true },
},
},
},
}
```
- 要不允许任何房间,保持允许列表为空或设置 `channels.nextcloud-talk.groupPolicy="disabled"`。
## 功能
| 功能 | 状态 |
| -------- | ------ |
| 私信 | 支持 |
| 房间 | 支持 |
| 线程 | 不支持 |
| 媒体 | 仅 URL |
| 回应 | 支持 |
| 原生命令 | 不支持 |
## 配置参考Nextcloud Talk
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.nextcloud-talk.enabled`:启用/禁用渠道启动。
- `channels.nextcloud-talk.baseUrl`Nextcloud 实例 URL。
- `channels.nextcloud-talk.botSecret`:机器人共享密钥。
- `channels.nextcloud-talk.botSecretFile`:密钥文件路径。
- `channels.nextcloud-talk.apiUser`:用于房间查询的 API 用户(私信检测)。
- `channels.nextcloud-talk.apiPassword`:用于房间查询的 API/应用密码。
- `channels.nextcloud-talk.apiPasswordFile`API 密码文件路径。
- `channels.nextcloud-talk.webhookPort`webhook 监听端口默认8788
- `channels.nextcloud-talk.webhookHost`webhook 主机默认0.0.0.0)。
- `channels.nextcloud-talk.webhookPath`webhook 路径(默认:/nextcloud-talk-webhook
- `channels.nextcloud-talk.webhookPublicUrl`:外部可达的 webhook URL。
- `channels.nextcloud-talk.dmPolicy``pairing | allowlist | open | disabled`。
- `channels.nextcloud-talk.allowFrom`:私信允许列表(用户 ID。`open` 需要 `"*"`。
- `channels.nextcloud-talk.groupPolicy``allowlist | open | disabled`。
- `channels.nextcloud-talk.groupAllowFrom`:群组允许列表(用户 ID
- `channels.nextcloud-talk.rooms`:按房间设置和允许列表。
- `channels.nextcloud-talk.historyLimit`群组历史限制0 禁用)。
- `channels.nextcloud-talk.dmHistoryLimit`私信历史限制0 禁用)。
- `channels.nextcloud-talk.dms`按私信覆盖historyLimit
- `channels.nextcloud-talk.textChunkLimit`:出站文本分块大小(字符)。
- `channels.nextcloud-talk.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.nextcloud-talk.blockStreaming`:禁用此渠道的分块流式传输。
- `channels.nextcloud-talk.blockStreamingCoalesce`:分块流式传输合并调优。
- `channels.nextcloud-talk.mediaMaxMb`入站媒体上限MB

View File

@@ -0,0 +1,240 @@
---
read_when:
- 你想让 OpenClaw 通过 Nostr 接收私信
- 你正在设置去中心化消息
summary: 通过 NIP-04 加密消息的 Nostr 私信渠道
title: Nostr
x-i18n:
generated_at: "2026-02-01T19:26:55Z"
model: claude-opus-4-5
provider: pi
source_hash: 6b9fe4c74bf5e7c0f59bbaa129ec5270fd29a248551a8a9a7dde6cff8fb46111
source_path: channels/nostr.md
workflow: 14
---
# Nostr
**状态:** 可选插件(默认禁用)。
Nostr 是一个去中心化的社交网络协议。此渠道使 OpenClaw 能够通过 NIP-04 接收和回复加密私信DM
## 安装(按需)
### 上手引导(推荐)
- 上手引导向导(`openclaw onboard`)和 `openclaw channels add` 会列出可选的渠道插件。
- 选择 Nostr 时会提示你按需安装插件。
安装默认行为:
- **开发渠道 + 可用 git 检出:** 使用本地插件路径。
- **稳定版/测试版:** 从 npm 下载。
你始终可以在提示中覆盖此选择。
### 手动安装
```bash
openclaw plugins install @openclaw/nostr
```
使用本地检出(开发工作流):
```bash
openclaw plugins install --link <path-to-openclaw>/extensions/nostr
```
安装或启用插件后请重启 Gateway。
## 快速设置
1. 生成 Nostr 密钥对(如需要):
```bash
# 使用 nak
nak key generate
```
2. 添加到配置:
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}"
}
}
}
```
3. 导出密钥:
```bash
export NOSTR_PRIVATE_KEY="nsec1..."
```
4. 重启 Gateway。
## 配置参考
| 键 | 类型 | 默认值 | 描述 |
| ------------ | -------- | ------------------------------------------- | --------------------------- |
| `privateKey` | string | 必填 | `nsec` 或十六进制格式的私钥 |
| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URLWebSocket |
| `dmPolicy` | string | `pairing` | 私信访问策略 |
| `allowFrom` | string[] | `[]` | 允许的发送者公钥 |
| `enabled` | boolean | `true` | 启用/禁用渠道 |
| `name` | string | - | 显示名称 |
| `profile` | object | - | NIP-01 个人资料元数据 |
## 个人资料元数据
个人资料数据作为 NIP-01 `kind:0` 事件发布。你可以从控制 UIChannels -> Nostr -> Profile管理它或直接在配置中设置。
示例:
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"profile": {
"name": "openclaw",
"displayName": "OpenClaw",
"about": "Personal assistant DM bot",
"picture": "https://example.com/avatar.png",
"banner": "https://example.com/banner.png",
"website": "https://example.com",
"nip05": "openclaw@example.com",
"lud16": "openclaw@example.com"
}
}
}
}
```
注意事项:
- 个人资料 URL 必须使用 `https://`
- 从中继导入会合并字段并保留本地覆盖。
## 访问控制
### 私信策略
- **pairing**(默认):未知发送者会收到配对码。
- **allowlist**:只有 `allowFrom` 中的公钥可以发私信。
- **open**:公开入站私信(需要 `allowFrom: ["*"]`)。
- **disabled**:忽略入站私信。
### 允许列表示例
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"dmPolicy": "allowlist",
"allowFrom": ["npub1abc...", "npub1xyz..."]
}
}
}
```
## 密钥格式
接受的格式:
- **私钥:** `nsec...` 或 64 字符十六进制
- **公钥(`allowFrom`** `npub...` 或十六进制
## 中继
默认值:`relay.damus.io``nos.lol`
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"relays": ["wss://relay.damus.io", "wss://relay.primal.net", "wss://nostr.wine"]
}
}
}
```
建议:
- 使用 2-3 个中继以实现冗余。
- 避免使用过多中继(延迟、重复)。
- 付费中继可以提高可靠性。
- 本地中继适用于测试(`ws://localhost:7777`)。
## 协议支持
| NIP | 状态 | 描述 |
| ------ | ------ | ----------------------------- |
| NIP-01 | 支持 | 基本事件格式 + 个人资料元数据 |
| NIP-04 | 支持 | 加密私信(`kind:4` |
| NIP-17 | 计划中 | Gift-wrapped 私信 |
| NIP-44 | 计划中 | 版本化加密 |
## 测试
### 本地中继
```bash
# 启动 strfry
docker run -p 7777:7777 ghcr.io/hoytech/strfry
```
```json
{
"channels": {
"nostr": {
"privateKey": "${NOSTR_PRIVATE_KEY}",
"relays": ["ws://localhost:7777"]
}
}
}
```
### 手动测试
1. 从日志中记下机器人公钥npub
2. 打开一个 Nostr 客户端Damus、Amethyst 等)。
3. 私信机器人公钥。
4. 验证回复。
## 故障排除
### 无法收到消息
- 验证私钥是否有效。
- 确保中继 URL 可达并使用 `wss://`(本地使用 `ws://`)。
- 确认 `enabled` 未设为 `false`
- 检查 Gateway 日志中的中继连接错误。
### 无法发送回复
- 检查中继是否接受写入。
- 验证出站连接。
- 注意中继速率限制。
### 重复回复
- 使用多个中继时属于预期行为。
- 消息按事件 ID 去重;只有第一次投递会触发回复。
## 安全
- 绝不提交私钥。
- 使用环境变量存储密钥。
- 生产机器人请考虑使用 `allowlist`
## 限制MVP
- 仅支持私信(无群聊)。
- 不支持媒体附件。
- 仅支持 NIP-04计划支持 NIP-17 gift-wrap

View File

@@ -0,0 +1,209 @@
---
read_when:
- 设置 Signal 支持
- 调试 Signal 收发
summary: 通过 signal-cliJSON-RPC + SSE实现 Signal 支持、设置和号码模型
title: Signal
x-i18n:
generated_at: "2026-02-01T19:27:25Z"
model: claude-opus-4-5
provider: pi
source_hash: ca4de8b3685017f54a959e3e2699357ab40b3e4e68574bd7fb5739e4679e7d8a
source_path: channels/signal.md
workflow: 14
---
# Signalsignal-cli
状态:外部 CLI 集成。Gateway 通过 HTTP JSON-RPC + SSE 与 `signal-cli` 通信。
## 快速设置(新手)
1. 为机器人使用一个**单独的 Signal 号码**(推荐)。
2. 安装 `signal-cli`(需要 Java
3. 链接机器人设备并启动守护进程:
- `signal-cli link -n "OpenClaw"`
4. 配置 OpenClaw 并启动 Gateway。
最小配置:
```json5
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
```
## 它是什么
- 通过 `signal-cli` 的 Signal 渠道(非嵌入式 libsignal
- 确定性路由:回复始终发回 Signal。
- 私信共享智能体的主会话;群组是隔离的(`agent:<agentId>:signal:group:<groupId>`)。
## 配置写入
默认情况下Signal 允许通过 `/config set|unset` 触发的配置更新写入(需要 `commands.config: true`)。
通过以下方式禁用:
```json5
{
channels: { signal: { configWrites: false } },
}
```
## 号码模型(重要)
- Gateway 连接到一个 **Signal 设备**`signal-cli` 账户)。
- 如果你在**个人 Signal 账户**上运行机器人,它会忽略你自己的消息(循环保护)。
- 要实现"我给机器人发消息它回复我",请使用一个**单独的机器人号码**。
## 设置(快速路径)
1. 安装 `signal-cli`(需要 Java
2. 链接机器人账户:
- `signal-cli link -n "OpenClaw"` 然后在 Signal 中扫描二维码。
3. 配置 Signal 并启动 Gateway。
示例:
```json5
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
```
多账户支持:使用 `channels.signal.accounts`,每个账户配置独立选项和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
## 外部守护进程模式httpUrl
如果你想自行管理 `signal-cli`JVM 冷启动慢、容器初始化或共享 CPU可以单独运行守护进程并将 OpenClaw 指向它:
```json5
{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}
```
这会跳过 OpenClaw 内部的自动启动和启动等待。当自动启动较慢时,请设置 `channels.signal.startupTimeoutMs`
## 访问控制(私信 + 群组)
私信:
- 默认:`channels.signal.dmPolicy = "pairing"`
- 未知发送者会收到配对码;在批准之前消息会被忽略(配对码 1 小时后过期)。
- 通过以下方式批准:
- `openclaw pairing list signal`
- `openclaw pairing approve signal <CODE>`
- 配对是 Signal 私信的默认令牌交换方式。详情:[配对](/start/pairing)
- 仅 UUID 的发送者(来自 `sourceUuid`)以 `uuid:<id>` 形式存储在 `channels.signal.allowFrom` 中。
群组:
- `channels.signal.groupPolicy = open | allowlist | disabled`
- 当设置为 `allowlist` 时,`channels.signal.groupAllowFrom` 控制谁可以在群组中触发。
## 工作原理(行为)
- `signal-cli` 作为守护进程运行Gateway 通过 SSE 读取事件。
- 入站消息被标准化为共享的渠道信封。
- 回复始终路由回同一个号码或群组。
## 媒体 + 限制
- 出站文本按 `channels.signal.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.signal.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 支持附件(从 `signal-cli` 获取 base64
- 默认媒体上限:`channels.signal.mediaMaxMb`(默认 8
- 使用 `channels.signal.ignoreAttachments` 跳过媒体下载。
- 群组历史上下文使用 `channels.signal.historyLimit`(或 `channels.signal.accounts.*.historyLimit`),回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
## 输入指示 + 已读回执
- **输入指示**OpenClaw 通过 `signal-cli sendTyping` 发送输入信号,并在回复运行期间刷新。
- **已读回执**:当 `channels.signal.sendReadReceipts` 为 true 时OpenClaw 为允许的私信转发已读回执。
- signal-cli 不暴露群组的已读回执。
## 回应message 工具)
- 使用 `message action=react` 配合 `channel=signal`
- 目标:发送者 E.164 或 UUID使用配对输出中的 `uuid:<id>`;裸 UUID 也可以)。
- `messageId` 是你要回应的消息的 Signal 时间戳。
- 群组回应需要 `targetAuthor``targetAuthorUuid`
示例:
```
message action=react channel=signal target=uuid:123e4567-e89b-12d3-a456-426614174000 messageId=1737630212345 emoji=🔥
message action=react channel=signal target=+15551234567 messageId=1737630212345 emoji=🔥 remove=true
message action=react channel=signal target=signal:group:<groupId> targetAuthor=uuid:<sender-uuid> messageId=1737630212345 emoji=✅
```
配置:
- `channels.signal.actions.reactions`:启用/禁用回应操作(默认 true
- `channels.signal.reactionLevel``off | ack | minimal | extensive`
- `off`/`ack` 禁用智能体回应message 工具 `react` 会报错)。
- `minimal`/`extensive` 启用智能体回应并设置引导级别。
- 按账户覆盖:`channels.signal.accounts.<id>.actions.reactions``channels.signal.accounts.<id>.reactionLevel`
## 投递目标CLI/定时任务)
- 私信:`signal:+15551234567`(或纯 E.164)。
- UUID 私信:`uuid:<id>`(或裸 UUID
- 群组:`signal:group:<groupId>`
- 用户名:`username:<name>`(如果你的 Signal 账户支持)。
## 配置参考Signal
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.signal.enabled`:启用/禁用渠道启动。
- `channels.signal.account`:机器人账户的 E.164。
- `channels.signal.cliPath``signal-cli` 的路径。
- `channels.signal.httpUrl`:完整守护进程 URL覆盖 host/port
- `channels.signal.httpHost``channels.signal.httpPort`:守护进程绑定(默认 127.0.0.1:8080
- `channels.signal.autoStart`:自动启动守护进程(未设置 `httpUrl` 时默认 true
- `channels.signal.startupTimeoutMs`:启动等待超时,单位毫秒(上限 120000
- `channels.signal.receiveMode``on-start | manual`
- `channels.signal.ignoreAttachments`:跳过附件下载。
- `channels.signal.ignoreStories`:忽略来自守护进程的动态。
- `channels.signal.sendReadReceipts`:转发已读回执。
- `channels.signal.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.signal.allowFrom`私信允许列表E.164 或 `uuid:<id>`)。`open` 需要 `"*"`。Signal 没有用户名;使用电话/UUID 标识。
- `channels.signal.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.signal.groupAllowFrom`:群组发送者允许列表。
- `channels.signal.historyLimit`包含为上下文的最大群组消息数0 禁用)。
- `channels.signal.dmHistoryLimit`:私信历史限制(用户回合数)。按用户覆盖:`channels.signal.dms["<phone_or_uuid>"].historyLimit`
- `channels.signal.textChunkLimit`:出站分块大小(字符)。
- `channels.signal.chunkMode``length`(默认)或 `newline`,在按长度分块之前按空行(段落边界)分割。
- `channels.signal.mediaMaxMb`:入站/出站媒体上限MB
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`Signal 不支持原生提及)。
- `messages.groupChat.mentionPatterns`(全局回退)。
- `messages.responsePrefix`

View File

@@ -0,0 +1,530 @@
---
read_when: 设置 Slack 或调试 Slack Socket/HTTP 模式
summary: Slack 的 Socket 或 HTTP webhook 模式设置
title: Slack
x-i18n:
generated_at: "2026-02-01T19:29:15Z"
model: claude-opus-4-5
provider: pi
source_hash: 703b4b4333bebfef26b64710ba452bdfc3e7d2115048d4e552e8659425b3609b
source_path: channels/slack.md
workflow: 14
---
# Slack
## Socket 模式(默认)
### 快速设置(新手)
1. 创建一个 Slack 应用并启用 **Socket Mode**
2. 创建一个 **App Token**`xapp-...`)和 **Bot Token**`xoxb-...`)。
3. 为 OpenClaw 设置 token 并启动 Gateway。
最小配置:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
},
},
}
```
### 设置
1. 在 https://api.slack.com/apps 创建 Slack 应用(从头开始)。
2. **Socket Mode** → 开启。然后进入 **Basic Information****App-Level Tokens****Generate Token and Scopes**,使用范围 `connections:write`。复制 **App Token**`xapp-...`)。
3. **OAuth & Permissions** → 添加 bot token 范围(使用下方清单)。点击 **Install to Workspace**。复制 **Bot User OAuth Token**`xoxb-...`)。
4. 可选:**OAuth & Permissions** → 添加 **User Token Scopes**(参见下方只读列表)。重新安装应用并复制 **User OAuth Token**`xoxp-...`)。
5. **Event Subscriptions** → 启用事件并订阅:
- `message.*`(包括编辑/删除/线程广播)
- `app_mention`
- `reaction_added``reaction_removed`
- `member_joined_channel``member_left_channel`
- `channel_rename`
- `pin_added``pin_removed`
6. 邀请机器人加入你希望它读取的频道。
7. Slash Commands → 如果你使用 `channels.slack.slashCommand`,创建 `/openclaw`。如果你启用原生命令,为每个内置命令添加一个斜杠命令(名称与 `/help` 列表相同。Slack 的原生命令默认关闭,除非你设置 `channels.slack.commands.native: true`(全局 `commands.native``"auto"`Slack 下默认关闭)。
8. App Home → 启用 **Messages Tab** 以便用户可以给机器人发私信。
使用下方清单以保持范围和事件同步。
多账户支持:使用 `channels.slack.accounts`,每个账户配置独立 token 和可选的 `name`。共享模式请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts)。
### OpenClaw 配置(最小)
通过环境变量设置 token推荐
- `SLACK_APP_TOKEN=xapp-...`
- `SLACK_BOT_TOKEN=xoxb-...`
或通过配置:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
},
},
}
```
### 用户 token可选
OpenClaw 可以使用 Slack 用户 token`xoxp-...`)进行读取操作(历史记录、置顶、回应、表情、成员信息)。默认保持只读:有用户 token 时读取操作优先使用它,写入仍使用 bot token除非你明确选择。即使设置了 `userTokenReadOnly: false`,当 bot token 可用时写入操作仍优先使用它。
用户 token 在配置文件中设置(不支持环境变量)。多账户时设置 `channels.slack.accounts.<id>.userToken`
同时使用 bot + app + user token 的示例:
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-...",
},
},
}
```
显式设置 userTokenReadOnly 的示例(允许用户 token 写入):
```json5
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-...",
userTokenReadOnly: false,
},
},
}
```
#### Token 使用
- 读取操作(历史记录、回应列表、置顶列表、表情列表、成员信息、搜索)在配置了用户 token 时优先使用,否则使用 bot token。
- 写入操作(发送/编辑/删除消息、添加/移除回应、置顶/取消置顶、文件上传)默认使用 bot token。如果 `userTokenReadOnly: false` 且没有 bot token 可用OpenClaw 回退到用户 token。
### 历史上下文
- `channels.slack.historyLimit`(或 `channels.slack.accounts.*.historyLimit`)控制多少条最近的频道/群组消息被包含在提示中。
- 回退到 `messages.groupChat.historyLimit`。设置 `0` 可禁用(默认 50
## HTTP 模式Events API
当你的 Gateway 可通过 HTTPS 被 Slack 访问时使用 HTTP webhook 模式适用于服务器部署。HTTP 模式使用 Events API + Interactivity + Slash Commands共享请求 URL。
### 设置
1. 创建 Slack 应用并**禁用 Socket Mode**(如果你只使用 HTTP 则可选)。
2. **Basic Information** → 复制 **Signing Secret**
3. **OAuth & Permissions** → 安装应用并复制 **Bot User OAuth Token**`xoxb-...`)。
4. **Event Subscriptions** → 启用事件并将 **Request URL** 设置为你的 Gateway webhook 路径(默认 `/slack/events`)。
5. **Interactivity & Shortcuts** → 启用并设置相同的 **Request URL**
6. **Slash Commands** → 为你的命令设置相同的 **Request URL**
示例请求 URL
`https://gateway-host/slack/events`
### OpenClaw 配置(最小)
```json5
{
channels: {
slack: {
enabled: true,
mode: "http",
botToken: "xoxb-...",
signingSecret: "your-signing-secret",
webhookPath: "/slack/events",
},
},
}
```
多账户 HTTP 模式:设置 `channels.slack.accounts.<id>.mode = "http"` 并为每个账户提供唯一的 `webhookPath`,以便每个 Slack 应用可以指向自己的 URL。
### 清单(可选)
使用此 Slack 应用清单可快速创建应用(根据需要调整名称/命令)。如果你计划配置用户 token请包含用户范围。
```json
{
"display_information": {
"name": "OpenClaw",
"description": "Slack connector for OpenClaw"
},
"features": {
"bot_user": {
"display_name": "OpenClaw",
"always_online": false
},
"app_home": {
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
},
"slash_commands": [
{
"command": "/openclaw",
"description": "Send a message to OpenClaw",
"should_escape": false
}
]
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"groups:write",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"users:read",
"app_mentions:read",
"reactions:read",
"reactions:write",
"pins:read",
"pins:write",
"emoji:read",
"commands",
"files:read",
"files:write"
],
"user": [
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"im:history",
"im:read",
"mpim:history",
"mpim:read",
"users:read",
"reactions:read",
"pins:read",
"emoji:read",
"search:read"
]
}
},
"settings": {
"socket_mode_enabled": true,
"event_subscriptions": {
"bot_events": [
"app_mention",
"message.channels",
"message.groups",
"message.im",
"message.mpim",
"reaction_added",
"reaction_removed",
"member_joined_channel",
"member_left_channel",
"channel_rename",
"pin_added",
"pin_removed"
]
}
}
}
```
如果你启用原生命令,为你想暴露的每个命令添加一个 `slash_commands` 条目(匹配 `/help` 列表)。通过 `channels.slack.commands.native` 覆盖。
## 范围(当前 vs 可选)
Slack 的 Conversations API 按类型设定范围你只需要你实际使用的会话类型channels、groups、im、mpim对应的范围。概览请参见 https://docs.slack.dev/apis/web-api/using-the-conversations-api/。
### Bot token 范围(必需)
- `chat:write`(通过 `chat.postMessage` 发送/更新/删除消息)
https://docs.slack.dev/reference/methods/chat.postMessage
- `im:write`(通过 `conversations.open` 打开用户私信)
https://docs.slack.dev/reference/methods/conversations.open
- `channels:history``groups:history``im:history``mpim:history`
https://docs.slack.dev/reference/methods/conversations.history
- `channels:read``groups:read``im:read``mpim:read`
https://docs.slack.dev/reference/methods/conversations.info
- `users:read`(用户查找)
https://docs.slack.dev/reference/methods/users.info
- `reactions:read``reactions:write``reactions.get` / `reactions.add`
https://docs.slack.dev/reference/methods/reactions.get
https://docs.slack.dev/reference/methods/reactions.add
- `pins:read``pins:write``pins.list` / `pins.add` / `pins.remove`
https://docs.slack.dev/reference/scopes/pins.read
https://docs.slack.dev/reference/scopes/pins.write
- `emoji:read``emoji.list`
https://docs.slack.dev/reference/scopes/emoji.read
- `files:write`(通过 `files.uploadV2` 上传)
https://docs.slack.dev/messaging/working-with-files/#upload
### 用户 token 范围(可选,默认只读)
如果你配置了 `channels.slack.userToken`,请在 **User Token Scopes** 下添加这些。
- `channels:history``groups:history``im:history``mpim:history`
- `channels:read``groups:read``im:read``mpim:read`
- `users:read`
- `reactions:read`
- `pins:read`
- `emoji:read`
- `search:read`
### 目前不需要(但未来可能)
- `mpim:write`(仅在我们添加群组私信打开/私信开始功能时需要,通过 `conversations.open`
- `groups:write`(仅在我们添加私有频道管理时需要:创建/重命名/邀请/归档)
- `chat:write.public`(仅在我们想向机器人未加入的频道发帖时需要)
https://docs.slack.dev/reference/scopes/chat.write.public
- `users:read.email`(仅在我们需要从 `users.info` 获取邮箱字段时需要)
https://docs.slack.dev/changelog/2017-04-narrowing-email-access
- `files:read`(仅在我们开始列出/读取文件元数据时需要)
## 配置
Slack 仅使用 Socket Mode无 HTTP webhook 服务器)。提供两个 token
```json
{
"slack": {
"enabled": true,
"botToken": "xoxb-...",
"appToken": "xapp-...",
"groupPolicy": "allowlist",
"dm": {
"enabled": true,
"policy": "pairing",
"allowFrom": ["U123", "U456", "*"],
"groupEnabled": false,
"groupChannels": ["G123"],
"replyToMode": "all"
},
"channels": {
"C123": { "allow": true, "requireMention": true },
"#general": {
"allow": true,
"requireMention": true,
"users": ["U123"],
"skills": ["search", "docs"],
"systemPrompt": "Keep answers short."
}
},
"reactionNotifications": "own",
"reactionAllowlist": ["U123"],
"replyToMode": "off",
"actions": {
"reactions": true,
"messages": true,
"pins": true,
"memberInfo": true,
"emojiList": true
},
"slashCommand": {
"enabled": true,
"name": "openclaw",
"sessionPrefix": "slack:slash",
"ephemeral": true
},
"textChunkLimit": 4000,
"mediaMaxMb": 20
}
}
```
Token 也可以通过环境变量提供:
- `SLACK_BOT_TOKEN`
- `SLACK_APP_TOKEN`
确认回应由 `messages.ackReaction` + `messages.ackReactionScope` 全局控制。使用 `messages.removeAckAfterReply` 在机器人回复后清除确认回应。
## 限制
- 出站文本按 `channels.slack.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.slack.chunkMode="newline"` 在按长度分块之前按空行(段落边界)分割。
- 媒体上传上限由 `channels.slack.mediaMaxMb` 限制(默认 20
## 回复线程
默认情况下OpenClaw 在主频道中回复。使用 `channels.slack.replyToMode` 控制自动线程行为:
| 模式 | 行为 |
| ------- | ------------------------------------------------------------------------------------------------ |
| `off` | **默认。** 在主频道回复。仅在触发消息已在线程中时才在线程中回复。 |
| `first` | 第一条回复进入线程(在触发消息下方),后续回复进入主频道。适用于保持上下文可见同时避免线程杂乱。 |
| `all` | 所有回复都进入线程。保持对话集中但可能降低可见性。 |
该模式同时适用于自动回复和智能体工具调用(`slack sendMessage`)。
### 按聊天类型设置线程
你可以通过设置 `channels.slack.replyToModeByChatType` 为不同聊天类型配置不同的线程行为:
```json5
{
channels: {
slack: {
replyToMode: "off", // 频道默认
replyToModeByChatType: {
direct: "all", // 私信始终使用线程
group: "first", // 群组私信/MPIM 第一条回复使用线程
},
},
},
}
```
支持的聊天类型:
- `direct`一对一私信Slack `im`
- `group`:群组私信 / MPIMSlack `mpim`
- `channel`:标准频道(公共/私有)
优先级:
1. `replyToModeByChatType.<chatType>`
2. `replyToMode`
3. 提供商默认值(`off`
旧版 `channels.slack.dm.replyToMode` 在未设置聊天类型覆盖时仍作为 `direct` 的回退值。
示例:
仅私信使用线程:
```json5
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { direct: "all" },
},
},
}
```
群组私信使用线程但频道保持在根级:
```json5
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { group: "first" },
},
},
}
```
频道使用线程,私信保持在根级:
```json5
{
channels: {
slack: {
replyToMode: "first",
replyToModeByChatType: { direct: "off", group: "off" },
},
},
}
```
### 手动线程标签
对于精细控制,在智能体回复中使用以下标签:
- `[[reply_to_current]]` — 回复触发消息(开始/继续线程)。
- `[[reply_to:<id>]]` — 回复特定消息 ID。
## 会话 + 路由
- 私信共享 `main` 会话(与 WhatsApp/Telegram 类似)。
- 频道映射到 `agent:<agentId>:slack:channel:<channelId>` 会话。
- 斜杠命令使用 `agent:<agentId>:slack:slash:<userId>` 会话(前缀可通过 `channels.slack.slashCommand.sessionPrefix` 配置)。
- 如果 Slack 不提供 `channel_type`OpenClaw 从频道 ID 前缀(`D``C``G`)推断并默认为 `channel` 以保持会话键稳定。
- 原生命令注册使用 `commands.native`(全局默认 `"auto"` → Slack 关闭),可通过 `channels.slack.commands.native` 按工作区覆盖。文本命令需要独立的 `/...` 消息,可通过 `commands.text: false` 禁用。Slack 斜杠命令在 Slack 应用中管理,不会自动移除。使用 `commands.useAccessGroups: false` 可绕过命令的访问组检查。
- 完整命令列表 + 配置:[斜杠命令](/tools/slash-commands)
## 私信安全(配对)
- 默认:`channels.slack.dm.policy="pairing"` — 未知私信发送者会收到配对码1 小时后过期)。
- 通过 `openclaw pairing approve slack <code>` 批准。
- 要允许任何人:设置 `channels.slack.dm.policy="open"``channels.slack.dm.allowFrom=["*"]`
- `channels.slack.dm.allowFrom` 接受用户 ID、@用户名或邮箱(启动时当 token 允许时解析)。向导在设置期间当 token 允许时接受用户名并将其解析为 ID。
## 群组策略
- `channels.slack.groupPolicy` 控制频道处理方式(`open|disabled|allowlist`)。
- `allowlist` 需要频道列在 `channels.slack.channels` 中。
- 如果你只设置了 `SLACK_BOT_TOKEN`/`SLACK_APP_TOKEN` 且从未创建 `channels.slack` 部分,运行时默认将 `groupPolicy` 设为 `open`。添加 `channels.slack.groupPolicy``channels.defaults.groupPolicy` 或频道允许列表来锁定它。
- 配置向导接受 `#channel` 名称并在可能时将其解析为 ID公共 + 私有);如果存在多个匹配,优先选择活跃频道。
- 启动时OpenClaw 将允许列表中的频道/用户名称解析为 ID当 token 允许时)并记录映射;未解析的条目保持原样。
- 要**不允许任何频道**,设置 `channels.slack.groupPolicy: "disabled"`(或保持空的允许列表)。
频道选项(`channels.slack.channels.<id>``channels.slack.channels.<name>`
- `allow`:当 `groupPolicy="allowlist"` 时允许/拒绝频道。
- `requireMention`:频道的提及门控。
- `tools`:可选的按频道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。
- `toolsBySender`:可选的频道内按发送者工具策略覆盖(键为发送者 ID/@用户名/邮箱;支持 `"*"` 通配符)。
- `allowBots`允许此频道中机器人发送的消息默认false
- `users`:可选的按频道用户允许列表。
- `skills`:技能过滤器(省略 = 所有技能,空 = 无)。
- `systemPrompt`:频道的额外系统提示(与主题/目的合并)。
- `enabled`:设置 `false` 可禁用频道。
## 投递目标
在定时任务/CLI 发送中使用:
- `user:<id>` 用于私信
- `channel:<id>` 用于频道
## 工具操作
Slack 工具操作可通过 `channels.slack.actions.*` 控制:
| 操作组 | 默认值 | 说明 |
| ---------- | ------ | ------------------- |
| reactions | 启用 | 添加回应 + 列出回应 |
| messages | 启用 | 读取/发送/编辑/删除 |
| pins | 启用 | 置顶/取消置顶/列出 |
| memberInfo | 启用 | 成员信息 |
| emojiList | 启用 | 自定义表情列表 |
## 安全注意事项
- 写入操作默认使用 bot token以便状态变更操作保持在应用机器人权限和身份范围内。
- 设置 `userTokenReadOnly: false` 允许在 bot token 不可用时使用用户 token 进行写入操作,这意味着操作以安装用户的访问权限运行。请将用户 token 视为高权限凭据,并严格设置操作门控和允许列表。
- 如果你启用用户 token 写入,请确保用户 token 包含你预期的写入范围(`chat:write``reactions:write``pins:write``files:write`),否则这些操作会失败。
## 注意事项
- 提及门控通过 `channels.slack.channels` 控制(将 `requireMention` 设为 `true``agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)也算作提及。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 回应通知遵循 `channels.slack.reactionNotifications`(使用 `reactionAllowlist` 配合 `allowlist` 模式)。
- 机器人发送的消息默认被忽略;通过 `channels.slack.allowBots``channels.slack.channels.<id>.allowBots` 启用。
- 警告:如果你允许回复其他机器人(`channels.slack.allowBots=true``channels.slack.channels.<id>.allowBots=true`),请使用 `requireMention``channels.slack.channels.<id>.users` 允许列表和/或在 `AGENTS.md``SOUL.md` 中设置明确的防护规则来防止机器人之间的回复循环。
- Slack 工具的回应移除语义请参见 [/tools/reactions](/tools/reactions)。
- 在权限允许且未超过大小限制时,附件会被下载到媒体存储。

View File

@@ -0,0 +1,755 @@
---
read_when:
- 开发 Telegram 功能或 webhook 时
summary: Telegram 机器人支持状态、功能与配置
title: Telegram
x-i18n:
generated_at: "2026-02-01T19:54:11Z"
model: claude-opus-4-5
provider: pi
source_hash: 63198fce8c29a1020590d6a3ca142314b30c35d50317b878bf1fb1bfd8d54747
source_path: channels/telegram.md
workflow: 14
---
# Telegram (Bot API)
状态:通过 grammY 实现的机器人私聊 + 群组功能已可用于生产环境。默认使用长轮询webhook 可选。
## 快速设置(新手)
1. 通过 **@BotFather**[直达链接](https://t.me/BotFather))创建机器人。确认用户名确实是 `@BotFather`,然后复制令牌。
2. 设置令牌:
- 环境变量:`TELEGRAM_BOT_TOKEN=...`
- 或配置:`channels.telegram.botToken: "..."`
- 如果两者都设置了,配置优先(环境变量回退仅适用于默认账户)。
3. 启动 Gateway。
4. 私聊访问默认为配对模式;首次联系时需批准配对码。
最小配置:
```json5
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
},
},
}
```
## 简介
- 由 Gateway 管理的 Telegram Bot API 渠道。
- 确定性路由:回复始终发回 Telegram模型不会选择渠道。
- 私聊共享智能体的主会话;群组保持隔离(`agent:<agentId>:telegram:group:<chatId>`)。
## 设置(快速路径)
### 1创建机器人令牌BotFather
1. 打开 Telegram**@BotFather**[直达链接](https://t.me/BotFather))对话。确认用户名确实是 `@BotFather`
2. 运行 `/newbot`,然后按提示操作(名称 + 以 `bot` 结尾的用户名)。
3. 复制令牌并安全保存。
可选的 BotFather 设置:
- `/setjoingroups` — 允许/禁止将机器人添加到群组。
- `/setprivacy` — 控制机器人是否能看到所有群组消息。
### 2配置令牌环境变量或配置
示例:
```json5
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
},
}
```
环境变量选项:`TELEGRAM_BOT_TOKEN=...`(适用于默认账户)。
如果环境变量和配置都设置了,配置优先。
多账户支持:使用 `channels.telegram.accounts`,为每个账户设置令牌和可选的 `name`。请参阅 [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts) 了解通用模式。
3. 启动 Gateway。当令牌被解析后配置优先环境变量回退Telegram 即启动。
4. 私聊访问默认为配对模式。机器人首次被联系时需批准配对码。
5. 对于群组:添加机器人,决定隐私/管理员行为(见下文),然后设置 `channels.telegram.groups` 来控制提及门控 + 白名单。
## 令牌 + 隐私 + 权限Telegram 端)
### 令牌创建BotFather
- `/newbot` 创建机器人并返回令牌(请保密)。
- 如果令牌泄露,通过 @BotFather 撤销/重新生成令牌并更新配置。
### 群组消息可见性(隐私模式)
Telegram 机器人默认启用**隐私模式**,这会限制它们能接收到的群组消息。
如果你的机器人必须看到*所有*群组消息,有两种选择:
- 使用 `/setprivacy` 禁用隐私模式,**或者**
- 将机器人设为群组**管理员**(管理员机器人可以接收所有消息)。
**注意:** 切换隐私模式后Telegram 要求将机器人从每个群组中移除并重新添加,
更改才能生效。
### 群组权限(管理员权限)
管理员状态在群组内设置Telegram 界面)。管理员机器人始终能接收所有
群组消息,因此如果需要完全可见性,请使用管理员身份。
## 工作原理(行为)
- 入站消息被规范化为共享渠道信封,包含回复上下文和媒体占位符。
- 群组回复默认需要提及(原生 @提及或 `agents.list[].groupChat.mentionPatterns` / `messages.groupChat.mentionPatterns`)。
- 多智能体覆盖:在 `agents.list[].groupChat.mentionPatterns` 上设置每个智能体的模式。
- 回复始终路由回同一个 Telegram 聊天。
- 长轮询使用 grammY runner按聊天排序总体并发受 `agents.defaults.maxConcurrent` 限制。
- Telegram Bot API 不支持已读回执;没有 `sendReadReceipts` 选项。
## 草稿流式传输
OpenClaw 可以使用 `sendMessageDraft` 在 Telegram 私聊中流式传输部分回复。
要求:
-@BotFather 中为机器人启用话题模式(论坛话题模式)。
- 仅限私聊话题Telegram 在入站消息中包含 `message_thread_id`)。
- `channels.telegram.streamMode` 未设为 `"off"`(默认:`"partial"``"block"` 启用分块草稿更新)。
草稿流式传输仅适用于私聊Telegram 在群组或频道中不支持此功能。
## 格式化Telegram HTML
- 出站 Telegram 文本使用 `parse_mode: "HTML"`Telegram 支持的标签子集)。
- 类 Markdown 输入被渲染为 **Telegram 安全的 HTML**(粗体/斜体/删除线/代码/链接);块级元素被扁平化为带换行符/项目符号的文本。
- 来自模型的原始 HTML 会被转义,以避免 Telegram 解析错误。
- 如果 Telegram 拒绝 HTML 负载OpenClaw 会以纯文本重试同一条消息。
## 命令(原生 + 自定义)
OpenClaw 在启动时将原生命令(如 `/status``/reset``/model`)注册到 Telegram 的机器人菜单。
你可以通过配置向菜单添加自定义命令:
```json5
{
channels: {
telegram: {
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" },
],
},
},
}
```
## 故障排除
- 日志中出现 `setMyCommands failed` 通常意味着到 `api.telegram.org` 的出站 HTTPS/DNS 被阻止。
- 如果看到 `sendMessage``sendChatAction` 失败,请检查 IPv6 路由和 DNS。
更多帮助:[渠道故障排除](/channels/troubleshooting)。
注意:
- 自定义命令**仅为菜单条目**;除非你在其他地方处理它们,否则 OpenClaw 不会实现它们。
- 命令名称会被规范化(去除前导 `/`,转为小写),且必须匹配 `a-z``0-9``_`132 个字符)。
- 自定义命令**不能覆盖原生命令**。冲突会被忽略并记录到日志。
- 如果 `commands.native` 被禁用,则只注册自定义命令(如果没有自定义命令则清空)。
## 限制
- 出站文本按 `channels.telegram.textChunkLimit` 分块(默认 4000
- 可选的换行分块:设置 `channels.telegram.chunkMode="newline"` 以在空行(段落边界)处拆分,然后再按长度分块。
- 媒体下载/上传受 `channels.telegram.mediaMaxMb` 限制(默认 5
- Telegram Bot API 请求在 `channels.telegram.timeoutSeconds` 后超时(通过 grammY 默认 500。设置更低的值以避免长时间挂起。
- 群组历史上下文使用 `channels.telegram.historyLimit`(或 `channels.telegram.accounts.*.historyLimit`),回退到 `messages.groupChat.historyLimit`。设为 `0` 以禁用(默认 50
- 私聊历史可通过 `channels.telegram.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.telegram.dms["<user_id>"].historyLimit`
## 群组激活模式
默认情况下,机器人在群组中只响应提及(`@botname``agents.list[].groupChat.mentionPatterns` 中的模式)。要更改此行为:
### 通过配置(推荐)
```json5
{
channels: {
telegram: {
groups: {
"-1001234567890": { requireMention: false }, // 在此群组中始终回复
},
},
},
}
```
**重要:** 设置 `channels.telegram.groups` 会创建一个**白名单** - 只有列出的群组(或 `"*"`)会被接受。
论坛话题继承其父群组配置allowFrom、requireMention、skills、prompts除非你在 `channels.telegram.groups.<groupId>.topics.<topicId>` 下添加每个话题的覆盖。
允许所有群组且始终回复:
```json5
{
channels: {
telegram: {
groups: {
"*": { requireMention: false }, // 所有群组,始终回复
},
},
},
}
```
保持所有群组仅提及时回复(默认行为):
```json5
{
channels: {
telegram: {
groups: {
"*": { requireMention: true }, // 或完全省略 groups
},
},
},
}
```
### 通过命令(会话级别)
在群组中发送:
- `/activation always` - 回复所有消息
- `/activation mention` - 需要提及(默认)
**注意:** 命令仅更新会话状态。要在重启后保持行为,请使用配置。
### 获取群组聊天 ID
将群组中的任意消息转发给 Telegram 上的 `@userinfobot``@getidsbot`,即可看到聊天 ID负数`-1001234567890`)。
**提示:** 要获取你自己的用户 ID私聊机器人它会回复你的用户 ID配对消息或者在命令启用后使用 `/whoami`
**隐私提示:** `@userinfobot` 是第三方机器人。如果你更注重隐私,可以将机器人添加到群组,发送一条消息,然后使用 `openclaw logs --follow` 读取 `chat.id`,或使用 Bot API 的 `getUpdates`
## 配置写入
默认情况下Telegram 允许写入由渠道事件或 `/config set|unset` 触发的配置更新。
以下情况会发生配置写入:
- 群组升级为超级群组时Telegram 发出 `migrate_to_chat_id`(聊天 ID 变更。OpenClaw 可以自动迁移 `channels.telegram.groups`
- 你在 Telegram 聊天中运行 `/config set``/config unset`(需要 `commands.config: true`)。
禁用方式:
```json5
{
channels: { telegram: { configWrites: false } },
}
```
## 话题(论坛超级群组)
Telegram 论坛话题在每条消息中包含 `message_thread_id`。OpenClaw
-`:topic:<threadId>` 追加到 Telegram 群组会话键,使每个话题相互隔离。
- 发送输入指示器和回复时携带 `message_thread_id`,确保回复留在话题内。
- 通用话题thread id `1`)比较特殊:消息发送时省略 `message_thread_id`Telegram 会拒绝),但输入指示器仍包含它。
- 在模板上下文中暴露 `MessageThreadId` + `IsForum`,用于路由/模板。
- 话题级配置可在 `channels.telegram.groups.<chatId>.topics.<threadId>` 下设置skills、白名单、自动回复、系统提示词、禁用
- 话题配置继承群组设置requireMention、白名单、skills、提示词、enabled除非按话题覆盖。
私聊在某些边缘情况下可能包含 `message_thread_id`。OpenClaw 保持私聊会话键不变,但在存在 thread id 时仍将其用于回复/草稿流式传输。
## 内联按钮
Telegram 支持带回调按钮的内联键盘。
```json5
{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
}
```
按账户配置:
```json5
{
channels: {
telegram: {
accounts: {
main: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
},
},
}
```
作用域:
- `off` — 禁用内联按钮
- `dm` — 仅私聊(群组目标被阻止)
- `group` — 仅群组(私聊目标被阻止)
- `all` — 私聊 + 群组
- `allowlist` — 私聊 + 群组,但仅限 `allowFrom`/`groupAllowFrom` 允许的发送者(与控制命令规则相同)
默认值:`allowlist`
旧版:`capabilities: ["inlineButtons"]` = `inlineButtons: "all"`
### 发送按钮
使用消息工具的 `buttons` 参数:
```json5
{
action: "send",
channel: "telegram",
to: "123456789",
message: "Choose an option:",
buttons: [
[
{ text: "Yes", callback_data: "yes" },
{ text: "No", callback_data: "no" },
],
[{ text: "Cancel", callback_data: "cancel" }],
],
}
```
当用户点击按钮时,回调数据会以以下格式作为消息发送回智能体:
`callback_data: value`
### 配置选项
Telegram 功能可在两个层级配置(上面展示了对象形式;旧版字符串数组仍受支持):
- `channels.telegram.capabilities`:全局默认功能配置,应用于所有 Telegram 账户,除非被覆盖。
- `channels.telegram.accounts.<account>.capabilities`:按账户的功能配置,覆盖该账户的全局默认值。
当所有 Telegram 机器人/账户应具有相同行为时,使用全局设置。当不同机器人需要不同行为时,使用按账户配置(例如,一个账户只处理私聊,另一个允许在群组中使用)。
## 访问控制(私聊 + 群组)
### 私聊访问
- 默认:`channels.telegram.dmPolicy = "pairing"`。未知发送者会收到配对码;消息在批准前被忽略(配对码 1 小时后过期)。
- 批准方式:
- `openclaw pairing list telegram`
- `openclaw pairing approve telegram <CODE>`
- 配对是 Telegram 私聊使用的默认令牌交换方式。详情:[配对](/start/pairing)
- `channels.telegram.allowFrom` 接受数字用户 ID推荐`@username` 条目。这**不是**机器人用户名;请使用人类发送者的 ID。向导接受 `@username` 并在可能时将其解析为数字 ID。
#### 查找你的 Telegram 用户 ID
更安全的方式(无需第三方机器人):
1. 启动 Gateway 并私聊你的机器人。
2. 运行 `openclaw logs --follow` 并查找 `from.id`
替代方式(官方 Bot API
1. 私聊你的机器人。
2. 使用你的机器人令牌获取更新,并读取 `message.from.id`
```bash
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
```
第三方方式(隐私性较低):
- 私聊 `@userinfobot` 或 `@getidsbot` 并使用返回的用户 ID。
### 群组访问
两个独立的控制:
**1. 允许哪些群组**(通过 `channels.telegram.groups` 的群组白名单):
- 没有 `groups` 配置 = 允许所有群组
- 有 `groups` 配置 = 只允许列出的群组或 `"*"`
- 示例:`"groups": { "-1001234567890": {}, "*": {} }` 允许所有群组
**2. 允许哪些发送者**(通过 `channels.telegram.groupPolicy` 的发送者过滤):
- `"open"` = 允许的群组中所有发送者都可以发消息
- `"allowlist"` = 只有 `channels.telegram.groupAllowFrom` 中的发送者可以发消息
- `"disabled"` = 完全不接受群组消息
默认为 `groupPolicy: "allowlist"`(除非添加 `groupAllowFrom`,否则被阻止)。
大多数用户需要:`groupPolicy: "allowlist"` + `groupAllowFrom` + 在 `channels.telegram.groups` 中列出特定群组
## 长轮询 vs webhook
- 默认:长轮询(不需要公网 URL
- Webhook 模式:设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`(可选 `channels.telegram.webhookPath`)。
- 本地监听器绑定到 `0.0.0.0:8787`,默认服务 `POST /telegram-webhook`。
- 如果你的公网 URL 不同,请使用反向代理并将 `channels.telegram.webhookUrl` 指向公网端点。
## 回复线程
Telegram 通过标签支持可选的线程回复:
- `[[reply_to_current]]` -- 回复触发消息。
- `[[reply_to:<id>]]` -- 回复特定消息 ID。
通过 `channels.telegram.replyToMode` 控制:
- `first`(默认)、`all`、`off`。
## 音频消息(语音 vs 文件)
Telegram 区分**语音消息**(圆形气泡)和**音频文件**(元数据卡片)。
OpenClaw 默认使用音频文件以保持向后兼容。
要在智能体回复中强制使用语音消息气泡,在回复中的任意位置包含此标签:
- `[[audio_as_voice]]` — 以语音消息而非文件形式发送音频。
该标签会从发送的文本中移除。其他渠道会忽略此标签。
对于消息工具发送,设置 `asVoice: true` 并附带兼容语音的音频 `media` URL
(当有 media 时 `message` 为可选):
```json5
{
action: "send",
channel: "telegram",
to: "123456789",
media: "https://example.com/voice.ogg",
asVoice: true,
}
```
## 贴纸
OpenClaw 支持接收和发送 Telegram 贴纸,并带有智能缓存。
### 接收贴纸
当用户发送贴纸时OpenClaw 根据贴纸类型进行处理:
- **静态贴纸WEBP** 下载并通过视觉能力处理。贴纸在消息内容中显示为 `<media:sticker>` 占位符。
- **动态贴纸TGS** 跳过(不支持 Lottie 格式处理)。
- **视频贴纸WEBM** 跳过(不支持视频格式处理)。
接收贴纸时可用的模板上下文字段:
- `Sticker` — 包含以下属性的对象:
- `emoji` — 与贴纸关联的表情
- `setName` — 贴纸集名称
- `fileId` — Telegram 文件 ID可用于发回同一贴纸
- `fileUniqueId` — 用于缓存查找的稳定 ID
- `cachedDescription` — 可用时的缓存视觉描述
### 贴纸缓存
贴纸通过 AI 的视觉能力处理以生成描述。由于相同的贴纸经常被重复发送OpenClaw 会缓存这些描述以避免冗余的 API 调用。
**工作原理:**
1. **首次遇到:** 贴纸图像被发送给 AI 进行视觉分析。AI 生成描述(例如"一只卡通猫热情地挥手")。
2. **缓存存储:** 描述与贴纸的文件 ID、表情和集合名称一起保存。
3. **后续遇到:** 再次看到同一贴纸时,直接使用缓存的描述,不再将图像发送给 AI。
**缓存位置:** `~/.openclaw/telegram/sticker-cache.json`
**缓存条目格式:**
```json
{
"fileId": "CAACAgIAAxkBAAI...",
"fileUniqueId": "AgADBAADb6cxG2Y",
"emoji": "👋",
"setName": "CoolCats",
"description": "A cartoon cat waving enthusiastically",
"cachedAt": "2026-01-15T10:30:00.000Z"
}
```
**优势:**
- 通过避免对同一贴纸重复调用视觉能力来降低 API 成本
- 缓存贴纸的响应速度更快(无视觉处理延迟)
- 支持基于缓存描述的贴纸搜索功能
缓存在接收贴纸时自动填充,无需手动管理。
### 发送贴纸
智能体可以使用 `sticker` 和 `sticker-search` 动作发送和搜索贴纸。这些功能默认禁用,必须在配置中启用:
```json5
{
channels: {
telegram: {
actions: {
sticker: true,
},
},
},
}
```
**发送贴纸:**
```json5
{
action: "sticker",
channel: "telegram",
to: "123456789",
fileId: "CAACAgIAAxkBAAI...",
}
```
参数:
- `fileId`(必填)— 贴纸的 Telegram 文件 ID。可从接收贴纸时的 `Sticker.fileId` 获取,或从 `sticker-search` 结果获取。
- `replyTo`(可选)— 要回复的消息 ID。
- `threadId`(可选)— 论坛话题的消息线程 ID。
**搜索贴纸:**
智能体可以通过描述、表情或集合名称搜索缓存的贴纸:
```json5
{
action: "sticker-search",
channel: "telegram",
query: "cat waving",
limit: 5,
}
```
从缓存返回匹配的贴纸:
```json5
{
ok: true,
count: 2,
stickers: [
{
fileId: "CAACAgIAAxkBAAI...",
emoji: "👋",
description: "A cartoon cat waving enthusiastically",
setName: "CoolCats",
},
],
}
```
搜索使用跨描述文本、表情字符和集合名称的模糊匹配。
**带线程的示例:**
```json5
{
action: "sticker",
channel: "telegram",
to: "-1001234567890",
fileId: "CAACAgIAAxkBAAI...",
replyTo: 42,
threadId: 123,
}
```
## 流式传输(草稿)
Telegram 可以在智能体生成回复时流式传输**草稿气泡**。
OpenClaw 使用 Bot API 的 `sendMessageDraft`(非真实消息),然后将
最终回复作为普通消息发送。
要求Telegram Bot API 9.3+
- **启用话题的私聊**(机器人的论坛话题模式)。
- 入站消息必须包含 `message_thread_id`(私聊话题线程)。
- 群组/超级群组/频道中的流式传输会被忽略。
配置:
- `channels.telegram.streamMode: "off" | "partial" | "block"`(默认:`partial`
- `partial`:用最新的流式文本更新草稿气泡。
- `block`:以更大的块更新草稿气泡(分块)。
- `off`:禁用草稿流式传输。
- 可选(仅适用于 `streamMode: "block"`
- `channels.telegram.draftChunk: { minChars?, maxChars?, breakPreference? }`
- 默认值:`minChars: 200`、`maxChars: 800`、`breakPreference: "paragraph"`(受 `channels.telegram.textChunkLimit` 限制)。
注意:草稿流式传输与**分块流式传输**(渠道消息)不同。
分块流式传输默认关闭,如果你想要提前的 Telegram 消息而非草稿更新,需要设置 `channels.telegram.blockStreaming: true`。
推理流式传输(仅 Telegram
- `/reasoning stream` 在回复生成时将推理过程流式传输到草稿气泡中,然后发送不包含推理过程的最终答案。
- 如果 `channels.telegram.streamMode` 为 `off`,推理流式传输将被禁用。
更多上下文:[流式传输 + 分块](/concepts/streaming)。
## 重试策略
出站 Telegram API 调用在遇到瞬态网络/429 错误时会以指数退避和抖动进行重试。通过 `channels.telegram.retry` 配置。参见[重试策略](/concepts/retry)。
## 智能体工具(消息 + 表情回应)
- 工具:`telegram``sendMessage` 动作(`to`、`content`,可选 `mediaUrl`、`replyToMessageId`、`messageThreadId`)。
- 工具:`telegram``react` 动作(`chatId`、`messageId`、`emoji`)。
- 工具:`telegram``deleteMessage` 动作(`chatId`、`messageId`)。
- 表情回应移除语义:参见 [/tools/reactions](/tools/reactions)。
- 工具门控:`channels.telegram.actions.reactions`、`channels.telegram.actions.sendMessage`、`channels.telegram.actions.deleteMessage`(默认:启用),以及 `channels.telegram.actions.sticker`(默认:禁用)。
## 表情回应通知
**表情回应的工作原理:**
Telegram 表情回应作为**独立的 `message_reaction` 事件**到达而非消息负载中的属性。当用户添加表情回应时OpenClaw
1. 从 Telegram API 接收 `message_reaction` 更新
2. 将其转换为**系统事件**,格式为:`"Telegram reaction added: {emoji} by {user} on msg {id}"`
3. 使用与常规消息**相同的会话键**将系统事件入队
4. 当该对话中的下一条消息到达时,系统事件被排出并添加到智能体上下文的前面
智能体将表情回应视为对话历史中的**系统通知**,而非消息元数据。
**配置:**
- `channels.telegram.reactionNotifications`:控制哪些表情回应触发通知
- `"off"` — 忽略所有表情回应
- `"own"` — 当用户对机器人消息做出表情回应时通知(尽力而为;内存中)(默认)
- `"all"` — 对所有表情回应进行通知
- `channels.telegram.reactionLevel`:控制智能体的表情回应能力
- `"off"` — 智能体不能对消息做表情回应
- `"ack"` — 机器人发送确认表情回应(处理时显示 👀)(默认)
- `"minimal"` — 智能体可以少量使用表情回应(指导原则:每 5-10 次交流 1 次)
- `"extensive"` — 智能体可以在适当时大量使用表情回应
**论坛群组:** 论坛群组中的表情回应包含 `message_thread_id`,使用如 `agent:main:telegram:group:{chatId}:topic:{threadId}` 的会话键。这确保同一话题中的表情回应和消息保持在一起。
**示例配置:**
```json5
{
channels: {
telegram: {
reactionNotifications: "all", // 查看所有表情回应
reactionLevel: "minimal", // 智能体可以少量使用表情回应
},
},
}
```
**要求:**
- Telegram 机器人必须在 `allowed_updates` 中显式请求 `message_reaction`(由 OpenClaw 自动配置)
- 对于 webhook 模式,表情回应包含在 webhook 的 `allowed_updates` 中
- 对于轮询模式,表情回应包含在 `getUpdates` 的 `allowed_updates` 中
## 投递目标CLI/定时任务)
- 使用聊天 ID`123456789`)或用户名(`@name`)作为目标。
- 示例:`openclaw message send --channel telegram --target 123456789 --message "hi"`。
## 故障排除
**机器人在群组中不响应非提及消息:**
- 如果你设置了 `channels.telegram.groups.*.requireMention=false`Telegram 的 Bot API **隐私模式**必须被禁用。
- BotFather`/setprivacy` → **Disable**(然后从群组中移除并重新添加机器人)
- `openclaw channels status` 在配置期望接收非提及群组消息时会显示警告。
- `openclaw channels status --probe` 可以额外检查显式数字群组 ID 的成员资格(无法审计通配符 `"*"` 规则)。
- 快速测试:`/activation always`(仅会话级别;持久化请使用配置)
**机器人完全看不到群组消息:**
- 如果设置了 `channels.telegram.groups`,群组必须被列出或使用 `"*"`
- 在 @BotFather 中检查隐私设置 → "Group Privacy" 应为 **OFF**
- 确认机器人确实是成员(而非只是没有读取权限的管理员)
- 检查 Gateway 日志:`openclaw logs --follow`(查找 "skipping group message"
**机器人响应提及但不响应 `/activation always`**
- `/activation` 命令更新会话状态但不会持久化到配置
- 要持久化行为,将群组添加到 `channels.telegram.groups` 并设置 `requireMention: false`
**`/status` 等命令不工作:**
- 确保你的 Telegram 用户 ID 已授权(通过配对或 `channels.telegram.allowFrom`
- 即使在 `groupPolicy: "open"` 的群组中,命令也需要授权
**长轮询在 Node 22+ 上立即中止(通常涉及代理/自定义 fetch**
- Node 22+ 对 `AbortSignal` 实例更严格;外部信号可能会立即中止 `fetch` 调用。
- 升级到规范化 abort 信号的 OpenClaw 版本,或在 Node 20 上运行 Gateway 直到可以升级。
**机器人启动后静默停止响应(或日志中出现 `HttpError: Network request ... failed`**
- 某些主机优先将 `api.telegram.org` 解析为 IPv6。如果你的服务器没有可用的 IPv6 出口grammY 可能会卡在仅 IPv6 的请求上。
- 修复方法:启用 IPv6 出口**或者**强制 `api.telegram.org` 使用 IPv4 解析(例如,使用 IPv4 A 记录添加 `/etc/hosts` 条目,或在操作系统 DNS 栈中优先使用 IPv4然后重启 Gateway。
- 快速检查:`dig +short api.telegram.org A` 和 `dig +short api.telegram.org AAAA` 确认 DNS 返回的内容。
## 配置参考Telegram
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.telegram.enabled`:启用/禁用渠道启动。
- `channels.telegram.botToken`机器人令牌BotFather
- `channels.telegram.tokenFile`:从文件路径读取令牌。
- `channels.telegram.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.telegram.allowFrom`私聊白名单ID/用户名)。`open` 需要 `"*"`。
- `channels.telegram.groupPolicy``open | allowlist | disabled`默认allowlist
- `channels.telegram.groupAllowFrom`群组发送者白名单ID/用户名)。
- `channels.telegram.groups`:按群组的默认设置 + 白名单(使用 `"*"` 作为全局默认)。
- `channels.telegram.groups.<id>.requireMention`:提及门控默认值。
- `channels.telegram.groups.<id>.skills`:技能过滤(省略 = 所有技能,空 = 无技能)。
- `channels.telegram.groups.<id>.allowFrom`:按群组的发送者白名单覆盖。
- `channels.telegram.groups.<id>.systemPrompt`:群组的额外系统提示词。
- `channels.telegram.groups.<id>.enabled`:设为 `false` 时禁用该群组。
- `channels.telegram.groups.<id>.topics.<threadId>.*`:按话题覆盖(与群组字段相同)。
- `channels.telegram.groups.<id>.topics.<threadId>.requireMention`:按话题的提及门控覆盖。
- `channels.telegram.capabilities.inlineButtons``off | dm | group | all | allowlist`默认allowlist
- `channels.telegram.accounts.<account>.capabilities.inlineButtons`:按账户覆盖。
- `channels.telegram.replyToMode``off | first | all`(默认:`first`)。
- `channels.telegram.textChunkLimit`:出站分块大小(字符数)。
- `channels.telegram.chunkMode``length`(默认)或 `newline`,在空行(段落边界)处拆分后再按长度分块。
- `channels.telegram.linkPreview`切换出站消息的链接预览默认true
- `channels.telegram.streamMode``off | partial | block`(草稿流式传输)。
- `channels.telegram.mediaMaxMb`:入站/出站媒体上限MB
- `channels.telegram.retry`:出站 Telegram API 调用的重试策略attempts、minDelayMs、maxDelayMs、jitter
- `channels.telegram.network.autoSelectFamily`:覆盖 Node 的 autoSelectFamilytrue=启用false=禁用)。在 Node 22 上默认禁用以避免 Happy Eyeballs 超时。
- `channels.telegram.proxy`Bot API 调用的代理 URLSOCKS/HTTP
- `channels.telegram.webhookUrl`:启用 webhook 模式(需要 `channels.telegram.webhookSecret`)。
- `channels.telegram.webhookSecret`webhook 密钥(设置 webhookUrl 时必填)。
- `channels.telegram.webhookPath`:本地 webhook 路径(默认 `/telegram-webhook`)。
- `channels.telegram.actions.reactions`Telegram 工具表情回应门控。
- `channels.telegram.actions.sendMessage`Telegram 工具消息发送门控。
- `channels.telegram.actions.deleteMessage`Telegram 工具消息删除门控。
- `channels.telegram.actions.sticker`Telegram 贴纸动作门控 — 发送和搜索默认false
- `channels.telegram.reactionNotifications``off | own | all` — 控制哪些表情回应触发系统事件(未设置时默认:`own`)。
- `channels.telegram.reactionLevel``off | ack | minimal | extensive` — 控制智能体的表情回应能力(未设置时默认:`minimal`)。
相关全局选项:
- `agents.list[].groupChat.mentionPatterns`(提及门控模式)。
- `messages.groupChat.mentionPatterns`(全局回退)。
- `commands.native`(默认为 `"auto"` → Telegram/Discord 启用Slack 禁用)、`commands.text`、`commands.useAccessGroups`(命令行为)。通过 `channels.telegram.commands.native` 覆盖。
- `messages.responsePrefix`、`messages.ackReaction`、`messages.ackReactionScope`、`messages.removeAckAfterReply`。

138
docs/zh-CN/channels/tlon.md Normal file
View File

@@ -0,0 +1,138 @@
---
read_when:
- 开发 Tlon/Urbit 渠道功能时
summary: Tlon/Urbit 支持状态、功能和配置
title: Tlon
x-i18n:
generated_at: "2026-02-01T19:58:15Z"
model: claude-opus-4-5
provider: pi
source_hash: 19d7ffe23e82239fd2a2e35913e0d52c809b2c2b939dd39184e6c27a539ed97d
source_path: channels/tlon.md
workflow: 14
---
# Tlon插件
Tlon 是一个基于 Urbit 构建的去中心化通讯工具。OpenClaw 连接到你的 Urbit ship可以
回复私信和群聊消息。群聊回复默认需要 @ 提及,并可通过白名单进一步限制。
状态:通过插件支持。支持私信、群组提及、线程回复和纯文本媒体回退
URL 附加到标题)。不支持反应、投票和原生媒体上传。
## 需要插件
Tlon 以插件形式提供,不包含在核心安装包中。
通过 CLI 安装npm 注册表):
```bash
openclaw plugins install @openclaw/tlon
```
本地签出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/tlon
```
详情:[插件](/plugin)
## 设置
1. 安装 Tlon 插件。
2. 获取你的 ship URL 和登录代码。
3. 配置 `channels.tlon`
4. 重启 Gateway。
5. 向机器人发送私信或在群组渠道中提及它。
最小配置(单账户):
```json5
{
channels: {
tlon: {
enabled: true,
ship: "~sampel-palnet",
url: "https://your-ship-host",
code: "lidlut-tabwed-pillex-ridrup",
},
},
}
```
## 群组渠道
默认启用自动发现。你也可以手动固定渠道:
```json5
{
channels: {
tlon: {
groupChannels: ["chat/~host-ship/general", "chat/~host-ship/support"],
},
},
}
```
禁用自动发现:
```json5
{
channels: {
tlon: {
autoDiscoverChannels: false,
},
},
}
```
## 访问控制
私信白名单(为空 = 允许所有):
```json5
{
channels: {
tlon: {
dmAllowlist: ["~zod", "~nec"],
},
},
}
```
群组授权(默认为受限模式):
```json5
{
channels: {
tlon: {
defaultAuthorizedShips: ["~zod"],
authorization: {
channelRules: {
"chat/~host-ship/general": {
mode: "restricted",
allowedShips: ["~zod", "~nec"],
},
"chat/~host-ship/announcements": {
mode: "open",
},
},
},
},
},
}
```
## 投递目标CLI/定时任务)
`openclaw message send` 或定时投递配合使用:
- 私信:`~sampel-palnet``dm/~sampel-palnet`
- 群组:`chat/~host-ship/channel``group:~host-ship/channel`
## 备注
- 群聊回复需要提及(例如 `~your-bot-ship`)才会响应。
- 线程回复如果收到的消息在线程中OpenClaw 会在线程内回复。
- 媒体:`sendMedia` 回退为文本 + URL不支持原生上传

View File

@@ -0,0 +1,36 @@
---
read_when:
- 渠道已连接但消息无法流通
- 排查渠道配置错误(意图、权限、隐私模式)
summary: 渠道专属故障排除快捷指南Discord/Telegram/WhatsApp
title: 渠道故障排除
x-i18n:
generated_at: "2026-02-01T19:58:09Z"
model: claude-opus-4-5
provider: pi
source_hash: 6542ee86b3e50929caeaab127642d135dfbc0d8a44876ec2df0fff15bf57cd63
source_path: channels/troubleshooting.md
workflow: 14
---
# 渠道故障排除
首先运行:
```bash
openclaw doctor
openclaw channels status --probe
```
`channels status --probe` 会在检测到常见渠道配置错误时输出警告,并包含小型实时检查(凭据、部分权限/成员资格)。
## 渠道
- Discord[/channels/discord#troubleshooting](/channels/discord#troubleshooting)
- Telegram[/channels/telegram#troubleshooting](/channels/telegram#troubleshooting)
- WhatsApp[/channels/whatsapp#troubleshooting-quick](/channels/whatsapp#troubleshooting-quick)
## Telegram 快速修复
- 日志显示 `HttpError: Network request for 'sendMessage' failed``sendChatAction` → 检查 IPv6 DNS。如果 `api.telegram.org` 优先解析为 IPv6 而主机缺少 IPv6 出站连接,请强制使用 IPv4 或启用 IPv6。参见 [/channels/telegram#troubleshooting](/channels/telegram#troubleshooting)。
- 日志显示 `setMyCommands failed` → 检查到 `api.telegram.org` 的出站 HTTPS 和 DNS 可达性(常见于限制严格的 VPS 或代理环境)。

View File

@@ -0,0 +1,384 @@
---
read_when:
- 为 OpenClaw 设置 Twitch 聊天集成
summary: Twitch 聊天机器人配置与设置
title: Twitch
x-i18n:
generated_at: "2026-02-01T19:58:38Z"
model: claude-opus-4-5
provider: pi
source_hash: aa7d60444e7f7e5dd7d02ce21527089058e024b8f427aeedf9e200a2818eb007
source_path: channels/twitch.md
workflow: 14
---
# Twitch插件
通过 IRC 连接支持 Twitch 聊天。OpenClaw 以 Twitch 用户(机器人账号)身份连接,在频道中接收和发送消息。
## 需要插件
Twitch 以插件形式提供,未包含在核心安装中。
通过 CLInpm 注册表)安装:
```bash
openclaw plugins install @openclaw/twitch
```
本地签出(从 git 仓库运行时):
```bash
openclaw plugins install ./extensions/twitch
```
详情:[插件](/plugin)
## 快速设置(入门)
1. 为机器人创建一个专用 Twitch 账号(或使用现有账号)。
2. 生成凭证:[Twitch Token Generator](https://twitchtokengenerator.com/)
- 选择 **Bot Token**
- 确认已勾选 `chat:read``chat:write` 权限范围
- 复制 **Client ID****Access Token**
3. 查找你的 Twitch 用户 IDhttps://www.streamweasels.com/tools/convert-twitch-username-to-user-id/
4. 配置令牌:
- 环境变量:`OPENCLAW_TWITCH_ACCESS_TOKEN=...`(仅限默认账号)
- 或配置文件:`channels.twitch.accessToken`
- 如果两者都设置了,配置文件优先(环境变量回退仅适用于默认账号)。
5. 启动 Gateway。
**⚠️ 重要:** 添加访问控制(`allowFrom``allowedRoles`)以防止未授权用户触发机器人。`requireMention` 默认为 `true`
最小配置:
```json5
{
channels: {
twitch: {
enabled: true,
username: "openclaw", // 机器人的 Twitch 账号
accessToken: "oauth:abc123...", // OAuth Access Token或使用 OPENCLAW_TWITCH_ACCESS_TOKEN 环境变量)
clientId: "xyz789...", // 从 Token Generator 获取的 Client ID
channel: "vevisk", // 要加入的 Twitch 频道聊天室(必填)
allowFrom: ["123456789"], // (推荐)仅限你的 Twitch 用户 ID - 从 https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/ 获取
},
},
}
```
## 工作原理
- 由 Gateway 拥有的 Twitch 渠道。
- 确定性路由:回复始终返回到 Twitch。
- 每个账号映射到一个隔离的会话键 `agent:<agentId>:twitch:<accountName>`
- `username` 是机器人的账号(用于认证),`channel` 是要加入的聊天室。
## 设置(详细)
### 生成凭证
使用 [Twitch Token Generator](https://twitchtokengenerator.com/)
- 选择 **Bot Token**
- 确认已勾选 `chat:read``chat:write` 权限范围
- 复制 **Client ID****Access Token**
无需手动注册应用。令牌在数小时后过期。
### 配置机器人
**环境变量(仅限默认账号):**
```bash
OPENCLAW_TWITCH_ACCESS_TOKEN=oauth:abc123...
```
**或配置文件:**
```json5
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
},
}
```
如果环境变量和配置文件都设置了,配置文件优先。
### 访问控制(推荐)
```json5
{
channels: {
twitch: {
allowFrom: ["123456789"], // (推荐)仅限你的 Twitch 用户 ID
allowedRoles: ["moderator"], // 或按角色限制
},
},
}
```
**可用角色:** `"moderator"``"owner"``"vip"``"subscriber"``"all"`
**为什么使用用户 ID** 用户名可以更改,存在冒充风险。用户 ID 是永久的。
查找你的 Twitch 用户 IDhttps://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/(将 Twitch 用户名转换为 ID
## 令牌刷新(可选)
从 [Twitch Token Generator](https://twitchtokengenerator.com/) 获取的令牌无法自动刷新——过期后需重新生成。
如需自动刷新令牌,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置中:
```json5
{
channels: {
twitch: {
clientSecret: "your_client_secret",
refreshToken: "your_refresh_token",
},
},
}
```
机器人会在令牌过期前自动刷新,并记录刷新事件。
## 多账号支持
使用 `channels.twitch.accounts` 配置每个账号的令牌。参见 [`gateway/configuration`](/gateway/configuration) 了解通用模式。
示例(一个机器人账号加入两个频道):
```json5
{
channels: {
twitch: {
accounts: {
channel1: {
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
},
channel2: {
username: "openclaw",
accessToken: "oauth:def456...",
clientId: "uvw012...",
channel: "secondchannel",
},
},
},
},
}
```
**注意:** 每个账号需要自己的令牌(每个频道一个令牌)。
## 访问控制
### 基于角色的限制
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowedRoles: ["moderator", "vip"],
},
},
},
},
}
```
### 按用户 ID 设置允许列表(最安全)
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowFrom: ["123456789", "987654321"],
},
},
},
},
}
```
### 组合允许列表 + 角色
`allowFrom` 中的用户可绕过角色检查:
```json5
{
channels: {
twitch: {
accounts: {
default: {
allowFrom: ["123456789"],
allowedRoles: ["moderator"],
},
},
},
},
}
```
### 禁用 @提及要求
默认情况下,`requireMention``true`。要禁用并响应所有消息:
```json5
{
channels: {
twitch: {
accounts: {
default: {
requireMention: false,
},
},
},
},
}
```
## 故障排除
首先,运行诊断命令:
```bash
openclaw doctor
openclaw channels status --probe
```
### 机器人不响应消息
**检查访问控制:** 临时设置 `allowedRoles: ["all"]` 进行测试。
**检查机器人是否在频道中:** 机器人必须加入 `channel` 中指定的频道。
### 令牌问题
**"Failed to connect" 或认证错误:**
- 确认 `accessToken` 是 OAuth 访问令牌值(通常以 `oauth:` 前缀开头)
- 检查令牌是否具有 `chat:read``chat:write` 权限范围
- 如果使用令牌刷新,确认已设置 `clientSecret``refreshToken`
### 令牌刷新不工作
**检查日志中的刷新事件:**
```
Using env token source for mybot
Access token refreshed for user 123456 (expires in 14400s)
```
如果看到 "token refresh disabled (no refresh token)"
- 确保已提供 `clientSecret`
- 确保已提供 `refreshToken`
## 配置
**账号配置:**
- `username` - 机器人用户名
- `accessToken` - 具有 `chat:read``chat:write` 权限的 OAuth 访问令牌
- `clientId` - Twitch Client ID来自 Token Generator 或你的应用)
- `channel` - 要加入的频道(必填)
- `enabled` - 启用此账号(默认:`true`
- `clientSecret` - 可选:用于自动刷新令牌
- `refreshToken` - 可选:用于自动刷新令牌
- `expiresIn` - 令牌过期时间(秒)
- `obtainmentTimestamp` - 令牌获取时间戳
- `allowFrom` - 用户 ID 允许列表
- `allowedRoles` - 基于角色的访问控制(`"moderator" | "owner" | "vip" | "subscriber" | "all"`
- `requireMention` - 要求 @提及(默认:`true`
**提供商选项:**
- `channels.twitch.enabled` - 启用/禁用渠道启动
- `channels.twitch.username` - 机器人用户名(简化单账号配置)
- `channels.twitch.accessToken` - OAuth 访问令牌(简化单账号配置)
- `channels.twitch.clientId` - Twitch Client ID简化单账号配置
- `channels.twitch.channel` - 要加入的频道(简化单账号配置)
- `channels.twitch.accounts.<accountName>` - 多账号配置(上述所有账号字段)
完整示例:
```json5
{
channels: {
twitch: {
enabled: true,
username: "openclaw",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "vevisk",
clientSecret: "secret123...",
refreshToken: "refresh456...",
allowFrom: ["123456789"],
allowedRoles: ["moderator", "vip"],
accounts: {
default: {
username: "mybot",
accessToken: "oauth:abc123...",
clientId: "xyz789...",
channel: "your_channel",
enabled: true,
clientSecret: "secret123...",
refreshToken: "refresh456...",
expiresIn: 14400,
obtainmentTimestamp: 1706092800000,
allowFrom: ["123456789", "987654321"],
allowedRoles: ["moderator"],
},
},
},
},
}
```
## 工具操作
智能体可以调用 `twitch` 执行以下操作:
- `send` - 向频道发送消息
示例:
```json5
{
action: "twitch",
params: {
message: "Hello Twitch!",
to: "#mychannel",
},
}
```
## 安全与运维
- **将令牌视为密码** - 切勿将令牌提交到 git
- **使用自动令牌刷新** 用于长时间运行的机器人
- **使用用户 ID 允许列表** 而非用户名进行访问控制
- **监控日志** 关注令牌刷新事件和连接状态
- **最小化令牌权限范围** - 仅请求 `chat:read``chat:write`
- **如遇问题**:确认没有其他进程占用会话后,重启 Gateway
## 限制
- 每条消息最多 **500 个字符**(按词边界自动分块)
- 分块前会移除 Markdown 格式
- 无速率限制(使用 Twitch 内置的速率限制)

View File

@@ -0,0 +1,410 @@
---
read_when:
- 处理 WhatsApp/网页渠道行为或收件箱路由时
summary: WhatsApp网页渠道集成登录、收件箱、回复、媒体和运维
title: WhatsApp
x-i18n:
generated_at: "2026-02-01T20:00:02Z"
model: claude-opus-4-5
provider: pi
source_hash: 44fd88f8e269284999e5a5a52b230edae6e6f978528dd298d6a5603d03c0c38d
source_path: channels/whatsapp.md
workflow: 14
---
# WhatsApp网页渠道
状态:仅支持通过 Baileys 的 WhatsApp Web。Gateway 拥有会话。
## 快速设置(入门)
1. 如果可能,使用**单独的手机号码**(推荐)。
2.`~/.openclaw/openclaw.json` 中配置 WhatsApp。
3. 运行 `openclaw channels login` 扫描二维码(已关联设备)。
4. 启动 Gateway。
最小配置:
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
## 目标
- 单个 Gateway 进程中支持多个 WhatsApp 账号(多账号)。
- 确定性路由:回复返回到 WhatsApp无模型路由。
- 模型获得足够的上下文以理解引用回复。
## 配置写入
默认情况下WhatsApp 允许通过 `/config set|unset` 触发配置更新写入(需要 `commands.config: true`)。
禁用方式:
```json5
{
channels: { whatsapp: { configWrites: false } },
}
```
## 架构(职责划分)
- **Gateway** 拥有 Baileys socket 和收件箱循环。
- **CLI / macOS 应用** 与 Gateway 通信;不直接使用 Baileys。
- **活跃监听器** 是出站发送的必要条件;否则发送会快速失败。
## 获取手机号码(两种模式)
WhatsApp 需要真实的手机号码进行验证。VoIP 和虚拟号码通常会被屏蔽。在 WhatsApp 上运行 OpenClaw 有两种支持的方式:
### 专用号码(推荐)
为 OpenClaw 使用**单独的手机号码**。最佳用户体验,干净的路由,无自聊天问题。理想设置:**备用/旧 Android 手机 + eSIM**。保持 Wi-Fi 和充电连接,通过二维码关联。
**WhatsApp Business** 你可以在同一设备上使用不同号码的 WhatsApp Business。非常适合将个人 WhatsApp 分开 — 安装 WhatsApp Business 并在其中注册 OpenClaw 号码。
**示例配置(专用号码,单用户允许列表):**
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
**配对模式(可选):**
如果你想使用配对而非允许列表,将 `channels.whatsapp.dmPolicy` 设置为 `pairing`。未知发送者会收到配对码;通过以下命令批准:
`openclaw pairing approve whatsapp <code>`
### 个人号码(备选方案)
快速备选方案:在**你自己的号码**上运行 OpenClaw。给自己发消息WhatsApp "给自己发消息")进行测试,避免打扰联系人。在设置和实验期间,需要在主手机上读取验证码。**必须启用自聊天模式。**
当向导询问你的个人 WhatsApp 号码时,输入你将用来发消息的手机号(所有者/发送者),而不是助手号码。
**示例配置(个人号码,自聊天):**
```json
{
"whatsapp": {
"selfChatMode": true,
"dmPolicy": "allowlist",
"allowFrom": ["+15551234567"]
}
}
```
当设置了 `messages.responsePrefix` 时,自聊天回复默认使用 `[{identity.name}]`(否则为 `[openclaw]`)。
如果 `messages.responsePrefix` 未设置,则使用默认值。显式设置可自定义或禁用前缀(使用 `""` 来移除)。
### 号码获取技巧
- **本国 eSIM**,来自你所在国家的移动运营商(最可靠)
- 奥地利:[hot.at](https://www.hot.at)
- 英国:[giffgaff](https://www.giffgaff.com) — 免费 SIM 卡,无合约
- **预付费 SIM 卡** — 便宜,只需接收一条验证短信
**避免使用:** TextNow、Google Voice、大多数"免费短信"服务 — WhatsApp 会积极屏蔽这些号码。
**提示:** 该号码只需接收一条验证短信。之后WhatsApp Web 会话通过 `creds.json` 持久保存。
## 为什么不用 Twilio
- 早期 OpenClaw 版本支持 Twilio 的 WhatsApp Business 集成。
- WhatsApp Business 号码不适合个人助手。
- Meta 强制执行 24 小时回复窗口;如果你在过去 24 小时内没有回复,商业号码无法发起新消息。
- 高频或"频繁"使用会触发激进的封禁,因为商业账号不适合发送大量个人助手消息。
- 结果:投递不可靠且频繁被封禁,因此已移除支持。
## 登录 + 凭证
- 登录命令:`openclaw channels login`(通过已关联设备扫描二维码)。
- 多账号登录:`openclaw channels login --account <id>``<id>` = `accountId`)。
- 默认账号(省略 `--account` 时):如果存在则为 `default`,否则为第一个已配置的账号 ID排序后
- 凭证存储在 `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
- 备份副本位于 `creds.json.bak`(损坏时恢复)。
- 旧版兼容:早期安装将 Baileys 文件直接存储在 `~/.openclaw/credentials/`
- 注销:`openclaw channels logout`(或 `--account <id>`)删除 WhatsApp 认证状态(但保留共享的 `oauth.json`)。
- 已注销的 socket => 错误提示重新关联。
## 入站流程(私聊 + 群聊)
- WhatsApp 事件来自 `messages.upsert`Baileys
- 收件箱监听器在关闭时解除绑定,以避免在测试/重启中累积事件处理器。
- 状态/广播聊天被忽略。
- 私聊使用 E.164 格式;群聊使用群组 JID。
- **私聊策略**`channels.whatsapp.dmPolicy` 控制私聊访问(默认:`pairing`)。
- 配对:未知发送者会收到配对码(通过 `openclaw pairing approve whatsapp <code>` 批准;码在 1 小时后过期)。
- 开放:需要 `channels.whatsapp.allowFrom` 包含 `"*"`
- 你关联的 WhatsApp 号码被隐式信任,因此自消息跳过 `channels.whatsapp.dmPolicy``channels.whatsapp.allowFrom` 检查。
### 个人号码模式(备选方案)
如果你在**个人 WhatsApp 号码**上运行 OpenClaw启用 `channels.whatsapp.selfChatMode`(参见上方示例配置)。
行为:
- 出站私聊消息不会触发配对回复(防止骚扰联系人)。
- 入站未知发送者仍遵循 `channels.whatsapp.dmPolicy`
- 自聊天模式allowFrom 包含你的号码)避免自动已读回执并忽略提及 JID。
- 非自聊天私聊会发送已读回执。
## 已读回执
默认情况下Gateway 会在接受入站 WhatsApp 消息后将其标记为已读(蓝色对勾)。
全局禁用:
```json5
{
channels: { whatsapp: { sendReadReceipts: false } },
}
```
按账号禁用:
```json5
{
channels: {
whatsapp: {
accounts: {
personal: { sendReadReceipts: false },
},
},
},
}
```
备注:
- 自聊天模式始终跳过已读回执。
## WhatsApp 常见问题:发送消息 + 配对
**关联 WhatsApp 后OpenClaw 会给随机联系人发消息吗?**
不会。默认私聊策略是**配对**,因此未知发送者只会收到配对码,其消息**不会被处理**。OpenClaw 只回复收到的聊天,或你显式触发的发送(智能体/CLI
**WhatsApp 上的配对是如何工作的?**
配对是针对未知发送者的私聊门控:
- 新发送者的首条私聊消息会返回一个短码(消息不会被处理)。
- 通过以下命令批准:`openclaw pairing approve whatsapp <code>`(用 `openclaw pairing list whatsapp` 列出)。
- 码在 1 小时后过期;每个渠道的待处理请求上限为 3 个。
**多人可以在同一个 WhatsApp 号码上使用不同的 OpenClaw 实例吗?**
可以,通过 `bindings` 将每个发送者路由到不同的智能体peer `kind: "dm"`,发送者 E.164 如 `+15551234567`)。回复仍然来自**同一个 WhatsApp 账号**,且私聊会折叠到每个智能体的主会话,因此请使用**每人一个智能体**。私聊访问控制(`dmPolicy`/`allowFrom`)在每个 WhatsApp 账号级别是全局的。参见[多智能体路由](/concepts/multi-agent)。
**为什么向导要询问我的手机号码?**
向导使用它来设置你的**允许列表/所有者**,以便允许你自己的私聊消息。它不用于自动发送。如果你在个人 WhatsApp 号码上运行,使用相同的号码并启用 `channels.whatsapp.selfChatMode`
## 消息标准化(模型看到的内容)
- `Body` 是当前消息正文及其信封。
- 引用回复上下文**始终附加**
```
[Replying to +1555 id:ABC123]
<quoted text or <media:...>>
[/Replying]
```
- 回复元数据也会设置:
- `ReplyToId` = stanzaId
- `ReplyToBody` = 引用正文或媒体占位符
- `ReplyToSender` = E.164(已知时)
- 纯媒体入站消息使用占位符:
- `<media:image|video|audio|document|sticker>`
## 群聊
- 群聊映射到 `agent:<agentId>:whatsapp:group:<jid>` 会话。
- 群聊策略:`channels.whatsapp.groupPolicy = open|disabled|allowlist`(默认 `allowlist`)。
- 激活模式:
- `mention`(默认):需要 @提及或正则匹配。
- `always`:始终触发。
- `/activation mention|always` 仅限所有者且必须作为独立消息发送。
- 所有者 = `channels.whatsapp.allowFrom`(未设置时为自身 E.164)。
- **历史注入**(仅待处理):
- 最近*未处理*的消息(默认 50 条)插入在:
`[Chat messages since your last reply - for context]`(已在会话中的消息不会被重复注入)
- 当前消息位于:
`[Current message - respond to this]`
- 发送者后缀附加:`[from: Name (+E164)]`
- 群聊元数据缓存 5 分钟(主题 + 参与者)。
## 回复投递(线程)
- WhatsApp Web 发送标准消息(当前 Gateway 中无引用回复线程)。
- 此渠道忽略回复标签。
## 确认反应(收到消息时自动反应)
WhatsApp 可以在收到消息时立即自动发送表情反应,在机器人生成回复之前。这为用户提供即时反馈,表明其消息已收到。
**配置:**
```json
{
"whatsapp": {
"ackReaction": {
"emoji": "👀",
"direct": true,
"group": "mentions"
}
}
}
```
**选项:**
- `emoji`(字符串):用于确认的表情(例如 "👀"、"✅"、"📨")。为空或省略 = 功能禁用。
- `direct`(布尔值,默认:`true`):在私聊/DM 中发送反应。
- `group`(字符串,默认:`"mentions"`):群聊行为:
- `"always"`:对所有群聊消息做出反应(即使没有 @提及)
- `"mentions"`:仅在机器人被 @提及时做出反应
- `"never"`:从不在群聊中做出反应
**按账号覆盖:**
```json
{
"whatsapp": {
"accounts": {
"work": {
"ackReaction": {
"emoji": "✅",
"direct": false,
"group": "always"
}
}
}
}
}
```
**行为说明:**
- 反应在收到消息时**立即**发送,在输入指示器或机器人回复之前。
- 在 `requireMention: false`激活模式always的群组中`group: "mentions"` 会对所有消息做出反应(不仅仅是 @提及)。
- 即发即忘:反应失败会被记录但不会阻止机器人回复。
- 群聊反应会自动包含参与者 JID。
- WhatsApp 忽略 `messages.ackReaction`;请改用 `channels.whatsapp.ackReaction`。
## 智能体工具(反应)
- 工具:`whatsapp`,使用 `react` 动作(`chatJid`、`messageId`、`emoji`,可选 `remove`)。
- 可选:`participant`(群聊发送者)、`fromMe`(对自己的消息做出反应)、`accountId`(多账号)。
- 反应移除语义:参见 [/tools/reactions](/tools/reactions)。
- 工具门控:`channels.whatsapp.actions.reactions`(默认:启用)。
## 限制
- 出站文本按 `channels.whatsapp.textChunkLimit` 分块(默认 4000
- 可选换行分块:设置 `channels.whatsapp.chunkMode="newline"` 在空行(段落边界)处分割,再进行长度分块。
- 入站媒体保存受 `channels.whatsapp.mediaMaxMb` 限制(默认 50 MB
- 出站媒体项受 `agents.defaults.mediaMaxMb` 限制(默认 5 MB
## 出站发送(文本 + 媒体)
- 使用活跃的网页监听器;如果 Gateway 未运行则报错。
- 文本分块:每条消息最大 4k可通过 `channels.whatsapp.textChunkLimit` 配置,可选 `channels.whatsapp.chunkMode`)。
- 媒体:
- 支持图片/视频/音频/文档。
- 音频以 PTT 发送;`audio/ogg` => `audio/ogg; codecs=opus`。
- 仅第一个媒体项带字幕。
- 媒体获取支持 HTTP(S) 和本地路径。
- 动态 GIFWhatsApp 期望带 `gifPlayback: true` 的 MP4 以实现内联循环播放。
- CLI`openclaw message send --media <mp4> --gif-playback`
- Gateway`send` 参数包含 `gifPlayback: true`
## 语音消息PTT 音频)
WhatsApp 以**语音消息**PTT 气泡)发送音频。
- 最佳效果OGG/Opus。OpenClaw 将 `audio/ogg` 重写为 `audio/ogg; codecs=opus`。
- WhatsApp 忽略 `[[audio_as_voice]]`(音频已作为语音消息发送)。
## 媒体限制 + 优化
- 默认出站上限5 MB每个媒体项
- 覆盖:`agents.defaults.mediaMaxMb`。
- 图片会自动优化为 JPEG 以控制在上限内(缩放 + 质量扫描)。
- 超大媒体 => 错误;媒体回复回退为文本警告。
## 心跳
- **Gateway 心跳** 记录连接健康状态(`web.heartbeatSeconds`,默认 60 秒)。
- **智能体心跳** 可按智能体配置(`agents.list[].heartbeat`)或通过
`agents.defaults.heartbeat` 全局配置(未设置每智能体条目时的回退)。
- 使用配置的心跳提示(默认:`Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`+ `HEARTBEAT_OK` 跳过行为。
- 投递默认到最后使用的渠道(或已配置的目标)。
## 重连行为
- 退避策略:`web.reconnect`
- `initialMs`、`maxMs`、`factor`、`jitter`、`maxAttempts`。
- 如果达到 maxAttempts网页监控停止降级
- 已注销 => 停止并要求重新关联。
## 配置速查表
- `channels.whatsapp.dmPolicy`私聊策略pairing/allowlist/open/disabled
- `channels.whatsapp.selfChatMode`(同号设置;机器人使用你的个人 WhatsApp 号码)。
- `channels.whatsapp.allowFrom`私聊允许列表。WhatsApp 使用 E.164 手机号码(无用户名)。
- `channels.whatsapp.mediaMaxMb`(入站媒体保存上限)。
- `channels.whatsapp.ackReaction`(消息收到时的自动反应:`{emoji, direct, group}`)。
- `channels.whatsapp.accounts.<accountId>.*`(按账号设置 + 可选 `authDir`)。
- `channels.whatsapp.accounts.<accountId>.mediaMaxMb`(按账号入站媒体上限)。
- `channels.whatsapp.accounts.<accountId>.ackReaction`(按账号确认反应覆盖)。
- `channels.whatsapp.groupAllowFrom`(群聊发送者允许列表)。
- `channels.whatsapp.groupPolicy`(群聊策略)。
- `channels.whatsapp.historyLimit` / `channels.whatsapp.accounts.<accountId>.historyLimit`(群聊历史上下文;`0` 禁用)。
- `channels.whatsapp.dmHistoryLimit`(私聊历史限制,按用户轮数)。按用户覆盖:`channels.whatsapp.dms["<phone>"].historyLimit`。
- `channels.whatsapp.groups`(群聊允许列表 + 提及门控默认值;使用 `"*"` 允许全部)
- `channels.whatsapp.actions.reactions`WhatsApp 工具反应门控)。
- `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`
- `messages.groupChat.historyLimit`
- `channels.whatsapp.messagePrefix`(入站前缀;按账号:`channels.whatsapp.accounts.<accountId>.messagePrefix`;已弃用:`messages.messagePrefix`
- `messages.responsePrefix`(出站前缀)
- `agents.defaults.mediaMaxMb`
- `agents.defaults.heartbeat.every`
- `agents.defaults.heartbeat.model`(可选覆盖)
- `agents.defaults.heartbeat.target`
- `agents.defaults.heartbeat.to`
- `agents.defaults.heartbeat.session`
- `agents.list[].heartbeat.*`(按智能体覆盖)
- `session.*`scope、idle、store、mainKey
- `web.enabled`(为 false 时禁用渠道启动)
- `web.heartbeatSeconds`
- `web.reconnect.*`
## 日志 + 故障排除
- 子系统:`whatsapp/inbound`、`whatsapp/outbound`、`web-heartbeat`、`web-reconnect`。
- 日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`(可配置)。
- 故障排除指南:[Gateway 故障排除](/gateway/troubleshooting)。
## 故障排除(快速)
**未关联 / 需要二维码登录**
- 症状:`channels status` 显示 `linked: false` 或警告"未关联"。
- 修复:在 Gateway 主机上运行 `openclaw channels login` 并扫描二维码WhatsApp → 设置 → 已关联设备)。
**已关联但断开连接 / 重连循环**
- 症状:`channels status` 显示 `running, disconnected` 或警告"已关联但断开连接"。
- 修复:`openclaw doctor`(或重启 Gateway。如果问题持续通过 `channels login` 重新关联并检查 `openclaw logs --follow`。
**Bun 运行时**
- **不推荐**使用 Bun。WhatsAppBaileys和 Telegram 在 Bun 上不稳定。
请使用 **Node** 运行 Gateway。参见入门指南运行时说明。

196
docs/zh-CN/channels/zalo.md Normal file
View File

@@ -0,0 +1,196 @@
---
read_when:
- 处理 Zalo 功能或 webhook 时
summary: Zalo 机器人支持状态、功能和配置
title: Zalo
x-i18n:
generated_at: "2026-02-01T19:58:32Z"
model: claude-opus-4-5
provider: pi
source_hash: 0311d932349f96412b712970b5d37329b91929bf3020536edf3ca0ff464373c0
source_path: channels/zalo.md
workflow: 14
---
# Zalo (Bot API)
状态:实验性。仅支持私信;根据 Zalo 文档,群组功能即将推出。
## 需要插件
Zalo 以插件形式提供,不包含在核心安装中。
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalo`
- 或在上手引导中选择 **Zalo** 并确认安装提示
- 详情:[插件](/plugin)
## 快速设置(新手)
1. 安装 Zalo 插件:
- 从源码检出安装:`openclaw plugins install ./extensions/zalo`
- 从 npm 安装(如已发布):`openclaw plugins install @openclaw/zalo`
- 或在上手引导中选择 **Zalo** 并确认安装提示
2. 设置令牌:
- 环境变量:`ZALO_BOT_TOKEN=...`
- 或配置:`channels.zalo.botToken: "..."`
3. 重启 Gateway或完成上手引导
4. 私信访问默认使用配对模式;首次联系时需批准配对码。
最小配置:
```json5
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}
```
## 简介
Zalo 是一款面向越南市场的即时通讯应用;其 Bot API 允许 Gateway 运行一个用于一对一对话的机器人。
它非常适合需要将消息确定性路由回 Zalo 的客服或通知场景。
- 由 Gateway 管理的 Zalo Bot API 渠道。
- 确定性路由:回复始终返回 Zalo模型不会选择渠道。
- 私信共享智能体的主会话。
- 群组尚不支持Zalo 文档标注"即将推出")。
## 设置(快速路径)
### 1) 创建机器人令牌Zalo Bot Platform
1. 前往 **https://bot.zaloplatforms.com** 并登录。
2. 创建新机器人并配置其设置。
3. 复制机器人令牌(格式:`12345689:abc-xyz`)。
### 2) 配置令牌(环境变量或配置文件)
示例:
```json5
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}
```
环境变量选项:`ZALO_BOT_TOKEN=...`(仅适用于默认账户)。
多账户支持:使用 `channels.zalo.accounts`,为每个账户配置令牌和可选的 `name`
3. 重启 Gateway。当令牌被解析通过环境变量或配置Zalo 将启动。
4. 私信访问默认使用配对模式。机器人首次被联系时,请批准配对码。
## 工作原理(行为)
- 入站消息被标准化为共享渠道信封,并包含媒体占位符。
- 回复始终路由回同一个 Zalo 聊天。
- 默认使用长轮询;可通过 `channels.zalo.webhookUrl` 启用 webhook 模式。
## 限制
- 出站文本按 2000 字符分块Zalo API 限制)。
- 媒体下载/上传受 `channels.zalo.mediaMaxMb` 限制(默认 5
- 由于 2000 字符限制导致流式传输意义不大,默认禁用流式传输。
## 访问控制(私信)
### 私信访问
- 默认:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到配对码;消息在批准前将被忽略(配对码 1 小时后过期)。
- 批准方式:
- `openclaw pairing list zalo`
- `openclaw pairing approve zalo <CODE>`
- 配对是默认的令牌交换方式。详情:[配对](/start/pairing)
- `channels.zalo.allowFrom` 接受数字用户 ID不支持用户名查找
## 长轮询与 webhook
- 默认:长轮询(无需公网 URL
- Webhook 模式:设置 `channels.zalo.webhookUrl``channels.zalo.webhookSecret`
- Webhook 密钥必须为 8-256 个字符。
- Webhook URL 必须使用 HTTPS。
- Zalo 通过 `X-Bot-Api-Secret-Token` 请求头发送事件以进行验证。
- Gateway HTTP 在 `channels.zalo.webhookPath` 处理 webhook 请求(默认为 webhook URL 路径)。
**注意:** 根据 Zalo API 文档getUpdates轮询和 webhook 互斥。
## 支持的消息类型
- **文本消息**:完全支持,按 2000 字符分块。
- **图片消息**:下载并处理入站图片;通过 `sendPhoto` 发送图片。
- **贴纸**:已记录但未完全处理(无智能体响应)。
- **不支持的类型**:已记录(例如来自受保护用户的消息)。
## 功能
| 功能 | 状态 |
| ------------ | ----------------------------- |
| 私信 | ✅ 支持 |
| 群组 | ❌ 即将推出(根据 Zalo 文档) |
| 媒体(图片) | ✅ 支持 |
| 表情回应 | ❌ 不支持 |
| 话题 | ❌ 不支持 |
| 投票 | ❌ 不支持 |
| 原生命令 | ❌ 不支持 |
| 流式传输 | ⚠️ 已禁用2000 字符限制) |
## 投递目标CLI/定时任务)
- 使用聊天 ID 作为目标。
- 示例:`openclaw message send --channel zalo --target 123456789 --message "hi"`
## 故障排除
**机器人无响应:**
- 检查令牌是否有效:`openclaw channels status --probe`
- 验证发送者是否已批准(配对或 allowFrom
- 检查 Gateway 日志:`openclaw logs --follow`
**Webhook 未收到事件:**
- 确保 webhook URL 使用 HTTPS
- 验证密钥令牌为 8-256 个字符
- 确认 Gateway HTTP 端点在配置的路径上可达
- 检查 getUpdates 轮询是否未在运行(两者互斥)
## 配置参考Zalo
完整配置:[配置](/gateway/configuration)
提供商选项:
- `channels.zalo.enabled`:启用/禁用渠道启动。
- `channels.zalo.botToken`:来自 Zalo Bot Platform 的机器人令牌。
- `channels.zalo.tokenFile`:从文件路径读取令牌。
- `channels.zalo.dmPolicy``pairing | allowlist | open | disabled`默认pairing
- `channels.zalo.allowFrom`:私信允许列表(用户 ID`open` 需要 `"*"`。向导会要求输入数字 ID。
- `channels.zalo.mediaMaxMb`:入站/出站媒体大小上限MB默认 5
- `channels.zalo.webhookUrl`:启用 webhook 模式(需要 HTTPS
- `channels.zalo.webhookSecret`webhook 密钥8-256 个字符)。
- `channels.zalo.webhookPath`Gateway HTTP 服务器上的 webhook 路径。
- `channels.zalo.proxy`API 请求的代理 URL。
多账户选项:
- `channels.zalo.accounts.<id>.botToken`:每个账户的令牌。
- `channels.zalo.accounts.<id>.tokenFile`:每个账户的令牌文件。
- `channels.zalo.accounts.<id>.name`:显示名称。
- `channels.zalo.accounts.<id>.enabled`:启用/禁用账户。
- `channels.zalo.accounts.<id>.dmPolicy`:每个账户的私信策略。
- `channels.zalo.accounts.<id>.allowFrom`:每个账户的允许列表。
- `channels.zalo.accounts.<id>.webhookUrl`:每个账户的 webhook URL。
- `channels.zalo.accounts.<id>.webhookSecret`:每个账户的 webhook 密钥。
- `channels.zalo.accounts.<id>.webhookPath`:每个账户的 webhook 路径。
- `channels.zalo.accounts.<id>.proxy`:每个账户的代理 URL。

View File

@@ -0,0 +1,147 @@
---
read_when:
- 为 OpenClaw 设置 Zalo Personal
- 调试 Zalo Personal 登录或消息流
summary: 通过 zca-cli二维码登录支持 Zalo 个人账号,功能与配置说明
title: Zalo Personal
x-i18n:
generated_at: "2026-02-01T19:58:27Z"
model: claude-opus-4-5
provider: pi
source_hash: 2a249728d556e5cc52274627bdaf390fa10e815afa04f4497feb57a2a0cb9261
source_path: channels/zalouser.md
workflow: 14
---
# Zalo Personal非官方
状态:实验性。此集成通过 `zca-cli` 自动化操作一个**个人 Zalo 账号**。
> **警告:** 这是一个非官方集成,可能导致账号被暂停或封禁。使用风险自负。
## 需要安装插件
Zalo Personal 以插件形式提供,不包含在核心安装包中。
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalouser`
- 或从源码检出安装:`openclaw plugins install ./extensions/zalouser`
- 详情:[插件](/plugin)
## 前置条件zca-cli
Gateway 所在机器必须在 `PATH` 中包含 `zca` 可执行文件。
- 验证:`zca --version`
- 如果缺失,请安装 zca-cli参见 `extensions/zalouser/README.md` 或上游 zca-cli 文档)。
## 快速设置(入门)
1. 安装插件(见上文)。
2. 登录(二维码方式,在 Gateway 机器上操作):
- `openclaw channels login --channel zalouser`
- 使用 Zalo 手机应用扫描终端中的二维码。
3. 启用渠道:
```json5
{
channels: {
zalouser: {
enabled: true,
dmPolicy: "pairing",
},
},
}
```
4. 重启 Gateway或完成上手引导
5. 私信访问默认为配对模式;首次联系时需批准配对码。
## 功能说明
- 使用 `zca listen` 接收入站消息。
- 使用 `zca msg ...` 发送回复(文本/媒体/链接)。
- 专为 Zalo Bot API 不可用时的"个人账号"使用场景设计。
## 命名说明
渠道 ID 为 `zalouser`,以明确表示这是对**个人 Zalo 用户账号**的自动化操作(非官方)。我们将 `zalo` 保留给未来可能的官方 Zalo API 集成。
## 查找 ID通讯录
使用通讯录 CLI 发现联系人/群组及其 ID
```bash
openclaw directory self --channel zalouser
openclaw directory peers list --channel zalouser --query "name"
openclaw directory groups list --channel zalouser --query "work"
```
## 限制
- 出站文本按约 2000 字符分块Zalo 客户端限制)。
- 流式传输默认被禁用。
## 访问控制(私信)
`channels.zalouser.dmPolicy` 支持:`pairing | allowlist | open | disabled`(默认:`pairing`)。
`channels.zalouser.allowFrom` 接受用户 ID 或名称。向导在可用时通过 `zca friend find` 将名称解析为 ID。
通过以下方式批准:
- `openclaw pairing list zalouser`
- `openclaw pairing approve zalouser <code>`
## 群组访问(可选)
- 默认:`channels.zalouser.groupPolicy = "open"`(允许群组)。未设置时使用 `channels.defaults.groupPolicy` 覆盖默认值。
- 通过允许列表进行限制:
- `channels.zalouser.groupPolicy = "allowlist"`
- `channels.zalouser.groups`(键为群组 ID 或名称)
- 禁止所有群组:`channels.zalouser.groupPolicy = "disabled"`
- 配置向导可以提示设置群组允许列表。
- 启动时OpenClaw 会将允许列表中的群组/用户名称解析为 ID 并记录映射关系;未解析的条目保持原样。
示例:
```json5
{
channels: {
zalouser: {
groupPolicy: "allowlist",
groups: {
"123456789": { allow: true },
"Work Chat": { allow: true },
},
},
},
}
```
## 多账号
账号映射到 zca 配置文件。示例:
```json5
{
channels: {
zalouser: {
enabled: true,
defaultAccount: "default",
accounts: {
work: { enabled: true, profile: "work" },
},
},
},
}
```
## 故障排除
**找不到 `zca`**
- 安装 zca-cli 并确保 Gateway 进程的 `PATH` 中包含该命令。
**登录状态无法保持:**
- `openclaw channels status --probe`
- 重新登录:`openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser`