chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
4dc9a8f78c
commit
e37d579dc3
@ -1,33 +1,30 @@
|
||||
---
|
||||
read_when:
|
||||
- 开发 Microsoft Teams 渠道功能
|
||||
summary: Microsoft Teams 机器人支持状态、能力和配置
|
||||
- 正在开发 Microsoft Teams 渠道功能
|
||||
summary: Microsoft Teams 机器人支持状态、功能和配置
|
||||
title: Microsoft Teams
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:38Z"
|
||||
generated_at: "2026-05-02T21:57:01Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: a4639844c8caea8120e375d042ad10e41c5dda1e532fdceb460040c90bd767fe
|
||||
source_hash: f26d6403934a654ef847aff1563500649083598cfdcb3d463890706e31480525
|
||||
source_path: channels/msteams.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status:支持文本 + 私信附件;渠道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见[在群聊中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作会公开显式的 `upload-file`,用于以文件优先的方式发送。
|
||||
Status:支持文本和私信附件;渠道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见[在群组聊天中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作为以文件优先的发送公开了显式的 `upload-file`。
|
||||
|
||||
## 内置插件
|
||||
|
||||
Microsoft Teams 在当前 OpenClaw 版本中作为内置插件提供,因此在常规打包构建中不需要
|
||||
单独安装。
|
||||
在当前 OpenClaw 版本中,Microsoft Teams 作为内置插件随附,因此在常规打包构建中不需要单独安装。
|
||||
|
||||
如果你使用的是较旧构建,或排除了内置 Teams 的自定义安装,
|
||||
请直接安装 npm 包:
|
||||
如果你使用的是较旧构建,或排除了内置 Teams 的自定义安装,请直接安装 npm 包:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/msteams
|
||||
```
|
||||
|
||||
当你跟随 OpenClaw beta 渠道,且 npmjs 显示 `beta` 领先于 `latest` 时,
|
||||
使用 `@openclaw/msteams@beta`。
|
||||
使用裸包名可跟随当前官方发布标签。仅在需要可复现安装时,才固定精确版本。
|
||||
|
||||
本地检出(从 git 仓库运行时):
|
||||
|
||||
@ -39,7 +36,7 @@ openclaw plugins install ./path/to/local/msteams-plugin
|
||||
|
||||
## 快速设置
|
||||
|
||||
[`@microsoft/teams.cli`](https://www.npmjs.com/package/@microsoft/teams.cli) 可以用一条命令处理机器人注册、清单创建和凭证生成。
|
||||
[`@microsoft/teams.cli`](https://www.npmjs.com/package/@microsoft/teams.cli) 会用一个命令处理机器人注册、清单创建和凭据生成。
|
||||
|
||||
**1. 安装并登录**
|
||||
|
||||
@ -50,12 +47,12 @@ teams status # verify you're logged in and see your tenant info
|
||||
```
|
||||
|
||||
<Note>
|
||||
Teams CLI 目前处于预览阶段。命令和标志可能会在版本之间变化。
|
||||
Teams CLI 目前处于预览阶段。命令和标志可能会在不同版本之间变化。
|
||||
</Note>
|
||||
|
||||
**2. 启动隧道**(Teams 无法访问 localhost)
|
||||
|
||||
如果你尚未安装和认证 devtunnel CLI,请先完成([入门指南](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started))。
|
||||
如果你尚未安装和认证 devtunnel CLI,请先完成这些操作([入门指南](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started))。
|
||||
|
||||
```bash
|
||||
# One-time setup (persistent URL across sessions):
|
||||
@ -68,10 +65,10 @@ devtunnel host my-openclaw-bot
|
||||
```
|
||||
|
||||
<Note>
|
||||
需要 `--allow-anonymous`,因为 Teams 无法通过 devtunnels 认证。每个传入的机器人请求仍会由 Teams SDK 自动验证。
|
||||
必须使用 `--allow-anonymous`,因为 Teams 无法通过 devtunnels 进行认证。每个传入的机器人请求仍会由 Teams SDK 自动验证。
|
||||
</Note>
|
||||
|
||||
替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(但这些可能会在每个会话中更改 URL)。
|
||||
替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(但这些方式可能每个会话都会更改 URL)。
|
||||
|
||||
**3. 创建应用**
|
||||
|
||||
@ -81,16 +78,16 @@ teams app create \
|
||||
--endpoint "https://<your-tunnel-url>/api/messages"
|
||||
```
|
||||
|
||||
这一条命令会:
|
||||
这个单一命令会:
|
||||
|
||||
- 创建一个 Entra ID(Azure AD)应用
|
||||
- 创建 Entra ID(Azure AD)应用程序
|
||||
- 生成客户端密钥
|
||||
- 构建并上传 Teams 应用清单(含图标)
|
||||
- 注册机器人(默认由 Teams 管理,无需 Azure 订阅)
|
||||
|
||||
输出会显示 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID` 和一个 **Teams App ID**,请记下这些值以用于后续步骤。它还会提供直接在 Teams 中安装应用的选项。
|
||||
输出会显示 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID` 和一个 **Teams App ID**,请记录它们以供后续步骤使用。它还会提供直接在 Teams 中安装应用的选项。
|
||||
|
||||
**4. 使用输出中的凭证配置 OpenClaw**:
|
||||
**4. 使用输出中的凭据配置 OpenClaw**:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -106,11 +103,11 @@ teams app create \
|
||||
}
|
||||
```
|
||||
|
||||
或者直接使用环境变量:`MSTEAMS_APP_ID`、`MSTEAMS_APP_PASSWORD`、`MSTEAMS_TENANT_ID`。
|
||||
也可以直接使用环境变量:`MSTEAMS_APP_ID`、`MSTEAMS_APP_PASSWORD`、`MSTEAMS_TENANT_ID`。
|
||||
|
||||
**5. 在 Teams 中安装应用**
|
||||
|
||||
`teams app create` 会提示你安装应用,请选择 “Install in Teams”。如果你跳过了这一步,之后可以获取链接:
|
||||
`teams app create` 会提示你安装应用,请选择 “Install in Teams”。如果你跳过了这一步,可以稍后获取链接:
|
||||
|
||||
```bash
|
||||
teams app get <teamsAppId> --install-link
|
||||
@ -122,25 +119,25 @@ teams app get <teamsAppId> --install-link
|
||||
teams app doctor <teamsAppId>
|
||||
```
|
||||
|
||||
这会针对机器人注册、AAD 应用配置、清单有效性和 SSO 设置运行诊断。
|
||||
这会跨机器人注册、AAD 应用配置、清单有效性和 SSO 设置运行诊断。
|
||||
|
||||
对于生产部署,请考虑使用[联合认证](/zh-CN/channels/msteams#federated-authentication-certificate-plus-managed-identity)(证书或托管身份)而不是客户端密钥。
|
||||
对于生产部署,请考虑使用[联合认证](/zh-CN/channels/msteams#federated-authentication-certificate-plus-managed-identity)(证书或托管身份)来替代客户端密钥。
|
||||
|
||||
<Note>
|
||||
群聊默认会被阻止(`channels.msteams.groupPolicy: "allowlist"`)。若要允许群组回复,请设置 `channels.msteams.groupAllowFrom`,或使用 `groupPolicy: "open"` 允许任何成员(需要提及才触发)。
|
||||
默认会阻止群组聊天(`channels.msteams.groupPolicy: "allowlist"`)。要允许群组回复,请设置 `channels.msteams.groupAllowFrom`,或使用 `groupPolicy: "open"` 允许任何成员(需要提及才会触发)。
|
||||
</Note>
|
||||
|
||||
## 目标
|
||||
|
||||
- 通过 Teams 私信、群聊或渠道与 OpenClaw 对话。
|
||||
- 保持路由确定性:回复始终返回到消息到达的渠道。
|
||||
- 默认使用安全的渠道行为(除非另有配置,否则需要提及)。
|
||||
- 通过 Teams 私信、群组聊天或渠道与 OpenClaw 对话。
|
||||
- 保持路由确定性:回复始终返回到接收消息的渠道。
|
||||
- 默认采用安全的渠道行为(除非另有配置,否则需要提及)。
|
||||
|
||||
## 配置写入
|
||||
|
||||
默认情况下,允许 Microsoft Teams 写入由 `/config set|unset` 触发的配置更新(需要 `commands.config: true`)。
|
||||
默认情况下,Microsoft Teams 允许写入由 `/config set|unset` 触发的配置更新(需要 `commands.config: true`)。
|
||||
|
||||
用以下配置禁用:
|
||||
可通过以下方式禁用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -152,17 +149,17 @@ teams app doctor <teamsAppId>
|
||||
|
||||
**私信访问**
|
||||
|
||||
- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在获批前会被忽略。
|
||||
- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者会被忽略,直到获批。
|
||||
- `channels.msteams.allowFrom` 应使用稳定的 AAD 对象 ID。
|
||||
- 不要依赖 UPN/显示名称匹配来配置允许列表,它们可能会变化。OpenClaw 默认禁用直接名称匹配;如需启用,请显式设置 `channels.msteams.dangerouslyAllowNameMatching: true`。
|
||||
- 当凭证允许时,向导可以通过 Microsoft Graph 将名称解析为 ID。
|
||||
- 不要依赖 UPN/显示名称匹配来设置允许列表,因为它们可能会变化。OpenClaw 默认禁用直接名称匹配;如需启用,请显式设置 `channels.msteams.dangerouslyAllowNameMatching: true`。
|
||||
- 当凭据允许时,向导可以通过 Microsoft Graph 将名称解析为 ID。
|
||||
|
||||
**群组访问**
|
||||
|
||||
- 默认:`channels.msteams.groupPolicy = "allowlist"`(除非你添加 `groupAllowFrom`,否则阻止)。使用 `channels.defaults.groupPolicy` 覆盖未设置时的默认值。
|
||||
- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群聊/渠道中触发(回退到 `channels.msteams.allowFrom`)。
|
||||
- 设置 `groupPolicy: "open"` 以允许任何成员(默认仍需要提及)。
|
||||
- 若要不允许**任何渠道**,请设置 `channels.msteams.groupPolicy: "disabled"`。
|
||||
- 默认:`channels.msteams.groupPolicy = "allowlist"`(除非添加 `groupAllowFrom`,否则会阻止)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。
|
||||
- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群组聊天/渠道中触发(回退到 `channels.msteams.allowFrom`)。
|
||||
- 设置 `groupPolicy: "open"` 可允许任何成员(默认仍需要提及才会触发)。
|
||||
- 要不允许**任何渠道**,请设置 `channels.msteams.groupPolicy: "disabled"`。
|
||||
|
||||
示例:
|
||||
|
||||
@ -179,12 +176,12 @@ teams app doctor <teamsAppId>
|
||||
|
||||
**Teams + 渠道允许列表**
|
||||
|
||||
- 在 `channels.msteams.teams` 下列出团队和渠道,以限定群组/渠道回复范围。
|
||||
- 通过在 `channels.msteams.teams` 下列出团队和渠道来限定群组/渠道回复范围。
|
||||
- 键应使用来自 Teams 链接的稳定 Teams 会话 ID,而不是可变的显示名称。
|
||||
- 当 `groupPolicy="allowlist"` 且存在 teams 允许列表时,仅接受列出的团队/渠道(需要提及才触发)。
|
||||
- 配置向导接受 `Team/Channel` 条目并为你存储。
|
||||
- 当 `groupPolicy="allowlist"` 且存在团队允许列表时,只接受列出的团队/渠道(需要提及才会触发)。
|
||||
- 配置向导接受 `Team/Channel` 条目,并为你保存。
|
||||
- 启动时,OpenClaw 会将团队/渠道和用户允许列表名称解析为 ID(当 Graph 权限允许时)
|
||||
并记录映射;默认情况下,未解析的团队/渠道名称会按输入保留,但会在路由中被忽略,除非启用了 `channels.msteams.dangerouslyAllowNameMatching: true`。
|
||||
并记录映射;未解析的团队/渠道名称会按输入保留,但默认会在路由中忽略,除非启用了 `channels.msteams.dangerouslyAllowNameMatching: true`。
|
||||
|
||||
示例:
|
||||
|
||||
@ -212,11 +209,11 @@ teams app doctor <teamsAppId>
|
||||
|
||||
### 工作原理
|
||||
|
||||
1. 确保 Microsoft Teams 插件可用(当前版本中已内置)。
|
||||
2. 创建一个 **Azure Bot**(App ID + 密钥 + tenant ID)。
|
||||
3. 构建一个引用该机器人并包含以下 RSC 权限的 **Teams 应用包**。
|
||||
4. 将 Teams 应用上传/安装到一个团队中(或用于私信的个人范围)。
|
||||
5. 在 `~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams` 并启动 Gateway 网关。
|
||||
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 流量。
|
||||
|
||||
### 步骤 1:创建 Azure Bot
|
||||
@ -224,30 +221,30 @@ teams app doctor <teamsAppId>
|
||||
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** |
|
||||
| **机器人句柄** | 你的机器人名称,例如 `openclaw-msteams`(必须唯一) |
|
||||
| **订阅** | 选择你的 Azure 订阅 |
|
||||
| **资源组** | 新建或使用现有资源组 |
|
||||
| **定价层** | 开发/测试使用 **Free** |
|
||||
| **应用类型** | **Single Tenant**(推荐,见下方说明) |
|
||||
| **创建类型** | **Create new Microsoft App ID** |
|
||||
|
||||
<Warning>
|
||||
创建新的多租户机器人已在 2025-07-31 之后弃用。新机器人请使用 **Single Tenant**。
|
||||
新的多租户机器人创建已在 2025-07-31 后弃用。新机器人请使用 **Single Tenant**。
|
||||
</Warning>
|
||||
|
||||
3. 点击 **Review + create** → **Create**(等待约 1-2 分钟)
|
||||
|
||||
### 步骤 2:获取凭证
|
||||
### 步骤 2:获取凭据
|
||||
|
||||
1. 前往你的 Azure Bot 资源 → **Configuration**
|
||||
2. 复制 **Microsoft App ID** → 这就是你的 `appId`
|
||||
2. 复制 **Microsoft App ID** → 这是你的 `appId`
|
||||
3. 点击 **Manage Password** → 前往 App Registration
|
||||
4. 在 **Certificates & secrets** 下 → **New client secret** → 复制 **Value** → 这就是你的 `appPassword`
|
||||
5. 前往 **Overview** → 复制 **Directory (tenant) ID** → 这就是你的 `tenantId`
|
||||
4. 在 **Certificates & secrets** 下 → **New client secret** → 复制 **Value** → 这是你的 `appPassword`
|
||||
5. 前往 **Overview** → 复制 **Directory (tenant) ID** → 这是你的 `tenantId`
|
||||
|
||||
### 步骤 3:配置消息传递端点
|
||||
### 步骤 3:配置消息端点
|
||||
|
||||
1. 在 Azure Bot → **Configuration**
|
||||
2. 将 **Messaging endpoint** 设置为你的 webhook URL:
|
||||
@ -257,7 +254,7 @@ teams app doctor <teamsAppId>
|
||||
### 步骤 4:启用 Teams 渠道
|
||||
|
||||
1. 在 Azure Bot → **Channels**
|
||||
2. 点击 **Microsoft Teams** → Configure → Save
|
||||
2. 点击 **Microsoft Teams** → 配置 → 保存
|
||||
3. 接受服务条款
|
||||
|
||||
### 步骤 5:构建 Teams 应用清单
|
||||
@ -289,7 +286,7 @@ teams app doctor <teamsAppId>
|
||||
|
||||
### 步骤 7:运行 Gateway 网关
|
||||
|
||||
当插件可用且 `msteams` 配置存在并包含凭证时,Teams 渠道会自动启动。
|
||||
当插件可用且带凭据的 `msteams` 配置存在时,Teams 渠道会自动启动。
|
||||
|
||||
</details>
|
||||
|
||||
@ -297,16 +294,16 @@ teams app doctor <teamsAppId>
|
||||
|
||||
> 添加于 2026.4.11
|
||||
|
||||
对于生产部署,OpenClaw 支持**联合认证**,作为比客户端密钥更安全的替代方案。可用的方法有两种:
|
||||
对于生产部署,OpenClaw 支持**联合认证**,作为比客户端密钥更安全的替代方案。可用两种方法:
|
||||
|
||||
### 选项 A:基于证书的认证
|
||||
|
||||
使用已在你的 Entra ID 应用注册中登记的 PEM 证书。
|
||||
使用在你的 Entra ID 应用注册中注册的 PEM 证书。
|
||||
|
||||
**设置:**
|
||||
|
||||
1. 生成或获取一个证书(带私钥的 PEM 格式)。
|
||||
2. 在 Entra ID → App Registration → **Certificates & secrets** → **Certificates** → 上传公钥证书。
|
||||
1. 生成或获取证书(带私钥的 PEM 格式)。
|
||||
2. 在 Entra ID → App Registration → **Certificates & secrets** → **Certificates** 中上传公钥证书。
|
||||
|
||||
**配置:**
|
||||
|
||||
@ -330,21 +327,21 @@ teams app doctor <teamsAppId>
|
||||
- `MSTEAMS_AUTH_TYPE=federated`
|
||||
- `MSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem`
|
||||
|
||||
### 选项 B:Azure Managed Identity
|
||||
### 选项 B:Azure 托管身份
|
||||
|
||||
使用 Azure Managed Identity 进行无密码认证。这非常适合部署在 Azure 基础设施(AKS、App Service、Azure VM)上且可用托管身份的场景。
|
||||
使用 Azure 托管身份进行无密码认证。这非常适合部署在有可用托管身份的 Azure 基础设施上(AKS、App Service、Azure VM)。
|
||||
|
||||
**工作原理:**
|
||||
|
||||
1. 机器人 pod/VM 具有托管身份(系统分配或用户分配)。
|
||||
2. **联合身份凭证**将托管身份链接到 Entra ID 应用注册。
|
||||
1. 机器人 pod/VM 拥有托管身份(系统分配或用户分配)。
|
||||
2. **联合身份凭据**将托管身份链接到 Entra ID 应用注册。
|
||||
3. 运行时,OpenClaw 使用 `@azure/identity` 从 Azure IMDS 端点(`169.254.169.254`)获取令牌。
|
||||
4. 令牌会传递给 Teams SDK,用于机器人认证。
|
||||
|
||||
**前提条件:**
|
||||
|
||||
- 已启用托管身份的 Azure 基础设施(AKS workload identity、App Service、VM)
|
||||
- 已在 Entra ID 应用注册上创建联合身份凭证
|
||||
- 启用了托管身份的 Azure 基础设施(AKS 工作负载身份、App Service、VM)
|
||||
- 在 Entra ID 应用注册上创建了联合身份凭据
|
||||
- pod/VM 能够访问 IMDS(`169.254.169.254:80`)
|
||||
|
||||
**配置(系统分配的托管身份):**
|
||||
@ -404,7 +401,7 @@ teams app doctor <teamsAppId>
|
||||
}'
|
||||
```
|
||||
|
||||
3. 使用应用客户端 ID **注释 Kubernetes 服务账户**:
|
||||
3. 使用应用客户端 ID **注解 Kubernetes 服务账号**:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@ -415,7 +412,7 @@ teams app doctor <teamsAppId>
|
||||
azure.workload.identity/client-id: "<APP_CLIENT_ID>"
|
||||
```
|
||||
|
||||
4. 为工作负载身份注入**标记 Pod**:
|
||||
4. 为工作负载身份注入给 **pod 添加标签**:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
@ -423,21 +420,21 @@ teams app doctor <teamsAppId>
|
||||
azure.workload.identity/use: "true"
|
||||
```
|
||||
|
||||
5. **确保网络可以访问** IMDS(`169.254.169.254`)——如果使用 NetworkPolicy,请添加出站规则,允许流量通过端口 80 访问 `169.254.169.254/32`。
|
||||
5. **确保网络访问** IMDS(`169.254.169.254`)——如果使用 NetworkPolicy,请添加一条出站规则,允许流量通过端口 80 访问 `169.254.169.254/32`。
|
||||
|
||||
### 身份验证类型对比
|
||||
|
||||
| 方法 | 配置 | 优点 | 缺点 |
|
||||
| ---------------- | ---------------------------------------------- | -------------------- | -------------------------- |
|
||||
| **客户端密钥** | `appPassword` | 设置简单 | 需要轮换密钥,安全性较低 |
|
||||
| **证书** | `authType: "federated"` + `certificatePath` | 不通过网络共享密钥 | 证书管理开销 |
|
||||
| **托管身份** | `authType: "federated"` + `useManagedIdentity` | 无密码,无需管理密钥 | 需要 Azure 基础设施 |
|
||||
| 方法 | 配置 | 优点 | 缺点 |
|
||||
| -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- |
|
||||
| **客户端密钥** | `appPassword` | 设置简单 | 需要轮换密钥,安全性较低 |
|
||||
| **证书** | `authType: "federated"` + `certificatePath` | 网络中没有共享密钥 | 证书管理开销 |
|
||||
| **托管身份** | `authType: "federated"` + `useManagedIdentity` | 无密码,无需管理密钥 | 需要 Azure 基础设施 |
|
||||
|
||||
**默认行为:**当未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需更改即可继续工作。
|
||||
**默认行为:** 未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需更改即可继续工作。
|
||||
|
||||
## 本地开发(隧道)
|
||||
|
||||
Teams 无法访问 `localhost`。使用持久开发隧道,让你的 URL 在不同会话中保持不变:
|
||||
Teams 无法访问 `localhost`。请使用持久开发隧道,让你的 URL 在不同会话中保持不变:
|
||||
|
||||
```bash
|
||||
# One-time setup:
|
||||
@ -448,7 +445,7 @@ devtunnel port create my-openclaw-bot -p 3978 --protocol auto
|
||||
devtunnel host my-openclaw-bot
|
||||
```
|
||||
|
||||
替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(URL 可能在每个会话中变化)。
|
||||
替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(URL 可能会在每个会话中变化)。
|
||||
|
||||
如果你的隧道 URL 发生变化,请更新端点:
|
||||
|
||||
@ -456,7 +453,7 @@ devtunnel host my-openclaw-bot
|
||||
teams app update <teamsAppId> --endpoint "https://<new-url>/api/messages"
|
||||
```
|
||||
|
||||
## 测试机器人
|
||||
## 测试 Bot
|
||||
|
||||
**运行诊断:**
|
||||
|
||||
@ -464,12 +461,12 @@ teams app update <teamsAppId> --endpoint "https://<new-url>/api/messages"
|
||||
teams app doctor <teamsAppId>
|
||||
```
|
||||
|
||||
一次性检查机器人注册、AAD 应用、清单和 SSO 配置。
|
||||
一次性检查 bot 注册、AAD 应用、清单和 SSO 配置。
|
||||
|
||||
**发送测试消息:**
|
||||
|
||||
1. 安装 Teams 应用(使用来自 `teams app get <id> --install-link` 的安装链接)
|
||||
2. 在 Teams 中找到机器人并发送私信
|
||||
2. 在 Teams 中找到 bot 并发送私信
|
||||
3. 检查 Gateway 网关日志中的传入活动
|
||||
|
||||
## 环境变量
|
||||
@ -483,45 +480,45 @@ teams app doctor <teamsAppId>
|
||||
- `MSTEAMS_CERTIFICATE_PATH`(联合 + 证书)
|
||||
- `MSTEAMS_CERTIFICATE_THUMBPRINT`(可选,身份验证不需要)
|
||||
- `MSTEAMS_USE_MANAGED_IDENTITY`(联合 + 托管身份)
|
||||
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(仅限用户分配的 MI)
|
||||
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(仅用户分配的 MI)
|
||||
|
||||
## 成员信息操作
|
||||
|
||||
OpenClaw 为 Microsoft Teams 暴露基于 Graph 的 `member-info` 操作,使智能体和自动化可以直接从 Microsoft Graph 解析渠道成员详细信息(显示名称、电子邮件、角色)。
|
||||
OpenClaw 为 Microsoft Teams 暴露由 Graph 支持的 `member-info` 操作,使智能体和自动化可以直接从 Microsoft Graph 解析渠道成员详情(显示名称、电子邮件、角色)。
|
||||
|
||||
要求:
|
||||
|
||||
- `Member.Read.Group` RSC 权限(已包含在推荐清单中)
|
||||
- 对于跨团队查询:带管理员同意的 `User.Read.All` Graph 应用权限
|
||||
- `Member.Read.Group` RSC 权限(已在推荐清单中)
|
||||
- 对于跨团队查询:需要已获管理员同意的 `User.Read.All` Graph 应用程序权限
|
||||
|
||||
该操作由 `channels.msteams.actions.memberInfo` 控制(默认:当 Graph 凭据可用时启用)。
|
||||
此操作由 `channels.msteams.actions.memberInfo` 控制(默认:当 Graph 凭据可用时启用)。
|
||||
|
||||
## 历史上下文
|
||||
|
||||
- `channels.msteams.historyLimit` 控制将多少最近的渠道/群组消息包装进提示词。
|
||||
- `channels.msteams.historyLimit` 控制将多少条最近的渠道/群组消息包装进提示词。
|
||||
- 回退到 `messages.groupChat.historyLimit`。设置为 `0` 可禁用(默认 50)。
|
||||
- 获取到的线程历史会按发送者允许列表(`allowFrom` / `groupAllowFrom`)过滤,因此线程上下文种子仅包含来自允许发送者的消息。
|
||||
- 引用附件上下文(从 Teams 回复 HTML 派生的 `ReplyTo*`)目前会按接收原样传递。
|
||||
- 换句话说,允许列表控制谁可以触发智能体;目前只有特定的补充上下文路径会被过滤。
|
||||
- 私信历史可以通过 `channels.msteams.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.msteams.dms["<user_id>"].historyLimit`。
|
||||
- 拉取的线程历史会按发送者允许列表(`allowFrom` / `groupAllowFrom`)过滤,因此线程上下文种子只包含允许的发送者的消息。
|
||||
- 引用附件上下文(从 Teams 回复 HTML 派生的 `ReplyTo*`)当前会按收到的形式传递。
|
||||
- 换句话说,允许列表会限制谁可以触发智能体;目前只有特定的补充上下文路径会被过滤。
|
||||
- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.msteams.dms["<user_id>"].historyLimit`。
|
||||
|
||||
## 当前 Teams RSC 权限(清单)
|
||||
|
||||
这些是我们 Teams 应用清单中**现有的 resourceSpecific 权限**。它们只适用于安装了该应用的团队/聊天内部。
|
||||
这些是我们 Teams 应用清单中的**现有 resourceSpecific 权限**。它们只适用于安装该应用的团队/聊天内。
|
||||
|
||||
**对于渠道(团队范围):**
|
||||
|
||||
- `ChannelMessage.Read.Group`(应用)- 无需 @mention 即可接收所有渠道消息
|
||||
- `ChannelMessage.Send.Group`(应用)
|
||||
- `Member.Read.Group`(应用)
|
||||
- `Owner.Read.Group`(应用)
|
||||
- `ChannelSettings.Read.Group`(应用)
|
||||
- `TeamMember.Read.Group`(应用)
|
||||
- `TeamSettings.Read.Group`(应用)
|
||||
- `ChannelMessage.Read.Group`(Application)- 无需 @mention 即可接收所有渠道消息
|
||||
- `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`(应用)- 无需 @mention 即可接收所有群聊消息
|
||||
- `ChatMessage.Read.Chat`(Application)- 无需 @mention 即可接收所有群聊消息
|
||||
|
||||
通过 Teams CLI 添加 RSC 权限:
|
||||
|
||||
@ -529,9 +526,9 @@ OpenClaw 为 Microsoft Teams 暴露基于 Graph 的 `member-info` 操作,使
|
||||
teams app rsc add <teamsAppId> ChannelMessage.Read.Group --type Application
|
||||
```
|
||||
|
||||
## 示例 Teams 清单(已脱敏)
|
||||
## Teams 清单示例(已脱敏)
|
||||
|
||||
包含必需字段的最小有效示例。替换 ID 和 URL。
|
||||
包含必填字段的最小有效示例。替换 ID 和 URL。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -579,17 +576,17 @@ teams app rsc add <teamsAppId> ChannelMessage.Read.Group --type Application
|
||||
}
|
||||
```
|
||||
|
||||
### 清单注意事项(必需字段)
|
||||
### 清单注意事项(必备字段)
|
||||
|
||||
- `bots[].botId` **必须**匹配 Azure Bot 应用 ID。
|
||||
- `webApplicationInfo.id` **必须**匹配 Azure Bot 应用 ID。
|
||||
- `bots[].scopes` 必须包含你计划使用的表面(`personal`、`team`、`groupChat`)。
|
||||
- `bots[].supportsFiles: true` 是在个人范围内处理文件的必需项。
|
||||
- 如果你需要渠道流量,`authorization.permissions.resourceSpecific` 必须包含渠道读取/发送权限。
|
||||
- `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 权限):
|
||||
要更新已安装的 Teams 应用(例如添加 RSC 权限):
|
||||
|
||||
```bash
|
||||
# Download, edit, and re-upload the manifest
|
||||
@ -599,21 +596,21 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
# Version is auto-bumped if content changed
|
||||
```
|
||||
|
||||
更新后,请在每个团队中重新安装该应用,使新权限生效,并**完全退出并重新启动 Teams**(而不是仅关闭窗口),以清除缓存的应用元数据。
|
||||
更新后,请在每个团队中重新安装该应用,使新权限生效,并**完全退出并重新启动 Teams**(不只是关闭窗口),以清除缓存的应用元数据。
|
||||
|
||||
<details>
|
||||
<summary>手动更新清单(不使用 CLI)</summary>
|
||||
|
||||
1. 使用新设置更新你的 `manifest.json`
|
||||
2. **递增 `version` 字段**(例如,`1.0.0` → `1.1.0`)
|
||||
3. 将清单与图标(`manifest.json`、`outline.png`、`color.png`)**重新打包为 zip**
|
||||
3. 使用图标**重新打包 zip** 清单(`manifest.json`、`outline.png`、`color.png`)
|
||||
4. 上传新的 zip:
|
||||
- **Teams 管理中心:** Teams 应用 → 管理应用 → 找到你的应用 → 上传新版本
|
||||
- **旁加载:** 在 Teams 中 → 应用 → 管理你的应用 → 上传自定义应用
|
||||
|
||||
</details>
|
||||
|
||||
## 功能:仅 RSC 与 Graph
|
||||
## 能力:仅 RSC 与 Graph
|
||||
|
||||
### 仅使用 **Teams RSC**(已安装应用,无 Graph API 权限)
|
||||
|
||||
@ -625,13 +622,13 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
|
||||
不可用:
|
||||
|
||||
- 渠道/群组**图片或文件内容**(负载仅包含 HTML 占位)。
|
||||
- 渠道/群组**图片或文件内容**(载荷只包含 HTML 占位)。
|
||||
- 下载存储在 SharePoint/OneDrive 中的附件。
|
||||
- 读取消息历史(实时 webhook 事件之外)。
|
||||
- 读取消息历史(超出实时 webhook 事件)。
|
||||
|
||||
### 使用 **Teams RSC + Microsoft Graph 应用权限**
|
||||
### 使用 **Teams RSC + Microsoft Graph 应用程序权限**
|
||||
|
||||
新增:
|
||||
增加:
|
||||
|
||||
- 下载托管内容(粘贴到消息中的图片)。
|
||||
- 下载存储在 SharePoint/OneDrive 中的文件附件。
|
||||
@ -639,47 +636,47 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
|
||||
### RSC 与 Graph API
|
||||
|
||||
| 能力 | RSC 权限 | Graph API |
|
||||
| ---------------- | ------------------ | ---------------------------- |
|
||||
| **实时消息** | 是(通过 webhook) | 否(仅轮询) |
|
||||
| **历史消息** | 否 | 是(可以查询历史) |
|
||||
| **设置复杂度** | 仅应用清单 | 需要管理员同意 + 令牌流程 |
|
||||
| **离线可用** | 否(必须在运行) | 是(随时查询) |
|
||||
| 能力 | RSC 权限 | Graph API |
|
||||
| ----------------------- | -------------------- | ----------------------------------- |
|
||||
| **实时消息** | 是(通过 webhook) | 否(仅轮询) |
|
||||
| **历史消息** | 否 | 是(可查询历史) |
|
||||
| **设置复杂度** | 仅应用清单 | 需要管理员同意 + 令牌流程 |
|
||||
| **离线可用** | 否(必须运行中) | 是(随时查询) |
|
||||
|
||||
**结论:**RSC 用于实时监听;Graph API 用于历史访问。要在离线后补收错过的消息,你需要带 `ChannelMessage.Read.All` 的 Graph API(需要管理员同意)。
|
||||
**结论:** RSC 用于实时监听;Graph API 用于历史访问。要在离线期间补取错过的消息,你需要带有 `ChannelMessage.Read.All` 的 Graph API(需要管理员同意)。
|
||||
|
||||
## 启用 Graph 的媒体 + 历史(渠道必需)
|
||||
## 支持 Graph 的媒体 + 历史(渠道必需)
|
||||
|
||||
如果你需要**渠道**中的图片/文件,或想获取**消息历史**,必须启用 Microsoft Graph 权限并授予管理员同意。
|
||||
如果你需要**渠道**中的图片/文件,或想拉取**消息历史**,必须启用 Microsoft Graph 权限并授予管理员同意。
|
||||
|
||||
1. 在 Entra ID(Azure AD)**应用注册**中,添加 Microsoft Graph **应用权限**:
|
||||
1. 在 Entra ID(Azure AD)**应用注册**中,添加 Microsoft Graph **应用程序权限**:
|
||||
- `ChannelMessage.Read.All`(渠道附件 + 历史)
|
||||
- `Chat.Read.All` 或 `ChatMessage.Read.All`(群聊)
|
||||
2. 为租户**授予管理员同意**。
|
||||
3. 递增 Teams 应用**清单版本**,重新上传,并**在 Teams 中重新安装应用**。
|
||||
3. 提升 Teams 应用的**清单版本**,重新上传,并**在 Teams 中重新安装应用**。
|
||||
4. **完全退出并重新启动 Teams**,以清除缓存的应用元数据。
|
||||
|
||||
**用户提及的额外权限:**对于对话中的用户,用户 @mentions 开箱即用。不过,如果你想动态搜索并提及**不在当前对话中**的用户,请添加 `User.Read.All`(应用)权限并授予管理员同意。
|
||||
**用户提及的附加权限:** 对话中的用户可开箱即用地使用用户 @mentions。但是,如果你想动态搜索并提及**不在当前对话中**的用户,请添加 `User.Read.All`(Application)权限并授予管理员同意。
|
||||
|
||||
## 已知限制
|
||||
|
||||
### Webhook 超时
|
||||
|
||||
Teams 通过 HTTP webhook 传递消息。如果处理耗时过长(例如,LLM 响应缓慢),你可能会看到:
|
||||
Teams 通过 HTTP webhook 传递消息。如果处理时间过长(例如,LLM 响应较慢),你可能会看到:
|
||||
|
||||
- Gateway 网关超时
|
||||
- Teams 重试消息(导致重复)
|
||||
- 回复被丢弃
|
||||
- 回复丢失
|
||||
|
||||
OpenClaw 通过快速返回并主动发送回复来处理这种情况,但非常慢的响应仍可能导致问题。
|
||||
|
||||
### 格式
|
||||
|
||||
Teams markdown 比 Slack 或 Discord 更受限制:
|
||||
Teams Markdown 比 Slack 或 Discord 更受限:
|
||||
|
||||
- 基本格式可用:**粗体**、_斜体_、`code`、链接
|
||||
- 复杂 Markdown(表格、嵌套列表)可能无法正确渲染
|
||||
- Adaptive Cards 支持投票和语义展示发送(见下文)
|
||||
- Adaptive Cards 支持投票和语义化演示发送(见下文)
|
||||
|
||||
## 配置
|
||||
|
||||
@ -690,53 +687,53 @@ Teams markdown 比 Slack 或 Discord 更受限制:
|
||||
- `channels.msteams.webhook.port`(默认 `3978`)
|
||||
- `channels.msteams.webhook.path`(默认 `/api/messages`)
|
||||
- `channels.msteams.dmPolicy`:`pairing | allowlist | open | disabled`(默认:pairing)
|
||||
- `channels.msteams.allowFrom`:私信 allowlist(建议使用 AAD 对象 ID)。当 Graph 访问可用时,向导会在设置期间将名称解析为 ID。
|
||||
- `channels.msteams.dangerouslyAllowNameMatching`:应急开关,用于重新启用可变 UPN/显示名称匹配以及直接的团队/渠道名称路由。
|
||||
- `channels.msteams.allowFrom`:私信允许列表(建议使用 AAD 对象 ID)。当 Graph 访问可用时,向导会在设置期间将名称解析为 ID。
|
||||
- `channels.msteams.dangerouslyAllowNameMatching`:应急开关,用于重新启用可变的 UPN/显示名称匹配以及直接的团队/渠道名称路由。
|
||||
- `channels.msteams.textChunkLimit`:出站文本分块大小。
|
||||
- `channels.msteams.chunkMode`:`length`(默认)或 `newline`,用于在按长度分块前先按空行(段落边界)拆分。
|
||||
- `channels.msteams.mediaAllowHosts`:入站附件主机 allowlist(默认为 Microsoft/Teams 域名)。
|
||||
- `channels.msteams.mediaAuthAllowHosts`:媒体重试时可附加 Authorization 标头的主机 allowlist(默认为 Graph + Bot Framework 主机)。
|
||||
- `channels.msteams.requireMention`:在渠道/群组中要求 @mention(默认 true)。
|
||||
- `channels.msteams.mediaAllowHosts`:入站附件主机允许列表(默认为 Microsoft/Teams 域名)。
|
||||
- `channels.msteams.mediaAuthAllowHosts`:媒体重试时允许附加 Authorization 标头的主机允许列表(默认为 Graph + Bot Framework 主机)。
|
||||
- `channels.msteams.requireMention`:在渠道/群组中要求 @提及(默认 true)。
|
||||
- `channels.msteams.replyStyle`:`thread | top-level`(见[回复样式](#reply-style-threads-vs-posts))。
|
||||
- `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>.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.teams.<teamId>.channels.<conversationId>.toolsBySender`:按渠道、按发送者工具策略覆盖(支持 `"*"` 通配符)。
|
||||
- `toolsBySender` 键应使用显式前缀:
|
||||
`id:`、`e164:`、`username:`、`name:`(旧版无前缀键仍只映射到 `id:`)。
|
||||
- `channels.msteams.actions.memberInfo`:启用或禁用由 Graph 支持的成员信息操作(默认:Graph 凭证可用时启用)。
|
||||
- `channels.msteams.authType`:认证类型 — `"secret"`(默认)或 `"federated"`。
|
||||
- `channels.msteams.certificatePath`:PEM 证书文件路径(联合 + 证书认证)。
|
||||
- `channels.msteams.certificateThumbprint`:证书指纹(可选,认证不需要)。
|
||||
- `channels.msteams.useManagedIdentity`:启用托管身份认证(联合模式)。
|
||||
- `channels.msteams.actions.memberInfo`:启用或禁用由 Graph 支持的成员信息操作(默认:当 Graph 凭证可用时启用)。
|
||||
- `channels.msteams.authType`:身份验证类型 — `"secret"`(默认)或 `"federated"`。
|
||||
- `channels.msteams.certificatePath`:PEM 证书文件路径(联合 + 证书身份验证)。
|
||||
- `channels.msteams.certificateThumbprint`:证书指纹(可选,身份验证不需要)。
|
||||
- `channels.msteams.useManagedIdentity`:启用托管身份身份验证(联合模式)。
|
||||
- `channels.msteams.managedIdentityClientId`:用户分配托管身份的客户端 ID。
|
||||
- `channels.msteams.sharePointSiteId`:用于群聊/渠道中文件上传的 SharePoint 站点 ID(见[在群聊中发送文件](#sending-files-in-group-chats))。
|
||||
- `channels.msteams.sharePointSiteId`:群聊/渠道中文件上传使用的 SharePoint 站点 ID(见[在群聊中发送文件](#sending-files-in-group-chats))。
|
||||
|
||||
## 路由和会话
|
||||
## 路由与会话
|
||||
|
||||
- 会话键遵循标准智能体格式(见 [/concepts/session](/zh-CN/concepts/session)):
|
||||
- 私信共享主会话(`agent:<agentId>:<mainKey>`)。
|
||||
- 渠道/群组消息使用对话 ID:
|
||||
- 渠道/群组消息使用会话 ID:
|
||||
- `agent:<agentId>:msteams:channel:<conversationId>`
|
||||
- `agent:<agentId>:msteams:group:<conversationId>`
|
||||
|
||||
## 回复样式:线程与帖子
|
||||
|
||||
Teams 最近在同一个底层数据模型上引入了两种渠道 UI 样式:
|
||||
Teams 最近在同一底层数据模型上引入了两种渠道 UI 样式:
|
||||
|
||||
| 样式 | 描述 | 推荐的 `replyStyle` |
|
||||
| ------------------------ | --------------------------------------------------------- | ------------------------ |
|
||||
| **帖子**(经典) | 消息显示为卡片,下方带有线程回复 | `thread`(默认) |
|
||||
| **线程**(类似 Slack) | 消息线性流动,更像 Slack | `top-level` |
|
||||
| 样式 | 描述 | 推荐的 `replyStyle` |
|
||||
| ------------------------ | ----------------------------------------- | ------------------- |
|
||||
| **帖子**(经典) | 消息显示为卡片,下方带有线程回复 | `thread`(默认) |
|
||||
| **线程**(类似 Slack) | 消息线性流动,更像 Slack | `top-level` |
|
||||
|
||||
**问题:** Teams API 不会暴露渠道使用哪种 UI 样式。如果使用了错误的 `replyStyle`:
|
||||
**问题:** Teams API 不会暴露某个渠道使用哪种 UI 样式。如果使用了错误的 `replyStyle`:
|
||||
|
||||
- Threads 样式渠道中的 `thread` → 回复会以别扭的嵌套形式显示
|
||||
- Posts 样式渠道中的 `top-level` → 回复会显示为单独的顶级帖子,而不是线程内回复
|
||||
- 在线程样式渠道中使用 `thread` → 回复会显得嵌套别扭
|
||||
- 在帖子样式渠道中使用 `top-level` → 回复会显示为单独的顶层帖子,而不是在线程内
|
||||
|
||||
**解决方案:** 根据渠道的设置方式按渠道配置 `replyStyle`:
|
||||
|
||||
@ -759,27 +756,27 @@ Teams 最近在同一个底层数据模型上引入了两种渠道 UI 样式:
|
||||
}
|
||||
```
|
||||
|
||||
## 附件和图片
|
||||
## 附件与图片
|
||||
|
||||
**当前限制:**
|
||||
|
||||
- **私信:** 图片和文件附件通过 Teams 机器人文件 API 工作。
|
||||
- **渠道/群组:** 附件存放在 M365 存储(SharePoint/OneDrive)中。Webhook 载荷只包含 HTML 占位片段,不包含实际文件字节。**需要 Graph API 权限**才能下载渠道附件。
|
||||
- 对于显式以文件优先的发送,使用 `action=upload-file`,并带上 `media` / `filePath` / `path`;可选的 `message` 会成为随附文本/评论,`filename` 会覆盖上传名称。
|
||||
- **私信:** 图片和文件附件可通过 Teams 机器人文件 API 使用。
|
||||
- **渠道/群组:** 附件存放在 M365 存储(SharePoint/OneDrive)中。Webhook 载荷只包含 HTML 存根,而不是实际文件字节。**需要 Graph API 权限**才能下载渠道附件。
|
||||
- 对于明确以文件为先的发送,使用带有 `media` / `filePath` / `path` 的 `action=upload-file`;可选的 `message` 会成为随附文本/评论,`filename` 会覆盖上传名称。
|
||||
|
||||
没有 Graph 权限时,带图片的渠道消息会以纯文本形式接收(机器人无法访问图片内容)。
|
||||
默认情况下,OpenClaw 只从 Microsoft/Teams 主机名下载媒体。可用 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任意主机)。
|
||||
Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认为 Graph + Bot Framework 主机)。保持此列表严格(避免多租户后缀)。
|
||||
如果没有 Graph 权限,包含图片的渠道消息会以纯文本形式接收(机器人无法访问图片内容)。
|
||||
默认情况下,OpenClaw 只会从 Microsoft/Teams 主机名下载媒体。可使用 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任何主机)。
|
||||
Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认为 Graph + Bot Framework 主机)。请保持此列表严格(避免多租户后缀)。
|
||||
|
||||
## 在群聊中发送文件
|
||||
|
||||
机器人可以使用 FileConsentCard 流程在私信中发送文件(内置)。但是,**在群聊/渠道中发送文件**需要额外设置:
|
||||
|
||||
| 上下文 | 文件发送方式 | 所需设置 |
|
||||
| ------------------------ | -------------------------------------------- | ----------------------------------------------- |
|
||||
| **私信** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 |
|
||||
| **群聊/渠道** | 上传到 SharePoint → 共享链接 | 需要 `sharePointSiteId` + Graph 权限 |
|
||||
| **图片(任意上下文)** | Base64 编码内联 | 开箱即用 |
|
||||
| 上下文 | 文件发送方式 | 需要的设置 |
|
||||
| ------------------------ | --------------------------------------------- | ----------------------------------------------- |
|
||||
| **私信** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 |
|
||||
| **群聊/渠道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 |
|
||||
| **图片(任何上下文)** | Base64 编码内联 | 开箱即用 |
|
||||
|
||||
### 为什么群聊需要 SharePoint
|
||||
|
||||
@ -787,7 +784,7 @@ Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中
|
||||
|
||||
### 设置
|
||||
|
||||
1. 在 Entra ID(Azure AD)→ App Registration 中**添加 Graph API 权限**:
|
||||
1. 在 Entra ID (Azure AD) → App Registration 中**添加 Graph API 权限**:
|
||||
- `Sites.ReadWrite.All`(Application)- 将文件上传到 SharePoint
|
||||
- `Chat.Read.All`(Application)- 可选,启用按用户共享链接
|
||||
|
||||
@ -822,21 +819,21 @@ Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中
|
||||
|
||||
### 共享行为
|
||||
|
||||
| 权限 | 共享行为 |
|
||||
| --------------------------------------- | --------------------------------------------------------- |
|
||||
| 仅 `Sites.ReadWrite.All` | 组织范围共享链接(组织中的任何人都可访问) |
|
||||
| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(只有聊天成员可访问) |
|
||||
| 权限 | 共享行为 |
|
||||
| --------------------------------------- | ------------------------------------------------- |
|
||||
| 仅 `Sites.ReadWrite.All` | 组织范围共享链接(组织中的任何人都可访问) |
|
||||
| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(只有聊天成员可访问) |
|
||||
|
||||
按用户共享更安全,因为只有聊天参与者可以访问该文件。如果缺少 `Chat.Read.All` 权限,机器人会回退到组织范围共享。
|
||||
|
||||
### 回退行为
|
||||
|
||||
| 场景 | 结果 |
|
||||
| ------------------------------------------------- | -------------------------------------------------- |
|
||||
| 群聊 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint,发送共享链接 |
|
||||
| 群聊 + 文件 + 无 `sharePointSiteId` | 尝试 OneDrive 上传(可能失败),仅发送文本 |
|
||||
| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint 即可工作) |
|
||||
| 任意上下文 + 图片 | Base64 编码内联(无需 SharePoint 即可工作) |
|
||||
| 场景 | 结果 |
|
||||
| ------------------------------------------------- | --------------------------------------------------- |
|
||||
| 已配置 `sharePointSiteId` 的群聊 + 文件 | 上传到 SharePoint,发送共享链接 |
|
||||
| 未配置 `sharePointSiteId` 的群聊 + 文件 | 尝试上传到 OneDrive(可能失败),仅发送文本 |
|
||||
| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint 即可使用) |
|
||||
| 任意上下文 + 图片 | Base64 编码内联(无需 SharePoint 即可使用) |
|
||||
|
||||
### 文件存储位置
|
||||
|
||||
@ -844,18 +841,18 @@ Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中
|
||||
|
||||
## 投票(Adaptive Cards)
|
||||
|
||||
OpenClaw 将 Teams 投票作为 Adaptive Cards 发送(没有原生 Teams 投票 API)。
|
||||
OpenClaw 会将 Teams 投票作为 Adaptive Cards 发送(没有原生 Teams 投票 API)。
|
||||
|
||||
- CLI:`openclaw message poll --channel msteams --target conversation:<id> ...`
|
||||
- 投票由 Gateway 网关记录在 `~/.openclaw/msteams-polls.json` 中。
|
||||
- Gateway 网关必须保持在线才能记录投票。
|
||||
- 投票还不会自动发布结果摘要(如有需要,请检查存储文件)。
|
||||
|
||||
## 展示卡片
|
||||
## 演示卡片
|
||||
|
||||
使用 `message` 工具或 CLI 向 Teams 用户或对话发送语义展示载荷。OpenClaw 会根据通用展示契约将它们渲染为 Teams Adaptive Cards。
|
||||
使用 `message` 工具或 CLI 向 Teams 用户或会话发送语义化演示载荷。OpenClaw 会根据通用演示契约将其渲染为 Teams Adaptive Cards。
|
||||
|
||||
`presentation` 参数接受语义块。提供 `presentation` 时,消息文本是可选的。
|
||||
`presentation` 参数接受语义块。当提供 `presentation` 时,消息文本是可选的。
|
||||
|
||||
**智能体工具:**
|
||||
|
||||
@ -883,14 +880,14 @@ openclaw message send --channel msteams \
|
||||
|
||||
## 目标格式
|
||||
|
||||
MSTeams 目标使用前缀来区分用户和对话:
|
||||
MSTeams 目标使用前缀来区分用户和会话:
|
||||
|
||||
| 目标类型 | 格式 | 示例 |
|
||||
| 目标类型 | 格式 | 示例 |
|
||||
| ------------------- | -------------------------------- | --------------------------------------------------- |
|
||||
| 用户(按 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`) |
|
||||
| 用户(按 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 示例:**
|
||||
|
||||
@ -933,17 +930,17 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread.
|
||||
```
|
||||
|
||||
<Note>
|
||||
没有 `user:` 前缀时,名称默认按群组或团队解析。按显示名称定位用户时,始终使用 `user:`。
|
||||
如果没有 `user:` 前缀,名称默认会按群组或团队解析。按显示名称指定人员时,始终使用 `user:`。
|
||||
</Note>
|
||||
|
||||
## 主动消息
|
||||
## 主动消息传递
|
||||
|
||||
- 只有在用户发生过交互**之后**,才能发送主动消息,因为我们会在那时存储会话引用。
|
||||
- 请参阅 `/gateway/configuration`,了解 `dmPolicy` 和 allowlist 门控。
|
||||
- 只有在用户交互**之后**,才可以发送主动消息,因为我们会在那时存储会话引用。
|
||||
- 有关 `dmPolicy` 和允许列表门控,请参阅 `/gateway/configuration`。
|
||||
|
||||
## 团队和渠道 ID(常见陷阱)
|
||||
|
||||
Teams URL 中的 `groupId` 查询参数**不是**配置所用的团队 ID。请改为从 URL 路径中提取 ID:
|
||||
Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请改为从 URL 路径中提取 ID:
|
||||
|
||||
**团队 URL:**
|
||||
|
||||
@ -963,50 +960,50 @@ https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?gr
|
||||
|
||||
**用于配置:**
|
||||
|
||||
- 团队键 = `/team/` 后面的路径段(URL 解码后,例如 `19:Bk4j...@thread.tacv2`;较旧的租户可能显示 `@thread.skype`,这同样有效)
|
||||
- 渠道键 = `/channel/` 后面的路径段(URL 解码后)
|
||||
- OpenClaw 路由应**忽略** `groupId` 查询参数。它是 Microsoft Entra 群组 ID,而不是传入 Teams 活动中使用的 Bot Framework 会话 ID。
|
||||
- 团队键 = `/team/` 之后的路径段(URL 解码后,例如 `19:Bk4j...@thread.tacv2`;较旧的租户可能显示 `@thread.skype`,这也是有效的)
|
||||
- 渠道键 = `/channel/` 之后的路径段(URL 解码后)
|
||||
- **忽略**用于 OpenClaw 路由的 `groupId` 查询参数。它是 Microsoft Entra 组 ID,而不是传入 Teams 活动中使用的 Bot Framework 会话 ID。
|
||||
|
||||
## 私有渠道
|
||||
|
||||
机器人在私有渠道中的支持有限:
|
||||
|
||||
| 功能 | 标准渠道 | 私有渠道 |
|
||||
| ---------------------------- | -------- | -------------------- |
|
||||
| 机器人安装 | 是 | 有限支持 |
|
||||
| 实时消息(webhook) | 是 | 可能无法工作 |
|
||||
| RSC 权限 | 是 | 行为可能有所不同 |
|
||||
| @提及 | 是 | 如果机器人可访问 |
|
||||
| Graph API 历史记录 | 是 | 是(需要权限) |
|
||||
| 功能 | 标准渠道 | 私有渠道 |
|
||||
| ---------------------------- | -------- | ------------------------ |
|
||||
| 机器人安装 | 是 | 有限 |
|
||||
| 实时消息(webhook) | 是 | 可能无法工作 |
|
||||
| RSC 权限 | 是 | 行为可能不同 |
|
||||
| @提及 | 是 | 如果机器人可访问 |
|
||||
| Graph API 历史记录 | 是 | 是(需要权限) |
|
||||
|
||||
**如果私有渠道无法工作,可使用以下变通办法:**
|
||||
**如果私有渠道无法工作,可用的解决方法:**
|
||||
|
||||
1. 使用标准渠道进行机器人交互
|
||||
2. 使用私信 - 用户始终可以直接给机器人发消息
|
||||
3. 使用 Graph API 进行历史访问(需要 `ChannelMessage.Read.All`)
|
||||
3. 使用 Graph API 访问历史记录(需要 `ChannelMessage.Read.All`)
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
- **图片未在渠道中显示:** 缺少 Graph 权限或管理员同意。重新安装 Teams 应用,并完全退出/重新打开 Teams。
|
||||
- **图片未显示在渠道中:** 缺少 Graph 权限或管理员同意。重新安装 Teams 应用,并完全退出后重新打开 Teams。
|
||||
- **渠道中没有响应:** 默认需要提及;设置 `channels.msteams.requireMention=false`,或按团队/渠道配置。
|
||||
- **版本不匹配(Teams 仍显示旧清单):** 移除并重新添加应用,然后完全退出 Teams 以刷新。
|
||||
- **webhook 返回 401 Unauthorized:** 手动测试时未使用 Azure JWT 属于预期情况 - 表示端点可访问,但认证失败。使用 Azure Web Chat 进行正确测试。
|
||||
- **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](https://admin.teams.microsoft.com) 上传,打开浏览器 DevTools(F12)→ Network 标签页,并检查响应正文中的实际错误。
|
||||
- **旁加载失败:** 尝试使用“Upload an app to your org's app catalog”,而不是“Upload a custom app” - 这通常可以绕过旁加载限制。
|
||||
- **“图标文件不能为空”:** 清单引用的图标文件为 0 字节。创建有效的 PNG 图标(`outline.png` 为 32x32,`color.png` 为 192x192)。
|
||||
- **“webApplicationInfo.Id 已被使用”:** 应用仍安装在另一个团队/聊天中。先找到并卸载它,或等待 5-10 分钟让变更传播。
|
||||
- **上传时显示“出现问题”:** 改为通过 [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) 上传,打开浏览器 DevTools(F12)→ 网络标签页,并检查响应正文中的实际错误。
|
||||
- **旁加载失败:** 尝试使用“将应用上传到组织的应用目录”,而不是“上传自定义应用” - 这通常可以绕过旁加载限制。
|
||||
|
||||
### RSC 权限不工作
|
||||
### RSC 权限无法工作
|
||||
|
||||
1. 验证 `webApplicationInfo.id` 与你的机器人的 App ID 完全匹配
|
||||
1. 验证 `webApplicationInfo.id` 与你的机器人 App ID 完全匹配
|
||||
2. 重新上传应用,并在团队/聊天中重新安装
|
||||
3. 检查你的组织管理员是否阻止了 RSC 权限
|
||||
4. 确认你使用了正确的 scope:团队使用 `ChannelMessage.Read.Group`,群聊使用 `ChatMessage.Read.Chat`
|
||||
4. 确认你使用了正确范围:团队使用 `ChannelMessage.Read.Group`,群聊使用 `ChatMessage.Read.Chat`
|
||||
|
||||
## 参考
|
||||
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 正在开发 Nextcloud Talk 渠道功能
|
||||
summary: Nextcloud Talk 支持状态、功能和配置
|
||||
- 开发 Nextcloud Talk 渠道功能
|
||||
summary: Nextcloud Talk 支持状态、能力和配置
|
||||
title: Nextcloud Talk
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:39Z"
|
||||
generated_at: "2026-05-02T21:57:04Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: b05d31a3e57cd8989ccb2ac122f2cd548de4120a54a8a04aa979e5ebc94eab61
|
||||
source_hash: 4956586ae8622118dcf136f4279c6ed1c2895fd4bb4576a7f5799de600a95740
|
||||
source_path: channels/nextcloud-talk.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status: 内置插件(webhook 机器人)。支持私信、房间、回应和 Markdown 消息。
|
||||
Status:内置插件(webhook 机器人)。支持私信、房间、表情回应和 Markdown 消息。
|
||||
|
||||
## 内置插件
|
||||
|
||||
@ -20,7 +20,7 @@ Nextcloud Talk 在当前 OpenClaw 版本中作为内置插件提供,因此
|
||||
普通打包构建不需要单独安装。
|
||||
|
||||
如果你使用的是较旧构建,或自定义安装中排除了 Nextcloud Talk,
|
||||
请直接安装 npm 包:
|
||||
请直接安装 npm package:
|
||||
|
||||
通过 CLI 安装(npm registry):
|
||||
|
||||
@ -28,10 +28,10 @@ Nextcloud Talk 在当前 OpenClaw 版本中作为内置插件提供,因此
|
||||
openclaw plugins install @openclaw/nextcloud-talk
|
||||
```
|
||||
|
||||
当跟随 OpenClaw beta 渠道,并且
|
||||
npmjs 显示 `beta` 领先于 `latest` 时,请使用 `@openclaw/nextcloud-talk@beta`。
|
||||
使用裸 package 可跟随当前官方发布标签。只有在需要可复现安装时,
|
||||
才固定精确版本。
|
||||
|
||||
本地检出(从 git 仓库运行时):
|
||||
本地检出(从 git repo 运行时):
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
@ -42,9 +42,9 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
## 快速设置(初学者)
|
||||
|
||||
1. 确保 Nextcloud Talk 插件可用。
|
||||
- 当前打包的 OpenClaw 版本已内置它。
|
||||
- 较旧/自定义安装可以使用上面的命令手动添加它。
|
||||
2. 在你的 Nextcloud 服务器上,创建一个机器人:
|
||||
- 当前打包的 OpenClaw 版本已经内置它。
|
||||
- 较旧/自定义安装可以使用上面的命令手动添加。
|
||||
2. 在你的 Nextcloud 服务器上创建一个机器人:
|
||||
|
||||
```bash
|
||||
./occ talk:bot:install "OpenClaw" "<shared-secret>" "<webhook-url>" --feature reaction
|
||||
@ -71,7 +71,7 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
--secret "<shared-secret>"
|
||||
```
|
||||
|
||||
文件提供的密钥:
|
||||
基于文件的 secret:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel nextcloud-talk \
|
||||
@ -98,23 +98,23 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 机器人无法主动发起私信。用户必须先给机器人发送消息。
|
||||
- Webhook URL 必须能被 Gateway 网关访问;如果位于代理后方,请设置 `webhookPublicUrl`。
|
||||
- 机器人不能发起私信。用户必须先给机器人发送消息。
|
||||
- Webhook URL 必须能被 Gateway 网关访问;如果位于代理之后,请设置 `webhookPublicUrl`。
|
||||
- 机器人 API 不支持媒体上传;媒体会以 URL 形式发送。
|
||||
- webhook payload 不区分私信和房间;设置 `apiUser` + `apiPassword` 可启用房间类型查询(否则私信会被视为房间)。
|
||||
- webhook payload 不区分私信和房间;设置 `apiUser` + `apiPassword` 以启用房间类型查询(否则私信会被视为房间)。
|
||||
|
||||
## 访问控制(私信)
|
||||
|
||||
- 默认:`channels.nextcloud-talk.dmPolicy = "pairing"`。未知发送者会收到配对码。
|
||||
- 默认值:`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=["*"]`。
|
||||
- `allowFrom` 仅匹配 Nextcloud 用户 ID;显示名称会被忽略。
|
||||
- 公开私信:`channels.nextcloud-talk.dmPolicy="open"` 加上 `channels.nextcloud-talk.allowFrom=["*"]`。
|
||||
- `allowFrom` 只匹配 Nextcloud 用户 ID;显示名称会被忽略。
|
||||
|
||||
## 房间(群组)
|
||||
|
||||
- 默认:`channels.nextcloud-talk.groupPolicy = "allowlist"`(需要提及)。
|
||||
- 默认值:`channels.nextcloud-talk.groupPolicy = "allowlist"`(需要提及)。
|
||||
- 使用 `channels.nextcloud-talk.rooms` 将房间加入允许列表:
|
||||
|
||||
```json5
|
||||
@ -129,17 +129,17 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
}
|
||||
```
|
||||
|
||||
- 要不允许任何房间,请保持允许列表为空,或设置 `channels.nextcloud-talk.groupPolicy="disabled"`。
|
||||
- 如需不允许任何房间,请保持允许列表为空,或设置 `channels.nextcloud-talk.groupPolicy="disabled"`。
|
||||
|
||||
## 能力
|
||||
|
||||
| 功能 | Status |
|
||||
| 功能 | Status |
|
||||
| --------------- | ------------- |
|
||||
| 私信 | 支持 |
|
||||
| 房间 | 支持 |
|
||||
| 话题串 | 不支持 |
|
||||
| 媒体 | 仅 URL |
|
||||
| 回应 | 支持 |
|
||||
| 私信 | 支持 |
|
||||
| 房间 | 支持 |
|
||||
| 线程 | 不支持 |
|
||||
| 媒体 | 仅 URL |
|
||||
| 表情回应 | 支持 |
|
||||
| 原生命令 | 不支持 |
|
||||
|
||||
## 配置参考(Nextcloud Talk)
|
||||
@ -150,15 +150,15 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
|
||||
- `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.botSecret`:机器人共享 secret。
|
||||
- `channels.nextcloud-talk.botSecretFile`:普通文件 secret 路径。符号链接会被拒绝。
|
||||
- `channels.nextcloud-talk.apiUser`:用于房间查询(私信检测)的 API 用户。
|
||||
- `channels.nextcloud-talk.apiPassword`:用于房间查询的 API/app 密码。
|
||||
- `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.webhookHost`:webhook host(默认:0.0.0.0)。
|
||||
- `channels.nextcloud-talk.webhookPath`:webhook path(默认:/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`。
|
||||
@ -168,8 +168,8 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin
|
||||
- `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.chunkMode`:`length`(默认)或 `newline`,用于在按长度分块前按空行(段落边界)拆分。
|
||||
- `channels.nextcloud-talk.blockStreaming`:为此渠道禁用分块流式传输。
|
||||
- `channels.nextcloud-talk.blockStreamingCoalesce`:分块流式传输合并调优。
|
||||
- `channels.nextcloud-talk.mediaMaxMb`:入站媒体上限(MB)。
|
||||
|
||||
|
||||
@ -1,30 +1,30 @@
|
||||
---
|
||||
read_when:
|
||||
- 你希望 OpenClaw 通过 Nostr 接收私信
|
||||
- 你想让 OpenClaw 通过 Nostr 接收私信
|
||||
- 你正在设置去中心化消息传递
|
||||
summary: 通过 NIP-04 加密消息实现的 Nostr 私信渠道
|
||||
title: Nostr
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:47Z"
|
||||
generated_at: "2026-05-02T21:57:07Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c3bf033d99b779cdf7b038461c9155694e22f65b1d54dbc28d0314bcf5424ddf
|
||||
source_hash: d6158c22c0ffc5aea56d0ac2b68955f30c3a785013dba5410cbd70f9b689dc3c
|
||||
source_path: channels/nostr.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
**Status:** 可选内置插件(默认禁用,直到完成配置)。
|
||||
**Status:** 可选内置插件(默认禁用,直到配置后启用)。
|
||||
|
||||
Nostr 是一个用于社交网络的去中心化协议。此渠道使 OpenClaw 能够通过 NIP-04 接收和回复加密的直接消息(私信)。
|
||||
Nostr 是一种用于社交网络的去中心化协议。此渠道让 OpenClaw 能够通过 NIP-04 接收并回复加密私信。
|
||||
|
||||
## 内置插件
|
||||
|
||||
当前 OpenClaw 版本将 Nostr 作为内置插件发布,因此普通打包
|
||||
构建不需要单独安装。
|
||||
当前 OpenClaw 版本以内置插件形式随附 Nostr,因此常规打包构建
|
||||
不需要单独安装。
|
||||
|
||||
### 较旧/自定义安装
|
||||
|
||||
- 新手引导(`openclaw onboard`)和 `openclaw channels add` 仍会从共享渠道目录中显示
|
||||
- 新手引导(`openclaw onboard`)和 `openclaw channels add` 仍会从共享渠道目录中展示
|
||||
Nostr。
|
||||
- 如果你的构建排除了内置 Nostr,请直接安装 npm 包。
|
||||
|
||||
@ -32,8 +32,8 @@ Nostr 是一个用于社交网络的去中心化协议。此渠道使 OpenClaw
|
||||
openclaw plugins install @openclaw/nostr
|
||||
```
|
||||
|
||||
当你使用 OpenClaw beta 渠道,并且 npmjs
|
||||
显示 `beta` 领先于 `latest` 时,请使用 `@openclaw/nostr@beta`。
|
||||
使用裸包名可跟随当前官方发布标签。仅在需要可复现安装时才固定精确
|
||||
版本。
|
||||
|
||||
使用本地检出(开发工作流):
|
||||
|
||||
@ -50,11 +50,11 @@ openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY"
|
||||
openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY" --relay-urls "wss://relay.damus.io,wss://relay.primal.net"
|
||||
```
|
||||
|
||||
使用 `--use-env` 将 `NOSTR_PRIVATE_KEY` 保留在环境中,而不是把密钥存入配置。
|
||||
使用 `--use-env` 可将 `NOSTR_PRIVATE_KEY` 保留在环境中,而不是把密钥存入配置。
|
||||
|
||||
## 快速设置
|
||||
|
||||
1. 生成 Nostr 密钥对(如需要):
|
||||
1. 生成 Nostr 密钥对(如果需要):
|
||||
|
||||
```bash
|
||||
# Using nak
|
||||
@ -83,19 +83,19 @@ export NOSTR_PRIVATE_KEY="nsec1..."
|
||||
|
||||
## 配置参考
|
||||
|
||||
| 键 | 类型 | 默认值 | 描述 |
|
||||
| ------------ | -------- | ------------------------------------------- | --------------------------------- |
|
||||
| `privateKey` | string | 必填 | `nsec` 或十六进制格式的私钥 |
|
||||
| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URL(WebSocket) |
|
||||
| `dmPolicy` | string | `pairing` | 私信访问策略 |
|
||||
| `allowFrom` | string[] | `[]` | 允许的发送方公钥 |
|
||||
| `enabled` | boolean | `true` | 启用/禁用渠道 |
|
||||
| `name` | string | - | 显示名称 |
|
||||
| `profile` | object | - | NIP-01 个人资料元数据 |
|
||||
| 键 | 类型 | 默认值 | 描述 |
|
||||
| ------------ | -------- | ------------------------------------------- | ----------------------------------- |
|
||||
| `privateKey` | string | required | `nsec` 或十六进制格式的私钥 |
|
||||
| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URL(WebSocket) |
|
||||
| `dmPolicy` | string | `pairing` | 私信访问策略 |
|
||||
| `allowFrom` | string[] | `[]` | 允许的发送者公钥 |
|
||||
| `enabled` | boolean | `true` | 启用/禁用渠道 |
|
||||
| `name` | string | - | 显示名称 |
|
||||
| `profile` | object | - | NIP-01 个人资料元数据 |
|
||||
|
||||
## 个人资料元数据
|
||||
|
||||
个人资料数据会作为 NIP-01 `kind:0` 事件发布。你可以从 Control UI(Channels -> Nostr -> Profile)管理它,或直接在配置中设置。
|
||||
个人资料数据会作为 NIP-01 `kind:0` 事件发布。你可以从控制界面(渠道 -> Nostr -> 个人资料)管理它,或直接在配置中设置。
|
||||
|
||||
示例:
|
||||
|
||||
@ -122,22 +122,22 @@ export NOSTR_PRIVATE_KEY="nsec1..."
|
||||
注意:
|
||||
|
||||
- 个人资料 URL 必须使用 `https://`。
|
||||
- 从中继导入会合并字段并保留本地覆盖。
|
||||
- 从中继导入会合并字段,并保留本地覆盖项。
|
||||
|
||||
## 访问控制
|
||||
|
||||
### 私信策略
|
||||
|
||||
- **pairing**(默认):未知发送方会收到配对码。
|
||||
- **pairing**(默认):未知发送者会收到配对码。
|
||||
- **allowlist**:只有 `allowFrom` 中的公钥可以发送私信。
|
||||
- **open**:公开入站私信(需要 `allowFrom: ["*"]`)。
|
||||
- **disabled**:忽略入站私信。
|
||||
|
||||
强制执行说明:
|
||||
|
||||
- 入站事件签名会先于发送方策略和 NIP-04 解密进行验证,因此伪造事件会被提前拒绝。
|
||||
- 在发送者策略和 NIP-04 解密之前会验证入站事件签名,因此伪造事件会被提前拒绝。
|
||||
- 配对回复会在不处理原始私信正文的情况下发送。
|
||||
- 入站私信会受到速率限制,超大载荷会在解密前被丢弃。
|
||||
- 入站私信会受到速率限制,过大的载荷会在解密前被丢弃。
|
||||
|
||||
### 允许列表示例
|
||||
|
||||
@ -177,19 +177,19 @@ export NOSTR_PRIVATE_KEY="nsec1..."
|
||||
|
||||
提示:
|
||||
|
||||
- 使用 2-3 个中继以实现冗余。
|
||||
- 使用 2-3 个中继以提供冗余。
|
||||
- 避免使用过多中继(延迟、重复)。
|
||||
- 付费中继可以提高可靠性。
|
||||
- 本地中继适合测试(`ws://localhost:7777`)。
|
||||
|
||||
## 协议支持
|
||||
|
||||
| NIP | Status | 描述 |
|
||||
| ------ | ------ | ------------------------------- |
|
||||
| NIP-01 | 已支持 | 基本事件格式 + 个人资料元数据 |
|
||||
| NIP-04 | 已支持 | 加密私信(`kind:4`) |
|
||||
| NIP-17 | 已计划 | 礼物包装私信 |
|
||||
| NIP-44 | 已计划 | 版本化加密 |
|
||||
| NIP | Status | 描述 |
|
||||
| ------ | --------- | ------------------------------------- |
|
||||
| NIP-01 | Supported | 基本事件格式 + 个人资料元数据 |
|
||||
| NIP-04 | Supported | 加密私信(`kind:4`) |
|
||||
| NIP-17 | Planned | 礼物包装私信 |
|
||||
| NIP-44 | Planned | 版本化加密 |
|
||||
|
||||
## 测试
|
||||
|
||||
@ -213,9 +213,9 @@ docker run -p 7777:7777 ghcr.io/hoytech/strfry
|
||||
|
||||
### 手动测试
|
||||
|
||||
1. 从日志中记下 bot 公钥(npub)。
|
||||
1. 从日志中记下机器人的公钥(npub)。
|
||||
2. 打开一个 Nostr 客户端(Damus、Amethyst 等)。
|
||||
3. 向 bot 公钥发送私信。
|
||||
3. 向机器人公钥发送私信。
|
||||
4. 验证响应。
|
||||
|
||||
## 故障排除
|
||||
@ -223,38 +223,38 @@ docker run -p 7777:7777 ghcr.io/hoytech/strfry
|
||||
### 未收到消息
|
||||
|
||||
- 验证私钥有效。
|
||||
- 确保中继 URL 可访问并使用 `wss://`(本地使用 `ws://`)。
|
||||
- 确保中继 URL 可访问并使用 `wss://`(本地可使用 `ws://`)。
|
||||
- 确认 `enabled` 不是 `false`。
|
||||
- 检查 Gateway 网关日志中的中继连接错误。
|
||||
|
||||
### 未发送响应
|
||||
|
||||
- 检查中继是否接受写入。
|
||||
- 验证出站连接能力。
|
||||
- 验证出站连接。
|
||||
- 留意中继速率限制。
|
||||
|
||||
### 重复响应
|
||||
|
||||
- 使用多个中继时这是预期情况。
|
||||
- 消息会按事件 ID 去重;只有第一次送达会触发响应。
|
||||
- 使用多个中继时属于预期情况。
|
||||
- 消息会按事件 ID 去重;只有首次投递会触发响应。
|
||||
|
||||
## 安全
|
||||
|
||||
- 切勿提交私钥。
|
||||
- 对密钥使用环境变量。
|
||||
- 对生产 bot 考虑使用 `allowlist`。
|
||||
- 签名会先于发送方策略进行验证,并且发送方策略会在解密前强制执行,因此伪造事件会被提前拒绝,未知发送方也无法强制执行完整加密工作。
|
||||
- 对生产机器人考虑使用 `allowlist`。
|
||||
- 会在发送者策略之前验证签名,并在解密之前强制执行发送者策略,因此伪造事件会被提前拒绝,未知发送者也无法强制执行完整加密工作。
|
||||
|
||||
## 限制(MVP)
|
||||
|
||||
- 仅支持直接消息(不支持群聊)。
|
||||
- 不支持媒体附件。
|
||||
- 仅支持 NIP-04(已计划 NIP-17 礼物包装)。
|
||||
- 仅支持 NIP-04(计划支持 NIP-17 礼物包装)。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程
|
||||
- [渠道概览](/zh-CN/channels) — 所有受支持渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程
|
||||
- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型和加固
|
||||
|
||||
@ -1,29 +1,30 @@
|
||||
---
|
||||
read_when:
|
||||
- 正在开发 Tlon/Urbit 渠道功能
|
||||
- 开发 Tlon/Urbit 渠道功能
|
||||
summary: Tlon/Urbit 支持状态、能力和配置
|
||||
title: Tlon
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:37Z"
|
||||
generated_at: "2026-05-02T21:57:10Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 39dd46d94c708b5be9eae9457aa5b2b945fe701b3900207f996719b48090dd45
|
||||
source_hash: 30915170786fc1ee8b84fb8be2ea42280262923064cfa9ca7107036096a13add
|
||||
source_path: channels/tlon.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Tlon 是构建在 Urbit 上的去中心化消息工具。OpenClaw 会连接到你的 Urbit ship,并可以
|
||||
响应私信和群聊消息。默认情况下,群组回复需要 @ 提及,也可以通过 allowlist 进一步限制。
|
||||
Tlon 是构建在 Urbit 上的去中心化消息应用。OpenClaw 会连接到你的 Urbit ship,并且可以
|
||||
回复私信和群聊消息。默认情况下,群组回复需要 @ 提及,也可以
|
||||
通过 allowlist 进一步限制。
|
||||
|
||||
Status: 内置插件。支持私信、群组提及、线程回复、富文本格式和
|
||||
图片上传。尚不支持回应和投票。
|
||||
Status: 内置插件。支持私信、群组提及、thread 回复、富文本格式以及
|
||||
图片上传。尚不支持 Reactions 和投票。
|
||||
|
||||
## 内置插件
|
||||
|
||||
Tlon 在当前 OpenClaw 版本中作为内置插件随附,因此普通打包
|
||||
Tlon 在当前 OpenClaw 版本中作为内置插件发布,因此常规打包
|
||||
构建不需要单独安装。
|
||||
|
||||
如果你使用的是较旧版本,或排除了 Tlon 的自定义安装,请安装
|
||||
如果你使用的是较旧构建,或是不包含 Tlon 的自定义安装,请安装
|
||||
当前 npm 包:
|
||||
|
||||
通过 CLI 安装(npm registry):
|
||||
@ -32,8 +33,8 @@ Tlon 在当前 OpenClaw 版本中作为内置插件随附,因此普通打包
|
||||
openclaw plugins install @openclaw/tlon
|
||||
```
|
||||
|
||||
当你跟随 OpenClaw beta channel,且 npmjs 显示 `beta` 领先于 `latest` 时,
|
||||
使用 `@openclaw/tlon@beta`。
|
||||
使用裸包名以跟随当前官方发布标签。只有在需要可复现安装时,
|
||||
才固定到精确版本。
|
||||
|
||||
本地 checkout(从 git repo 运行时):
|
||||
|
||||
@ -47,11 +48,11 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
|
||||
1. 确保 Tlon 插件可用。
|
||||
- 当前打包的 OpenClaw 版本已内置它。
|
||||
- 较旧/自定义安装可以用上面的命令手动添加它。
|
||||
2. 获取你的 ship URL 和登录代码。
|
||||
- 较旧/自定义安装可以使用上面的命令手动添加。
|
||||
2. 收集你的 ship URL 和登录 code。
|
||||
3. 配置 `channels.tlon`。
|
||||
4. 重启 Gateway 网关。
|
||||
5. 私信 bot,或在群组渠道中提及它。
|
||||
5. 给机器人发送私信,或在群组 channel 中提及它。
|
||||
|
||||
最小配置(单账号):
|
||||
|
||||
@ -71,9 +72,9 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
|
||||
## 私有/LAN ships
|
||||
|
||||
默认情况下,OpenClaw 会阻止私有/内部主机名和 IP 范围以提供 SSRF 防护。
|
||||
默认情况下,OpenClaw 会阻止私有/内部主机名和 IP 范围,以提供 SSRF 防护。
|
||||
如果你的 ship 运行在私有网络上(localhost、LAN IP 或内部主机名),
|
||||
你必须明确选择启用:
|
||||
你必须显式选择启用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -92,12 +93,12 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
- `http://192.168.x.x:8080`
|
||||
- `http://my-ship.local:8080`
|
||||
|
||||
⚠️ 仅在你信任本地网络时启用此项。此设置会对发往你的 ship URL 的请求
|
||||
⚠️ 只有在你信任本地网络时才启用此项。此设置会对发往你的 ship URL 的请求
|
||||
禁用 SSRF 防护。
|
||||
|
||||
## 群组渠道
|
||||
## 群组 channels
|
||||
|
||||
默认启用自动发现。你也可以手动固定渠道:
|
||||
默认启用自动发现。你也可以手动固定 channels:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -123,7 +124,7 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
|
||||
## 访问控制
|
||||
|
||||
私信 allowlist(空 = 不允许任何私信,使用 `ownerShip` 进行审批流程):
|
||||
私信 allowlist(空 = 不允许私信,使用 `ownerShip` 走审批流程):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -160,7 +161,7 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
|
||||
## 所有者和审批系统
|
||||
|
||||
设置所有者 ship,以便未经授权的用户尝试交互时接收审批请求:
|
||||
设置 owner ship,以便在未授权用户尝试交互时接收审批请求:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -172,19 +173,19 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
}
|
||||
```
|
||||
|
||||
所有者 ship 会**在所有位置自动获得授权** — 私信邀请会自动接受,
|
||||
渠道消息也始终允许。你不需要将所有者添加到 `dmAllowlist` 或
|
||||
owner ship 会**在所有位置自动获得授权** — 私信邀请会自动接受,
|
||||
channel 消息始终允许。你不需要把 owner 添加到 `dmAllowlist` 或
|
||||
`defaultAuthorizedShips`。
|
||||
|
||||
设置后,所有者会收到以下私信通知:
|
||||
设置后,owner 会收到以下私信通知:
|
||||
|
||||
- 来自不在 allowlist 中的 ships 的私信请求
|
||||
- 未获授权的渠道中的提及
|
||||
- 来自未在 allowlist 中的 ships 的私信请求
|
||||
- 未经授权的 channels 中的提及
|
||||
- 群组邀请请求
|
||||
|
||||
## 自动接受设置
|
||||
|
||||
自动接受私信邀请(来自 dmAllowlist 中的 ships):
|
||||
自动接受私信邀请(针对 dmAllowlist 中的 ships):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -208,9 +209,9 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
}
|
||||
```
|
||||
|
||||
## 发送目标(CLI/cron)
|
||||
## 投递目标(CLI/cron)
|
||||
|
||||
将这些目标用于 `openclaw message send` 或 cron 发送:
|
||||
将这些目标与 `openclaw message send` 或 cron 投递一起使用:
|
||||
|
||||
- 私信:`~sampel-palnet` 或 `dm/~sampel-palnet`
|
||||
- 群组:`chat/~host-ship/channel` 或 `group:~host-ship/channel`
|
||||
@ -218,33 +219,33 @@ openclaw plugins install ./path/to/local/tlon-plugin
|
||||
## 内置 skill
|
||||
|
||||
Tlon 插件包含一个内置 skill([`@tloncorp/tlon-skill`](https://github.com/tloncorp/tlon-skill)),
|
||||
它提供对 Tlon 操作的 CLI 访问:
|
||||
可提供对 Tlon 操作的 CLI 访问:
|
||||
|
||||
- **联系人**:获取/更新资料,列出联系人
|
||||
- **渠道**:列出、创建、发布消息、获取历史记录
|
||||
- **Channels**:列出、创建、发布消息、获取历史记录
|
||||
- **群组**:列出、创建、管理成员
|
||||
- **私信**:发送消息,对消息回应
|
||||
- **回应**:向帖子和私信添加/移除 emoji 回应
|
||||
- **私信**:发送消息、对消息作出反应
|
||||
- **Reactions**:为帖子和私信添加/移除 emoji reactions
|
||||
- **设置**:通过 slash commands 管理插件权限
|
||||
|
||||
安装插件后,该 skill 会自动可用。
|
||||
插件安装后,该 skill 会自动可用。
|
||||
|
||||
## 能力
|
||||
|
||||
| 功能 | Status |
|
||||
| 功能 | Status |
|
||||
| --------------- | --------------------------------------- |
|
||||
| 直接消息 | ✅ 支持 |
|
||||
| 群组/渠道 | ✅ 支持(默认需要提及) |
|
||||
| 线程 | ✅ 支持(在线程中自动回复) |
|
||||
| 富文本 | ✅ Markdown 转换为 Tlon 格式 |
|
||||
| 图片 | ✅ 上传到 Tlon 存储 |
|
||||
| 回应 | ✅ 通过[内置 skill](#bundled-skill) |
|
||||
| 投票 | ❌ 尚不支持 |
|
||||
| 原生命令 | ✅ 支持(默认仅所有者可用) |
|
||||
| 直接消息 | ✅ 支持 |
|
||||
| 群组/channels | ✅ 支持(默认需要提及) |
|
||||
| Threads | ✅ 支持(在 thread 中自动回复) |
|
||||
| 富文本 | ✅ Markdown 会转换为 Tlon 格式 |
|
||||
| 图片 | ✅ 上传到 Tlon storage |
|
||||
| Reactions | ✅ 通过[内置 skill](#bundled-skill) |
|
||||
| 投票 | ❌ 尚不支持 |
|
||||
| 原生命令 | ✅ 支持(默认仅限 owner) |
|
||||
|
||||
## 故障排除
|
||||
|
||||
先运行这组排查命令:
|
||||
先运行这个排查阶梯:
|
||||
|
||||
```bash
|
||||
openclaw status
|
||||
@ -253,12 +254,12 @@ openclaw logs --follow
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
常见失败:
|
||||
常见故障:
|
||||
|
||||
- **私信被忽略**:发送者不在 `dmAllowlist` 中,且未配置用于审批流程的 `ownerShip`。
|
||||
- **群组消息被忽略**:渠道未被发现,或发送者未获授权。
|
||||
- **私信被忽略**:发送者不在 `dmAllowlist` 中,并且没有为审批流程配置 `ownerShip`。
|
||||
- **群组消息被忽略**:channel 未被发现,或发送者未获授权。
|
||||
- **连接错误**:检查 ship URL 是否可访问;对本地 ships 启用 `allowPrivateNetwork`。
|
||||
- **认证错误**:确认登录代码是当前有效的(代码会轮换)。
|
||||
- **认证错误**:验证登录 code 是否为当前有效 code(codes 会轮换)。
|
||||
|
||||
## 配置参考
|
||||
|
||||
@ -266,32 +267,32 @@ openclaw doctor
|
||||
|
||||
提供商选项:
|
||||
|
||||
- `channels.tlon.enabled`:启用/禁用渠道启动。
|
||||
- `channels.tlon.ship`:bot 的 Urbit ship 名称(例如 `~sampel-palnet`)。
|
||||
- `channels.tlon.enabled`:启用/禁用 channel 启动。
|
||||
- `channels.tlon.ship`:机器人的 Urbit ship 名称(例如 `~sampel-palnet`)。
|
||||
- `channels.tlon.url`:ship URL(例如 `https://sampel-palnet.tlon.network`)。
|
||||
- `channels.tlon.code`:ship 登录代码。
|
||||
- `channels.tlon.allowPrivateNetwork`:允许 localhost/LAN URL(SSRF 绕过)。
|
||||
- `channels.tlon.ownerShip`:审批系统的所有者 ship(始终授权)。
|
||||
- `channels.tlon.code`:ship 登录 code。
|
||||
- `channels.tlon.allowPrivateNetwork`:允许 localhost/LAN URLs(绕过 SSRF)。
|
||||
- `channels.tlon.ownerShip`:审批系统的 owner ship(始终授权)。
|
||||
- `channels.tlon.dmAllowlist`:允许发送私信的 ships(空 = 无)。
|
||||
- `channels.tlon.autoAcceptDmInvites`:自动接受来自 allowlist 中 ships 的私信。
|
||||
- `channels.tlon.autoAcceptDmInvites`:自动接受 allowlisted ships 的私信。
|
||||
- `channels.tlon.autoAcceptGroupInvites`:自动接受所有群组邀请。
|
||||
- `channels.tlon.autoDiscoverChannels`:自动发现群组渠道(默认:true)。
|
||||
- `channels.tlon.groupChannels`:手动固定的渠道 nests。
|
||||
- `channels.tlon.defaultAuthorizedShips`:对所有渠道授权的 ships。
|
||||
- `channels.tlon.authorization.channelRules`:按渠道设置的认证规则。
|
||||
- `channels.tlon.autoDiscoverChannels`:自动发现群组 channels(默认:true)。
|
||||
- `channels.tlon.groupChannels`:手动固定的 channel nests。
|
||||
- `channels.tlon.defaultAuthorizedShips`:对所有 channels 授权的 ships。
|
||||
- `channels.tlon.authorization.channelRules`:按 channel 配置的 auth rules。
|
||||
- `channels.tlon.showModelSignature`:在消息后附加模型名称。
|
||||
|
||||
## 说明
|
||||
## 备注
|
||||
|
||||
- 群组回复需要提及(例如 `~your-bot-ship`)才会响应。
|
||||
- 线程回复:如果入站消息在线程中,OpenClaw 会在线程内回复。
|
||||
- 富文本:Markdown 格式(粗体、斜体、代码、标题、列表)会转换为 Tlon 的原生格式。
|
||||
- 图片:URL 会上传到 Tlon 存储,并作为图片块嵌入。
|
||||
- Thread 回复:如果传入消息位于 thread 中,OpenClaw 会在同一 thread 中回复。
|
||||
- 富文本:Markdown 格式(粗体、斜体、code、headers、列表)会转换为 Tlon 的原生格式。
|
||||
- 图片:URLs 会上传到 Tlon storage,并作为 image blocks 嵌入。
|
||||
|
||||
## 相关
|
||||
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [Channels 概览](/zh-CN/channels) — 所有支持的 channels
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程
|
||||
- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型和加固
|
||||
|
||||
@ -2,26 +2,26 @@
|
||||
read_when:
|
||||
- 为 OpenClaw 设置 Twitch 聊天集成
|
||||
sidebarTitle: Twitch
|
||||
summary: Twitch 聊天机器人配置和设置
|
||||
summary: Twitch 聊天机器人配置与设置
|
||||
title: Twitch
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:40Z"
|
||||
generated_at: "2026-05-02T21:57:03Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0738d0a2095370f771fa5a1967c8bbcb88e052648c6da8c0d9f8367600e101e0
|
||||
source_hash: c0d5f16d1369e2783bec6e0c7b2d7bee8aae86f2a424b77b9adf14850de0f20b
|
||||
source_path: channels/twitch.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
通过 IRC 连接支持 Twitch 聊天。OpenClaw 会以 Twitch 用户(bot 账号)身份连接,以便在频道中接收和发送消息。
|
||||
通过 IRC 连接支持 Twitch 聊天。OpenClaw 以 Twitch 用户(机器人账号)身份连接,用于在频道中接收和发送消息。
|
||||
|
||||
## 内置插件
|
||||
|
||||
<Note>
|
||||
Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包构建不需要单独安装。
|
||||
Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包构建不需要单独安装。
|
||||
</Note>
|
||||
|
||||
如果你使用的是较旧构建,或排除了 Twitch 的自定义安装,请直接安装 npm 包:
|
||||
如果你使用的是较旧构建,或是排除了 Twitch 的自定义安装,请直接安装 npm 包:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="npm registry">
|
||||
@ -29,27 +29,27 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
openclaw plugins install @openclaw/twitch
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Local checkout">
|
||||
<Tab title="本地检出">
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/twitch-plugin
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
当你跟随 OpenClaw beta 渠道且 npmjs 显示 `beta` 领先于 `latest` 时,使用 `@openclaw/twitch@beta`。
|
||||
使用裸包名可跟随当前官方发布标签。仅在需要可复现安装时才固定精确版本。
|
||||
|
||||
详情:[插件](/zh-CN/tools/plugin)
|
||||
|
||||
## 快速设置(初学者)
|
||||
|
||||
<Steps>
|
||||
<Step title="Ensure plugin is available">
|
||||
当前打包的 OpenClaw 版本已经内置了它。较旧版本或自定义安装可以使用上面的命令手动添加。
|
||||
<Step title="确保插件可用">
|
||||
当前打包的 OpenClaw 版本已内置该插件。较旧/自定义安装可以使用上面的命令手动添加。
|
||||
</Step>
|
||||
<Step title="Create a Twitch bot account">
|
||||
为 bot 创建一个专用 Twitch 账号(或使用现有账号)。
|
||||
<Step title="创建 Twitch 机器人账号">
|
||||
为机器人创建一个专用 Twitch 账号(或使用现有账号)。
|
||||
</Step>
|
||||
<Step title="Generate credentials">
|
||||
<Step title="生成凭证">
|
||||
使用 [Twitch Token Generator](https://twitchtokengenerator.com/):
|
||||
|
||||
- 选择 **Bot Token**
|
||||
@ -57,23 +57,23 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
- 复制 **Client ID** 和 **Access Token**
|
||||
|
||||
</Step>
|
||||
<Step title="Find your Twitch user ID">
|
||||
<Step title="查找你的 Twitch 用户 ID">
|
||||
使用 [https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/](https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/) 将用户名转换为 Twitch 用户 ID。
|
||||
</Step>
|
||||
<Step title="Configure the token">
|
||||
<Step title="配置令牌">
|
||||
- 环境变量:`OPENCLAW_TWITCH_ACCESS_TOKEN=...`(仅默认账号)
|
||||
- 或配置:`channels.twitch.accessToken`
|
||||
|
||||
如果两者都设置了,配置优先(环境变量回退仅适用于默认账号)。
|
||||
如果两者都已设置,配置优先(环境变量回退仅适用于默认账号)。
|
||||
|
||||
</Step>
|
||||
<Step title="Start the gateway">
|
||||
<Step title="启动 Gateway 网关">
|
||||
使用已配置的渠道启动 Gateway 网关。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Warning>
|
||||
添加访问控制(`allowFrom` 或 `allowedRoles`),防止未授权用户触发 bot。`requireMention` 默认为 `true`。
|
||||
添加访问控制(`allowFrom` 或 `allowedRoles`),防止未经授权的用户触发机器人。`requireMention` 默认值为 `true`。
|
||||
</Warning>
|
||||
|
||||
最小配置:
|
||||
@ -95,10 +95,10 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
|
||||
## 它是什么
|
||||
|
||||
- 由 Gateway 网关拥有的 Twitch 渠道。
|
||||
- 一个由 Gateway 网关拥有的 Twitch 渠道。
|
||||
- 确定性路由:回复始终返回 Twitch。
|
||||
- 每个账号都会映射到一个隔离的会话键 `agent:<agentId>:twitch:<accountName>`。
|
||||
- `username` 是 bot 的账号(用于身份验证),`channel` 是要加入的聊天室。
|
||||
- `username` 是机器人的账号(用于认证),`channel` 是要加入的聊天室。
|
||||
|
||||
## 设置(详细)
|
||||
|
||||
@ -111,18 +111,18 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
- 复制 **Client ID** 和 **Access Token**
|
||||
|
||||
<Note>
|
||||
不需要手动注册应用。令牌会在几个小时后过期。
|
||||
不需要手动注册应用。令牌会在数小时后过期。
|
||||
</Note>
|
||||
|
||||
### 配置 bot
|
||||
### 配置机器人
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Env var (default account only)">
|
||||
<Tab title="环境变量(仅默认账号)">
|
||||
```bash
|
||||
OPENCLAW_TWITCH_ACCESS_TOKEN=oauth:abc123...
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Config">
|
||||
<Tab title="配置">
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
@ -153,7 +153,7 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
}
|
||||
```
|
||||
|
||||
优先使用 `allowFrom` 作为严格允许列表。如果你想使用基于角色的访问,请改用 `allowedRoles`。
|
||||
优先使用 `allowFrom` 作为硬性允许列表。如果你想要基于角色的访问,请改用 `allowedRoles`。
|
||||
|
||||
**可用角色:** `"moderator"`、`"owner"`、`"vip"`、`"subscriber"`、`"all"`。
|
||||
|
||||
@ -165,9 +165,9 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
|
||||
## 令牌刷新(可选)
|
||||
|
||||
来自 [Twitch Token Generator](https://twitchtokengenerator.com/) 的令牌无法自动刷新,过期时需要重新生成。
|
||||
来自 [Twitch Token Generator](https://twitchtokengenerator.com/) 的令牌无法自动刷新,请在过期后重新生成。
|
||||
|
||||
如需自动刷新令牌,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置:
|
||||
若要自动刷新令牌,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -180,13 +180,13 @@ Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
}
|
||||
```
|
||||
|
||||
bot 会在过期前自动刷新令牌,并记录刷新事件。
|
||||
机器人会在过期前自动刷新令牌,并记录刷新事件。
|
||||
|
||||
## 多账号支持
|
||||
|
||||
使用 `channels.twitch.accounts` 配置每个账号的令牌。共享模式请参阅[配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
示例(一个 bot 账号加入两个频道):
|
||||
示例(一个机器人账号加入两个频道):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -218,7 +218,7 @@ bot 会在过期前自动刷新令牌,并记录刷新事件。
|
||||
## 访问控制
|
||||
|
||||
<Tabs>
|
||||
<Tab title="User ID allowlist (most secure)">
|
||||
<Tab title="用户 ID 允许列表(最安全)">
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
@ -233,7 +233,7 @@ bot 会在过期前自动刷新令牌,并记录刷新事件。
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Role-based">
|
||||
<Tab title="基于角色">
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
@ -248,11 +248,11 @@ bot 会在过期前自动刷新令牌,并记录刷新事件。
|
||||
}
|
||||
```
|
||||
|
||||
`allowFrom` 是严格允许列表。设置后,仅允许这些用户 ID。如果你想使用基于角色的访问,请不要设置 `allowFrom`,改为配置 `allowedRoles`。
|
||||
`allowFrom` 是硬性允许列表。设置后,仅允许这些用户 ID。如果你想要基于角色的访问,请不要设置 `allowFrom`,而是配置 `allowedRoles`。
|
||||
|
||||
</Tab>
|
||||
<Tab title="Disable @mention requirement">
|
||||
默认情况下,`requireMention` 为 `true`。要禁用并响应所有消息:
|
||||
<Tab title="禁用 @mention 要求">
|
||||
默认情况下,`requireMention` 为 `true`。若要禁用并响应所有消息:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -273,7 +273,7 @@ bot 会在过期前自动刷新令牌,并记录刷新事件。
|
||||
|
||||
## 故障排除
|
||||
|
||||
首先,运行诊断命令:
|
||||
首先运行诊断命令:
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
@ -281,20 +281,20 @@ openclaw channels status --probe
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Bot does not respond to messages">
|
||||
<Accordion title="机器人不响应消息">
|
||||
- **检查访问控制:** 确保你的用户 ID 位于 `allowFrom` 中,或临时移除 `allowFrom` 并设置 `allowedRoles: ["all"]` 进行测试。
|
||||
- **检查 bot 是否在频道中:** bot 必须加入 `channel` 中指定的频道。
|
||||
- **检查机器人是否在频道中:** 机器人必须加入 `channel` 中指定的频道。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Token issues">
|
||||
“Failed to connect” 或身份验证错误:
|
||||
<Accordion title="令牌问题">
|
||||
“连接失败”或认证错误:
|
||||
|
||||
- 确认 `accessToken` 是 OAuth 访问令牌值(通常以 `oauth:` 前缀开头)
|
||||
- 检查令牌是否具有 `chat:read` 和 `chat:write` 作用域
|
||||
- 如果使用令牌刷新,请确认已设置 `clientSecret` 和 `refreshToken`
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Token refresh not working">
|
||||
<Accordion title="令牌刷新无法工作">
|
||||
检查日志中的刷新事件:
|
||||
|
||||
```
|
||||
@ -315,7 +315,7 @@ openclaw channels status --probe
|
||||
### 账号配置
|
||||
|
||||
<ParamField path="username" type="string">
|
||||
Bot 用户名。
|
||||
机器人用户名。
|
||||
</ParamField>
|
||||
<ParamField path="accessToken" type="string">
|
||||
具有 `chat:read` 和 `chat:write` 的 OAuth 访问令牌。
|
||||
@ -330,13 +330,13 @@ openclaw channels status --probe
|
||||
启用此账号。
|
||||
</ParamField>
|
||||
<ParamField path="clientSecret" type="string">
|
||||
可选:用于自动令牌刷新。
|
||||
可选:用于自动刷新令牌。
|
||||
</ParamField>
|
||||
<ParamField path="refreshToken" type="string">
|
||||
可选:用于自动令牌刷新。
|
||||
可选:用于自动刷新令牌。
|
||||
</ParamField>
|
||||
<ParamField path="expiresIn" type="number">
|
||||
令牌过期时间,单位为秒。
|
||||
令牌有效期(秒)。
|
||||
</ParamField>
|
||||
<ParamField path="obtainmentTimestamp" type="number">
|
||||
令牌获取时间戳。
|
||||
@ -348,17 +348,17 @@ openclaw channels status --probe
|
||||
基于角色的访问控制。
|
||||
</ParamField>
|
||||
<ParamField path="requireMention" type="boolean" default="true">
|
||||
要求 @提及。
|
||||
要求 @mention。
|
||||
</ParamField>
|
||||
|
||||
### 提供商选项
|
||||
|
||||
- `channels.twitch.enabled` - 启用/禁用渠道启动
|
||||
- `channels.twitch.username` - Bot 用户名(简化的单账号配置)
|
||||
- `channels.twitch.username` - 机器人用户名(简化的单账号配置)
|
||||
- `channels.twitch.accessToken` - OAuth 访问令牌(简化的单账号配置)
|
||||
- `channels.twitch.clientId` - Twitch Client ID(简化的单账号配置)
|
||||
- `channels.twitch.channel` - 要加入的频道(简化的单账号配置)
|
||||
- `channels.twitch.accounts.<accountName>` - 多账号配置(上面的所有账号字段)
|
||||
- `channels.twitch.accounts.<accountName>` - 多账号配置(上方所有账号字段)
|
||||
|
||||
完整示例:
|
||||
|
||||
@ -397,7 +397,7 @@ openclaw channels status --probe
|
||||
|
||||
## 工具动作
|
||||
|
||||
智能体可以调用 `twitch` 并使用动作:
|
||||
智能体可以调用 `twitch` 并使用 action:
|
||||
|
||||
- `send` - 向频道发送消息
|
||||
|
||||
@ -416,22 +416,22 @@ openclaw channels status --probe
|
||||
## 安全与运维
|
||||
|
||||
- **像对待密码一样对待令牌** — 切勿将令牌提交到 git。
|
||||
- **使用自动令牌刷新** 用于长期运行的 bot。
|
||||
- **使用用户 ID 允许列表** 进行访问控制,而不是用户名。
|
||||
- **使用自动令牌刷新** 适用于长期运行的机器人。
|
||||
- **使用用户 ID 允许列表** 而不是用户名来进行访问控制。
|
||||
- **监控日志** 以查看令牌刷新事件和连接状态。
|
||||
- **最小化令牌作用域** — 仅请求 `chat:read` 和 `chat:write`。
|
||||
- **如果卡住**:确认没有其他进程占用该会话后,重启 Gateway 网关。
|
||||
|
||||
## 限制
|
||||
|
||||
- 每条消息 **500 个字符**(按单词边界自动分块)。
|
||||
- 每条消息 **500 个字符**(会在词边界自动分块)。
|
||||
- Markdown 会在分块前被移除。
|
||||
- 没有限速(使用 Twitch 内置的速率限制)。
|
||||
- 无速率限制(使用 Twitch 内置速率限制)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [渠道概览](/zh-CN/channels) — 所有受支持的渠道
|
||||
- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控
|
||||
- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型和加固
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证与配对流程
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型与加固
|
||||
|
||||
@ -1,27 +1,26 @@
|
||||
---
|
||||
read_when:
|
||||
- 处理 WhatsApp/网页渠道行为或收件箱路由
|
||||
- 处理 WhatsApp/web 渠道行为或收件箱路由
|
||||
summary: WhatsApp 渠道支持、访问控制、投递行为和运维
|
||||
title: WhatsApp
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:37Z"
|
||||
generated_at: "2026-05-02T21:57:04Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 4ce4696b9d055695e340be5d9570316f957118d1925af577783c27443e725056
|
||||
source_hash: ffe2fce121dd1230fbcf20d55ec3855beb22c39f80b926eed41bf56183178ab2
|
||||
source_path: channels/whatsapp.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status:通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关拥有已链接的会话。
|
||||
Status:通过 WhatsApp Web(Baileys)可用于生产。Gateway 网关拥有已链接会话。
|
||||
|
||||
## 安装(按需)
|
||||
|
||||
- 新手引导(`openclaw onboard`)和 `openclaw channels add --channel whatsapp`
|
||||
会在你首次选择 WhatsApp 插件时提示安装。
|
||||
- 当插件尚未存在时,`openclaw channels login --channel whatsapp` 也会提供安装流程。
|
||||
- 开发渠道 + git checkout:默认使用本地插件路径。
|
||||
- Stable/Beta:使用 npm 包 `@openclaw/whatsapp`;当 `beta` 标签可用时,beta 渠道更新优先使用
|
||||
`@openclaw/whatsapp@beta`。
|
||||
- Dev 渠道 + git checkout:默认使用本地插件路径。
|
||||
- Stable/Beta:在当前官方发布标签上使用 npm 包 `@openclaw/whatsapp`。
|
||||
|
||||
仍可手动安装:
|
||||
|
||||
@ -29,11 +28,11 @@ Status:通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关拥
|
||||
openclaw plugins install @openclaw/whatsapp
|
||||
```
|
||||
|
||||
当你跟随 OpenClaw beta 渠道且 npmjs 显示 `beta` 领先于 `latest` 时,使用 `@openclaw/whatsapp@beta`。
|
||||
使用裸包名以跟随当前官方发布标签。仅在需要可复现安装时才固定精确版本。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Pairing" icon="link" href="/zh-CN/channels/pairing">
|
||||
未知发送者的默认私信策略是配对。
|
||||
默认私信策略会为未知发送者配对。
|
||||
</Card>
|
||||
<Card title="Channel troubleshooting" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断和修复手册。
|
||||
@ -75,7 +74,7 @@ openclaw channels login --channel whatsapp
|
||||
openclaw channels login --channel whatsapp --account work
|
||||
```
|
||||
|
||||
若要在登录前挂接现有/自定义 WhatsApp Web 认证目录:
|
||||
如需在登录前挂接现有/自定义 WhatsApp Web 认证目录:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth
|
||||
@ -105,7 +104,7 @@ openclaw pairing approve whatsapp <CODE>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
OpenClaw 建议尽可能使用单独号码运行 WhatsApp。(渠道元数据和设置流程针对这种设置进行了优化,但也支持个人号码设置。)
|
||||
OpenClaw 建议尽可能在单独号码上运行 WhatsApp。(渠道元数据和设置流程已针对这种设置优化,但也支持个人号码设置。)
|
||||
</Note>
|
||||
|
||||
## 部署模式
|
||||
@ -115,7 +114,7 @@ OpenClaw 建议尽可能使用单独号码运行 WhatsApp。(渠道元数据
|
||||
这是最清晰的运维模式:
|
||||
|
||||
- 为 OpenClaw 使用单独的 WhatsApp 身份
|
||||
- 更清晰的私信 allowlist 和路由边界
|
||||
- 更清晰的私信允许列表和路由边界
|
||||
- 降低自聊混淆的可能性
|
||||
|
||||
最小策略模式:
|
||||
@ -134,7 +133,7 @@ OpenClaw 建议尽可能使用单独号码运行 WhatsApp。(渠道元数据
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Personal-number fallback">
|
||||
新手引导支持个人号码模式,并写入适合自聊的基线:
|
||||
新手引导支持个人号码模式,并会写入适合自聊的基线:
|
||||
|
||||
- `dmPolicy: "allowlist"`
|
||||
- `allowFrom` 包含你的个人号码
|
||||
@ -154,21 +153,21 @@ OpenClaw 建议尽可能使用单独号码运行 WhatsApp。(渠道元数据
|
||||
|
||||
## 运行时模型
|
||||
|
||||
- Gateway 网关拥有 WhatsApp 套接字和重连循环。
|
||||
- 重连看门狗使用 WhatsApp Web 传输活动,而不只依赖入站应用消息量,因此安静的已链接设备会话不会仅因为最近没人发送消息而重启。如果传输帧持续到达但在看门狗窗口内没有处理任何应用消息,较长的应用静默上限仍会强制重连;对于最近活跃会话发生的临时重连,第一次恢复窗口中的应用静默检查会使用正常消息超时。
|
||||
- Baileys 套接字计时在 `web.whatsapp.*` 下显式配置:`keepAliveIntervalMs` 控制 WhatsApp Web 应用 ping,`connectTimeoutMs` 控制开启握手超时,`defaultQueryTimeoutMs` 控制 Baileys 查询超时。
|
||||
- 出站发送要求目标账号有活跃的 WhatsApp 监听器。
|
||||
- Gateway 网关拥有 WhatsApp socket 和重连循环。
|
||||
- 重连 watchdog 使用 WhatsApp Web 传输活动,而不仅是入站应用消息量,因此安静的已链接设备会话不会仅因为近期没有人发送消息就被重启。如果传输帧持续到达但 watchdog 窗口内没有处理任何应用消息,较长的应用静默上限仍会强制重连;对于最近活跃会话的临时重连,首次恢复窗口中的应用静默检查会使用正常消息超时。
|
||||
- Baileys socket 计时在 `web.whatsapp.*` 下显式配置:`keepAliveIntervalMs` 控制 WhatsApp Web 应用 ping,`connectTimeoutMs` 控制打开握手超时,`defaultQueryTimeoutMs` 控制 Baileys 查询超时。
|
||||
- 出站发送要求目标账号有活动的 WhatsApp 监听器。
|
||||
- Status 和广播聊天会被忽略(`@status`、`@broadcast`)。
|
||||
- 重连看门狗跟随 WhatsApp Web 传输活动,而不只依赖入站应用消息量:只要传输帧持续,安静的已链接设备会话就会保持在线,但传输停滞会在更晚的远端断开路径之前强制重连。
|
||||
- 重连 watchdog 遵循 WhatsApp Web 传输活动,而不仅是入站应用消息量:只要传输帧继续,安静的已链接设备会话就会保持在线,但传输停滞会在更晚的远端断开路径之前强制重连。
|
||||
- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。
|
||||
- 群组会话是隔离的(`agent:<agentId>:whatsapp:group:<jid>`)。
|
||||
- WhatsApp Channels/Newsletters 可以作为显式出站目标,并使用其原生 `@newsletter` JID。出站 newsletter 发送使用渠道会话元数据(`agent:<agentId>:whatsapp:channel:<jid>`),而不是私信会话语义。
|
||||
- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` / 小写变体)。优先使用主机级代理配置,而不是渠道专用的 WhatsApp 代理设置。
|
||||
- 启用 `messages.removeAckAfterReply` 后,OpenClaw 会在可见回复送达后清除 WhatsApp 确认回应。
|
||||
- 群组会话相互隔离(`agent:<agentId>:whatsapp:group:<jid>`)。
|
||||
- WhatsApp Channels/Newsletters 可以作为显式出站目标,使用其原生 `@newsletter` JID。出站 newsletter 发送使用渠道会话元数据(`agent:<agentId>:whatsapp:channel:<jid>`),而不是私信会话语义。
|
||||
- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` / 小写变体)。优先使用主机级代理配置,而不是特定于渠道的 WhatsApp 代理设置。
|
||||
- 启用 `messages.removeAckAfterReply` 时,OpenClaw 会在可见回复送达后清除 WhatsApp ack reaction。
|
||||
|
||||
## 插件钩子和隐私
|
||||
|
||||
WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标识符、发送者姓名和会话关联字段。因此,除非你显式选择加入,否则 WhatsApp 不会向插件广播入站 `message_received` 钩子负载:
|
||||
WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标识符、发送者姓名和会话关联字段。因此,除非你显式选择启用,否则 WhatsApp 不会向插件广播入站 `message_received` 钩子载荷:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -182,7 +181,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
}
|
||||
```
|
||||
|
||||
你可以将选择加入限定到一个账号:
|
||||
你可以将选择启用限定到一个账号:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -200,7 +199,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
}
|
||||
```
|
||||
|
||||
只应为你信任其接收 WhatsApp 入站消息内容和标识符的插件启用此项。
|
||||
仅对你信任可接收入站 WhatsApp 消息内容和标识符的插件启用此项。
|
||||
|
||||
## 访问控制和激活
|
||||
|
||||
@ -213,39 +212,39 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`allowFrom` 接受 E.164 风格的号码(内部会规范化)。
|
||||
`allowFrom` 接受 E.164 风格号码(内部会规范化)。
|
||||
|
||||
`allowFrom` 是私信发送者访问控制列表。它不会限制对 WhatsApp 群组 JID 或 `@newsletter` 渠道 JID 的显式出站发送。
|
||||
`allowFrom` 是私信发送者访问控制列表。它不会限制发往 WhatsApp 群组 JID 或 `@newsletter` 渠道 JID 的显式出站发送。
|
||||
|
||||
多账号覆盖:`channels.whatsapp.accounts.<id>.dmPolicy`(以及 `allowFrom`)优先于该账号的渠道级默认值。
|
||||
|
||||
运行时行为详情:
|
||||
运行时行为细节:
|
||||
|
||||
- 配对会持久化在渠道 allow-store 中,并与配置的 `allowFrom` 合并
|
||||
- 定时自动化和 heartbeat 收件人回退使用显式投递目标或配置的 `allowFrom`;私信配对批准不会隐式成为 cron 或 heartbeat 收件人
|
||||
- 如果未配置 allowlist,则默认允许已链接的自身号码
|
||||
- OpenClaw 从不会自动配对出站 `fromMe` 私信(你从已链接设备发送给自己的消息)
|
||||
- 配对会持久化在渠道允许存储中,并与配置的 `allowFrom` 合并
|
||||
- 定时自动化和 Heartbeat 收件人回退使用显式投递目标或配置的 `allowFrom`;私信配对批准不会隐式成为 cron 或 Heartbeat 收件人
|
||||
- 如果未配置允许列表,默认允许已链接的自身号码
|
||||
- OpenClaw 永远不会自动配对出站 `fromMe` 私信(你从已链接设备发送给自己的消息)
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Group policy + allowlists">
|
||||
群组访问有两层:
|
||||
|
||||
1. **群组成员 allowlist**(`channels.whatsapp.groups`)
|
||||
- 如果省略 `groups`,则所有群组都有资格
|
||||
- 如果存在 `groups`,则它作为群组 allowlist(允许 `"*"`)
|
||||
1. **群组成员允许列表**(`channels.whatsapp.groups`)
|
||||
- 如果省略 `groups`,则所有群组都符合条件
|
||||
- 如果存在 `groups`,它会作为群组允许列表(允许 `"*"`)
|
||||
|
||||
2. **群组发送者策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
|
||||
- `open`:绕过发送者 allowlist
|
||||
- `open`:绕过发送者允许列表
|
||||
- `allowlist`:发送者必须匹配 `groupAllowFrom`(或 `*`)
|
||||
- `disabled`:阻止所有群组入站
|
||||
|
||||
发送者 allowlist 回退:
|
||||
发送者允许列表回退:
|
||||
|
||||
- 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom`
|
||||
- 发送者 allowlist 会在提及/回复激活前评估
|
||||
- 会先评估发送者允许列表,再进行提及/回复激活
|
||||
|
||||
注意:如果完全不存在 `channels.whatsapp` 块,即使设置了 `channels.defaults.groupPolicy`,运行时群组策略回退也是 `allowlist`(并记录警告日志)。
|
||||
注意:如果完全不存在 `channels.whatsapp` 配置块,即使设置了 `channels.defaults.groupPolicy`,运行时群组策略回退也是 `allowlist`(并记录警告日志)。
|
||||
|
||||
</Tab>
|
||||
|
||||
@ -254,22 +253,22 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
|
||||
提及检测包括:
|
||||
|
||||
- 对机器人身份的显式 WhatsApp 提及
|
||||
- 对 bot 身份的显式 WhatsApp 提及
|
||||
- 配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`)
|
||||
- 授权群组消息的入站语音便条转录文本
|
||||
- 隐式回复机器人检测(回复发送者匹配机器人身份)
|
||||
- 已授权群组消息的入站语音笔记转录
|
||||
- 隐式回复 bot 检测(回复发送者匹配 bot 身份)
|
||||
|
||||
安全注意事项:
|
||||
安全说明:
|
||||
|
||||
- 引用/回复只满足提及门控;它**不会**授予发送者授权
|
||||
- 使用 `groupPolicy: "allowlist"` 时,即使非 allowlisted 发送者回复了 allowlisted 用户的消息,仍会被阻止
|
||||
- quote/reply 只满足提及门控;它**不会**授予发送者授权
|
||||
- 使用 `groupPolicy: "allowlist"` 时,即使非允许列表发送者回复了允许列表用户的消息,仍会被阻止
|
||||
|
||||
会话级激活命令:
|
||||
|
||||
- `/activation mention`
|
||||
- `/activation always`
|
||||
|
||||
`activation` 更新会话状态(不是全局配置)。它受所有者门控。
|
||||
`activation` 会更新会话状态(不是全局配置)。它受 owner 门控。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@ -279,16 +278,16 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
当已链接的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会激活:
|
||||
|
||||
- 跳过自聊回合的已读回执
|
||||
- 忽略可能会 ping 你自己的 mention-JID 自动触发行为
|
||||
- 忽略否则会 ping 你自己的 mention-JID 自动触发行为
|
||||
- 如果未设置 `messages.responsePrefix`,自聊回复默认使用 `[{identity.name}]` 或 `[openclaw]`
|
||||
|
||||
## 消息规范化和上下文
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Inbound envelope + reply context">
|
||||
入站 WhatsApp 消息会封装在共享入站信封中。
|
||||
传入的 WhatsApp 消息会包装在共享入站 envelope 中。
|
||||
|
||||
如果存在引用回复,上下文会以这种形式追加:
|
||||
如果存在 quoted reply,上下文会按以下形式追加:
|
||||
|
||||
```text
|
||||
[Replying to <sender> id:<stanzaId>]
|
||||
@ -297,12 +296,12 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
```
|
||||
|
||||
可用时也会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。
|
||||
当被引用的回复目标是可下载媒体时,OpenClaw 会通过正常入站媒体存储保存它,并将其暴露为 `MediaPath`/`MediaType`,这样智能体可以检查引用的图片,而不是只看到 `<media:image>`。
|
||||
当引用回复目标是可下载媒体时,OpenClaw 会通过正常入站媒体存储保存它,并将其公开为 `MediaPath`/`MediaType`,以便智能体可以检查被引用的图像,而不仅是看到 `<media:image>`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Media placeholders and location/contact extraction">
|
||||
纯媒体入站消息会使用如下占位符规范化:
|
||||
仅媒体的入站消息会使用如下占位符规范化:
|
||||
|
||||
- `<media:image>`
|
||||
- `<media:video>`
|
||||
@ -310,14 +309,14 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
- `<media:document>`
|
||||
- `<media:sticker>`
|
||||
|
||||
授权群组语音便条会在提及门控前转录,当正文只有 `<media:audio>` 时,在语音便条中说出机器人提及也可以触发回复。如果转录文本仍未提及机器人,该转录文本会保留在待处理群组历史中,而不是保留原始占位符。
|
||||
已授权群组语音笔记会在提及门控前转录,当正文只有 `<media:audio>` 时,在语音笔记中说出 bot 提及即可触发回复。如果转录文本仍未提及 bot,则会将转录文本保留在待处理群组历史中,而不是保留原始占位符。
|
||||
|
||||
位置正文使用简短坐标文本。位置标签/评论和联系人/vCard 详情会呈现为围栏包裹的不可信元数据,而不是内联 prompt 文本。
|
||||
位置正文使用简短坐标文本。位置标签/评论和联系人/vCard 详情会渲染为带围栏的不受信任元数据,而不是内联提示文本。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Pending group history injection">
|
||||
对于群组,未处理消息可以被缓冲,并在机器人最终被触发时作为上下文注入。
|
||||
对于群组,未处理消息可以被缓冲,并在 bot 最终触发时作为上下文注入。
|
||||
|
||||
- 默认限制:`50`
|
||||
- 配置:`channels.whatsapp.historyLimit`
|
||||
@ -346,7 +345,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
}
|
||||
```
|
||||
|
||||
按账号覆盖:
|
||||
单账号覆盖:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -362,30 +361,30 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
}
|
||||
```
|
||||
|
||||
即使全局启用,发给自己的聊天轮次也会跳过已读回执。
|
||||
即使全局启用,Self-chat 回合也会跳过已读回执。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 送达、分块与媒体
|
||||
## 投递、分块和媒体
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="文本分块">
|
||||
- 默认分块限制:`channels.whatsapp.textChunkLimit = 4000`
|
||||
- `channels.whatsapp.chunkMode = "length" | "newline"`
|
||||
- `newline` 模式优先使用段落边界(空行),然后回退到按长度安全分块
|
||||
- `newline` 模式优先使用段落边界(空行),然后回退到长度安全的分块
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="出站媒体行为">
|
||||
- 支持图片、视频、音频(PTT 语音便签)和文档载荷
|
||||
- 音频媒体会通过 Baileys `audio` 载荷并带上 `ptt: true` 发送,因此 WhatsApp 客户端会将其渲染为按住说话的语音便签
|
||||
- 回复载荷会保留 `audioAsVoice`;即使提供商返回 MP3 或 WebM,WhatsApp 的 TTS 语音便签输出仍会保持在这个 PTT 路径上
|
||||
- 原生 Ogg/Opus 音频会以 `audio/ogg; codecs=opus` 发送,以兼容语音便签
|
||||
- 非 Ogg 音频(包括 Microsoft Edge TTS 的 MP3/WebM 输出)会在 PTT 送达前用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus
|
||||
- `/tts latest` 会把最新的助手回复作为一个语音便签发送,并禁止对同一回复重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS
|
||||
- 支持图片、视频、音频(PTT 语音备注)和文档负载
|
||||
- 音频媒体会通过 Baileys `audio` 负载发送,并带有 `ptt: true`,因此 WhatsApp 客户端会将其渲染为按住说话语音备注
|
||||
- 回复负载会保留 `audioAsVoice`;即使提供商返回 MP3 或 WebM,WhatsApp 的 TTS 语音备注输出仍会使用这条 PTT 路径
|
||||
- 原生 Ogg/Opus 音频会作为 `audio/ogg; codecs=opus` 发送,以兼容语音备注
|
||||
- 非 Ogg 音频,包括 Microsoft Edge TTS MP3/WebM 输出,会先用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus,再进行 PTT 投递
|
||||
- `/tts latest` 会将最新的助手回复作为一条语音备注发送,并抑制同一条回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS
|
||||
- 通过视频发送中的 `gifPlayback: true` 支持动画 GIF 播放
|
||||
- 发送多媒体回复载荷时,说明文字会应用到第一个媒体项;但 PTT 语音便签会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端不会稳定渲染语音便签说明文字
|
||||
- 发送多媒体回复负载时,字幕会应用到第一个媒体项;但 PTT 语音备注会先发送音频,并单独发送可见文本,因为 WhatsApp 客户端不会稳定渲染语音备注字幕
|
||||
- 媒体来源可以是 HTTP(S)、`file://` 或本地路径
|
||||
|
||||
</Accordion>
|
||||
@ -393,25 +392,25 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标
|
||||
<Accordion title="媒体大小限制和回退行为">
|
||||
- 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 按账号覆盖使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
|
||||
- 图片会自动优化(调整大小/质量扫描)以符合限制
|
||||
- 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃响应
|
||||
- 每账号覆盖使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
|
||||
- 图片会自动优化(调整尺寸/质量扫描)以符合限制
|
||||
- 媒体发送失败时,第一项回退会发送文本警告,而不是静默丢弃响应
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 回复引用
|
||||
|
||||
WhatsApp 支持原生回复引用,出站回复会以可见方式引用入站消息。用 `channels.whatsapp.replyToMode` 控制它。
|
||||
WhatsApp 支持原生回复引用,其中出站回复会明显引用入站消息。使用 `channels.whatsapp.replyToMode` 控制它。
|
||||
|
||||
| 值 | 行为 |
|
||||
| ----------- | ------------------------------------------------------------------- |
|
||||
| `"off"` | 从不引用;作为普通消息发送 |
|
||||
| `"first"` | 只引用第一个出站回复分块 |
|
||||
| `"all"` | 引用每个出站回复分块 |
|
||||
| `"batched"` | 引用排队的批量回复,同时让即时回复不带引用 |
|
||||
| 值 | 行为 |
|
||||
| ----------- | --------------------------------------------------------------------- |
|
||||
| `"off"` | 从不引用;作为普通消息发送 |
|
||||
| `"first"` | 只引用第一个出站回复分块 |
|
||||
| `"all"` | 引用每个出站回复分块 |
|
||||
| `"batched"` | 引用排队的批量回复,同时让即时回复不带引用 |
|
||||
|
||||
默认值为 `"off"`。按账号覆盖使用 `channels.whatsapp.accounts.<id>.replyToMode`。
|
||||
默认值为 `"off"`。每账号覆盖使用 `channels.whatsapp.accounts.<id>.replyToMode`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -423,20 +422,20 @@ WhatsApp 支持原生回复引用,出站回复会以可见方式引用入站
|
||||
}
|
||||
```
|
||||
|
||||
## Reaction 级别
|
||||
## 反应级别
|
||||
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji reaction 的广度:
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用表情反应的范围:
|
||||
|
||||
| 级别 | Ack reaction | 智能体发起的 reaction | 描述 |
|
||||
| ------------- | ------------ | --------------------- | -------------------------------------------------- |
|
||||
| `"off"` | 否 | 否 | 完全没有 reaction |
|
||||
| `"ack"` | 是 | 否 | 仅 Ack reaction(回复前回执) |
|
||||
| `"minimal"` | 是 | 是(保守) | Ack + 带保守指引的智能体 reaction |
|
||||
| `"extensive"` | 是 | 是(鼓励) | Ack + 带鼓励指引的智能体 reaction |
|
||||
| 级别 | Ack 反应 | 智能体发起的反应 | 描述 |
|
||||
| ------------- | -------- | ------------------------- | ------------------------------------------------ |
|
||||
| `"off"` | 否 | 否 | 完全无反应 |
|
||||
| `"ack"` | 是 | 否 | 仅 Ack 反应(回复前回执) |
|
||||
| `"minimal"` | 是 | 是(保守) | Ack + 智能体反应,带保守指导 |
|
||||
| `"extensive"` | 是 | 是(鼓励) | Ack + 智能体反应,带鼓励指导 |
|
||||
|
||||
默认值:`"minimal"`。
|
||||
|
||||
按账号覆盖使用 `channels.whatsapp.accounts.<id>.reactionLevel`。
|
||||
每账号覆盖使用 `channels.whatsapp.accounts.<id>.reactionLevel`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -448,10 +447,10 @@ WhatsApp 支持原生回复引用,出站回复会以可见方式引用入站
|
||||
}
|
||||
```
|
||||
|
||||
## 确认 reaction
|
||||
## 确认反应
|
||||
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在入站收到时立即发送 ack reaction。
|
||||
Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时立即发送 ack 反应。
|
||||
Ack 反应受 `reactionLevel` 限制,当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -469,9 +468,9 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
|
||||
行为说明:
|
||||
|
||||
- 在入站被接受后立即发送(回复前)
|
||||
- 失败会被记录,但不会阻止正常回复送达
|
||||
- 组模式 `mentions` 会在由提及触发的轮次中发送 reaction;组激活 `always` 会作为此检查的旁路
|
||||
- 入站消息被接受后立即发送(回复前)
|
||||
- 失败会被记录,但不会阻止正常回复投递
|
||||
- 群组模式 `mentions` 会对由提及触发的回合作出反应;群组激活 `always` 会作为此检查的旁路
|
||||
- WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不使用旧版 `messages.ackReaction`)
|
||||
|
||||
## 多账号和凭证
|
||||
@ -479,7 +478,7 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
<AccordionGroup>
|
||||
<Accordion title="账号选择和默认值">
|
||||
- 账号 ID 来自 `channels.whatsapp.accounts`
|
||||
- 默认账号选择:如果存在 `default` 则使用它,否则使用第一个已配置的账号 ID(排序后)
|
||||
- 默认账号选择:如果存在则使用 `default`,否则使用第一个已配置的账号 ID(排序后)
|
||||
- 账号 ID 会在内部规范化以便查找
|
||||
|
||||
</Accordion>
|
||||
@ -494,26 +493,26 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
<Accordion title="登出行为">
|
||||
`openclaw channels logout --channel whatsapp [--account <id>]` 会清除该账号的 WhatsApp 认证状态。
|
||||
|
||||
当 Gateway 网关可达时,登出会先停止所选账号的实时 WhatsApp 监听器,这样已链接会话就不会继续接收消息直到下次重启。`openclaw channels remove --channel whatsapp` 也会在禁用或删除账号配置前停止实时监听器。
|
||||
当 Gateway 网关可达时,登出会先停止所选账号的实时 WhatsApp 监听器,以免已链接会话在下次重启前继续接收消息。`openclaw channels remove --channel whatsapp` 也会在禁用或删除账号配置前停止实时监听器。
|
||||
|
||||
在旧版认证目录中,`oauth.json` 会被保留,而 Baileys 认证文件会被移除。
|
||||
在旧版认证目录中,`oauth.json` 会保留,而 Baileys 认证文件会被移除。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 工具、操作和配置写入
|
||||
|
||||
- 智能体工具支持包括 WhatsApp reaction 操作(`react`)。
|
||||
- 智能体工具支持包括 WhatsApp 反应操作(`react`)。
|
||||
- 操作门控:
|
||||
- `channels.whatsapp.actions.reactions`
|
||||
- `channels.whatsapp.actions.polls`
|
||||
- 渠道发起的配置写入默认启用(可通过 `channels.whatsapp.configWrites=false` 禁用)。
|
||||
- 默认启用由渠道发起的配置写入(通过 `channels.whatsapp.configWrites=false` 禁用)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="未链接(需要 QR)">
|
||||
症状:渠道状态报告未链接。
|
||||
症状:渠道 Status 报告未链接。
|
||||
|
||||
修复:
|
||||
|
||||
@ -524,12 +523,12 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="已链接但断开 / 重连循环">
|
||||
<Accordion title="已链接但已断开 / 重连循环">
|
||||
症状:已链接账号反复断开或尝试重连。
|
||||
|
||||
安静账号可以在正常消息超时后保持连接;当 WhatsApp Web 传输活动停止、套接字关闭,或应用级活动在更长的安全窗口内持续静默时,watchdog 会重启。
|
||||
静默账号可以在正常消息超时后仍保持连接;当 WhatsApp Web 传输活动停止、套接字关闭,或应用级活动静默超过更长的安全窗口时,watchdog 会重启。
|
||||
|
||||
如果日志显示重复的 `status=408 Request Time-out Connection was lost`,请调整 `web.whatsapp` 下的 Baileys 套接字时序。先将 `keepAliveIntervalMs` 缩短到低于你的网络空闲超时,并在较慢或容易丢包的链路上增加 `connectTimeoutMs`:
|
||||
如果日志显示重复的 `status=408 Request Time-out Connection was lost`,请调整 `web.whatsapp` 下的 Baileys 套接字时序。先将 `keepAliveIntervalMs` 缩短到低于你的网络空闲超时时间,并在慢速或丢包链路上增大 `connectTimeoutMs`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -550,37 +549,37 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
openclaw logs --follow
|
||||
```
|
||||
|
||||
如果 `~/.openclaw/logs/whatsapp-health.log` 显示 `Gateway inactive`,但 `openclaw gateway status` 和 `openclaw channels status --probe` 显示 Gateway 网关和 WhatsApp 都健康,请运行 `openclaw doctor`。在 Linux 上,Doctor 会警告仍在调用 `~/.openclaw/bin/ensure-whatsapp.sh` 的旧版 crontab 条目;请用 `crontab -e` 移除这些过期条目,因为 cron 可能缺少 systemd 用户总线环境,并导致该旧脚本误报 Gateway 网关健康状态。
|
||||
如果 `~/.openclaw/logs/whatsapp-health.log` 显示 `Gateway inactive`,但 `openclaw gateway status` 和 `openclaw channels status --probe` 显示 Gateway 网关和 WhatsApp 都健康,请运行 `openclaw doctor`。在 Linux 上,Doctor 会警告仍调用 `~/.openclaw/bin/ensure-whatsapp.sh` 的旧版 crontab 条目;请使用 `crontab -e` 移除这些过时条目,因为 cron 可能缺少 systemd 用户总线环境,并导致旧脚本误报 Gateway 网关健康状态。
|
||||
|
||||
如有需要,请用 `channels login` 重新链接。
|
||||
如有需要,请使用 `channels login` 重新链接。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="代理后面的 QR 登录超时">
|
||||
<Accordion title="代理后方的 QR 登录超时">
|
||||
症状:`openclaw channels login --channel whatsapp` 在显示可用 QR 码之前失败,并出现 `status=408 Request Time-out` 或 TLS 套接字断开。
|
||||
|
||||
WhatsApp Web 登录使用 Gateway 网关主机的标准代理环境(`HTTPS_PROXY`、`HTTP_PROXY`、小写变体和 `NO_PROXY`)。确认 Gateway 网关进程继承了代理环境变量,并且 `NO_PROXY` 没有匹配 `mmg.whatsapp.net`。
|
||||
WhatsApp Web 登录使用 Gateway 网关主机的标准代理环境(`HTTPS_PROXY`、`HTTP_PROXY`、小写变体以及 `NO_PROXY`)。请验证 Gateway 网关进程继承了代理环境变量,并且 `NO_PROXY` 未匹配 `mmg.whatsapp.net`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="发送时没有活动监听器">
|
||||
当目标账号不存在活动的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
当目标账号没有活动的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
|
||||
请确认 Gateway 网关正在运行,并且账号已链接。
|
||||
确保 Gateway 网关正在运行且账号已链接。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回复出现在转录中,但没有出现在 WhatsApp 中">
|
||||
转录行记录的是智能体生成的内容。WhatsApp 送达会单独检查:只有在 Baileys 为至少一个可见文本或媒体发送返回出站消息 ID 后,OpenClaw 才会将自动回复视为已发送。
|
||||
<Accordion title="回复出现在转录中,但不在 WhatsApp 中">
|
||||
转录行记录智能体生成的内容。WhatsApp 投递会单独检查:OpenClaw 只有在 Baileys 为至少一次可见文本或媒体发送返回出站消息 ID 后,才会把自动回复视为已发送。
|
||||
|
||||
Ack reaction 是独立的回复前回执。reaction 成功并不能证明后续文本或媒体回复已被 WhatsApp 接受。
|
||||
Ack 反应是独立的回复前回执。反应成功并不能证明后续文本或媒体回复已被 WhatsApp 接受。
|
||||
|
||||
检查 Gateway 网关日志中是否有 `auto-reply delivery failed` 或 `auto-reply was not accepted by WhatsApp provider`。
|
||||
检查 Gateway 网关日志中的 `auto-reply delivery failed` 或 `auto-reply was not accepted by WhatsApp provider`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="组消息被意外忽略">
|
||||
按此顺序检查:
|
||||
<Accordion title="群组消息被意外忽略">
|
||||
按以下顺序检查:
|
||||
|
||||
- `groupPolicy`
|
||||
- `groupAllowFrom` / `allowFrom`
|
||||
@ -591,40 +590,40 @@ Ack reaction 受 `reactionLevel` 门控,当 `reactionLevel` 为 `"off"` 时会
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Bun 运行时警告">
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp/Telegram Gateway 网关操作。
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp/Telegram Gateway 网关运行。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 系统提示词
|
||||
## 系统提示
|
||||
|
||||
WhatsApp 支持通过 `groups` 和 `direct` 映射为群组和直接聊天设置 Telegram 风格的系统提示词。
|
||||
WhatsApp 支持通过 `groups` 和 `direct` 映射为群组和直接聊天配置 Telegram 风格的系统提示。
|
||||
|
||||
组消息的解析层级:
|
||||
群组消息的解析层级:
|
||||
|
||||
会先确定有效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根 `groups` 映射(不做深度合并)。随后,提示词查找会在生成的单个映射上运行:
|
||||
首先确定有效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根 `groups` 映射(不做深度合并)。然后在生成的单一映射上执行提示查找:
|
||||
|
||||
1. **组专属系统提示词**(`groups["<groupId>"].systemPrompt`):当映射中存在对应的组条目,**并且**其 `systemPrompt` 键已定义时使用。如果 `systemPrompt` 是空字符串(`""`),通配符会被抑制,并且不会应用系统提示词。
|
||||
2. **组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在对应的组条目,或该条目存在但未定义 `systemPrompt` 键时使用。
|
||||
1. **群组专用系统提示**(`groups["<groupId>"].systemPrompt`):当映射中存在特定群组条目,**且**定义了其 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,且不应用任何系统提示。
|
||||
2. **群组通配系统提示**(`groups["*"].systemPrompt`):当特定群组条目完全不存在于映射中,或存在但未定义 `systemPrompt` 键时使用。
|
||||
|
||||
直接消息的解析层级:
|
||||
|
||||
会先确定有效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根 `direct` 映射(不做深度合并)。随后,提示词查找会在生成的单个映射上运行:
|
||||
首先确定有效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根 `direct` 映射(不做深度合并)。然后在生成的单一映射上执行提示查找:
|
||||
|
||||
1. **直接聊天专属系统提示词**(`direct["<peerId>"].systemPrompt`):当映射中存在对应的对等方条目,**并且**其 `systemPrompt` 键已定义时使用。如果 `systemPrompt` 是空字符串(`""`),通配符会被抑制,并且不会应用系统提示词。
|
||||
2. **直接聊天通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在对应的对等方条目,或该条目存在但未定义 `systemPrompt` 键时使用。
|
||||
1. **直接聊天专用系统提示**(`direct["<peerId>"].systemPrompt`):当映射中存在特定对等方条目,**且**定义了其 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,且不应用任何系统提示。
|
||||
2. **直接聊天通配系统提示**(`direct["*"].systemPrompt`):当特定对等方条目完全不存在于映射中,或存在但未定义 `systemPrompt` 键时使用。
|
||||
|
||||
<Note>
|
||||
`dms` 仍然是轻量级的按私信历史覆盖桶(`dms.<id>.historyLimit`)。提示词覆盖位于 `direct` 下。
|
||||
`dms` 仍是轻量级的每私信历史覆盖桶(`dms.<id>.historyLimit`)。提示覆盖位于 `direct` 下。
|
||||
</Note>
|
||||
|
||||
**与 Telegram 多账号行为的区别:**在 Telegram 中,多账号设置会有意对所有账号抑制根级 `groups`,即使某些账号没有定义自己的 `groups`,也是如此,以防机器人接收它不属于的群组消息。WhatsApp 不应用这个防护:对于没有定义账号级覆盖的账号,无论配置了多少个账号,根级 `groups` 和根级 `direct` 始终会被继承。在多账号 WhatsApp 设置中,如果你需要按账号设置群组或私信提示词,请在每个账号下显式定义完整映射,而不是依赖根级默认值。
|
||||
**与 Telegram 多账号行为的区别:** 在 Telegram 中,多账号设置下会有意对所有账号抑制根级 `groups`,即使账号本身没有定义任何 `groups` 也是如此,以防止 bot 接收它不属于的群组消息。WhatsApp 不应用这个保护:对于没有定义账号级覆盖的账号,无论配置了多少个账号,都会始终继承根级 `groups` 和根级 `direct`。在多账号 WhatsApp 设置中,如果你想要按账号设置群组或直聊提示词,请在每个账号下显式定义完整映射,而不是依赖根级默认值。
|
||||
|
||||
重要行为:
|
||||
|
||||
- `channels.whatsapp.groups` 既是按群组配置映射,也是聊天级群组允许列表。在根级或账号作用域中,`groups["*"]` 表示该作用域“允许所有群组进入”。
|
||||
- 只有当你已经希望该作用域允许所有群组进入时,才添加通配符群组 `systemPrompt`。如果你仍然只希望一组固定的群组 ID 符合条件,请不要使用 `groups["*"]` 作为提示词默认值。改为在每个显式列入允许列表的群组条目上重复该提示词。
|
||||
- 群组准入和发送者授权是两个独立检查。`groups["*"]` 会扩大可进入群组处理的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 分别控制。
|
||||
- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 只会在私信已通过 `dmPolicy` 加 `allowFrom` 或配对存储规则准入后,提供默认的私信聊天配置。
|
||||
- `channels.whatsapp.groups` 既是按群组配置的映射,也是聊天级群组允许列表。在根级或账号作用域中,`groups["*"]` 表示该作用域“允许所有群组进入”。
|
||||
- 只有在你已经希望该作用域允许所有群组进入时,才添加通配群组 `systemPrompt`。如果你仍然只希望固定一组群组 ID 有资格进入,请不要使用 `groups["*"]` 作为提示词默认值。请改为在每个显式允许的群组条目上重复该提示词。
|
||||
- 群组准入和发送者授权是两个独立检查。`groups["*"]` 会扩大可以进入群组处理的群组集合,但它本身并不会授权这些群组中的每个发送者。发送者访问权限仍然由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。
|
||||
- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 只会在某个私信已经通过 `dmPolicy` 加 `allowFrom` 或配对存储规则准入后,提供默认的直聊配置。
|
||||
|
||||
示例:
|
||||
|
||||
@ -672,12 +671,12 @@ WhatsApp 支持通过 `groups` 和 `direct` 映射为群组和直接聊天设置
|
||||
|
||||
- [配置参考 - WhatsApp](/zh-CN/gateway/config-channels#whatsapp)
|
||||
|
||||
高信号 WhatsApp 字段:
|
||||
高价值 WhatsApp 字段:
|
||||
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`
|
||||
- 访问:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`
|
||||
- 投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`sendReadReceipts`、`ackReaction`、`reactionLevel`
|
||||
- 多账号:`accounts.<id>.enabled`、`accounts.<id>.authDir`、账号级覆盖
|
||||
- 运维:`configWrites`、`debounceMs`、`web.enabled`、`web.heartbeatSeconds`、`web.reconnect.*`、`web.whatsapp.*`
|
||||
- 操作:`configWrites`、`debounceMs`、`web.enabled`、`web.heartbeatSeconds`、`web.reconnect.*`、`web.whatsapp.*`
|
||||
- 会话行为:`session.dmScope`、`historyLimit`、`dmHistoryLimit`、`dms.<id>.historyLimit`
|
||||
- 提示词:`groups.<id>.systemPrompt`、`groups["*"].systemPrompt`、`direct.<id>.systemPrompt`、`direct["*"].systemPrompt`
|
||||
|
||||
|
||||
@ -1,42 +1,40 @@
|
||||
---
|
||||
read_when:
|
||||
- 开发 Zalo 功能或网络钩子
|
||||
- 处理 Zalo 功能或网络钩子
|
||||
summary: Zalo 机器人支持状态、能力和配置
|
||||
title: Zalo
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:04:42Z"
|
||||
generated_at: "2026-05-02T21:57:06Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 65c9bdb0994228a6916e52c35fa6ea8d09b9b686bb9dac1c74cb38b3e6db1e48
|
||||
source_hash: 6226af1217e1e8b03b485df99f6375872b487f7040c091f2bb2d85e18dec75d0
|
||||
source_path: channels/zalo.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status:实验性。支持私信。下面的 [能力](#capabilities) 部分反映当前 Marketplace 机器人的行为。
|
||||
Status:实验性。支持私信。下面的[能力](#capabilities)章节反映当前 Marketplace 机器人行为。
|
||||
|
||||
## 内置插件
|
||||
|
||||
Zalo 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包
|
||||
构建不需要单独安装。
|
||||
Zalo 在当前 OpenClaw 版本中作为内置插件发布,因此正常的打包构建不需要单独安装。
|
||||
|
||||
如果你使用的是较旧构建,或排除了 Zalo 的自定义安装,请直接安装
|
||||
npm 包:
|
||||
如果你使用的是旧版构建,或排除了 Zalo 的自定义安装,请直接安装 npm 包:
|
||||
|
||||
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalo`
|
||||
- Beta 渠道:`openclaw plugins install @openclaw/zalo@beta`
|
||||
- 固定版本:`openclaw plugins install @openclaw/zalo@2026.5.2`
|
||||
- 或从源码检出安装:`openclaw plugins install ./path/to/local/zalo-plugin`
|
||||
- 详情:[插件](/zh-CN/tools/plugin)
|
||||
|
||||
## 快速设置(初学者)
|
||||
|
||||
1. 确保 Zalo 插件可用。
|
||||
- 当前打包的 OpenClaw 版本已内置它。
|
||||
- 较旧/自定义安装可以用上面的命令手动添加它。
|
||||
- 当前打包的 OpenClaw 版本已经内置它。
|
||||
- 旧版/自定义安装可以使用上面的命令手动添加它。
|
||||
2. 设置令牌:
|
||||
- Env:`ZALO_BOT_TOKEN=...`
|
||||
- 环境变量:`ZALO_BOT_TOKEN=...`
|
||||
- 或配置:`channels.zalo.accounts.default.botToken: "..."`。
|
||||
3. 重启 Gateway 网关(或完成设置)。
|
||||
4. 私信访问默认通过配对;首次联系时批准配对码。
|
||||
4. 私信访问默认使用配对;首次联系时批准配对码。
|
||||
|
||||
最小配置:
|
||||
|
||||
@ -58,26 +56,26 @@ npm 包:
|
||||
|
||||
## 它是什么
|
||||
|
||||
Zalo 是一款面向越南的消息应用;它的 Bot API 允许 Gateway 网关为一对一对话运行机器人。
|
||||
当你希望确定性地路由回 Zalo 时,它很适合用于支持或通知。
|
||||
Zalo 是一款面向越南的消息应用;它的 Bot API 让 Gateway 网关可以运行用于一对一会话的机器人。
|
||||
当你希望将支持或通知确定性路由回 Zalo 时,它很适合。
|
||||
|
||||
本页反映当前 OpenClaw 对 **Zalo Bot Creator / Marketplace 机器人**的行为。
|
||||
**Zalo Official Account (OA) 机器人**是 Zalo 的另一个产品界面,行为可能不同。
|
||||
本页反映当前 OpenClaw 对 **Zalo Bot Creator / Marketplace bots** 的行为。
|
||||
**Zalo Official Account (OA) bots** 是不同的 Zalo 产品界面,行为可能不同。
|
||||
|
||||
- 由 Gateway 网关拥有的 Zalo Bot API 渠道。
|
||||
- 确定性路由:回复会回到 Zalo;模型永远不会选择渠道。
|
||||
- 确定性路由:回复会返回 Zalo;模型永远不会选择渠道。
|
||||
- 私信共享智能体的主会话。
|
||||
- 下面的 [能力](#capabilities) 部分展示当前 Marketplace 机器人的支持情况。
|
||||
- 下面的[能力](#capabilities)章节展示当前 Marketplace 机器人支持情况。
|
||||
|
||||
## 设置(快速路径)
|
||||
|
||||
### 1) 创建机器人令牌(Zalo Bot Platform)
|
||||
### 1. 创建机器人令牌(Zalo Bot Platform)
|
||||
|
||||
1. 前往 [https://bot.zaloplatforms.com](https://bot.zaloplatforms.com) 并登录。
|
||||
2. 创建新机器人并配置它的设置。
|
||||
3. 复制完整机器人令牌(通常是 `numeric_id:secret`)。对于 Marketplace 机器人,可用的运行时令牌可能会在创建后显示在机器人的欢迎消息中。
|
||||
2. 创建新机器人并配置其设置。
|
||||
3. 复制完整机器人令牌(通常是 `numeric_id:secret`)。对于 Marketplace 机器人,可用的运行时令牌可能会在创建后的机器人欢迎消息中出现。
|
||||
|
||||
### 2) 配置令牌(环境变量或配置)
|
||||
### 2. 配置令牌(环境变量或配置)
|
||||
|
||||
示例:
|
||||
|
||||
@ -97,105 +95,105 @@ Zalo 是一款面向越南的消息应用;它的 Bot API 允许 Gateway 网关
|
||||
}
|
||||
```
|
||||
|
||||
如果你以后迁移到支持群组的 Zalo 机器人界面,可以显式添加群组特定配置,例如 `groupPolicy` 和 `groupAllowFrom`。关于当前 Marketplace 机器人的行为,请参阅 [能力](#capabilities)。
|
||||
如果你之后迁移到支持群组的 Zalo 机器人界面,可以显式添加群组专用配置,例如 `groupPolicy` 和 `groupAllowFrom`。对于当前 Marketplace 机器人行为,请参阅[能力](#capabilities)。
|
||||
|
||||
环境变量选项:`ZALO_BOT_TOKEN=...`(仅适用于默认账号)。
|
||||
|
||||
多账号支持:使用 `channels.zalo.accounts`,并为每个账号配置令牌和可选的 `name`。
|
||||
|
||||
3. 重启 Gateway 网关。解析到令牌(环境变量或配置)后,Zalo 会启动。
|
||||
3. 重启 Gateway 网关。当解析到令牌(环境变量或配置)时,Zalo 会启动。
|
||||
4. 私信访问默认使用配对。机器人首次被联系时批准代码。
|
||||
|
||||
## 工作方式(行为)
|
||||
|
||||
- 入站消息会被规范化为带有媒体占位符的共享渠道信封。
|
||||
- 入站消息会被标准化为带有媒体占位符的共享渠道信封。
|
||||
- 回复始终路由回同一个 Zalo 聊天。
|
||||
- 默认使用长轮询;也可以通过 `channels.zalo.webhookUrl` 使用 Webhook 模式。
|
||||
- 默认使用长轮询;可通过 `channels.zalo.webhookUrl` 使用 webhook 模式。
|
||||
|
||||
## 限制
|
||||
|
||||
- 出站文本会被分块为 2000 个字符(Zalo API 限制)。
|
||||
- 出站文本会按 2000 个字符分块(Zalo API 限制)。
|
||||
- 媒体下载/上传受 `channels.zalo.mediaMaxMb` 限制(默认 5)。
|
||||
- 由于 2000 字符限制会降低流式传输的实用性,默认阻止流式传输。
|
||||
- 由于 2000 字符限制会降低流式传输的实用性,默认会阻止流式传输。
|
||||
|
||||
## 访问控制(私信)
|
||||
|
||||
### 私信访问
|
||||
|
||||
- 默认:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到配对码;批准前消息会被忽略(代码 1 小时后过期)。
|
||||
- 默认:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到配对码;在批准前消息会被忽略(代码 1 小时后过期)。
|
||||
- 通过以下方式批准:
|
||||
- `openclaw pairing list zalo`
|
||||
- `openclaw pairing approve zalo <CODE>`
|
||||
- 配对是默认令牌交换方式。详情:[配对](/zh-CN/channels/pairing)
|
||||
- `channels.zalo.allowFrom` 接受数字用户 ID(没有可用的用户名查找)。
|
||||
- 配对是默认令牌交换。详情:[配对](/zh-CN/channels/pairing)
|
||||
- `channels.zalo.allowFrom` 接受数字用户 ID(无可用的用户名查找)。
|
||||
|
||||
## 访问控制(群组)
|
||||
|
||||
对于 **Zalo Bot Creator / Marketplace 机器人**,群组支持在实践中不可用,因为机器人完全无法被添加到群组。
|
||||
对于 **Zalo Bot Creator / Marketplace bots**,群组支持在实践中不可用,因为机器人根本无法被加入群组。
|
||||
|
||||
这意味着下面的群组相关配置键存在于架构中,但 Marketplace 机器人无法使用:
|
||||
这意味着下面这些群组相关配置键存在于 schema 中,但无法用于 Marketplace 机器人:
|
||||
|
||||
- `channels.zalo.groupPolicy` 控制群组入站处理:`open | allowlist | disabled`。
|
||||
- `channels.zalo.groupAllowFrom` 限制哪些发送者 ID 可以在群组中触发机器人。
|
||||
- 如果未设置 `groupAllowFrom`,Zalo 会回退到 `allowFrom` 进行发送者检查。
|
||||
- 运行时注意事项:如果 `channels.zalo` 完全缺失,运行时仍会为了安全回退到 `groupPolicy="allowlist"`。
|
||||
- 运行时注意事项:如果完全缺少 `channels.zalo`,运行时仍会为安全起见回退到 `groupPolicy="allowlist"`。
|
||||
|
||||
群组策略值(当你的机器人界面支持群组访问时)如下:
|
||||
|
||||
- `groupPolicy: "disabled"` — 阻止所有群组消息。
|
||||
- `groupPolicy: "open"` — 允许任何群组成员(需要提及触发)。
|
||||
- `groupPolicy: "allowlist"` — 默认失败关闭;只接受允许的发送者。
|
||||
- `groupPolicy: "open"` — 允许任何群组成员(受提及门控限制)。
|
||||
- `groupPolicy: "allowlist"` — 默认失败关闭;仅接受允许的发送者。
|
||||
|
||||
如果你使用的是不同的 Zalo 机器人产品界面,并且已验证群组行为可用,请单独记录该行为,而不是假定它与 Marketplace 机器人流程一致。
|
||||
如果你使用的是不同的 Zalo 机器人产品界面,并且已经验证群组行为可用,请单独记录该行为,而不是假设它与 Marketplace 机器人流程一致。
|
||||
|
||||
## 长轮询与 Webhook
|
||||
## 长轮询与 webhook
|
||||
|
||||
- 默认:长轮询(不需要公开 URL)。
|
||||
- 默认:长轮询(不需要公共 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 发送事件时会带上 `X-Bot-Api-Secret-Token` 标头用于验证。
|
||||
- Gateway 网关 HTTP 在 `channels.zalo.webhookPath` 处理 webhook 请求(默认使用 webhook URL 路径)。
|
||||
- 请求必须使用 `Content-Type: application/json`(或 `+json` 媒体类型)。
|
||||
- 重复事件(`event_name + message_id`)会在短暂重放窗口内被忽略。
|
||||
- 突发流量会按路径/来源限速,并可能返回 HTTP 429。
|
||||
- 重复事件(`event_name + message_id`)会在较短的重放窗口内被忽略。
|
||||
- 突发流量会按路径/来源进行速率限制,并可能返回 HTTP 429。
|
||||
|
||||
**注意:**根据 Zalo API 文档,getUpdates(轮询)和 Webhook 每个机器人互斥。
|
||||
**注意:** 根据 Zalo API 文档,getUpdates(轮询)和 webhook 每个 Zalo API 互斥。
|
||||
|
||||
## 支持的消息类型
|
||||
|
||||
如需快速查看支持情况,请参阅 [能力](#capabilities)。下面的说明会在行为需要额外上下文时补充细节。
|
||||
如需快速支持情况快照,请参阅[能力](#capabilities)。以下注释会在行为需要额外上下文时补充细节。
|
||||
|
||||
- **文本消息**:完全支持,并按 2000 字符分块。
|
||||
- **文本中的纯 URL**:像普通文本输入一样处理。
|
||||
- **链接预览 / 富链接卡片**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态;它们无法可靠触发回复。
|
||||
- **图片消息**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态;入站图片处理不可靠(显示输入指示器但没有最终回复)。
|
||||
- **贴纸**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态。
|
||||
- **语音便笺 / 音频文件 / 视频 / 通用文件附件**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态。
|
||||
- **不支持的类型**:会记录日志(例如来自受保护用户的消息)。
|
||||
- **文本消息**:完全支持,带 2000 字符分块。
|
||||
- **文本中的普通 URL**:行为与普通文本输入相同。
|
||||
- **链接预览/富链接卡片**:请参阅[能力](#capabilities)中的 Marketplace 机器人 Status;它们无法可靠触发回复。
|
||||
- **图片消息**:请参阅[能力](#capabilities)中的 Marketplace 机器人 Status;入站图片处理不可靠(显示输入指示器但没有最终回复)。
|
||||
- **贴纸**:请参阅[能力](#capabilities)中的 Marketplace 机器人 Status。
|
||||
- **语音备注/音频文件/视频/通用文件附件**:请参阅[能力](#capabilities)中的 Marketplace 机器人 Status。
|
||||
- **不支持的类型**:会被记录(例如,来自受保护用户的消息)。
|
||||
|
||||
## 能力
|
||||
|
||||
此表总结当前 **Zalo Bot Creator / Marketplace 机器人**在 OpenClaw 中的行为。
|
||||
此表总结 OpenClaw 中当前 **Zalo Bot Creator / Marketplace bot** 行为。
|
||||
|
||||
| 功能 | Status |
|
||||
| 功能 | Status |
|
||||
| --------------------------- | --------------------------------------- |
|
||||
| 直接消息 | ✅ 支持 |
|
||||
| 群组 | ❌ Marketplace 机器人不可用 |
|
||||
| 媒体(入站图片) | ⚠️ 有限 / 请在你的环境中验证 |
|
||||
| 媒体(出站图片) | ⚠️ 尚未为 Marketplace 机器人重新测试 |
|
||||
| 文本中的纯 URL | ✅ 支持 |
|
||||
| 链接预览 | ⚠️ 对 Marketplace 机器人不可靠 |
|
||||
| 反应 | ❌ 不支持 |
|
||||
| 贴纸 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 语音便笺 / 音频 / 视频 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 文件附件 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 线程 | ❌ 不支持 |
|
||||
| 投票 | ❌ 不支持 |
|
||||
| 原生命令 | ❌ 不支持 |
|
||||
| 流式传输 | ⚠️ 已阻止(2000 字符限制) |
|
||||
| 直接消息 | ✅ 支持 |
|
||||
| 群组 | ❌ Marketplace 机器人不可用 |
|
||||
| 媒体(入站图片) | ⚠️ 受限/请在你的环境中验证 |
|
||||
| 媒体(出站图片) | ⚠️ 未针对 Marketplace 机器人重新测试 |
|
||||
| 文本中的普通 URL | ✅ 支持 |
|
||||
| 链接预览 | ⚠️ Marketplace 机器人不可靠 |
|
||||
| 反应 | ❌ 不支持 |
|
||||
| 贴纸 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 语音备注/音频/视频 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 文件附件 | ⚠️ Marketplace 机器人没有智能体回复 |
|
||||
| 话题线程 | ❌ 不支持 |
|
||||
| 投票 | ❌ 不支持 |
|
||||
| 原生命令 | ❌ 不支持 |
|
||||
| 流式传输 | ⚠️ 已阻止(2000 字符限制) |
|
||||
|
||||
## 递送目标(CLI/cron)
|
||||
## 交付目标(CLI/cron)
|
||||
|
||||
- 使用聊天 ID 作为目标。
|
||||
- 示例:`openclaw message send --channel zalo --target 123456789 --message "hi"`。
|
||||
@ -208,18 +206,18 @@ Zalo 是一款面向越南的消息应用;它的 Bot API 允许 Gateway 网关
|
||||
- 验证发送者已获批准(配对或 allowFrom)
|
||||
- 检查 Gateway 网关日志:`openclaw logs --follow`
|
||||
|
||||
**Webhook 没有收到事件:**
|
||||
**Webhook 未接收事件:**
|
||||
|
||||
- 确保 Webhook URL 使用 HTTPS
|
||||
- 确保 webhook URL 使用 HTTPS
|
||||
- 验证密钥令牌为 8-256 个字符
|
||||
- 确认 Gateway 网关 HTTP 端点可在配置的路径上访问
|
||||
- 检查 getUpdates 轮询未运行(它们互斥)
|
||||
- 检查 getUpdates 轮询没有运行(它们互斥)
|
||||
|
||||
## 配置参考(Zalo)
|
||||
|
||||
完整配置:[配置](/zh-CN/gateway/configuration)
|
||||
|
||||
扁平顶层键(`channels.zalo.botToken`、`channels.zalo.dmPolicy` 等类似键)是旧版单账号简写。新配置优先使用 `channels.zalo.accounts.<id>.*`。由于这两种形式都存在于架构中,因此此处仍记录它们。
|
||||
扁平顶层键(`channels.zalo.botToken`、`channels.zalo.dmPolicy` 以及类似键)是旧版单账号简写。新配置优先使用 `channels.zalo.accounts.<id>.*`。这里仍记录两种形式,因为它们存在于 schema 中。
|
||||
|
||||
提供商选项:
|
||||
|
||||
@ -228,33 +226,33 @@ Zalo 是一款面向越南的消息应用;它的 Bot API 允许 Gateway 网关
|
||||
- `channels.zalo.tokenFile`:从常规文件路径读取令牌。符号链接会被拒绝。
|
||||
- `channels.zalo.dmPolicy`:`pairing | allowlist | open | disabled`(默认:pairing)。
|
||||
- `channels.zalo.allowFrom`:私信允许列表(用户 ID)。`open` 需要 `"*"`。向导会要求输入数字 ID。
|
||||
- `channels.zalo.groupPolicy`:`open | allowlist | disabled`(默认:allowlist)。存在于配置中;关于当前 Marketplace 机器人行为,请参阅 [能力](#capabilities) 和 [访问控制(群组)](#access-control-groups)。
|
||||
- `channels.zalo.groupPolicy`:`open | allowlist | disabled`(默认:allowlist)。存在于配置中;关于当前 Marketplace 机器人行为,请参阅[能力](#capabilities)和[访问控制(群组)](#access-control-groups)。
|
||||
- `channels.zalo.groupAllowFrom`:群组发送者允许列表(用户 ID)。未设置时回退到 `allowFrom`。
|
||||
- `channels.zalo.mediaMaxMb`:入站/出站媒体上限(MB,默认 5)。
|
||||
- `channels.zalo.webhookUrl`:启用 Webhook 模式(需要 HTTPS)。
|
||||
- `channels.zalo.webhookSecret`:Webhook 密钥(8-256 个字符)。
|
||||
- `channels.zalo.webhookPath`:Gateway 网关 HTTP 服务器上的 Webhook 路径。
|
||||
- `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>.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>.groupPolicy`:按账号配置的群组策略。存在于配置中;关于当前 Marketplace 机器人行为,请参阅 [能力](#capabilities) 和 [访问控制(群组)](#access-control-groups)。
|
||||
- `channels.zalo.accounts.<id>.groupAllowFrom`:按账号配置的群组发送者允许列表。
|
||||
- `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。
|
||||
- `channels.zalo.accounts.<id>.dmPolicy`:每账号私信策略。
|
||||
- `channels.zalo.accounts.<id>.allowFrom`:每账号允许列表。
|
||||
- `channels.zalo.accounts.<id>.groupPolicy`:每账号群组策略。存在于配置中;关于当前 Marketplace 机器人行为,请参阅[能力](#capabilities)和[访问控制(群组)](#access-control-groups)。
|
||||
- `channels.zalo.accounts.<id>.groupAllowFrom`:每账号群组发送者允许列表。
|
||||
- `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。
|
||||
|
||||
## 相关
|
||||
|
||||
- [渠道概览](/zh-CN/channels) — 所有受支持渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程
|
||||
- [群组](/zh-CN/channels/groups) — 群组聊天行为和提及门控
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型和加固
|
||||
|
||||
@ -2,33 +2,33 @@
|
||||
read_when:
|
||||
- 为 OpenClaw 设置 Zalo Personal
|
||||
- 调试 Zalo Personal 登录或消息流程
|
||||
summary: 通过原生 zca-js(二维码登录)提供的 Zalo 个人账号支持、能力和配置
|
||||
title: Zalo 个人版
|
||||
summary: 通过原生 zca-js(二维码登录)提供 Zalo 个人账号支持、能力和配置
|
||||
title: Zalo 个人
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:05:20Z"
|
||||
generated_at: "2026-05-02T21:57:11Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: a8bd665c47705e0213e1a7c05c3242d6ff745346cdee184da4884e5365807b2d
|
||||
source_hash: 0096775e0017e504130f2e19e05ab8114eadb873a9e11f79ea8f0dd91297567f
|
||||
source_path: channels/zalouser.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status:实验性。此集成通过 OpenClaw 内部原生的 `zca-js` 自动化一个**个人 Zalo 账号**。
|
||||
Status:实验性。此集成通过 OpenClaw 内部的原生 `zca-js` 自动化一个**个人 Zalo 账号**。
|
||||
|
||||
<Warning>
|
||||
这是非官方集成,可能导致账号被暂停或封禁。使用风险由你自行承担。
|
||||
这是一个非官方集成,可能导致账号被暂停或封禁。使用风险自负。
|
||||
</Warning>
|
||||
|
||||
## 内置插件
|
||||
|
||||
Zalo Personal 在当前 OpenClaw 版本中作为内置插件随附,因此普通的
|
||||
Zalo Personal 在当前 OpenClaw 版本中作为内置插件提供,因此普通的
|
||||
打包构建不需要单独安装。
|
||||
|
||||
如果你使用的是旧版构建,或自定义安装中排除了 Zalo Personal,
|
||||
如果你使用的是较旧构建,或排除了 Zalo Personal 的自定义安装,
|
||||
请直接安装 npm 包:
|
||||
|
||||
- 通过 CLI 安装:`openclaw plugins install @openclaw/zalouser`
|
||||
- Beta 渠道:`openclaw plugins install @openclaw/zalouser@beta`
|
||||
- 固定版本:`openclaw plugins install @openclaw/zalouser@2026.5.2`
|
||||
- 或从源码检出安装:`openclaw plugins install ./path/to/local/zalouser-plugin`
|
||||
- 详情:[插件](/zh-CN/tools/plugin)
|
||||
|
||||
@ -37,11 +37,11 @@ Zalo Personal 在当前 OpenClaw 版本中作为内置插件随附,因此普
|
||||
## 快速设置(初学者)
|
||||
|
||||
1. 确保 Zalo Personal 插件可用。
|
||||
- 当前打包的 OpenClaw 版本已经内置它。
|
||||
- 旧版/自定义安装可以用上面的命令手动添加。
|
||||
2. 登录(QR,在 Gateway 网关机器上):
|
||||
- 当前打包的 OpenClaw 版本已内置该插件。
|
||||
- 较旧/自定义安装可以使用上面的命令手动添加。
|
||||
2. 登录(二维码,在 Gateway 网关机器上):
|
||||
- `openclaw channels login --channel zalouser`
|
||||
- 用 Zalo 移动应用扫描 QR 码。
|
||||
- 使用 Zalo 移动应用扫描二维码。
|
||||
3. 启用渠道:
|
||||
|
||||
```json5
|
||||
@ -56,22 +56,22 @@ Zalo Personal 在当前 OpenClaw 版本中作为内置插件随附,因此普
|
||||
```
|
||||
|
||||
4. 重启 Gateway 网关(或完成设置)。
|
||||
5. 私信访问默认使用配对;首次联系时批准配对码。
|
||||
5. 私信访问默认采用配对;首次联系时批准配对代码。
|
||||
|
||||
## 它是什么
|
||||
|
||||
- 完全通过 `zca-js` 在进程内运行。
|
||||
- 使用原生事件监听器接收入站消息。
|
||||
- 直接通过 JS API 发送回复(文本/媒体/链接)。
|
||||
- 面向 Zalo Bot API 不可用的“个人账号”使用场景而设计。
|
||||
- 直接通过 JS API(文本/媒体/链接)发送回复。
|
||||
- 面向无法使用 Zalo Bot API 的“个人账号”使用场景而设计。
|
||||
|
||||
## 命名
|
||||
|
||||
渠道 ID 是 `zalouser`,用于明确表示它自动化的是**个人 Zalo 用户账号**(非官方)。我们保留 `zalo`,用于未来可能出现的官方 Zalo API 集成。
|
||||
渠道 ID 为 `zalouser`,用于明确表示这会自动化一个**个人 Zalo 用户账号**(非官方)。我们保留 `zalo`,用于未来可能的官方 Zalo API 集成。
|
||||
|
||||
## 查找 ID(目录)
|
||||
|
||||
使用目录 CLI 发现联系人/群组及其 ID:
|
||||
使用目录 CLI 发现对等方/群组及其 ID:
|
||||
|
||||
```bash
|
||||
openclaw directory self --channel zalouser
|
||||
@ -81,7 +81,7 @@ openclaw directory groups list --channel zalouser --query "work"
|
||||
|
||||
## 限制
|
||||
|
||||
- 出站文本会被分块到约 2000 个字符(Zalo 客户端限制)。
|
||||
- 出站文本会被分块为约 2000 个字符(Zalo 客户端限制)。
|
||||
- 默认阻止流式传输。
|
||||
|
||||
## 访问控制(私信)
|
||||
@ -97,17 +97,17 @@ openclaw directory groups list --channel zalouser --query "work"
|
||||
|
||||
## 群组访问(可选)
|
||||
|
||||
- 默认值:`channels.zalouser.groupPolicy = "open"`(允许群组)。未设置时,使用 `channels.defaults.groupPolicy` 覆盖默认值。
|
||||
- 默认:`channels.zalouser.groupPolicy = "open"`(允许群组)。未设置时,使用 `channels.defaults.groupPolicy` 覆盖默认值。
|
||||
- 使用以下配置限制为允许列表:
|
||||
- `channels.zalouser.groupPolicy = "allowlist"`
|
||||
- `channels.zalouser.groups`(键应为稳定的群组 ID;启动时会在可能的情况下将名称解析为 ID)
|
||||
- `channels.zalouser.groupAllowFrom`(控制允许群组中的哪些发送者可以触发机器人)
|
||||
- `channels.zalouser.groups`(键应为稳定的群组 ID;启动时会尽可能将名称解析为 ID)
|
||||
- `channels.zalouser.groupAllowFrom`(控制允许的群组中哪些发送者可以触发机器人)
|
||||
- 阻止所有群组:`channels.zalouser.groupPolicy = "disabled"`。
|
||||
- 配置向导可以提示输入群组允许列表。
|
||||
- 启动时,OpenClaw 会将允许列表中的群组/用户名称解析为 ID,并记录映射。
|
||||
- 默认情况下,群组允许列表匹配仅按 ID 进行。除非启用 `channels.zalouser.dangerouslyAllowNameMatching: true`,否则未解析的名称会在身份验证中被忽略。
|
||||
- `channels.zalouser.dangerouslyAllowNameMatching: true` 是一个应急兼容模式,会重新启用可变的群组名称匹配。
|
||||
- 如果未设置 `groupAllowFrom`,运行时会回退到 `allowFrom` 来检查群组发送者。
|
||||
- 群组允许列表匹配默认仅按 ID 进行。未解析的名称不会用于认证,除非启用 `channels.zalouser.dangerouslyAllowNameMatching: true`。
|
||||
- `channels.zalouser.dangerouslyAllowNameMatching: true` 是一种应急兼容模式,会重新启用可变群组名称匹配。
|
||||
- 如果未设置 `groupAllowFrom`,运行时会回退到 `allowFrom` 进行群组发送者检查。
|
||||
- 发送者检查同时适用于普通群组消息和控制命令(例如 `/new`、`/reset`)。
|
||||
|
||||
示例:
|
||||
@ -132,10 +132,10 @@ openclaw directory groups list --channel zalouser --query "work"
|
||||
- `channels.zalouser.groups.<group>.requireMention` 控制群组回复是否需要提及。
|
||||
- 解析顺序:精确群组 ID/名称 -> 规范化群组 slug -> `*` -> 默认值(`true`)。
|
||||
- 这同时适用于允许列表群组和开放群组模式。
|
||||
- 引用机器人消息会计为用于群组激活的隐式提及。
|
||||
- 引用机器人消息会被视为用于群组激活的隐式提及。
|
||||
- 已授权的控制命令(例如 `/new`)可以绕过提及门控。
|
||||
- 当群组消息因需要提及而被跳过时,OpenClaw 会将其存储为待处理群组历史,并在下一条被处理的群组消息中包含它。
|
||||
- 群组历史限制默认使用 `messages.groupChat.historyLimit`(回退值为 `50`)。你可以用 `channels.zalouser.historyLimit` 按账号覆盖。
|
||||
- 群组历史限制默认使用 `messages.groupChat.historyLimit`(回退值为 `50`)。你可以使用 `channels.zalouser.historyLimit` 按账号覆盖。
|
||||
|
||||
示例:
|
||||
|
||||
@ -174,14 +174,14 @@ openclaw directory groups list --channel zalouser --query "work"
|
||||
## 输入状态、回应和送达确认
|
||||
|
||||
- OpenClaw 会在分发回复前发送输入状态事件(尽力而为)。
|
||||
- 渠道操作中,`zalouser` 支持消息回应操作 `react`。
|
||||
- 渠道操作中 `zalouser` 支持消息回应操作 `react`。
|
||||
- 使用 `remove: true` 从消息中移除特定回应表情。
|
||||
- 回应语义:[回应](/zh-CN/tools/reactions)
|
||||
- 对于包含事件元数据的入站消息,OpenClaw 会发送已送达 + 已读确认(尽力而为)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
**登录未保持:**
|
||||
**登录无法保持:**
|
||||
|
||||
- `openclaw channels status --probe`
|
||||
- 重新登录:`openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser`
|
||||
@ -197,8 +197,8 @@ openclaw directory groups list --channel zalouser --query "work"
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程
|
||||
- [渠道概览](/zh-CN/channels) — 所有受支持的渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程
|
||||
- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
- [安全](/zh-CN/gateway/security) — 访问模型和加固
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
read_when:
|
||||
- 你仍在 scripts 中使用 `openclaw daemon ...`
|
||||
- 你需要服务生命周期命令(install/start/stop/restart/status)
|
||||
summary: CLI 参考:`openclaw daemon`(Gateway 网关服务管理的旧版别名)
|
||||
summary: '`openclaw daemon` 的 CLI 参考(Gateway 网关服务管理的旧版别名)'
|
||||
title: 守护进程
|
||||
x-i18n:
|
||||
generated_at: "2026-04-28T11:47:48Z"
|
||||
generated_at: "2026-05-02T21:57:42Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 51839f7cbc180cc0c43caa2d7e83cc2add7cbca40665f83f64e6ce9dde8574dd
|
||||
source_hash: 3f11b75bf2781e69f6f59b23364f06cf359f9f24407f25f19b9d2186f7158512
|
||||
source_path: cli/daemon.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -17,7 +17,7 @@ x-i18n:
|
||||
|
||||
Gateway 网关服务管理命令的旧版别名。
|
||||
|
||||
`openclaw daemon ...` 映射到与 `openclaw gateway ...` 服务命令相同的服务控制界面。
|
||||
`openclaw daemon ...` 映射到与 `openclaw gateway ...` 服务命令相同的服务控制面。
|
||||
|
||||
## 用法
|
||||
|
||||
@ -32,7 +32,7 @@ openclaw daemon uninstall
|
||||
|
||||
## 子命令
|
||||
|
||||
- `status`:显示服务安装状态并探测 Gateway 网关健康状况
|
||||
- `status`:显示服务安装状态并探测 Gateway 网关健康状态
|
||||
- `install`:安装服务(`launchd`/`systemd`/`schtasks`)
|
||||
- `uninstall`:移除服务
|
||||
- `start`:启动服务
|
||||
@ -43,26 +43,27 @@ openclaw daemon uninstall
|
||||
|
||||
- `status`:`--url`、`--token`、`--password`、`--timeout`、`--no-probe`、`--require-rpc`、`--deep`、`--json`
|
||||
- `install`:`--port`、`--runtime <node|bun>`、`--token`、`--force`、`--json`
|
||||
- 生命周期(`uninstall|start|stop|restart`):`--json`
|
||||
- `restart`:`--force`、`--wait <duration>`、`--json`
|
||||
- 生命周期(`uninstall|start|stop`):`--json`
|
||||
|
||||
说明:
|
||||
注意事项:
|
||||
|
||||
- `status` 会在可行时解析已配置的认证 SecretRefs,用于探测认证。
|
||||
- 如果在此命令路径中所需的认证 SecretRef 未解析,当探测连接性或认证失败时,`daemon status --json` 会报告 `rpc.authWarning`;请显式传入 `--token`/`--password`,或先解析密钥来源。
|
||||
- `status` 会在可能时解析已配置的 auth SecretRefs,用于探测鉴权。
|
||||
- 如果此命令路径中所需的 auth SecretRef 未解析,当探测连接/鉴权失败时,`daemon status --json` 会报告 `rpc.authWarning`;请显式传入 `--token`/`--password`,或先解析密钥来源。
|
||||
- 如果探测成功,未解析的 auth-ref 警告会被抑制,以避免误报。
|
||||
- `status --deep` 会添加尽力而为的系统级服务扫描。当它发现其他类似 Gateway 网关的服务时,面向人类的输出会打印清理提示,并警告每台机器一个 Gateway 网关仍是常规建议。
|
||||
- 在 Linux systemd 安装中,`status` 的 token 漂移检查会同时包含 `Environment=` 和 `EnvironmentFile=` 单元来源。
|
||||
- 漂移检查会使用合并后的运行时环境解析 `gateway.auth.token` SecretRefs(先使用服务命令环境,然后回退到进程环境)。
|
||||
- 如果 token 认证实际上未启用(显式 `gateway.auth.mode` 为 `password`/`none`/`trusted-proxy`,或模式未设置且 password 可以胜出、没有 token 候选可以胜出),token 漂移检查会跳过配置 token 解析。
|
||||
- 当 token 认证需要 token 且 `gateway.auth.token` 由 SecretRef 管理时,`install` 会验证 SecretRef 可解析,但不会把解析出的 token 持久化到服务环境元数据中。
|
||||
- 如果 token 认证需要 token 且已配置的 token SecretRef 未解析,安装会失败并关闭。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且 `gateway.auth.mode` 未设置,则会阻止安装,直到显式设置模式。
|
||||
- 在 macOS 上,`install` 会保持 LaunchAgent plist 仅所有者可访问,并通过仅所有者可访问的文件和包装器加载托管服务环境值,而不是把 API key 或 auth-profile env 引用序列化到 `EnvironmentVariables` 中。
|
||||
- 如果你有意在一台主机上运行多个 Gateway 网关,请隔离端口、配置/状态和工作区;参见 [/gateway#multiple-gateways-same-host](/zh-CN/gateway#multiple-gateways-same-host)。
|
||||
- `status --deep` 会添加尽力而为的系统级服务扫描。当它发现其他类似 gateway 的服务时,面向人的输出会打印清理提示,并警告每台机器一个 gateway 仍是常规建议。
|
||||
- 在 Linux systemd 安装中,`status` token-drift 检查同时包含 `Environment=` 和 `EnvironmentFile=` 单元来源。
|
||||
- Drift 检查使用合并后的运行时 env(先使用服务命令 env,然后回退到进程 env)解析 `gateway.auth.token` SecretRefs。
|
||||
- 如果 token 鉴权并未实际启用(显式 `gateway.auth.mode` 为 `password`/`none`/`trusted-proxy`,或 mode 未设置且 password 可以胜出,并且没有 token 候选可以胜出),token-drift 检查会跳过配置 token 解析。
|
||||
- 当 token 鉴权需要 token 且 `gateway.auth.token` 由 SecretRef 管理时,`install` 会验证该 SecretRef 是否可解析,但不会将解析出的 token 持久化到服务环境元数据中。
|
||||
- 如果 token 鉴权需要 token 且已配置的 token SecretRef 未解析,安装会失败并关闭。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且 `gateway.auth.mode` 未设置,安装会被阻止,直到显式设置 mode。
|
||||
- 在 macOS 上,`install` 会保持 LaunchAgent plists 仅限所有者访问,并通过仅限所有者访问的文件和包装器加载托管服务环境值,而不是将 API keys 或 auth-profile env refs 序列化到 `EnvironmentVariables` 中。
|
||||
- 如果你有意在一台主机上运行多个 gateway,请隔离端口、配置/状态和工作区;参见 [/gateway#multiple-gateways-same-host](/zh-CN/gateway#multiple-gateways-same-host)。
|
||||
|
||||
## 推荐
|
||||
|
||||
请使用 [`openclaw gateway`](/zh-CN/cli/gateway) 查看当前文档和示例。
|
||||
使用 [`openclaw gateway`](/zh-CN/cli/gateway) 查看当前文档和示例。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
---
|
||||
read_when:
|
||||
- 从 CLI 运行 Gateway 网关(开发环境或服务器)
|
||||
- 调试 Gateway 网关身份验证、绑定模式和连接
|
||||
- 调试 Gateway 网关认证、绑定模式和连接性
|
||||
- 通过 Bonjour 发现 Gateway 网关(本地 + 广域 DNS-SD)
|
||||
sidebarTitle: Gateway
|
||||
summary: OpenClaw Gateway 网关 CLI (`openclaw gateway`) — 运行、查询和发现 Gateway 网关
|
||||
summary: OpenClaw Gateway 网关 CLI (`openclaw gateway`) — 运行、查询并发现 Gateway 网关
|
||||
title: Gateway 网关
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T20:36:47Z"
|
||||
generated_at: "2026-05-02T21:57:47Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0f204b58e03c9dd1b75a7ddb2be0634ee70b42aa317a2668ab86cb33a0570b01
|
||||
source_hash: f7f948a8f0ee6e065afa02f354e690ad5cc4f71bdb8b8674f1b0396c439ab242
|
||||
source_path: cli/gateway.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -22,10 +22,10 @@ Gateway 网关是 OpenClaw 的 WebSocket 服务器(渠道、节点、会话、
|
||||
本地 mDNS + 广域 DNS-SD 设置。
|
||||
</Card>
|
||||
<Card title="设备发现概览" href="/zh-CN/gateway/discovery">
|
||||
OpenClaw 如何发布和发现网关。
|
||||
OpenClaw 如何公布和查找 Gateway 网关。
|
||||
</Card>
|
||||
<Card title="配置" href="/zh-CN/gateway/configuration">
|
||||
顶层网关配置键。
|
||||
顶层 Gateway 网关配置键。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -45,12 +45,12 @@ openclaw gateway run
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="启动行为">
|
||||
- 默认情况下,除非在 `~/.openclaw/openclaw.json` 中设置了 `gateway.mode=local`,否则 Gateway 网关会拒绝启动。临时/开发运行请使用 `--allow-unconfigured`。
|
||||
- 默认情况下,除非在 `~/.openclaw/openclaw.json` 中设置了 `gateway.mode=local`,否则 Gateway 网关会拒绝启动。对临时/开发运行使用 `--allow-unconfigured`。
|
||||
- `openclaw onboard --mode local` 和 `openclaw setup` 预期会写入 `gateway.mode=local`。如果文件存在但缺少 `gateway.mode`,请将其视为损坏或被覆盖的配置并修复,而不是隐式假定为本地模式。
|
||||
- 如果文件存在且缺少 `gateway.mode`,Gateway 网关会将其视为可疑的配置损坏,并拒绝为你“猜测为本地模式”。
|
||||
- 不带身份验证绑定到回环之外会被阻止(安全护栏)。
|
||||
- 授权时,`SIGUSR1` 会触发进程内重启(`commands.restart` 默认启用;设置 `commands.restart: false` 可阻止手动重启,同时仍允许 gateway 工具/配置应用/更新)。
|
||||
- `SIGINT`/`SIGTERM` 处理程序会停止网关进程,但它们不会恢复任何自定义终端状态。如果你用 TUI 或原始模式输入封装 CLI,请在退出前恢复终端。
|
||||
- 如果文件存在且缺少 `gateway.mode`,Gateway 网关会将其视为可疑的配置损坏,并拒绝替你“猜测为本地”。
|
||||
- 未启用凭证时,禁止绑定到超出回环地址的范围(安全防护栏)。
|
||||
- 获得授权时,`SIGUSR1` 会触发进程内重启(`commands.restart` 默认启用;设置 `commands.restart: false` 可阻止手动重启,同时仍允许 Gateway 网关工具/配置应用/更新)。
|
||||
- `SIGINT`/`SIGTERM` 处理程序会停止 Gateway 网关进程,但不会恢复任何自定义终端状态。如果你用 TUI 或 raw-mode 输入包装 CLI,请在退出前恢复终端。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -64,16 +64,16 @@ openclaw gateway run
|
||||
监听器绑定模式。
|
||||
</ParamField>
|
||||
<ParamField path="--auth <token|password>" type="string">
|
||||
身份验证模式覆盖项。
|
||||
凭证模式覆盖。
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
令牌覆盖项(也会为该进程设置 `OPENCLAW_GATEWAY_TOKEN`)。
|
||||
令牌覆盖(也会为该进程设置 `OPENCLAW_GATEWAY_TOKEN`)。
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
密码覆盖项。
|
||||
密码覆盖。
|
||||
</ParamField>
|
||||
<ParamField path="--password-file <path>" type="string">
|
||||
从文件读取网关密码。
|
||||
从文件读取 Gateway 网关密码。
|
||||
</ParamField>
|
||||
<ParamField path="--tailscale <off|serve|funnel>" type="string">
|
||||
通过 Tailscale 暴露 Gateway 网关。
|
||||
@ -82,7 +82,7 @@ openclaw gateway run
|
||||
关闭时重置 Tailscale serve/funnel 配置。
|
||||
</ParamField>
|
||||
<ParamField path="--allow-unconfigured" type="boolean">
|
||||
允许在配置中没有 `gateway.mode=local` 时启动网关。仅为临时/开发引导绕过启动保护;不会写入或修复配置文件。
|
||||
允许在配置中没有 `gateway.mode=local` 时启动 Gateway 网关。仅对临时/开发引导绕过启动保护;不会写入或修复配置文件。
|
||||
</ParamField>
|
||||
<ParamField path="--dev" type="boolean">
|
||||
如果缺失,则创建开发配置 + 工作区(跳过 BOOTSTRAP.md)。
|
||||
@ -106,10 +106,10 @@ openclaw gateway run
|
||||
`--ws-log compact` 的别名。
|
||||
</ParamField>
|
||||
<ParamField path="--raw-stream" type="boolean">
|
||||
将原始模型流事件记录到 JSONL。
|
||||
将原始模型流事件记录到 jsonl。
|
||||
</ParamField>
|
||||
<ParamField path="--raw-stream-path <path>" type="string">
|
||||
原始流 JSONL 路径。
|
||||
原始流 jsonl 路径。
|
||||
</ParamField>
|
||||
|
||||
<Warning>
|
||||
@ -118,9 +118,9 @@ openclaw gateway run
|
||||
|
||||
### 启动性能分析
|
||||
|
||||
- 设置 `OPENCLAW_GATEWAY_STARTUP_TRACE=1` 可在 Gateway 网关启动期间记录阶段计时,包括每个阶段的 `eventLoopMax` 延迟,以及已安装索引、清单注册表、启动规划和所有者映射工作的插件查找表计时。
|
||||
- 将 `OPENCLAW_DIAGNOSTICS=timeline` 与 `OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=<path>` 一起设置,可为外部 QA 测试框架写入尽力而为的 JSONL 启动诊断时间线。你也可以在配置中使用 `diagnostics.flags: ["timeline"]` 启用该标志;路径仍由环境变量提供。添加 `OPENCLAW_DIAGNOSTICS_EVENT_LOOP=1` 可包含事件循环采样。
|
||||
- 运行 `pnpm test:startup:gateway -- --runs 5 --warmup 1` 可对 Gateway 网关启动进行基准测试。该基准测试会记录首次进程输出、`/healthz`、`/readyz`、启动跟踪计时、事件循环延迟,以及插件查找表计时详情。
|
||||
- 设置 `OPENCLAW_GATEWAY_STARTUP_TRACE=1` 可在 Gateway 网关启动期间记录阶段耗时,包括每个阶段的 `eventLoopMax` 延迟,以及已安装索引、插件清单注册表、启动规划和 owner-map 工作的插件查找表耗时。
|
||||
- 设置 `OPENCLAW_DIAGNOSTICS=timeline` 并配合 `OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=<path>`,可为外部 QA harness 写入尽力而为的 JSONL 启动诊断时间线。你也可以在配置中使用 `diagnostics.flags: ["timeline"]` 启用该标志;路径仍由环境变量提供。添加 `OPENCLAW_DIAGNOSTICS_EVENT_LOOP=1` 可包含事件循环采样。
|
||||
- 运行 `pnpm test:startup:gateway -- --runs 5 --warmup 1` 可对 Gateway 网关启动进行基准测试。该基准会记录首个进程输出、`/healthz`、`/readyz`、启动跟踪耗时、事件循环延迟,以及插件查找表耗时详情。
|
||||
|
||||
## 查询正在运行的 Gateway 网关
|
||||
|
||||
@ -129,16 +129,16 @@ openclaw gateway run
|
||||
<Tabs>
|
||||
<Tab title="输出模式">
|
||||
- 默认:人类可读(在 TTY 中带颜色)。
|
||||
- `--json`:机器可读 JSON(无样式/加载指示器)。
|
||||
- `--no-color`(或 `NO_COLOR=1`):禁用 ANSI,同时保留人类可读布局。
|
||||
- `--json`:机器可读 JSON(无样式/旋转指示器)。
|
||||
- `--no-color`(或 `NO_COLOR=1`):在保留人类可读布局的同时禁用 ANSI。
|
||||
|
||||
</Tab>
|
||||
<Tab title="共享选项">
|
||||
- `--url <url>`:Gateway 网关 WebSocket URL。
|
||||
- `--token <token>`:Gateway 网关令牌。
|
||||
- `--password <password>`:Gateway 网关密码。
|
||||
- `--timeout <ms>`:超时/预算(每个命令不同)。
|
||||
- `--expect-final`:等待“最终”响应(智能体调用)。
|
||||
- `--timeout <ms>`:超时/预算(因命令而异)。
|
||||
- `--expect-final`:等待 “final” 响应(智能体调用)。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@ -153,11 +153,11 @@ openclaw gateway run
|
||||
openclaw gateway health --url ws://127.0.0.1:18789
|
||||
```
|
||||
|
||||
HTTP `/healthz` 端点是存活探针:一旦服务器能够响应 HTTP,它就会返回。HTTP `/readyz` 端点更严格,在启动时的插件旁车进程、渠道或已配置钩子仍在就绪过程中时会保持红色状态。本地或已认证的详细就绪性响应包含一个 `eventLoop` 诊断块,其中包括事件循环延迟、事件循环利用率、CPU 核心比例,以及 `degraded` 标志。
|
||||
HTTP `/healthz` 端点是存活探针:只要服务器可以响应 HTTP,它就会返回。HTTP `/readyz` 端点更严格,并且会在启动中的插件 sidecar、渠道或已配置钩子仍在就绪过程中时保持红色。本地或已认证的详细就绪响应包含一个 `eventLoop` 诊断块,其中包含事件循环延迟、事件循环利用率、CPU 核心比例和 `degraded` 标志。
|
||||
|
||||
### `gateway usage-cost`
|
||||
|
||||
从会话日志获取用量成本汇总。
|
||||
从会话日志获取使用成本摘要。
|
||||
|
||||
```bash
|
||||
openclaw gateway usage-cost
|
||||
@ -171,7 +171,7 @@ openclaw gateway usage-cost --json
|
||||
|
||||
### `gateway stability`
|
||||
|
||||
从正在运行的 Gateway 网关获取近期诊断稳定性记录器内容。
|
||||
从正在运行的 Gateway 网关获取最近的诊断稳定性记录器。
|
||||
|
||||
```bash
|
||||
openclaw gateway stability
|
||||
@ -185,13 +185,13 @@ openclaw gateway stability --json
|
||||
要包含的最近事件最大数量(最大 `1000`)。
|
||||
</ParamField>
|
||||
<ParamField path="--type <type>" type="string">
|
||||
按诊断事件类型筛选,例如 `payload.large` 或 `diagnostic.memory.pressure`。
|
||||
按诊断事件类型过滤,例如 `payload.large` 或 `diagnostic.memory.pressure`。
|
||||
</ParamField>
|
||||
<ParamField path="--since-seq <seq>" type="number">
|
||||
仅包含某个诊断序列号之后的事件。
|
||||
仅包含诊断序列号之后的事件。
|
||||
</ParamField>
|
||||
<ParamField path="--bundle [path]" type="string">
|
||||
读取持久化稳定性诊断包,而不是调用正在运行的 Gateway 网关。对于状态目录下最新的诊断包,使用 `--bundle latest`(或仅使用 `--bundle`),也可以直接传入诊断包 JSON 路径。
|
||||
读取持久化稳定性捆绑包,而不是调用正在运行的 Gateway 网关。使用 `--bundle latest`(或仅使用 `--bundle`)读取状态目录下最新的捆绑包,或直接传入捆绑包 JSON 路径。
|
||||
</ParamField>
|
||||
<ParamField path="--export" type="boolean">
|
||||
写入可共享的支持诊断 zip,而不是打印稳定性详情。
|
||||
@ -201,16 +201,16 @@ openclaw gateway stability --json
|
||||
</ParamField>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私和诊断包行为">
|
||||
- 记录会保留运行元数据:事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称,以及经过遮盖的会话摘要。它们不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、cookie、机密值、主机名或原始会话 ID。设置 `diagnostics.enabled: false` 可完全禁用记录器。
|
||||
- 在 Gateway 网关致命退出、关闭超时和重启启动失败时,如果记录器中有事件,OpenClaw 会将相同的诊断快照写入 `~/.openclaw/logs/stability/openclaw-stability-*.json`。使用 `openclaw gateway stability --bundle latest` 检查最新诊断包;`--limit`、`--type` 和 `--since-seq` 也适用于诊断包输出。
|
||||
<Accordion title="隐私和捆绑包行为">
|
||||
- 记录会保留运行元数据:事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称,以及经过脱敏的会话摘要。它们不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、cookie、密钥值、主机名或原始会话 ID。设置 `diagnostics.enabled: false` 可完全禁用记录器。
|
||||
- 在 Gateway 网关致命退出、关闭超时和重启启动失败时,如果记录器有事件,OpenClaw 会将相同的诊断快照写入 `~/.openclaw/logs/stability/openclaw-stability-*.json`。使用 `openclaw gateway stability --bundle latest` 检查最新捆绑包;`--limit`、`--type` 和 `--since-seq` 也适用于捆绑包输出。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### `gateway diagnostics export`
|
||||
|
||||
写入一个本地诊断 zip,用于附加到错误报告。有关隐私模型和诊断包内容,请参阅 [诊断导出](/zh-CN/gateway/diagnostics)。
|
||||
写入一个本地诊断 zip,设计用于附加到错误报告。有关隐私模型和捆绑包内容,请参阅 [诊断导出](/zh-CN/gateway/diagnostics)。
|
||||
|
||||
```bash
|
||||
openclaw gateway diagnostics export
|
||||
@ -219,40 +219,40 @@ openclaw gateway diagnostics export --json
|
||||
```
|
||||
|
||||
<ParamField path="--output <path>" type="string">
|
||||
输出 zip 路径。默认是状态目录下的支持导出。
|
||||
输出 zip 路径。默认为状态目录下的支持导出。
|
||||
</ParamField>
|
||||
<ParamField path="--log-lines <count>" type="number" default="5000">
|
||||
要包含的脱敏日志行数上限。
|
||||
要包含的最大已清理日志行数。
|
||||
</ParamField>
|
||||
<ParamField path="--log-bytes <bytes>" type="number" default="1000000">
|
||||
要检查的日志字节数上限。
|
||||
要检查的最大日志字节数。
|
||||
</ParamField>
|
||||
<ParamField path="--url <url>" type="string">
|
||||
健康快照的 Gateway 网关 WebSocket URL。
|
||||
用于健康快照的 Gateway 网关 WebSocket URL。
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
健康快照的 Gateway 网关令牌。
|
||||
用于健康快照的 Gateway 网关令牌。
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
健康快照的 Gateway 网关密码。
|
||||
用于健康快照的 Gateway 网关密码。
|
||||
</ParamField>
|
||||
<ParamField path="--timeout <ms>" type="number" default="3000">
|
||||
状态/健康快照超时。
|
||||
Status/健康快照超时。
|
||||
</ParamField>
|
||||
<ParamField path="--no-stability-bundle" type="boolean">
|
||||
跳过持久化稳定性诊断包查找。
|
||||
跳过持久化稳定性捆绑包查找。
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
以 JSON 打印写入的路径、大小和清单。
|
||||
将写入路径、大小和清单打印为 JSON。
|
||||
</ParamField>
|
||||
|
||||
导出包含清单、Markdown 摘要、配置形状、脱敏配置详情、脱敏日志摘要、脱敏 Gateway 网关状态/健康快照,以及存在时的最新稳定性诊断包。
|
||||
该导出包含清单、Markdown 摘要、配置形状、已清理的配置详情、已清理的日志摘要、已清理的 Gateway 网关 Status/健康快照,以及存在时的最新稳定性捆绑包。
|
||||
|
||||
它旨在用于共享。它会保留有助于调试的运行详情,例如安全的 OpenClaw 日志字段、子系统名称、状态码、持续时间、已配置模式、端口、插件 ID、提供商 ID、非机密功能设置,以及经过遮盖的运行日志消息。它会省略或遮盖聊天文本、webhook 正文、工具输出、凭据、cookie、账号/消息标识符、提示/指令文本、主机名和机密值。当 LogTape 风格消息看起来像用户/聊天/工具载荷文本时,导出只保留消息被省略这一事实以及其字节数。
|
||||
它用于共享。它会保留有助于调试的运行细节,例如安全的 OpenClaw 日志字段、子系统名称、状态码、持续时间、已配置模式、端口、插件 ID、提供商 ID、非密钥功能设置,以及经过脱敏的运行日志消息。它会省略或脱敏聊天文本、webhook 正文、工具输出、凭据、cookie、账号/消息标识符、提示词/指令文本、主机名和密钥值。当 LogTape 风格的消息看起来像用户/聊天/工具载荷文本时,导出仅保留该消息已被省略以及其字节数。
|
||||
|
||||
### `gateway status`
|
||||
|
||||
`gateway status` 会显示 Gateway 网关服务(launchd/systemd/schtasks),以及可选的连接性/身份验证能力探针。
|
||||
`gateway status` 显示 Gateway 网关服务(launchd/systemd/schtasks),以及可选的连接性/凭证能力探针。
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
@ -261,13 +261,13 @@ openclaw gateway status --require-rpc
|
||||
```
|
||||
|
||||
<ParamField path="--url <url>" type="string">
|
||||
添加显式探针目标。已配置的远程端点 + localhost 仍会被探测。
|
||||
添加显式探针目标。仍会探测已配置的远程目标 + localhost。
|
||||
</ParamField>
|
||||
<ParamField path="--token <token>" type="string">
|
||||
探针的令牌身份验证。
|
||||
探针的令牌凭证。
|
||||
</ParamField>
|
||||
<ParamField path="--password <password>" type="string">
|
||||
探针的密码身份验证。
|
||||
探针的密码凭证。
|
||||
</ParamField>
|
||||
<ParamField path="--timeout <ms>" type="number" default="10000">
|
||||
探针超时。
|
||||
@ -284,21 +284,21 @@ openclaw gateway status --require-rpc
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Status 语义">
|
||||
- 即使本地 CLI 配置缺失或无效,`gateway status` 仍可用于诊断。
|
||||
- 默认的 `gateway status` 会验证服务状态、WebSocket 连接,以及握手时可见的身份验证能力。它不会验证读/写/管理员操作。
|
||||
- 诊断探测对首次设备身份验证不会产生变更:如果已有缓存的设备令牌,它们会复用该令牌,但不会仅为了检查 Status 而创建新的 CLI 设备身份或只读设备配对记录。
|
||||
- `gateway status` 会在可能时解析已配置的身份验证 SecretRefs,以用于探测身份验证。
|
||||
- 如果此命令路径中的必需身份验证 SecretRef 无法解析,当探测连接性/身份验证失败时,`gateway status --json` 会报告 `rpc.authWarning`;请显式传入 `--token`/`--password`,或先解析密钥来源。
|
||||
- 如果探测成功,未解析的身份验证引用警告会被抑制,以避免误报。
|
||||
- 在脚本和自动化中,当监听中的服务还不够、你还需要读作用域 RPC 调用也保持健康时,请使用 `--require-rpc`。
|
||||
- `--deep` 会尽力扫描额外的 launchd/systemd/schtasks 安装。当检测到多个类似 Gateway 网关的服务时,人类可读输出会打印清理提示,并警告大多数设置应在每台机器上运行一个 Gateway 网关。
|
||||
- 人类可读输出包含解析后的文件日志路径,以及 CLI 与服务配置路径/有效性快照,以帮助诊断配置文件或状态目录漂移。
|
||||
- `gateway status` 即使在本地 CLI 配置缺失或无效时,也仍可用于诊断。
|
||||
- 默认的 `gateway status` 会证明服务状态、WebSocket 连接,以及握手时可见的认证能力。它不会证明读/写/管理员操作。
|
||||
- 对于首次设备认证,诊断探测不会变更状态:当已有缓存设备令牌时会复用它,但不会仅为检查状态而创建新的 CLI 设备身份或只读设备配对记录。
|
||||
- `gateway status` 会在可行时解析已配置的认证 SecretRefs,用于探测认证。
|
||||
- 如果此命令路径中必需的认证 SecretRef 未解析,`gateway status --json` 会在探测连接/认证失败时报告 `rpc.authWarning`;请显式传入 `--token`/`--password`,或先解析密钥来源。
|
||||
- 如果探测成功,未解析的 auth-ref 警告会被抑制,以避免误报。
|
||||
- 在脚本和自动化中,如果监听中的服务还不够,并且你还需要读取范围的 RPC 调用也保持健康,请使用 `--require-rpc`。
|
||||
- `--deep` 会尽力扫描额外的 launchd/systemd/schtasks 安装。检测到多个类似 Gateway 网关的服务时,人工可读输出会打印清理提示,并警告大多数设置应在每台机器上运行一个 Gateway 网关。
|
||||
- 人工可读输出包含解析后的文件日志路径,以及 CLI 与服务的配置路径/有效性快照,用于帮助诊断配置文件或状态目录漂移。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Linux systemd 身份验证漂移检查">
|
||||
- 在 Linux systemd 安装中,服务身份验证漂移检查会从 unit 中读取 `Environment=` 和 `EnvironmentFile=` 值(包括 `%h`、带引号的路径、多个文件,以及可选的 `-` 文件)。
|
||||
<Accordion title="Linux systemd 认证漂移检查">
|
||||
- 在 Linux systemd 安装中,服务认证漂移检查会从 unit 中读取 `Environment=` 和 `EnvironmentFile=` 值(包括 `%h`、带引号的路径、多个文件,以及可选的 `-` 文件)。
|
||||
- 漂移检查会使用合并后的运行时环境解析 `gateway.auth.token` SecretRefs(先使用服务命令环境,再回退到进程环境)。
|
||||
- 如果令牌身份验证实际上未启用(显式 `gateway.auth.mode` 为 `password`/`none`/`trusted-proxy`,或未设置模式且密码可能胜出、并且没有令牌候选项可能胜出),令牌漂移检查会跳过配置令牌解析。
|
||||
- 如果令牌认证实际上未启用(显式 `gateway.auth.mode` 为 `password`/`none`/`trusted-proxy`,或模式未设置且密码可能胜出、没有令牌候选可胜出),令牌漂移检查会跳过配置令牌解析。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -310,14 +310,14 @@ openclaw gateway status --require-rpc
|
||||
- 你配置的远程 Gateway 网关(如果已设置),以及
|
||||
- localhost(loopback),**即使已配置远程目标**。
|
||||
|
||||
如果你传入 `--url`,该显式目标会被添加到两者之前。人类可读输出会将目标标记为:
|
||||
如果你传入 `--url`,该显式目标会添加到这两者之前。人工可读输出会将目标标记为:
|
||||
|
||||
- `URL (explicit)`
|
||||
- `Remote (configured)` 或 `Remote (configured, inactive)`
|
||||
- `Local loopback`
|
||||
|
||||
<Note>
|
||||
如果多个 Gateway 网关可达,它会全部打印出来。当你使用隔离的配置文件/端口(例如救援机器人)时,支持多个 Gateway 网关,但大多数安装仍然只运行单个 Gateway 网关。
|
||||
如果多个 Gateway 网关可达,它会全部打印出来。当你使用隔离的配置文件/端口(例如救援机器人)时,支持多个 Gateway 网关,但大多数安装仍只运行单个 Gateway 网关。
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
@ -328,12 +328,12 @@ openclaw gateway probe --json
|
||||
<AccordionGroup>
|
||||
<Accordion title="解读">
|
||||
- `Reachable: yes` 表示至少一个目标接受了 WebSocket 连接。
|
||||
- `Capability: read-only|write-capable|admin-capable|pairing-pending|connect-only` 报告探测能够证明的身份验证能力。它与可达性是分开的。
|
||||
- `Read probe: ok` 表示读作用域的详细 RPC 调用(`health`/`status`/`system-presence`/`config.get`)也成功了。
|
||||
- `Read probe: limited - missing scope: operator.read` 表示连接成功,但读作用域 RPC 受限。这会被报告为**降级**可达性,而不是完全失败。
|
||||
- 在 `Connect: ok` 之后出现 `Read probe: failed` 表示 Gateway 网关接受了 WebSocket 连接,但后续读诊断超时或失败。这同样是**降级**可达性,而不是 Gateway 网关不可达。
|
||||
- 与 `gateway status` 一样,probe 会复用现有缓存的设备身份验证,但不会创建首次设备身份或配对状态。
|
||||
- 只有当没有任何被探测目标可达时,退出码才为非零。
|
||||
- `Capability: read-only|write-capable|admin-capable|pairing-pending|connect-only` 报告探测可以证明的认证状态。它与可达性分开。
|
||||
- `Read probe: ok` 表示读取范围的详细 RPC 调用(`health`/`status`/`system-presence`/`config.get`)也成功。
|
||||
- `Read probe: limited - missing scope: operator.read` 表示连接成功,但读取范围的 RPC 受限。这会报告为**降级**可达性,而不是完全失败。
|
||||
- `Connect: ok` 之后的 `Read probe: failed` 表示 Gateway 网关接受了 WebSocket 连接,但后续读取诊断超时或失败。这也属于**降级**可达性,而不是 Gateway 网关不可达。
|
||||
- 与 `gateway status` 一样,探测会复用现有缓存设备认证,但不会创建首次设备身份或配对状态。
|
||||
- 只有在没有任何被探测目标可达时,退出码才非零。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="JSON 输出">
|
||||
@ -342,8 +342,8 @@ openclaw gateway probe --json
|
||||
- `ok`:至少一个目标可达。
|
||||
- `degraded`:至少一个目标接受了连接,但未完成完整的详细 RPC 诊断。
|
||||
- `capability`:在可达目标中看到的最佳能力(`read_only`、`write_capable`、`admin_capable`、`pairing_pending`、`connected_no_operator_scope` 或 `unknown`)。
|
||||
- `primaryTargetId`:按此顺序选出的最佳目标,作为活动胜出目标处理:显式 URL、SSH 隧道、已配置远程目标,然后是 local loopback。
|
||||
- `warnings[]`:尽力生成的警告记录,包含 `code`、`message` 和可选的 `targetIds`。
|
||||
- `primaryTargetId`:按以下顺序视为活动胜出者的最佳目标:显式 URL、SSH 隧道、已配置远程目标,然后是 local loopback。
|
||||
- `warnings[]`:尽力提供的警告记录,包含 `code`、`message` 和可选的 `targetIds`。
|
||||
- `network`:根据当前配置和主机网络推导出的 local loopback/tailnet URL 提示。
|
||||
- `discovery.timeoutMs` 和 `discovery.count`:此次探测实际使用的设备发现预算/结果数量。
|
||||
|
||||
@ -351,42 +351,42 @@ openclaw gateway probe --json
|
||||
|
||||
- `ok`:连接后的可达性 + 降级分类。
|
||||
- `rpcOk`:完整详细 RPC 成功。
|
||||
- `scopeLimited`:详细 RPC 因缺少操作员作用域而失败。
|
||||
- `scopeLimited`:详细 RPC 因缺少 operator scope 而失败。
|
||||
|
||||
每个目标(`targets[].auth`):
|
||||
|
||||
- `role`:可用时在 `hello-ok` 中报告的身份验证角色。
|
||||
- `scopes`:可用时在 `hello-ok` 中报告的已授予作用域。
|
||||
- `capability`:该目标暴露的身份验证能力分类。
|
||||
- `role`:可用时,在 `hello-ok` 中报告的认证角色。
|
||||
- `scopes`:可用时,在 `hello-ok` 中报告的已授予范围。
|
||||
- `capability`:该目标暴露的认证能力分类。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="常见警告代码">
|
||||
- `ssh_tunnel_failed`:SSH 隧道设置失败;命令已回退到直接探测。
|
||||
- `multiple_gateways`:多个目标可达;除非你有意运行隔离的配置文件(例如救援机器人),否则这并不常见。
|
||||
- `auth_secretref_unresolved`:无法为失败的目标解析已配置的身份验证 SecretRef。
|
||||
- `probe_scope_limited`:WebSocket 连接成功,但读探测因缺少 `operator.read` 而受限。
|
||||
- `multiple_gateways`:多个目标可达;除非你有意运行隔离配置文件,例如救援机器人,否则这并不常见。
|
||||
- `auth_secretref_unresolved`:无法为失败目标解析已配置的认证 SecretRef。
|
||||
- `probe_scope_limited`:WebSocket 连接成功,但读取探测因缺少 `operator.read` 而受限。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
#### 通过 SSH 访问远程(与 Mac 应用一致)
|
||||
#### 通过 SSH 访问远程目标(Mac 应用一致性)
|
||||
|
||||
macOS 应用的“通过 SSH 访问远程”模式使用本地端口转发,使远程 Gateway 网关(可能只绑定到 loopback)可通过 `ws://127.0.0.1:<port>` 访问。
|
||||
macOS 应用的“通过 SSH 访问远程目标”模式使用本地端口转发,使远程 Gateway 网关(可能只绑定到 loopback)可通过 `ws://127.0.0.1:<port>` 访问。
|
||||
|
||||
CLI 等效命令:
|
||||
CLI 等价命令:
|
||||
|
||||
```bash
|
||||
openclaw gateway probe --ssh user@gateway-host
|
||||
```
|
||||
|
||||
<ParamField path="--ssh <target>" type="string">
|
||||
`user@host` 或 `user@host:port`(端口默认为 `22`)。
|
||||
`user@host` 或 `user@host:port`(端口默认值为 `22`)。
|
||||
</ParamField>
|
||||
<ParamField path="--ssh-identity <path>" type="string">
|
||||
身份文件。
|
||||
</ParamField>
|
||||
<ParamField path="--ssh-auto" type="boolean">
|
||||
从解析出的设备发现端点(`local.` 加上已配置的广域域名,如果有)中选择第一个发现的 Gateway 网关主机作为 SSH 目标。仅 TXT 的提示会被忽略。
|
||||
从解析后的设备发现端点(`local.` 加上已配置的广域域名,如果有)中选择第一个发现的 Gateway 网关主机作为 SSH 目标。仅 TXT 的提示会被忽略。
|
||||
</ParamField>
|
||||
|
||||
配置(可选,用作默认值):
|
||||
@ -396,7 +396,7 @@ openclaw gateway probe --ssh user@gateway-host
|
||||
|
||||
### `gateway call <method>`
|
||||
|
||||
低级 RPC 辅助命令。
|
||||
低级 RPC 辅助工具。
|
||||
|
||||
```bash
|
||||
openclaw gateway call status
|
||||
@ -404,7 +404,7 @@ openclaw gateway call logs.tail --params '{"sinceMs": 60000}'
|
||||
```
|
||||
|
||||
<ParamField path="--params <json>" type="string" default="{}">
|
||||
用于 params 的 JSON 对象字符串。
|
||||
用于参数的 JSON 对象字符串。
|
||||
</ParamField>
|
||||
<ParamField path="--url <url>" type="string">
|
||||
Gateway 网关 WebSocket URL。
|
||||
@ -419,14 +419,14 @@ openclaw gateway call logs.tail --params '{"sinceMs": 60000}'
|
||||
超时预算。
|
||||
</ParamField>
|
||||
<ParamField path="--expect-final" type="boolean">
|
||||
主要用于智能体风格的 RPC,它们会在最终载荷前流式传输中间事件。
|
||||
主要用于 agent 风格的 RPC,它们会在最终载荷之前流式传输中间事件。
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
机器可读 JSON 输出。
|
||||
机器可读的 JSON 输出。
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
`--params` 必须是有效的 JSON。
|
||||
`--params` 必须是有效 JSON。
|
||||
</Note>
|
||||
|
||||
## 管理 Gateway 网关服务
|
||||
@ -441,9 +441,9 @@ openclaw gateway uninstall
|
||||
|
||||
### 使用包装器安装
|
||||
|
||||
当受管服务必须通过另一个可执行文件启动时,请使用 `--wrapper`,例如
|
||||
密钥管理器 shim 或 run-as 辅助程序。包装器会接收正常的 Gateway 网关参数,并
|
||||
负责最终使用这些参数 exec `openclaw` 或 Node。
|
||||
当托管服务必须通过另一个可执行文件启动时,请使用 `--wrapper`,例如
|
||||
密钥管理器 shim 或 run-as 辅助工具。包装器接收正常的 Gateway 网关参数,并负责
|
||||
最终使用这些参数执行 `openclaw` 或 Node。
|
||||
|
||||
```bash
|
||||
cat > ~/.local/bin/openclaw-doppler <<'EOF'
|
||||
@ -457,17 +457,17 @@ openclaw gateway install --wrapper ~/.local/bin/openclaw-doppler --force
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
你也可以通过环境设置包装器。`gateway install` 会验证路径是
|
||||
你也可以通过环境设置包装器。`gateway install` 会验证该路径是
|
||||
可执行文件,将包装器写入服务 `ProgramArguments`,并在服务环境中持久化
|
||||
`OPENCLAW_WRAPPER`,用于之后的强制重装、更新和 Doctor
|
||||
修复。
|
||||
`OPENCLAW_WRAPPER`,以供后续强制重新安装、更新和 Doctor
|
||||
修复使用。
|
||||
|
||||
```bash
|
||||
OPENCLAW_WRAPPER="$HOME/.local/bin/openclaw-doppler" openclaw gateway install --force
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
要移除已持久化的包装器,请在重新安装时清空 `OPENCLAW_WRAPPER`:
|
||||
要移除持久化的包装器,请在重新安装时清空 `OPENCLAW_WRAPPER`:
|
||||
|
||||
```bash
|
||||
OPENCLAW_WRAPPER= openclaw gateway install --force
|
||||
@ -478,20 +478,23 @@ openclaw gateway restart
|
||||
<Accordion title="命令选项">
|
||||
- `gateway status`:`--url`、`--token`、`--password`、`--timeout`、`--no-probe`、`--require-rpc`、`--deep`、`--json`
|
||||
- `gateway install`:`--port`、`--runtime <node|bun>`、`--token`、`--wrapper <path>`、`--force`、`--json`
|
||||
- `gateway uninstall|start|stop|restart`:`--json`
|
||||
- `gateway restart`:`--force`、`--wait <duration>`、`--json`
|
||||
- `gateway uninstall|start|stop`:`--json`
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="生命周期行为">
|
||||
- 使用 `gateway restart` 重启受管服务。不要把 `gateway stop` 和 `gateway start` 串起来作为重启替代;在 macOS 上,`gateway stop` 会在停止 LaunchAgent 之前有意禁用它。
|
||||
- 生命周期命令接受 `--json`,以便脚本使用。
|
||||
- 使用 `gateway restart` 重启托管服务。不要将 `gateway stop` 和 `gateway start` 串联起来替代重启;在 macOS 上,`gateway stop` 会在停止 LaunchAgent 前有意禁用它。
|
||||
- `gateway restart --wait 30s` 会为本次重启覆盖已配置的重启排空预算。裸数字表示毫秒;也接受 `s`、`m` 和 `h` 等单位。`--wait 0` 会无限期等待。
|
||||
- `gateway restart --force` 会跳过活跃工作排空并立即重启。当 operator 已经检查过列出的任务阻塞项,并且希望 Gateway 网关立即恢复时使用它。
|
||||
- 生命周期命令接受 `--json`,便于脚本使用。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="安装时的身份验证和 SecretRefs">
|
||||
- 当令牌身份验证需要令牌且 `gateway.auth.token` 由 SecretRef 管理时,`gateway install` 会验证 SecretRef 可解析,但不会将解析后的令牌持久化到服务环境元数据中。
|
||||
- 如果令牌身份验证需要令牌且配置的令牌 SecretRef 无法解析,安装会失败关闭,而不是持久化回退明文。
|
||||
- 对于 `gateway run` 上的密码身份验证,优先使用 `OPENCLAW_GATEWAY_PASSWORD`、`--password-file` 或由 SecretRef 支持的 `gateway.auth.password`,而不是内联 `--password`。
|
||||
- 在推断身份验证模式下,仅 shell 中的 `OPENCLAW_GATEWAY_PASSWORD` 不会放宽安装令牌要求;安装受管服务时,请使用持久配置(`gateway.auth.password` 或配置 `env`)。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且未设置 `gateway.auth.mode`,安装会被阻止,直到显式设置模式。
|
||||
<Accordion title="安装时的认证和 SecretRefs">
|
||||
- 当令牌认证需要令牌且 `gateway.auth.token` 由 SecretRef 管理时,`gateway install` 会验证 SecretRef 可解析,但不会将解析后的令牌持久化到服务环境元数据中。
|
||||
- 如果令牌认证需要令牌,而配置的令牌 SecretRef 未解析,安装会关闭失败,而不是持久化回退明文。
|
||||
- 对于 `gateway run` 上的密码认证,相比内联 `--password`,优先使用 `OPENCLAW_GATEWAY_PASSWORD`、`--password-file` 或由 SecretRef 支持的 `gateway.auth.password`。
|
||||
- 在推断认证模式中,仅 shell 的 `OPENCLAW_GATEWAY_PASSWORD` 不会放宽安装令牌要求;安装托管服务时请使用持久配置(`gateway.auth.password` 或配置 `env`)。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且 `gateway.auth.mode` 未设置,安装会被阻止,直到显式设置模式。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -500,10 +503,10 @@ openclaw gateway restart
|
||||
|
||||
`gateway discover` 会扫描 Gateway 网关信标(`_openclaw-gw._tcp`)。
|
||||
|
||||
- Multicast DNS-SD:`local.`
|
||||
- Unicast DNS-SD(Wide-Area Bonjour):选择一个域名(例如:`openclaw.internal.`),并设置 split DNS + DNS 服务器;参见 [Bonjour](/zh-CN/gateway/bonjour)。
|
||||
- 组播 DNS-SD:`local.`
|
||||
- 单播 DNS-SD(广域 Bonjour):选择一个域名(示例:`openclaw.internal.`)并设置拆分 DNS + DNS 服务器;请参阅 [Bonjour](/zh-CN/gateway/bonjour)。
|
||||
|
||||
只有启用了 Bonjour 设备发现(默认)的 Gateway 网关才会广播信标。
|
||||
只有启用了 Bonjour 设备发现(默认)的 Gateway 网关会广播信标。
|
||||
|
||||
广域设备发现记录包含(TXT):
|
||||
|
||||
@ -512,7 +515,7 @@ openclaw gateway restart
|
||||
- `gatewayPort`(WebSocket 端口,通常为 `18789`)
|
||||
- `sshPort`(可选;缺失时客户端默认 SSH 目标为 `22`)
|
||||
- `tailnetDns`(MagicDNS 主机名,可用时)
|
||||
- `gatewayTls` / `gatewayTlsSha256`(启用 TLS + 证书指纹)
|
||||
- `gatewayTls` / `gatewayTlsSha256`(TLS 已启用 + 证书指纹)
|
||||
- `cliPath`(写入广域区域的远程安装提示)
|
||||
|
||||
### `gateway discover`
|
||||
@ -525,7 +528,7 @@ openclaw gateway discover
|
||||
每条命令的超时时间(browse/resolve)。
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
机器可读输出(也会禁用样式/spinner)。
|
||||
机器可读输出(也会禁用样式/旋转指示器)。
|
||||
</ParamField>
|
||||
|
||||
示例:
|
||||
@ -536,8 +539,8 @@ openclaw gateway discover --json | jq '.beacons[].wsUrl'
|
||||
```
|
||||
|
||||
<Note>
|
||||
- 启用配置的广域域名时,CLI 会扫描 `local.` 以及该域名。
|
||||
- JSON 输出中的 `wsUrl` 派生自已解析的服务端点,而不是来自仅 TXT 的提示,例如 `lanHost` 或 `tailnetDns`。
|
||||
- CLI 会扫描 `local.` 以及已配置且启用的广域网域名。
|
||||
- JSON 输出中的 `wsUrl` 派生自解析后的服务端点,而不是来自仅 TXT 的提示,例如 `lanHost` 或 `tailnetDns`。
|
||||
- 在 `local.` mDNS 上,只有当 `discovery.mdns.mode` 为 `full` 时,才会广播 `sshPort` 和 `cliPath`。广域 DNS-SD 仍会写入 `cliPath`;`sshPort` 在那里也保持可选。
|
||||
|
||||
</Note>
|
||||
|
||||
@ -3,18 +3,18 @@ read_when:
|
||||
- 你想安装或管理 Gateway 网关插件或兼容包
|
||||
- 你想调试插件加载失败
|
||||
sidebarTitle: Plugins
|
||||
summary: 用于 `openclaw plugins` 的 CLI 参考(list、install、marketplace、uninstall、enable/disable、doctor)
|
||||
summary: 适用于 `openclaw plugins` 的 CLI 参考(list、install、marketplace、uninstall、enable/disable、doctor)
|
||||
title: 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:05:19Z"
|
||||
generated_at: "2026-05-02T21:57:47Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 48583cb22363837cf95ebc4de6f688f72921347240ac5cf228c20f9a6c5237fd
|
||||
source_hash: 3b077ab0739e2453ccba434aa3b02b1d441bab792b7b131216221a8048d551cd
|
||||
source_path: cli/plugins.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
管理 Gateway 网关插件、钩子包和兼容 bundle。
|
||||
管理 Gateway 网关插件、钩子包和兼容包。
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="插件系统" href="/zh-CN/tools/plugin">
|
||||
@ -23,11 +23,11 @@ x-i18n:
|
||||
<Card title="管理插件" href="/zh-CN/plugins/manage-plugins">
|
||||
安装、列出、更新、卸载和发布的快速示例。
|
||||
</Card>
|
||||
<Card title="插件 bundle" href="/zh-CN/plugins/bundles">
|
||||
Bundle 兼容性模型。
|
||||
<Card title="插件包" href="/zh-CN/plugins/bundles">
|
||||
包兼容性模型。
|
||||
</Card>
|
||||
<Card title="插件清单" href="/zh-CN/plugins/manifest">
|
||||
清单字段和配置 schema。
|
||||
清单字段和配置架构。
|
||||
</Card>
|
||||
<Card title="安全" href="/zh-CN/gateway/security">
|
||||
插件安装的安全加固。
|
||||
@ -62,14 +62,14 @@ openclaw plugins marketplace list <marketplace>
|
||||
openclaw plugins marketplace list <marketplace> --json
|
||||
```
|
||||
|
||||
如需调查缓慢的安装、检查、卸载或 registry 刷新,请使用 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行该命令。Trace 会将阶段耗时写入 stderr,并保持 JSON 输出可解析。参见 [调试](/zh-CN/help/debugging#plugin-lifecycle-trace)。
|
||||
如需调查安装、检查、卸载或注册表刷新速度慢的问题,请使用 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行该命令。跟踪会将阶段耗时写入 stderr,并保持 JSON 输出可解析。参见 [调试](/zh-CN/help/debugging#plugin-lifecycle-trace)。
|
||||
|
||||
<Note>
|
||||
内置插件随 OpenClaw 一起发布。部分插件默认启用(例如内置模型提供商、内置语音提供商,以及内置浏览器插件);其他插件需要执行 `plugins enable`。
|
||||
内置插件随 OpenClaw 一起发布。有些默认启用(例如内置模型提供商、内置语音提供商和内置浏览器插件);其他插件需要 `plugins enable`。
|
||||
|
||||
原生 OpenClaw 插件必须随附包含内联 JSON Schema 的 `openclaw.plugin.json`(`configSchema`,即使为空也需要)。兼容 bundle 则使用它们自己的 bundle 清单。
|
||||
原生 OpenClaw 插件必须随附 `openclaw.plugin.json`,并包含内联 JSON Schema(`configSchema`,即使为空)。兼容包改用它们自己的包清单。
|
||||
|
||||
`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细 list/info 输出还会显示 bundle 子类型(`codex`、`claude` 或 `cursor`)以及检测到的 bundle 能力。
|
||||
`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细列表/info 输出还会显示包子类型(`codex`、`claude` 或 `cursor`)以及检测到的包能力。
|
||||
</Note>
|
||||
|
||||
### 安装
|
||||
@ -94,65 +94,65 @@ openclaw plugins install <plugin> --marketplace https://github.com/<owner>/<repo
|
||||
在发布切换期间,裸包名默认从 npm 安装。对 ClawHub 使用 `clawhub:<package>`。请像运行代码一样对待插件安装。优先使用固定版本。
|
||||
</Warning>
|
||||
|
||||
`plugins search` 会查询 ClawHub 中可安装的插件包,并打印可直接安装的包名。它搜索 code-plugin 和 bundle-plugin 包,而不是 Skills。使用 `openclaw skills search` 搜索 ClawHub Skills。
|
||||
`plugins search` 会查询 ClawHub 中可安装的插件包,并打印可直接安装的包名。它搜索代码插件和包插件包,而不是 Skills。使用 `openclaw skills search` 搜索 ClawHub Skills。
|
||||
|
||||
<Note>
|
||||
ClawHub 是大多数插件的主要分发和发现界面。Npm 仍是受支持的备用方式和直接安装路径。OpenClaw 拥有的 `@openclaw/*` 插件包已重新发布到 npm;请在 [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) 或[插件清单](/zh-CN/plugins/plugin-inventory)查看当前列表。稳定版安装使用 `latest`。当 npm `beta` dist-tag 可用时,beta 渠道的安装和更新会优先使用该标签,然后回退到 `latest`。
|
||||
ClawHub 是大多数插件的主要分发和设备发现界面。Npm 仍是受支持的回退和直接安装路径。OpenClaw 拥有的 `@openclaw/*` 插件包已再次发布到 npm;请在 [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) 或 [插件清单](/zh-CN/plugins/plugin-inventory) 查看当前列表。稳定安装使用 `latest`。Beta 渠道安装和更新会优先使用 npm `beta` dist-tag(如果该标签可用),然后回退到 `latest`。
|
||||
</Note>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="配置 include 与无效配置恢复">
|
||||
如果你的 `plugins` 区段由单文件 `$include` 支撑,`plugins install/update/enable/disable/uninstall` 会写入该被包含文件,并保持 `openclaw.json` 不变。根 include、include 数组,以及带同级覆盖项的 include 会封闭失败,而不是展平。有关受支持的形状,请参见 [Config includes](/zh-CN/gateway/configuration)。
|
||||
<Accordion title="配置 include 和无效配置恢复">
|
||||
如果你的 `plugins` 部分由单文件 `$include` 支持,`plugins install/update/enable/disable/uninstall` 会写入该包含文件,并保持 `openclaw.json` 不变。根 include、include 数组以及带有同级覆盖的 include 会失败关闭,而不是被扁平化。有关支持的形状,请参见 [配置 include](/zh-CN/gateway/configuration)。
|
||||
|
||||
如果安装期间配置无效,`plugins install` 通常会封闭失败,并提示你先运行 `openclaw doctor --fix`。在 Gateway 网关启动期间,某个插件的无效配置会被隔离到该插件,因此其他渠道和插件可以继续运行;`openclaw doctor --fix` 可以隔离该无效插件条目。唯一有文档说明的安装时例外,是针对显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的狭窄内置插件恢复路径。
|
||||
如果安装期间配置无效,`plugins install` 通常会失败关闭,并提示你先运行 `openclaw doctor --fix`。在 Gateway 网关启动期间,单个插件的无效配置会隔离到该插件,因此其他渠道和插件可以继续运行;`openclaw doctor --fix` 可以隔离无效插件条目。唯一有文档记录的安装时例外,是面向显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的窄范围内置插件恢复路径。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--force 与重新安装和更新">
|
||||
`--force` 会复用现有安装目标,并原地覆盖已安装的插件或钩子包。当你有意从新的本地路径、归档、ClawHub 包或 npm 工件重新安装相同 id 时使用它。对于已被跟踪的 npm 插件的常规升级,优先使用 `openclaw plugins update <id-or-npm-spec>`。
|
||||
<Accordion title="--force 以及重新安装与更新">
|
||||
`--force` 会复用现有安装目标,并原地覆盖已安装的插件或钩子包。当你有意从新的本地路径、归档、ClawHub 包或 npm 构件重新安装同一 id 时使用它。对于已跟踪 npm 插件的常规升级,优先使用 `openclaw plugins update <id-or-npm-spec>`。
|
||||
|
||||
如果你对已安装的插件 id 运行 `plugins install`,OpenClaw 会停止,并将你指向用于正常升级的 `plugins update <id-or-npm-spec>`,或者在你确实想从不同来源覆盖当前安装时指向 `plugins install <package> --force`。
|
||||
如果你对已安装的插件 id 运行 `plugins install`,OpenClaw 会停止并指引你使用 `plugins update <id-or-npm-spec>` 进行正常升级,或者在确实想从不同来源覆盖当前安装时使用 `plugins install <package> --force`。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--pin 作用范围">
|
||||
`--pin` 仅适用于 npm 安装。它不支持 `git:` 安装;如果你想固定来源,请使用显式 git ref,例如 `git:github.com/acme/plugin@v1.2.3`。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。
|
||||
<Accordion title="--pin 范围">
|
||||
`--pin` 仅适用于 npm 安装。它不支持 `git:` 安装;当你想要固定来源时,请使用显式 git ref,例如 `git:github.com/acme/plugin@v1.2.3`。它不支持 `--marketplace`,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。
|
||||
</Accordion>
|
||||
<Accordion title="--dangerously-force-unsafe-install">
|
||||
`--dangerously-force-unsafe-install` 是针对内置危险代码扫描器误报的破窗选项。即使内置扫描器报告 `critical` 发现,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻断,也**不会**绕过扫描失败。
|
||||
`--dangerously-force-unsafe-install` 是内置危险代码扫描器出现误报时的应急选项。即使内置扫描器报告 `critical` 发现项,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻止,也**不会**绕过扫描失败。
|
||||
|
||||
此 CLI 标志适用于插件安装/更新流程。Gateway 网关支持的 skill 依赖安装使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖项,而 `openclaw skills install` 仍是独立的 ClawHub skill 下载/安装流程。
|
||||
此 CLI 标志适用于插件安装/更新流程。由 Gateway 网关支持的 skill 依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍是单独的 ClawHub skill 下载/安装流程。
|
||||
|
||||
如果你发布到 ClawHub 的插件被 registry 扫描阻断,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。
|
||||
如果你发布到 ClawHub 的插件被注册表扫描阻止,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="钩子包与 npm specs">
|
||||
`plugins install` 也是安装在 `package.json` 中公开 `openclaw.hooks` 的钩子包的界面。请使用 `openclaw hooks` 查看经过筛选的钩子可见性和按钩子启用,而不是进行包安装。
|
||||
<Accordion title="钩子包和 npm specs">
|
||||
`plugins install` 也是安装在 `package.json` 中暴露 `openclaw.hooks` 的钩子包的入口。使用 `openclaw hooks` 查看筛选后的钩子可见性并启用单个钩子,而不是安装包。
|
||||
|
||||
Npm specs **仅限 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file specs 和 semver 范围会被拒绝。为安全起见,依赖安装以项目本地方式配合 `--ignore-scripts` 运行,即使你的 shell 配置了全局 npm 安装设置也是如此。
|
||||
Npm specs **仅限注册表**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file specs 和 semver 范围会被拒绝。依赖安装以项目本地方式运行,并出于安全原因使用 `--ignore-scripts`,即使你的 shell 配有全局 npm 安装设置也是如此。
|
||||
|
||||
当你想明确使用 npm 解析时,请使用 `npm:<package>`。在发布切换期间,裸包 spec 也会直接从 npm 安装。
|
||||
当你想明确使用 npm 解析时,请使用 `npm:<package>`。在发布切换期间,裸包 specs 也会直接从 npm 安装。
|
||||
|
||||
裸 specs 和 `@latest` 会留在稳定轨道。如果 npm 将其中任一种解析到预发布版本,OpenClaw 会停止,并要求你通过预发布标签(例如 `@beta`/`@rc`)或精确预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。
|
||||
裸 specs 和 `@latest` 会保持在稳定轨道上。如果 npm 将其中任一解析为预发布版,OpenClaw 会停止并要求你使用预发布标签(例如 `@beta`/`@rc`)或精确预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。
|
||||
|
||||
如果裸安装 spec 匹配官方插件 id(例如 `diffs`),OpenClaw 会直接安装目录条目。若要安装同名 npm 包,请使用显式 scoped spec(例如 `@scope/diffs`)。
|
||||
如果裸安装 spec 匹配官方插件 id(例如 `diffs`),OpenClaw 会直接安装目录条目。要安装同名 npm 包,请使用显式 scoped spec(例如 `@scope/diffs`)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Git 仓库">
|
||||
使用 `git:<repo>` 可直接从 git 仓库安装。受支持形式包括 `git:github.com/owner/repo`、`git:owner/repo`、完整 `https://`、`ssh://`、`git://`、`file://`,以及 `git@host:owner/repo.git` clone URL。添加 `@<ref>` 或 `#<ref>` 可在安装前检出分支、标签或提交。
|
||||
使用 `git:<repo>` 直接从 git 仓库安装。支持的形式包括 `git:github.com/owner/repo`、`git:owner/repo`、完整 `https://`、`ssh://`、`git://`、`file://` 以及 `git@host:owner/repo.git` 克隆 URL。添加 `@<ref>` 或 `#<ref>` 可在安装前检出分支、标签或提交。
|
||||
|
||||
Git 安装会 clone 到临时目录,在存在请求的 ref 时将其检出,然后使用普通插件目录安装器。这意味着清单校验、危险代码扫描、包管理器安装工作和安装记录的行为都与 npm 安装类似。记录的 git 安装包含来源 URL/ref 以及解析后的提交,以便 `openclaw plugins update` 后续可以重新解析来源。
|
||||
Git 安装会克隆到临时目录,在存在请求的 ref 时检出它,然后使用正常的插件目录安装器。这意味着清单验证、危险代码扫描、包管理器安装工作和安装记录的行为都类似 npm 安装。记录的 git 安装会包含来源 URL/ref 以及解析后的提交,因此 `openclaw plugins update` 稍后可以重新解析来源。
|
||||
|
||||
从 git 安装后,使用 `openclaw plugins inspect <id> --runtime --json` 验证运行时注册项,例如 gateway 方法和 CLI 命令。如果插件通过 `api.registerCli` 注册了 CLI 根命令,请直接通过 OpenClaw 根 CLI 执行该命令,例如 `openclaw demo-plugin ping`。
|
||||
从 git 安装后,使用 `openclaw plugins inspect <id> --runtime --json` 验证运行时注册项,例如 gateway 方法和 CLI 命令。如果插件使用 `api.registerCli` 注册了 CLI 根命令,请直接通过 OpenClaw 根 CLI 执行该命令,例如 `openclaw demo-plugin ping`。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="归档">
|
||||
支持的归档格式:`.zip`、`.tgz`、`.tar.gz`、`.tar`。原生 OpenClaw 插件归档必须在解压后的插件根目录包含有效的 `openclaw.plugin.json`;仅包含 `package.json` 的归档会在 OpenClaw 写入安装记录前被拒绝。
|
||||
支持的归档:`.zip`、`.tgz`、`.tar.gz`、`.tar`。原生 OpenClaw 插件归档必须在解压后的插件根目录包含有效的 `openclaw.plugin.json`;只包含 `package.json` 的归档会在 OpenClaw 写入安装记录前被拒绝。
|
||||
|
||||
也支持 Claude marketplace 安装。
|
||||
Claude marketplace 安装也受支持。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
ClawHub 安装使用显式 `clawhub:<package>` 定位符:
|
||||
ClawHub 安装使用显式 `clawhub:<package>` 定位器:
|
||||
|
||||
```bash
|
||||
openclaw plugins install clawhub:openclaw-codex-app-server
|
||||
@ -165,26 +165,26 @@ openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3
|
||||
openclaw plugins install openclaw-codex-app-server
|
||||
```
|
||||
|
||||
使用 `npm:` 可明确仅使用 npm 解析:
|
||||
使用 `npm:` 明确仅使用 npm 解析:
|
||||
|
||||
```bash
|
||||
openclaw plugins install npm:openclaw-codex-app-server
|
||||
openclaw plugins install npm:@scope/plugin-name@1.0.1
|
||||
```
|
||||
|
||||
OpenClaw 会在安装前检查宣告的插件 API / 最低 Gateway 网关兼容性。当选中的 ClawHub 版本发布了 ClawPack 工件时,OpenClaw 会下载带版本的 npm-pack `.tgz`,验证 ClawHub 摘要标头和工件摘要,然后通过普通归档路径安装。没有 ClawPack 元数据的较旧 ClawHub 版本仍会通过旧版包归档验证路径安装。记录的安装会保留其 ClawHub 来源元数据、工件类型、npm 完整性、npm shasum、tarball 名称,以及 ClawPack 摘要事实,以供后续更新。
|
||||
未指定版本的 ClawHub 安装会保留未指定版本的记录 spec,以便 `openclaw plugins update` 可以跟随后续 ClawHub 版本;显式版本或标签选择器(例如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍固定到该选择器。
|
||||
OpenClaw 会在安装前检查宣告的插件 API / 最低 gateway 兼容性。当选定的 ClawHub 版本发布 ClawPack 构件时,OpenClaw 会下载带版本的 npm-pack `.tgz`,验证 ClawHub 摘要标头和构件摘要,然后通过正常归档路径安装。没有 ClawPack 元数据的较旧 ClawHub 版本仍会通过旧版包归档验证路径安装。记录的安装会保留其 ClawHub 来源元数据、构件类型、npm integrity、npm shasum、tarball 名称和 ClawPack 摘要信息,以便后续更新。
|
||||
未指定版本的 ClawHub 安装会保留未指定版本的记录 spec,因此 `openclaw plugins update` 可以跟随后续 ClawHub 版本;显式版本或标签选择器(例如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍固定到该选择器。
|
||||
|
||||
#### Marketplace 简写
|
||||
|
||||
当 marketplace 名称存在于 Claude 的本地 registry 缓存 `~/.claude/plugins/known_marketplaces.json` 时,使用 `plugin@marketplace` 简写:
|
||||
当 marketplace 名称存在于 Claude 位于 `~/.claude/plugins/known_marketplaces.json` 的本地注册表缓存中时,使用 `plugin@marketplace` 简写:
|
||||
|
||||
```bash
|
||||
openclaw plugins marketplace list <marketplace-name>
|
||||
openclaw plugins install <plugin-name>@<marketplace-name>
|
||||
```
|
||||
|
||||
当你想显式传入 marketplace 来源时,使用 `--marketplace`:
|
||||
当你想显式传递 marketplace 来源时,使用 `--marketplace`:
|
||||
|
||||
```bash
|
||||
openclaw plugins install <plugin-name> --marketplace <marketplace-name>
|
||||
@ -194,31 +194,31 @@ openclaw plugins install <plugin-name> --marketplace ./my-marketplace
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<Tab title="市场来源">
|
||||
- 来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知市场名称
|
||||
- 本地市场根目录或 `marketplace.json` 路径
|
||||
<Tab title="Marketplace sources">
|
||||
- `~/.claude/plugins/known_marketplaces.json` 中 Claude 已知的 marketplace 名称
|
||||
- 本地 marketplace 根目录或 `marketplace.json` 路径
|
||||
- GitHub 仓库简写,例如 `owner/repo`
|
||||
- GitHub 仓库 URL,例如 `https://github.com/owner/repo`
|
||||
- git URL
|
||||
|
||||
</Tab>
|
||||
<Tab title="远程市场规则">
|
||||
对于从 GitHub 或 git 加载的远程市场,插件条目必须保留在克隆的市场仓库内。OpenClaw 接受来自该仓库的相对路径来源,并拒绝远程清单中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件来源。
|
||||
<Tab title="Remote marketplace rules">
|
||||
对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保留在克隆的 marketplace 仓库内。OpenClaw 接受来自该仓库的相对路径来源,并拒绝远程清单中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件来源。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
对于本地路径和归档,OpenClaw 会自动检测:
|
||||
对于本地路径和归档文件,OpenClaw 会自动检测:
|
||||
|
||||
- 原生 OpenClaw 插件(`openclaw.plugin.json`)
|
||||
- 兼容 Codex 的包(`.codex-plugin/plugin.json`)
|
||||
- 兼容 Claude 的包(`.claude-plugin/plugin.json` 或默认 Claude 组件布局)
|
||||
- 兼容 Cursor 的包(`.cursor-plugin/plugin.json`)
|
||||
- 兼容 Codex 的 bundle(`.codex-plugin/plugin.json`)
|
||||
- 兼容 Claude 的 bundle(`.claude-plugin/plugin.json` 或默认 Claude 组件布局)
|
||||
- 兼容 Cursor 的 bundle(`.cursor-plugin/plugin.json`)
|
||||
|
||||
<Note>
|
||||
兼容包会安装到正常的插件根目录,并参与同一套列表/信息/启用/停用流程。目前支持包 Skills、Claude 命令 Skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor 命令 Skills,以及兼容的 Codex 钩子目录;其他检测到的包能力会显示在诊断/信息中,但尚未接入运行时执行。
|
||||
兼容 bundle 会安装到普通插件根目录,并参与相同的列表/信息/启用/禁用流程。目前支持 bundle Skills、Claude 命令 Skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor 命令 Skills,以及兼容的 Codex hook 目录;其他检测到的 bundle 能力会显示在诊断/信息中,但尚未接入运行时执行。
|
||||
</Note>
|
||||
|
||||
### 列表
|
||||
### 列出
|
||||
|
||||
```bash
|
||||
openclaw plugins list
|
||||
@ -234,56 +234,46 @@ openclaw plugins search <query> --json
|
||||
仅显示已启用的插件。
|
||||
</ParamField>
|
||||
<ParamField path="--verbose" type="boolean">
|
||||
从表格视图切换为每个插件的详情行,包含来源/源头/版本/激活元数据。
|
||||
从表格视图切换为按插件显示的详情行,包含来源/origin/版本/激活元数据。
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
机器可读的清单,以及注册表诊断和包依赖安装状态。
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
`plugins list` 会先读取持久化的本地插件注册表;如果注册表缺失或无效,则使用仅由清单派生的回退。它适合检查某个插件是否已安装、已启用,并且对冷启动规划可见,但它不是对已在运行的 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、钩子策略或 `plugins.load.paths` 后,请先重启服务该渠道的 Gateway 网关,再预期新的 `register(api)` 代码或钩子会运行。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不只是包装进程。
|
||||
`plugins list` 会先读取持久化的本地插件注册表;当注册表缺失或无效时,会回退到仅从清单派生的结果。它适合用于检查插件是否已安装、已启用,并且对冷启动规划可见,但它不是对已运行 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、hook 策略或 `plugins.load.paths` 后,需要重启为该渠道提供服务的 Gateway 网关,之后新的 `register(api)` 代码或 hook 才会运行。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不仅是包装器进程。
|
||||
|
||||
`plugins list --json` 会包含每个插件来自 `package.json`
|
||||
`dependencies` 和 `optionalDependencies` 的 `dependencyStatus`。OpenClaw 会检查这些包
|
||||
名称是否存在于插件正常的 Node `node_modules` 查找路径上;它
|
||||
不会导入插件运行时代码、运行包管理器,也不会修复缺失的
|
||||
依赖。
|
||||
`plugins list --json` 包含每个插件来自 `package.json`
|
||||
`dependencies` 和 `optionalDependencies` 的 `dependencyStatus`。OpenClaw 会检查这些包名是否存在于插件正常的 Node `node_modules` 查找路径中;它不会导入插件运行时代码、运行包管理器,也不会修复缺失的依赖。
|
||||
</Note>
|
||||
|
||||
`plugins search` 是远程 ClawHub 目录查询。它不会检查本地
|
||||
状态、修改配置、安装包或加载插件运行时代码。搜索
|
||||
结果包含 ClawHub 包名、系列、渠道、版本、摘要,以及
|
||||
安装提示,例如 `openclaw plugins install clawhub:<package>`。
|
||||
`plugins search` 是远程 ClawHub 目录查询。它不会检查本地状态、修改配置、安装包或加载插件运行时代码。搜索结果包含 ClawHub 包名、族、渠道、版本、摘要,以及类似 `openclaw plugins install clawhub:<package>` 的安装提示。
|
||||
|
||||
对于打包 Docker 镜像内的内置插件工作,请把插件
|
||||
源码目录绑定挂载到匹配的打包源码路径上,例如
|
||||
`/app/extensions/synology-chat`。OpenClaw 会先发现该已挂载的源码
|
||||
覆盖层,再发现 `/app/dist/extensions/synology-chat`;普通复制的源码
|
||||
目录会保持不生效,因此正常的打包安装仍会使用已编译的 dist。
|
||||
在打包的 Docker 镜像内处理内置插件时,将插件源码目录绑定挂载到匹配的打包源码路径上,例如 `/app/extensions/synology-chat`。OpenClaw 会先发现这个已挂载的源码覆盖层,再发现 `/app/dist/extensions/synology-chat`;单纯复制的源码目录保持不生效,因此普通打包安装仍会使用已编译的 dist。
|
||||
|
||||
对于运行时钩子调试:
|
||||
对于运行时 hook 调试:
|
||||
|
||||
- `openclaw plugins inspect <id> --runtime --json` 会显示来自模块加载检查流程的已注册钩子和诊断。运行时检查从不安装依赖;使用 `openclaw doctor --fix` 清理旧版依赖状态,或安装缺失的已配置可下载插件。
|
||||
- `openclaw gateway status --deep --require-rpc` 会确认可访问的 Gateway 网关、服务/进程提示、配置路径和 RPC 健康状态。
|
||||
- 非内置会话钩子(`llm_input`、`llm_output`、`before_agent_finalize`、`agent_end`)需要 `plugins.entries.<id>.hooks.allowConversationAccess=true`。
|
||||
- `openclaw plugins inspect <id> --runtime --json` 会显示一次已加载模块检查过程中注册的 hook 和诊断。运行时检查绝不会安装依赖;请使用 `openclaw doctor --fix` 清理旧版依赖状态,或安装缺失的已配置可下载插件。
|
||||
- `openclaw gateway status --deep --require-rpc` 会确认可达的 Gateway 网关、服务/进程提示、配置路径和 RPC 健康状态。
|
||||
- 非内置会话 hook(`llm_input`、`llm_output`、`before_agent_finalize`、`agent_end`)需要 `plugins.entries.<id>.hooks.allowConversationAccess=true`。
|
||||
|
||||
使用 `--link` 避免复制本地目录(添加到 `plugins.load.paths`):
|
||||
使用 `--link` 以避免复制本地目录(会添加到 `plugins.load.paths`):
|
||||
|
||||
```bash
|
||||
openclaw plugins install -l ./my-plugin
|
||||
```
|
||||
|
||||
<Note>
|
||||
`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是覆盖托管安装目标。
|
||||
`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源码路径,而不是覆盖托管安装目标。
|
||||
|
||||
在 npm 安装时使用 `--pin`,可以把解析后的精确规格(`name@version`)保存到托管插件索引,同时保持默认行为为不固定版本。
|
||||
在 npm 安装中使用 `--pin`,可将解析后的精确 spec(`name@version`)保存到托管插件索引中,同时保持默认行为不固定版本。
|
||||
</Note>
|
||||
|
||||
### 插件索引
|
||||
|
||||
插件安装元数据是机器管理的状态,不是用户配置。安装和更新会把它写入当前 OpenClaw 状态目录下的 `plugins/installs.json`。它顶层的 `installRecords` 映射是安装元数据的持久来源,包括损坏或缺失插件清单的记录。`plugins` 数组是从清单派生的冷注册表缓存。该文件包含“请勿编辑”警告,并由 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。
|
||||
插件安装元数据是机器管理的状态,而不是用户配置。安装和更新会把它写入活跃 OpenClaw 状态目录下的 `plugins/installs.json`。其顶层 `installRecords` 映射是安装元数据的持久来源,包括清单损坏或缺失的插件记录。`plugins` 数组是从清单派生的冷注册表缓存。该文件包含请勿编辑警告,并被 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。
|
||||
|
||||
当 OpenClaw 在配置中看到随产品附带的旧版 `plugins.installs` 记录时,会将它们迁移到插件索引并移除该配置键;如果任一写入失败,配置记录会被保留,以免安装元数据丢失。
|
||||
当 OpenClaw 在配置中看到随版本交付的旧版 `plugins.installs` 记录时,会将它们迁移到插件索引并删除该配置键;如果任一写入失败,则会保留配置记录,以免安装元数据丢失。
|
||||
|
||||
### 卸载
|
||||
|
||||
@ -293,7 +283,7 @@ openclaw plugins uninstall <id> --dry-run
|
||||
openclaw plugins uninstall <id> --keep-files
|
||||
```
|
||||
|
||||
`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时的链接 `plugins.load.paths` 条目中移除插件记录。除非设置 `--keep-files`,卸载还会移除被跟踪的托管安装目录,前提是它位于 OpenClaw 的插件扩展根目录内。对于主动记忆插件,记忆槽会重置为 `memory-core`。
|
||||
`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时链接的 `plugins.load.paths` 条目中删除插件记录。除非设置了 `--keep-files`,否则卸载还会删除被跟踪的托管安装目录,前提是它位于 OpenClaw 的插件 extensions 根目录内。对于主动记忆插件,记忆槽位会重置为 `memory-core`。
|
||||
|
||||
<Note>
|
||||
`--keep-config` 作为 `--keep-files` 的已弃用别名受支持。
|
||||
@ -305,33 +295,33 @@ openclaw plugins uninstall <id> --keep-files
|
||||
openclaw plugins update <id-or-npm-spec>
|
||||
openclaw plugins update --all
|
||||
openclaw plugins update <id-or-npm-spec> --dry-run
|
||||
openclaw plugins update @openclaw/voice-call@beta
|
||||
openclaw plugins update @openclaw/voice-call
|
||||
openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install
|
||||
```
|
||||
|
||||
更新适用于托管插件索引中被跟踪的插件安装,以及 `hooks.internal.installs` 中被跟踪的钩子包安装。
|
||||
更新会应用到托管插件索引中被跟踪的插件安装,以及 `hooks.internal.installs` 中被跟踪的 hook-pack 安装。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="解析插件 id 与 npm 规格">
|
||||
当你传入插件 id 时,OpenClaw 会复用为该插件记录的安装规格。这意味着先前存储的 dist-tag(例如 `@beta`)和精确固定版本,会继续用于后续的 `update <id>` 运行。
|
||||
<Accordion title="Resolving plugin id vs npm spec">
|
||||
当你传入插件 ID 时,OpenClaw 会复用该插件记录的安装 spec。这意味着之前存储的 dist-tag(例如 `@beta`)和精确固定版本,会在后续 `update <id>` 运行中继续使用。
|
||||
|
||||
对于 npm 安装,你也可以传入带 dist-tag 或精确版本的显式 npm 包规格。OpenClaw 会将该包名解析回被跟踪的插件记录,更新该已安装插件,并记录新的 npm 规格,以供未来基于 id 的更新使用。
|
||||
对于 npm 安装,你也可以传入带 dist-tag 或精确版本的显式 npm 包 spec。OpenClaw 会将该包名解析回被跟踪的插件记录,更新该已安装插件,并记录新的 npm spec 供未来基于 ID 的更新使用。
|
||||
|
||||
传入不带版本或标签的 npm 包名也会解析回被跟踪的插件记录。当某个插件被固定到精确版本,而你想把它移回注册表默认发布线时,请使用这种方式。
|
||||
传入不带版本或 tag 的 npm 包名也会解析回被跟踪的插件记录。当某个插件固定到了精确版本,而你希望将其移回注册表的默认发布线时,请使用这种方式。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Beta 渠道更新">
|
||||
`openclaw plugins update` 会复用被跟踪的插件规格,除非你传入新规格。`openclaw update` 还知道当前的 OpenClaw 更新渠道:在 beta 渠道上,默认线 npm 和 ClawHub 插件记录会先尝试 `@beta`,如果不存在插件 beta 版本,再回退到记录的 default/latest 规格。精确版本和显式标签会继续固定到该选择器。
|
||||
<Accordion title="Beta channel updates">
|
||||
除非你传入新的 spec,否则 `openclaw plugins update` 会复用被跟踪的插件 spec。`openclaw update` 还知道当前活跃的 OpenClaw 更新渠道:在 beta 渠道上,默认线 npm 和 ClawHub 插件记录会先尝试 `@beta`,如果不存在插件 beta 版本,再回退到记录的 default/latest spec。精确版本和显式 tag 会继续固定到该选择器。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="版本检查和完整性漂移">
|
||||
在实时 npm 更新之前,OpenClaw 会根据 npm 注册表元数据检查已安装的包版本。如果已安装版本和已记录的制品身份已经与解析后的目标匹配,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。
|
||||
<Accordion title="Version checks and integrity drift">
|
||||
在执行实时 npm 更新之前,OpenClaw 会根据 npm 注册表元数据检查已安装的包版本。如果已安装版本和记录的工件身份已经与解析出的目标匹配,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。
|
||||
|
||||
当存在已存储的完整性哈希且获取到的制品哈希发生变化时,OpenClaw 会将其视为 npm 制品漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新辅助程序会默认失败关闭,除非调用方提供显式继续策略。
|
||||
当存在已存储的完整性哈希且获取到的工件哈希发生变化时,OpenClaw 会将其视为 npm 工件漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新助手会默认失败关闭,除非调用方提供显式继续策略。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="更新时使用 --dangerously-force-unsafe-install">
|
||||
`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的应急覆盖。它仍然不会绕过插件 `before_install` 策略阻止或扫描失败阻止,并且只适用于插件更新,不适用于钩子包更新。
|
||||
<Accordion title="--dangerously-force-unsafe-install on update">
|
||||
`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的应急覆盖开关。它仍然不会绕过插件 `before_install` 策略阻断或扫描失败阻断,并且只适用于插件更新,不适用于 hook-pack 更新。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -343,21 +333,21 @@ openclaw plugins inspect <id> --runtime
|
||||
openclaw plugins inspect <id> --json
|
||||
```
|
||||
|
||||
默认情况下,Inspect 会显示身份、加载状态、来源、清单能力、策略标志、诊断、安装元数据、包能力,以及任何检测到的 MCP 或 LSP 服务器支持,而不会导入插件运行时。添加 `--runtime` 可加载插件模块,并包含已注册的钩子、工具、命令、服务、Gateway 网关方法和 HTTP 路由。运行时检查会直接报告缺失的插件依赖;安装和修复仍留在 `openclaw plugins install`、`openclaw plugins update` 和 `openclaw doctor --fix` 中完成。
|
||||
默认情况下,Inspect 会显示身份、加载状态、来源、清单能力、策略标志、诊断、安装元数据、bundle 能力,以及任何检测到的 MCP 或 LSP 服务器支持,而不导入插件运行时。添加 `--runtime` 会加载插件模块,并包含已注册的 hook、工具、命令、服务、gateway 方法和 HTTP 路由。运行时检查会直接报告缺失的插件依赖;安装和修复仍由 `openclaw plugins install`、`openclaw plugins update` 和 `openclaw doctor --fix` 处理。
|
||||
|
||||
插件拥有的 CLI 命令会作为根 `openclaw` 命令组安装。`inspect --runtime` 在 `cliCommands` 下显示命令后,请以 `openclaw <command> ...` 运行它;例如,注册了 `demo-git` 的插件可以用 `openclaw demo-git ping` 验证。
|
||||
插件拥有的 CLI 命令会作为根 `openclaw` 命令组安装。`inspect --runtime` 在 `cliCommands` 下显示命令后,将其作为 `openclaw <command> ...` 运行;例如,注册了 `demo-git` 的插件可以用 `openclaw demo-git ping` 验证。
|
||||
|
||||
每个插件会按其在运行时实际注册的内容分类:
|
||||
每个插件会根据其在运行时实际注册的内容分类:
|
||||
|
||||
- **plain-capability** — 一种能力类型(例如仅提供商插件)
|
||||
- **hybrid-capability** — 多种能力类型(例如文本 + 语音 + 图像)
|
||||
- **hook-only** — 仅钩子,没有能力或界面
|
||||
- **non-capability** — 工具/命令/服务,但没有能力
|
||||
- **hook-only** — 只有 hook,没有能力或表面
|
||||
- **non-capability** — 有工具/命令/服务,但没有能力
|
||||
|
||||
关于能力模型的更多信息,请参阅 [插件形态](/zh-CN/plugins/architecture#plugin-shapes)。
|
||||
|
||||
<Note>
|
||||
`--json` 标志会输出适合脚本和审计使用的机器可读报告。`inspect --all` 会呈现覆盖全部插件的表格,包含形态、能力类型、兼容性通知、包能力和钩子摘要列。`info` 是 `inspect` 的别名。
|
||||
`--json` 标志会输出适合脚本处理和审计的机器可读报告。`inspect --all` 会呈现全局表格,包含形态、能力种类、兼容性提示、bundle 能力和 hook 摘要列。`info` 是 `inspect` 的别名。
|
||||
</Note>
|
||||
|
||||
### Doctor
|
||||
@ -366,9 +356,9 @@ openclaw plugins inspect <id> --json
|
||||
openclaw plugins doctor
|
||||
```
|
||||
|
||||
`doctor` 会报告插件加载错误、清单/发现诊断和兼容性通知。一切正常时,它会打印 `No plugin issues detected.`
|
||||
`doctor` 会报告插件加载错误、清单/发现诊断和兼容性提示。当一切正常时,它会打印 `No plugin issues detected.`
|
||||
|
||||
对于缺少 `register`/`activate` 导出等模块形态故障,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以便在诊断输出中包含紧凑的导出形态摘要。
|
||||
对于缺少 `register`/`activate` 导出等模块形态失败,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以在诊断输出中包含紧凑的导出形态摘要。
|
||||
|
||||
### 注册表
|
||||
|
||||
@ -378,24 +368,24 @@ openclaw plugins registry --refresh
|
||||
openclaw plugins registry --json
|
||||
```
|
||||
|
||||
本地插件注册表是 OpenClaw 为已安装插件身份、启用状态、来源元数据和贡献归属持久化的冷读取模型。正常启动、提供商归属查找、渠道设置分类和插件清单可以在不导入插件运行时模块的情况下读取它。
|
||||
本地插件注册表是 OpenClaw 对已安装插件身份、启用状态、来源元数据和贡献归属的持久化冷读模型。普通启动、提供商 owner 查找、渠道设置分类和插件清单可以读取它,而无需导入插件运行时模块。
|
||||
|
||||
使用 `plugins registry` 检查持久化注册表是否存在、是否为当前版本或是否陈旧。使用 `--refresh` 根据持久化插件索引、配置策略和清单/包元数据重建它。这是修复路径,不是运行时激活路径。
|
||||
使用 `plugins registry` 检查持久化注册表是否存在、是否当前有效或是否陈旧。使用 `--refresh` 可基于持久化插件索引、配置策略和清单/包元数据重建它。这是修复路径,不是运行时激活路径。
|
||||
|
||||
<Warning>
|
||||
`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是用于注册表读取失败的已弃用破窗兼容性开关。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;环境变量回退仅用于迁移推出期间的紧急启动恢复。
|
||||
`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是一个已弃用的紧急兼容开关,用于插件注册表读取失败。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;环境变量回退仅用于迁移逐步推出期间的紧急启动恢复。
|
||||
</Warning>
|
||||
|
||||
### Marketplace
|
||||
### 市场
|
||||
|
||||
```bash
|
||||
openclaw plugins marketplace list <source>
|
||||
openclaw plugins marketplace list <source> --json
|
||||
```
|
||||
|
||||
Marketplace 列表接受本地 marketplace 路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL,或 git URL。`--json` 会打印解析后的来源标签,以及已解析的 marketplace 清单和插件条目。
|
||||
市场列表接受本地市场路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL,或 git URL。`--json` 会打印解析后的来源标签,以及解析出的市场清单和插件条目。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [构建插件](/zh-CN/plugins/building-plugins)
|
||||
- [CLI 参考](/zh-CN/cli)
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想要插件安装、列出、更新或卸载的快速示例
|
||||
- 你想在 ClawHub 和 npm 插件分发之间做选择
|
||||
- 你想在 ClawHub 和 npm 插件分发之间做出选择
|
||||
- 你正在发布一个插件包
|
||||
sidebarTitle: Manage plugins
|
||||
summary: 安装、列出、卸载、更新和发布 OpenClaw 插件的快速示例
|
||||
summary: 用于安装、列出、卸载、更新和发布 OpenClaw 插件的快速示例
|
||||
title: 管理插件
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T19:23:30Z"
|
||||
generated_at: "2026-05-02T21:57:54Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c5a1c58da41b243cebe1c163048918a94c492b77fdae1613bd008cb267670041
|
||||
source_hash: ec25a811b942f155f5d5e4cac475dbef74f0616bc85ff182c74598184e910320
|
||||
source_path: plugins/manage-plugins.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
大多数插件工作流只需要几个命令:搜索、安装、重启 Gateway 网关、验证,并在不再需要插件时卸载。
|
||||
大多数插件工作流只需要几个命令:搜索、安装、重启 Gateway 网关、验证,以及在不再需要插件时卸载。
|
||||
|
||||
## 列出插件
|
||||
|
||||
@ -33,28 +33,28 @@ openclaw plugins list --json \
|
||||
| jq '.plugins[] | {id, enabled, format, source, dependencyStatus}'
|
||||
```
|
||||
|
||||
`plugins list` 是一次冷清单检查。它会显示 OpenClaw 可以从配置、清单和插件注册表中发现的内容;它不能证明已经运行的 Gateway 网关进程已导入该插件运行时。
|
||||
`plugins list` 是一次冷态清单检查。它显示 OpenClaw 能从配置、清单和插件注册表中发现的内容;它不能证明已经运行的 Gateway 网关进程已导入该插件运行时。
|
||||
|
||||
## 安装插件
|
||||
|
||||
```bash
|
||||
# Search ClawHub for plugin packages.
|
||||
# 在 ClawHub 中搜索插件包。
|
||||
openclaw plugins search "calendar"
|
||||
|
||||
# Bare package specs try ClawHub first, then npm fallback.
|
||||
# 裸包规范会先尝试 ClawHub,然后回退到 npm。
|
||||
openclaw plugins install <package>
|
||||
|
||||
# Force one source.
|
||||
# 强制使用一个来源。
|
||||
openclaw plugins install clawhub:<package>
|
||||
openclaw plugins install npm:<package>
|
||||
|
||||
# Install a specific version or dist-tag.
|
||||
# 安装特定版本或 dist-tag。
|
||||
openclaw plugins install clawhub:<package>@1.2.3
|
||||
openclaw plugins install clawhub:<package>@beta
|
||||
openclaw plugins install npm:@scope/openclaw-plugin@1.2.3
|
||||
openclaw plugins install npm:@openclaw/codex@beta
|
||||
openclaw plugins install npm:@openclaw/codex
|
||||
|
||||
# Install from git or a local development checkout.
|
||||
# 从 git 或本地开发检出安装。
|
||||
openclaw plugins install git:github.com/acme/openclaw-plugin@v1.0.0
|
||||
openclaw plugins install ./my-plugin
|
||||
openclaw plugins install --link ./my-plugin
|
||||
@ -67,7 +67,7 @@ openclaw gateway restart
|
||||
openclaw plugins inspect <plugin-id> --runtime --json
|
||||
```
|
||||
|
||||
当你需要证明插件已注册工具、钩子、服务、Gateway 网关方法或插件自有 CLI 命令等运行时表面时,请使用 `inspect --runtime`。
|
||||
当你需要证明插件已注册运行时表面时,请使用 `inspect --runtime`,例如工具、钩子、服务、Gateway 网关方法,或插件拥有的 CLI 命令。
|
||||
|
||||
## 更新插件
|
||||
|
||||
@ -77,16 +77,16 @@ openclaw plugins update <npm-package-or-spec>
|
||||
openclaw plugins update --all
|
||||
```
|
||||
|
||||
如果插件是从 npm dist-tag(例如 `@beta`)安装的,后续 `update <plugin-id>` 调用会复用记录的该标签。传入显式 npm spec 会将后续更新跟踪的安装切换到该 spec。
|
||||
如果插件是从 npm dist-tag(例如 `@beta`)安装的,后续 `update <plugin-id>` 调用会复用该记录的标签。传入显式 npm 规范会将被跟踪的安装切换到该规范,以供后续更新使用。
|
||||
|
||||
```bash
|
||||
openclaw plugins update @scope/openclaw-plugin@beta
|
||||
openclaw plugins update @scope/openclaw-plugin
|
||||
```
|
||||
|
||||
当插件先前被固定到精确版本或标签时,第二个命令会将插件移回注册表的默认发布线。
|
||||
当插件此前固定到精确版本或标签时,第二个命令会将插件移回注册表的默认发布线。
|
||||
|
||||
当 `openclaw update` 在 beta 渠道运行时,默认线 npm 和 ClawHub 插件记录会先尝试匹配的插件 `@beta` 发布版。如果该 beta 发布版不存在,OpenClaw 会回退到记录的 default/latest spec。精确版本和显式标签(例如 `@rc` 或 `@beta`)会被保留。
|
||||
当 `openclaw update` 在 beta 渠道上运行时,默认线 npm 和 ClawHub 插件记录会先尝试匹配的插件 `@beta` 版本。如果该 beta 版本不存在,OpenClaw 会回退到记录的默认/latest 规范。精确版本和显式标签(例如 `@rc` 或 `@beta`)会被保留。
|
||||
|
||||
## 卸载插件
|
||||
|
||||
@ -101,7 +101,7 @@ openclaw gateway restart
|
||||
|
||||
## 发布插件
|
||||
|
||||
你可以将外部插件发布到 [ClawHub](https://clawhub.ai)、npmjs.com,或两者都发布。
|
||||
你可以将外部插件发布到 [ClawHub](https://clawhub.ai)、npmjs.com,或同时发布到两者。
|
||||
|
||||
### 发布到 ClawHub
|
||||
|
||||
@ -115,7 +115,7 @@ clawhub package publish your-org/your-plugin
|
||||
clawhub package publish your-org/your-plugin@v1.0.0
|
||||
```
|
||||
|
||||
用户可以通过以下方式从 ClawHub 安装:
|
||||
用户可通过以下方式从 ClawHub 安装:
|
||||
|
||||
```bash
|
||||
openclaw plugins install clawhub:<package>
|
||||
@ -143,7 +143,7 @@ openclaw plugins install <package>
|
||||
npm publish --access public
|
||||
```
|
||||
|
||||
用户可以通过以下方式仅从 npm 安装:
|
||||
用户可通过以下方式安装仅 npm 的插件:
|
||||
|
||||
```bash
|
||||
openclaw plugins install npm:@acme/openclaw-plugin
|
||||
@ -151,16 +151,16 @@ openclaw plugins install npm:@acme/openclaw-plugin@beta
|
||||
openclaw plugins install npm:@acme/openclaw-plugin@1.0.0
|
||||
```
|
||||
|
||||
如果同一个包也可在 ClawHub 上获取,`npm:` 会跳过 ClawHub 查找并强制使用 npm 解析。
|
||||
如果同一个包也可在 ClawHub 上获得,`npm:` 会跳过 ClawHub 查找,并强制使用 npm 解析。
|
||||
|
||||
## 来源选择
|
||||
|
||||
- **ClawHub**:当你需要 OpenClaw 原生的发现、扫描摘要、版本和安装提示时使用。
|
||||
- **ClawHub**:当你需要 OpenClaw 原生发现、扫描摘要、版本和安装提示时使用。
|
||||
- **npmjs.com**:当你已经发布 JavaScript 包,或需要 npm dist-tag/私有注册表工作流时使用。
|
||||
- **Git**:当你想直接从分支、标签或提交安装时使用。
|
||||
- **本地路径**:当你在同一台机器上开发或测试插件时使用。
|
||||
- **本地路径**:当你正在同一台机器上开发或测试插件时使用。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [插件](/zh-CN/tools/plugin) - 概览和故障排除
|
||||
- [`openclaw plugins`](/zh-CN/cli/plugins) - 完整 CLI 参考
|
||||
|
||||
@ -2,38 +2,44 @@
|
||||
read_when:
|
||||
- 你想从 OpenClaw 发起外呼语音通话
|
||||
- 你正在配置或开发语音通话插件
|
||||
- 你需要电话通信中的实时语音或流式转录
|
||||
- 你需要在电话通信中使用实时语音或流式转录
|
||||
sidebarTitle: Voice call
|
||||
summary: 通过 Twilio、Telnyx 或 Plivo 拨打出站语音电话并接听入站语音电话,可选支持实时语音和流式转录
|
||||
summary: 通过 Twilio、Telnyx 或 Plivo 发起外呼并接听来电,支持可选的实时语音和流式转录
|
||||
title: 语音通话插件
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:05:30Z"
|
||||
generated_at: "2026-05-02T21:57:59Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 1cf78847a16cdf6fddc47d045d1cad5acf70f7f220fb868a12ff9d69d6cbde6e
|
||||
source_hash: 18a9a0d7095ec92036b516cc26c69219a0a2fd9bb8e0cb2e7509123bb4f3f65a
|
||||
source_path: plugins/voice-call.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 的语音通话通过插件实现。支持出站通知、多轮对话、全双工实时语音、流式转写,以及带允许列表策略的入站通话。
|
||||
通过插件为 OpenClaw 提供语音通话。支持出站通知、
|
||||
多轮对话、全双工实时语音、流式转写,
|
||||
以及带允许列表策略的入站来电。
|
||||
|
||||
**当前提供商:** `twilio`(Programmable Voice + Media Streams)、`telnyx`(Call Control v2)、`plivo`(Voice API + XML transfer + GetInput speech)、`mock`(开发/无网络)。
|
||||
**当前提供商:** `twilio`(Programmable Voice + Media Streams)、
|
||||
`telnyx`(Call Control v2)、`plivo`(Voice API + XML 转接 + GetInput
|
||||
语音)、`mock`(开发/无网络)。
|
||||
|
||||
<Note>
|
||||
Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,然后重启 Gateway 网关以加载它。
|
||||
Voice Call 插件运行在 **Gateway 网关进程内**。如果你使用
|
||||
远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,
|
||||
然后重启 Gateway 网关以加载它。
|
||||
</Note>
|
||||
|
||||
## 快速开始
|
||||
|
||||
<Steps>
|
||||
<Step title="Install the plugin">
|
||||
<Step title="安装插件">
|
||||
<Tabs>
|
||||
<Tab title="From npm">
|
||||
<Tab title="来自 npm">
|
||||
```bash
|
||||
openclaw plugins install @openclaw/voice-call
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="From a local folder (dev)">
|
||||
<Tab title="来自本地文件夹(开发)">
|
||||
```bash
|
||||
PLUGIN_SRC=./path/to/local/voice-call-plugin
|
||||
openclaw plugins install "$PLUGIN_SRC"
|
||||
@ -42,29 +48,36 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
当你跟随 OpenClaw beta 渠道且 npmjs 显示 `beta` 领先于 `latest` 时,请使用 `@openclaw/voice-call@beta`。
|
||||
使用裸包名以跟随当前官方发布标签。只有在需要可复现安装时,
|
||||
才固定到精确版本。
|
||||
|
||||
随后重启 Gateway 网关,让插件加载。
|
||||
随后重启 Gateway 网关,以便插件加载。
|
||||
|
||||
</Step>
|
||||
<Step title="Configure provider and webhook">
|
||||
在 `plugins.entries.voice-call.config` 下设置配置(完整结构见下方的[配置](#configuration))。至少需要:`provider`、提供商凭证、`fromNumber`,以及一个可公开访问的 webhook URL。
|
||||
<Step title="配置提供商和 webhook">
|
||||
在 `plugins.entries.voice-call.config` 下设置配置(完整结构见下方
|
||||
[配置](#configuration))。至少需要:
|
||||
`provider`、提供商凭证、`fromNumber`,以及一个可公开访问的 webhook URL。
|
||||
</Step>
|
||||
<Step title="Verify setup">
|
||||
<Step title="验证设置">
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
```
|
||||
|
||||
默认输出适合在聊天日志和终端中阅读。它会检查插件启用状态、提供商凭证、webhook 暴露,以及是否只有一个音频模式(`streaming` 或 `realtime`)处于活跃状态。脚本请使用 `--json`。
|
||||
默认输出适合在聊天日志和终端中阅读。它会检查
|
||||
插件启用状态、提供商凭证、webhook 暴露情况,
|
||||
以及是否只有一种音频模式(`streaming` 或 `realtime`)处于活动状态。
|
||||
脚本请使用 `--json`。
|
||||
|
||||
</Step>
|
||||
<Step title="Smoke test">
|
||||
<Step title="冒烟测试">
|
||||
```bash
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
两者默认都是试运行。添加 `--yes` 可实际发起一次短的出站通知通话:
|
||||
两者默认都是空运行。添加 `--yes` 可真正发起一次简短的
|
||||
出站通知通话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" --yes
|
||||
@ -74,15 +87,21 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
</Steps>
|
||||
|
||||
<Warning>
|
||||
对于 Twilio、Telnyx 和 Plivo,设置必须解析为**公共 webhook URL**。如果 `publicUrl`、隧道 URL、Tailscale URL 或服务回退解析到 loopback 或私有网络空间,设置会失败,而不是启动一个无法接收运营商 webhook 的提供商。
|
||||
对于 Twilio、Telnyx 和 Plivo,设置必须解析到一个**公开 webhook URL**。
|
||||
如果 `publicUrl`、隧道 URL、Tailscale URL 或 serve 回退地址
|
||||
解析到 loopback 或私有网络空间,设置会失败,而不是启动一个
|
||||
无法接收运营商 webhook 的提供商。
|
||||
</Warning>
|
||||
|
||||
## 配置
|
||||
|
||||
如果 `enabled: true` 但所选提供商缺少凭证,Gateway 网关启动时会记录一条 setup-incomplete 警告,包含缺失键名,并跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会返回确切缺失的提供商配置。
|
||||
如果 `enabled: true` 但所选提供商缺少凭证,
|
||||
Gateway 网关启动时会记录一条设置未完成警告,列出缺失键名,
|
||||
并跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会
|
||||
返回精确缺失的提供商配置。
|
||||
|
||||
<Note>
|
||||
语音通话凭证支持 SecretRefs。`plugins.entries.voice-call.config.twilio.authToken`、`plugins.entries.voice-call.config.realtime.providers.*.apiKey`、`plugins.entries.voice-call.config.streaming.providers.*.apiKey` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;见 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。
|
||||
Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.authToken`、`plugins.entries.voice-call.config.realtime.providers.*.apiKey`、`plugins.entries.voice-call.config.streaming.providers.*.apiKey` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;见 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。
|
||||
</Note>
|
||||
|
||||
```json5
|
||||
@ -155,27 +174,31 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Provider exposure and security notes">
|
||||
<Accordion title="提供商暴露与安全说明">
|
||||
- Twilio、Telnyx 和 Plivo 都需要一个**可公开访问**的 webhook URL。
|
||||
- `mock` 是本地开发提供商(不发起网络调用)。
|
||||
- `mock` 是本地开发提供商(无网络调用)。
|
||||
- Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`),除非 `skipSignatureVerification` 为 true。
|
||||
- `skipSignatureVerification` 仅用于本地测试。
|
||||
- 在 ngrok 免费层上,将 `publicUrl` 设置为确切的 ngrok URL;签名验证始终强制执行。
|
||||
- 在 ngrok 免费层上,将 `publicUrl` 设置为精确的 ngrok URL;签名验证始终强制执行。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许带无效签名的 Twilio webhook。仅限本地开发。
|
||||
- Ngrok 免费层 URL 可能变化或添加插页行为;如果 `publicUrl` 漂移,Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。
|
||||
- Ngrok 免费层 URL 可能会变化或增加中间页行为;如果 `publicUrl` 漂移,Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Streaming connection caps">
|
||||
<Accordion title="流式连接上限">
|
||||
- `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的套接字。
|
||||
- `streaming.maxPendingConnections` 限制未认证预启动套接字总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证预启动套接字数量。
|
||||
- `streaming.maxConnections` 限制打开的媒体流套接字总数(待处理 + 活跃)。
|
||||
- `streaming.maxPendingConnections` 限制未经认证的预启动套接字总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未经认证预启动套接字数。
|
||||
- `streaming.maxConnections` 限制打开的媒体流套接字总数(待处理 + 活动)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Legacy config migrations">
|
||||
使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。运行时回退目前仍接受旧的 voice-call 键,但重写路径是 `openclaw doctor --fix`,兼容 shim 是临时的。
|
||||
<Accordion title="旧版配置迁移">
|
||||
使用 `provider: "log"`、`twilio.from` 或旧版
|
||||
`streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。
|
||||
运行时回退目前仍会接受旧的 voice-call 键,但
|
||||
重写路径是 `openclaw doctor --fix`,兼容垫片是
|
||||
临时的。
|
||||
|
||||
自动迁移的 streaming 键:
|
||||
自动迁移的流式键:
|
||||
|
||||
- `streaming.sttProvider` → `streaming.provider`
|
||||
- `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
|
||||
@ -188,26 +211,32 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
|
||||
## 会话作用域
|
||||
|
||||
默认情况下,Voice Call 使用 `sessionScope: "per-phone"`,因此同一来电者的重复通话会保留对话记忆。当每次运营商通话都应从全新上下文开始时,请设置 `sessionScope: "per-call"`,例如接待、预约、IVR,或同一电话号码可能代表不同会议的 Google Meet bridge 流程。
|
||||
默认情况下,Voice Call 使用 `sessionScope: "per-phone"`,因此来自
|
||||
同一来电者的重复来电会保留对话记忆。当每次运营商通话都应以
|
||||
全新上下文开始时,请设置 `sessionScope: "per-call"`,例如前台接待、
|
||||
预订、IVR,或同一电话号码可能代表不同会议的 Google Meet 桥接流程。
|
||||
|
||||
## 实时语音对话
|
||||
|
||||
`realtime` 会为实时通话音频选择一个全双工实时语音提供商。它与 `streaming` 分离,后者只会把音频转发到实时转写提供商。
|
||||
`realtime` 会为实时通话音频选择一个全双工实时语音提供商。
|
||||
它与 `streaming` 分离,后者只会将音频转发给
|
||||
实时转写提供商。
|
||||
|
||||
<Warning>
|
||||
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话请选择一种音频模式。
|
||||
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话请选择一种
|
||||
音频模式。
|
||||
</Warning>
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- Twilio Media Streams 支持 `realtime.enabled`。
|
||||
- `realtime.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时语音提供商。
|
||||
- `realtime.enabled` 支持 Twilio Media Streams。
|
||||
- `realtime.provider` 是可选的。如果未设置,Voice Call 会使用第一个注册的实时语音提供商。
|
||||
- 内置实时语音提供商:Google Gemini Live(`google`)和 OpenAI(`openai`),由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深层推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- `realtime.fastContext.enabled` 默认关闭。启用后,Voice Call 会先针对 consult 问题搜索已索引的记忆/会话上下文,并在 `realtime.fastContext.timeoutMs` 内将这些片段返回给实时模型;仅当 `realtime.fastContext.fallbackToConsult` 为 true 时,才回退到完整 consult 智能体。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或根本没有注册实时语音提供商,Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。
|
||||
- consult 会话键会在可用时复用已存储的通话会话,然后回退到配置的 `sessionScope`(默认 `per-phone`,隔离通话为 `per-call`)。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- `realtime.fastContext.enabled` 默认关闭。启用后,Voice Call 会先为 consult 问题搜索已索引的记忆/会话上下文,并在 `realtime.fastContext.timeoutMs` 内将这些片段返回给实时模型;只有当 `realtime.fastContext.fallbackToConsult` 为 true 时,才会回退到完整 consult 智能体。
|
||||
- 如果 `realtime.provider` 指向未注册提供商,或完全没有注册实时语音提供商,Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。
|
||||
- consult 会话键会在可用时复用已存储的通话会话,然后回退到配置的 `sessionScope`(默认为 `per-phone`,或用于隔离通话的 `per-call`)。
|
||||
|
||||
### 工具策略
|
||||
|
||||
@ -216,14 +245,16 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
| 策略 | 行为 |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `safe-read-only` | 暴露 consult 工具,并将常规智能体限制为 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。 |
|
||||
| `owner` | 暴露 consult 工具,并允许常规智能体使用普通智能体工具策略。 |
|
||||
| `none` | 不暴露 consult 工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
|
||||
| `owner` | 暴露 consult 工具,并让常规智能体使用普通智能体工具策略。 |
|
||||
| `none` | 不暴露 consult 工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
|
||||
|
||||
### 实时提供商示例
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Google Gemini Live">
|
||||
默认值:API key 来自 `realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`;模型为 `gemini-2.5-flash-native-audio-preview-12-2025`;语音为 `Kore`。
|
||||
默认值:API key 来自 `realtime.providers.google.apiKey`、
|
||||
`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`;模型
|
||||
`gemini-2.5-flash-native-audio-preview-12-2025`;语音 `Kore`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -278,7 +309,8 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
提供商特定的实时语音选项见 [Google provider](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。
|
||||
有关提供商特定的实时语音选项,请参阅 [Google 提供商](/zh-CN/providers/google) 和
|
||||
[OpenAI provider](/zh-CN/providers/openai)。
|
||||
|
||||
## 流式转写
|
||||
|
||||
@ -286,11 +318,11 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- `streaming.provider` 是可选的。如果未设置,语音通话会使用第一个已注册的实时转录提供商。
|
||||
- 内置实时转录提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由它们各自的提供商插件注册。
|
||||
- `streaming.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时转写提供商。
|
||||
- 内置实时转写提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- 在 Twilio 发送已接受的流 `start` 消息后,语音通话会立即注册该流,在提供商连接期间通过转录提供商排队入站媒体,并且只在实时转录就绪后才开始初始问候语。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或没有任何提供商已注册,语音通话会记录警告并跳过媒体流式传输,而不是让整个插件失败。
|
||||
- Twilio 发送已接受的流 `start` 消息后,Voice Call 会立即注册该流,在提供商连接期间通过转写提供商排队处理入站媒体,并且只在实时转写就绪后才开始初始问候。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或者没有注册任何提供商,Voice Call 会记录警告并跳过媒体流式传输,而不是让整个插件失败。
|
||||
|
||||
### 流式传输提供商示例
|
||||
|
||||
@ -362,8 +394,7 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
|
||||
## 通话的 TTS
|
||||
|
||||
语音通话使用核心 `messages.tts` 配置来处理通话中的流式
|
||||
语音。你可以在插件配置下用**相同结构**覆盖它——它会与 `messages.tts` 深度合并。
|
||||
Voice Call 使用核心 `messages.tts` 配置来为通话进行流式语音输出。你可以在插件配置下用**相同结构**覆盖它,它会与 `messages.tts` 深度合并。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -381,21 +412,21 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
|
||||
<Warning>
|
||||
**Microsoft speech 会被语音通话忽略。** 电话音频需要 PCM;
|
||||
当前的 Microsoft 传输协议不公开电话 PCM 输出。
|
||||
当前 Microsoft 传输协议未公开电话 PCM 输出。
|
||||
</Warning>
|
||||
|
||||
行为说明:
|
||||
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会由 `openclaw doctor --fix` 修复;已提交的配置应使用 `tts.providers.<provider>`。
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会由 `openclaw doctor --fix` 修复;提交的配置应使用 `tts.providers.<provider>`。
|
||||
- 启用 Twilio 媒体流式传输时会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已处于活动状态,语音通话不会回退到 TwiML `<Say>`。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混合两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,语音通话会记录一条包含提供商链(`from`、`to`、`attempts`)的警告,便于调试。
|
||||
- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不会让来电者一直等待播放完成。
|
||||
- 如果 Twilio 媒体流已经处于活动状态,Voice Call 不会回退到 TwiML `<Say>`。如果此状态下电话 TTS 不可用,播放请求会失败,而不是混合两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,Voice Call 会记录带有提供商链(`from`、`to`、`attempts`)的警告,用于调试。
|
||||
- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不是让呼叫者一直等待播放完成。
|
||||
|
||||
### TTS 示例
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Core TTS only">
|
||||
<Tab title="仅核心 TTS">
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
@ -409,7 +440,7 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Override to ElevenLabs (calls only)">
|
||||
<Tab title="覆盖到 ElevenLabs(仅通话)">
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
@ -433,7 +464,7 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="OpenAI model override (deep-merge)">
|
||||
<Tab title="OpenAI 模型覆盖(深度合并)">
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
@ -470,29 +501,17 @@ Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远
|
||||
```
|
||||
|
||||
<Warning>
|
||||
`inboundPolicy: "allowlist"` 是一种低保证的来电显示筛选。
|
||||
插件会规范化提供商提供的 `From` 值,并将其与
|
||||
`allowFrom` 比较。Webhook 验证会认证提供商投递和
|
||||
载荷完整性,但它**不会**证明 PSTN/VoIP 主叫号码
|
||||
所有权。请将 `allowFrom` 视为来电显示过滤,而不是强主叫
|
||||
身份。
|
||||
`inboundPolicy: "allowlist"` 是低保障的来电号码筛选。该插件会规范化提供商提供的 `From` 值并将其与 `allowFrom` 比较。Webhook 验证会认证提供商投递和载荷完整性,但它**不能**证明 PSTN/VoIP 来电号码所有权。请将 `allowFrom` 视为来电号码过滤,而不是强来电身份认证。
|
||||
</Warning>
|
||||
|
||||
自动响应使用智能体系统。可通过 `responseModel`、
|
||||
`responseSystemPrompt` 和 `responseTimeoutMs` 调整。
|
||||
自动响应使用智能体系统。通过 `responseModel`、`responseSystemPrompt` 和 `responseTimeoutMs` 调整。
|
||||
|
||||
### 按号码路由
|
||||
|
||||
当一个语音通话插件接收多个电话号码的来电,并且每个号码都应像不同线路一样工作时,请使用 `numbers`。例如,一个
|
||||
号码可以使用随意的个人助手,而另一个使用商务
|
||||
人设、不同的响应智能体和不同的 TTS 语音。
|
||||
当一个 Voice Call 插件接收多个电话号码的通话,并且每个号码都应像不同线路一样运作时,使用 `numbers`。例如,一个号码可以使用轻松的个人助理,而另一个号码使用商务人格、不同的响应智能体以及不同的 TTS 语音。
|
||||
|
||||
路由会根据提供商提供的被叫 `To` 号码选择。键必须是
|
||||
E.164 号码。当来电到达时,语音通话会解析一次匹配路由,
|
||||
将匹配的路由存储在通话记录上,并为问候语、经典自动响应路径、实时咨询路径和 TTS
|
||||
播放复用该生效配置。如果没有路由匹配,则使用全局语音通话配置。
|
||||
出站通话不使用 `numbers`;发起通话时请显式传入出站目标、消息和
|
||||
会话。
|
||||
路由会根据提供商提供的被拨 `To` 号码选择。键必须是 E.164 号码。通话到达时,Voice Call 会解析一次匹配路由,将匹配路由存储在通话记录上,并在问候、经典自动响应路径、实时咨询路径和 TTS 播放中复用该有效配置。如果没有路由匹配,则使用全局 Voice Call 配置。
|
||||
出站通话不使用 `numbers`;发起通话时请显式传入出站目标、消息和会话。
|
||||
|
||||
路由覆盖目前支持:
|
||||
|
||||
@ -503,8 +522,7 @@ E.164 号码。当来电到达时,语音通话会解析一次匹配路由,
|
||||
- `responseSystemPrompt`
|
||||
- `responseTimeoutMs`
|
||||
|
||||
`tts` 路由值会深度合并到全局语音通话 `tts` 配置之上,因此
|
||||
通常只需覆盖提供商语音:
|
||||
`tts` 路由值会深度合并到全局 Voice Call `tts` 配置之上,所以通常只需覆盖提供商语音:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -532,49 +550,45 @@ E.164 号码。当来电到达时,语音通话会解析一次匹配路由,
|
||||
|
||||
### 语音输出契约
|
||||
|
||||
对于自动响应,语音通话会向系统提示词追加严格的语音输出契约:
|
||||
对于自动响应,Voice Call 会向系统提示词追加严格的语音输出契约:
|
||||
|
||||
```text
|
||||
{"spoken":"..."}
|
||||
```
|
||||
|
||||
语音通话会防御性地提取语音文本:
|
||||
Voice Call 会以防御性方式提取语音文本:
|
||||
|
||||
- 忽略标记为推理/错误内容的载荷。
|
||||
- 解析直接 JSON、围栏 JSON,或内联 `"spoken"` 键。
|
||||
- 回退到纯文本,并移除可能的规划/元信息开头段落。
|
||||
|
||||
这会让语音播放聚焦于面向来电者的文本,并避免将规划文本泄露到音频中。
|
||||
这会让语音播放聚焦于面向呼叫者的文本,并避免将规划文本泄漏到音频中。
|
||||
|
||||
### 对话启动行为
|
||||
|
||||
对于出站 `conversation` 通话,首条消息处理与实时
|
||||
播放状态绑定:
|
||||
对于出站 `conversation` 通话,首条消息处理会绑定到实时播放状态:
|
||||
|
||||
- 只有在初始问候语正在主动播报时,才会抑制插话队列清空和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening`,并且初始消息仍会排队等待重试。
|
||||
- 仅在初始问候正在主动说话时,才会抑制插话队列清空和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening`,并且初始消息会继续排队以便重试。
|
||||
- Twilio 流式传输的初始播放会在流连接时开始,不会额外延迟。
|
||||
- 插话会中止活动播放,并清空已排队但尚未播放的 Twilio TTS 条目。被清空的条目会解析为已跳过,因此后续响应逻辑无需等待永远不会播放的音频即可继续。
|
||||
- 实时语音对话使用实时流自身的开场轮次。语音通话**不会**为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持连接。
|
||||
- 插话会中止活动播放,并清空已排队但尚未播放的 Twilio TTS 条目。已清空条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。
|
||||
- 实时语音对话使用实时流自身的开场轮次。Voice Call **不会**为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持附加状态。
|
||||
|
||||
### Twilio 流断开宽限期
|
||||
|
||||
当 Twilio 媒体流断开连接时,语音通话会等待 **2000 ms** 后再
|
||||
自动结束通话:
|
||||
当 Twilio 媒体流断开时,Voice Call 会等待 **2000 ms** 后再自动结束通话:
|
||||
|
||||
- 如果流在该窗口内重新连接,自动结束会被取消。
|
||||
- 如果宽限期后没有流重新注册,则结束通话以防止活动通话卡住。
|
||||
- 如果流在该窗口期内重新连接,自动结束会被取消。
|
||||
- 如果宽限期后没有流重新注册,通话会被结束,以防止出现卡住的活动通话。
|
||||
|
||||
## 过期通话清理器
|
||||
## 过期通话回收器
|
||||
|
||||
使用 `staleCallReaperSeconds` 结束从未收到终端
|
||||
Webhook 的通话(例如永不完成的通知模式通话)。默认值
|
||||
是 `0`(禁用)。
|
||||
使用 `staleCallReaperSeconds` 结束从未收到终止 webhook 的通话(例如永远没有完成的通知模式通话)。默认值是 `0`(已禁用)。
|
||||
|
||||
推荐范围:
|
||||
|
||||
- **生产环境:** 对于通知式流程,使用 `120`–`300` 秒。
|
||||
- 保持该值**高于 `maxDurationSeconds`**,以便正常通话可以完成。一个好的起点是 `maxDurationSeconds + 30–60` 秒。
|
||||
- **生产环境:** 对通知式流程使用 `120`–`300` 秒。
|
||||
- 保持该值**高于 `maxDurationSeconds`**,以便正常通话可以结束。一个好的起点是 `maxDurationSeconds + 30–60` 秒。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -593,26 +607,24 @@ Webhook 的通话(例如永不完成的通知模式通话)。默认值
|
||||
|
||||
## Webhook 安全
|
||||
|
||||
当代理或隧道位于 Gateway 网关 前面时,插件会
|
||||
重建用于签名验证的公开 URL。这些选项
|
||||
控制信任哪些转发标头:
|
||||
当代理或隧道位于 Gateway 网关前方时,该插件会重建用于签名验证的公开 URL。这些选项控制哪些转发标头受信任:
|
||||
|
||||
<ParamField path="webhookSecurity.allowedHosts" type="string[]">
|
||||
允许来自转发标头的主机列表。
|
||||
允许来自转发标头的主机名单。
|
||||
</ParamField>
|
||||
<ParamField path="webhookSecurity.trustForwardingHeaders" type="boolean">
|
||||
在没有允许列表的情况下信任转发标头。
|
||||
在没有允许名单的情况下信任转发标头。
|
||||
</ParamField>
|
||||
<ParamField path="webhookSecurity.trustedProxyIPs" type="string[]">
|
||||
仅当请求远程 IP 与列表匹配时才信任转发标头。
|
||||
</ParamField>
|
||||
|
||||
额外保护:
|
||||
其他防护:
|
||||
|
||||
- Twilio 和 Plivo 启用 Webhook **重放保护**。重放的有效 Webhook 请求会被确认,但会跳过副作用。
|
||||
- Twilio 对话轮次在 `<Gather>` 回调中包含每轮令牌,因此过期/重放的语音回调无法满足更新的待处理转录轮次。
|
||||
- 当缺少提供商要求的签名标头时,未经认证的 Webhook 请求会在读取正文前被拒绝。
|
||||
- voice-call Webhook 使用共享的预认证正文配置(64 KB / 5 秒),并在签名验证前加上按 IP 的进行中请求上限。
|
||||
- Twilio 和 Plivo 已启用 webhook **重放保护**。重放的有效 webhook 请求会被确认,但会跳过副作用。
|
||||
- Twilio 对话轮次在 `<Gather>` 回调中包含按轮次生成的令牌,因此过期/重放的语音回调无法满足较新的待处理转写轮次。
|
||||
- 当缺少提供商所需的签名标头时,未经认证的 webhook 请求会在读取正文之前被拒绝。
|
||||
- voice-call webhook 使用共享的预认证正文配置(64 KB / 5 秒),并在签名验证前加上按 IP 限制的进行中请求上限。
|
||||
|
||||
使用稳定公开主机的示例:
|
||||
|
||||
@ -648,15 +660,10 @@ openclaw voicecall latency # summarize turn latency from lo
|
||||
openclaw voicecall expose --mode funnel
|
||||
```
|
||||
|
||||
当 Gateway 网关 已在运行时,操作性 `voicecall` 命令会委托给
|
||||
Gateway 网关 拥有的 voice-call 运行时,因此 CLI 不会绑定第二个
|
||||
Webhook 服务器。如果无法访问任何 Gateway 网关,这些命令会回退到
|
||||
独立 CLI 运行时。
|
||||
当 Gateway 网关已经运行时,操作型 `voicecall` 命令会委托给 Gateway 网关拥有的 voice-call 运行时,因此 CLI 不会绑定第二个 webhook 服务器。如果无法连接到任何 Gateway 网关,这些命令会回退到独立的 CLI 运行时。
|
||||
|
||||
`latency` 会从默认语音通话存储路径读取 `calls.jsonl`。
|
||||
使用 `--file <path>` 指向其他日志,并使用 `--last <n>` 将
|
||||
分析限制为最后 N 条记录(默认 200)。输出包含回合延迟和监听等待时间的
|
||||
p50/p90/p99。
|
||||
`latency` 从默认语音通话存储路径读取 `calls.jsonl`。
|
||||
使用 `--file <path>` 指向不同的日志,并使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包含轮次延迟和监听等待时间的 p50/p90/p99。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
@ -671,7 +678,7 @@ p50/p90/p99。
|
||||
| `end_call` | `callId` |
|
||||
| `get_status` | `callId` |
|
||||
|
||||
此仓库在 `skills/voice-call/SKILL.md` 中提供匹配的 skill 文档。
|
||||
此仓库在 `skills/voice-call/SKILL.md` 中附带匹配的技能文档。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
@ -684,12 +691,11 @@ p50/p90/p99。
|
||||
| `voicecall.end` | `callId` |
|
||||
| `voicecall.status` | `callId` |
|
||||
|
||||
`dtmfSequence` 仅在 `mode: "conversation"` 下有效。通知模式通话
|
||||
如果需要连接后的数字,应在通话存在后使用 `voicecall.dtmf`。
|
||||
`dtmfSequence` 仅在 `mode: "conversation"` 下有效。通知模式通话如果需要接通后按键,应在通话存在后使用 `voicecall.dtmf`。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 设置无法暴露 webhook
|
||||
### 设置时 webhook 暴露失败
|
||||
|
||||
从运行 Gateway 网关的同一环境运行设置:
|
||||
|
||||
@ -698,17 +704,11 @@ openclaw voicecall setup
|
||||
openclaw voicecall setup --json
|
||||
```
|
||||
|
||||
对于 `twilio`、`telnyx` 和 `plivo`,`webhook-exposure` 必须为绿色。
|
||||
已配置的 `publicUrl` 如果指向本地或专用网络空间,仍会失败,
|
||||
因为运营商无法回调这些地址。不要将 `localhost`、`127.0.0.1`、
|
||||
`0.0.0.0`、`10.x`、`172.16.x`-`172.31.x`、`192.168.x`、`169.254.x`、
|
||||
`fc00::/7` 或 `fd00::/8` 用作 `publicUrl`。
|
||||
对于 `twilio`、`telnyx` 和 `plivo`,`webhook-exposure` 必须为绿色。已配置的 `publicUrl` 如果指向本地或私有网络空间仍会失败,因为运营商无法回调这些地址。不要将 `localhost`、`127.0.0.1`、`0.0.0.0`、`10.x`、`172.16.x`-`172.31.x`、`192.168.x`、`169.254.x`、`fc00::/7` 或 `fd00::/8` 用作 `publicUrl`。
|
||||
|
||||
Twilio 通知模式出站通话会在创建通话请求中直接发送初始 `<Say>` TwiML,
|
||||
因此第一条语音消息不依赖 Twilio 获取 webhook TwiML。状态回调、
|
||||
会话通话、连接前 DTMF、实时流和连接后通话控制仍需要公开 webhook。
|
||||
Twilio 通知模式外呼会在创建通话请求中直接发送其初始 `<Say>` TwiML,因此第一条语音消息不依赖 Twilio 获取 webhook TwiML。状态回调、对话通话、接通前 DTMF、实时流和接通后通话控制仍然需要公开 webhook。
|
||||
|
||||
使用一个公开暴露路径:
|
||||
使用一种公开暴露路径:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -735,23 +735,21 @@ openclaw voicecall setup
|
||||
openclaw voicecall smoke
|
||||
```
|
||||
|
||||
除非传入 `--yes`,否则 `voicecall smoke` 是空运行。
|
||||
除非你传入 `--yes`,否则 `voicecall smoke` 是一次空运行。
|
||||
|
||||
### 提供商凭据失败
|
||||
### 提供商凭证失败
|
||||
|
||||
检查所选提供商和必需的凭据字段:
|
||||
检查所选提供商和必需的凭证字段:
|
||||
|
||||
- Twilio:`twilio.accountSid`、`twilio.authToken` 和 `fromNumber`,或
|
||||
`TWILIO_ACCOUNT_SID`、`TWILIO_AUTH_TOKEN` 和 `TWILIO_FROM_NUMBER`。
|
||||
- Telnyx:`telnyx.apiKey`、`telnyx.connectionId`、`telnyx.publicKey` 和
|
||||
`fromNumber`。
|
||||
- Twilio:`twilio.accountSid`、`twilio.authToken` 和 `fromNumber`,或 `TWILIO_ACCOUNT_SID`、`TWILIO_AUTH_TOKEN` 和 `TWILIO_FROM_NUMBER`。
|
||||
- Telnyx:`telnyx.apiKey`、`telnyx.connectionId`、`telnyx.publicKey` 和 `fromNumber`。
|
||||
- Plivo:`plivo.authId`、`plivo.authToken` 和 `fromNumber`。
|
||||
|
||||
凭据必须存在于 Gateway 网关主机上。编辑本地 shell 配置文件不会影响已经运行的 Gateway 网关,直到它重启或重新加载其环境。
|
||||
凭证必须存在于 Gateway 网关主机上。编辑本地 shell 配置文件不会影响已运行的 Gateway 网关,直到它重启或重新加载其环境。
|
||||
|
||||
### 通话已启动但提供商 webhook 未到达
|
||||
### 通话已开始但提供商 webhook 未到达
|
||||
|
||||
确认提供商控制台指向精确的公开 webhook URL:
|
||||
确认提供商控制台指向准确的公开 webhook URL:
|
||||
|
||||
```text
|
||||
https://voice.example.com/voice/webhook
|
||||
@ -767,77 +765,65 @@ openclaw logs --follow
|
||||
|
||||
常见原因:
|
||||
|
||||
- `publicUrl` 指向的路径与 `serve.path` 不同。
|
||||
- Gateway 网关启动后隧道 URL 发生了变化。
|
||||
- 代理转发了请求,但剥离或重写了 host/proto 标头。
|
||||
- 防火墙或 DNS 将公开主机名路由到了 Gateway 网关以外的位置。
|
||||
- `publicUrl` 指向与 `serve.path` 不同的路径。
|
||||
- 隧道 URL 在 Gateway 网关启动后发生了变化。
|
||||
- 代理转发请求,但剥离或重写了 host/proto 标头。
|
||||
- 防火墙或 DNS 将公开主机名路由到 Gateway 网关以外的位置。
|
||||
- Gateway 网关重启时未启用 Voice Call 插件。
|
||||
|
||||
当反向代理或隧道位于 Gateway 网关前方时,将
|
||||
`webhookSecurity.allowedHosts` 设置为公开主机名,或对已知代理地址使用
|
||||
`webhookSecurity.trustedProxyIPs`。仅在代理边界由你控制时使用
|
||||
`webhookSecurity.trustForwardingHeaders`。
|
||||
当反向代理或隧道位于 Gateway 网关前方时,请将 `webhookSecurity.allowedHosts` 设置为公开主机名,或对已知代理地址使用 `webhookSecurity.trustedProxyIPs`。仅在代理边界由你控制时使用 `webhookSecurity.trustForwardingHeaders`。
|
||||
|
||||
### 签名验证失败
|
||||
|
||||
提供商签名会根据 OpenClaw 从传入请求重建的公开 URL 进行检查。
|
||||
如果签名失败:
|
||||
提供商签名会根据 OpenClaw 从传入请求重建的公开 URL 进行检查。如果签名失败:
|
||||
|
||||
- 确认提供商 webhook URL 与 `publicUrl` 完全匹配,包括 scheme、host 和 path。
|
||||
- 对于 ngrok 免费层 URL,在隧道主机名变化时更新 `publicUrl`。
|
||||
- 确保代理保留原始 host 和 proto 标头,或配置
|
||||
`webhookSecurity.allowedHosts`。
|
||||
- 不要在本地测试以外启用 `skipSignatureVerification`。
|
||||
- 对于 ngrok 免费层 URL,当隧道主机名变化时更新 `publicUrl`。
|
||||
- 确保代理保留原始 host 和 proto 标头,或配置 `webhookSecurity.allowedHosts`。
|
||||
- 不要在本地测试之外启用 `skipSignatureVerification`。
|
||||
|
||||
### Google Meet Twilio 加入失败
|
||||
|
||||
Google Meet 使用此插件进行 Twilio 拨入加入。首先验证 Voice Call:
|
||||
Google Meet 使用此插件进行 Twilio 拨入加入。先验证 Voice Call:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
然后明确验证 Google Meet 传输:
|
||||
然后显式验证 Google Meet 传输:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup --transport twilio
|
||||
```
|
||||
|
||||
如果 Voice Call 为绿色但 Meet 参与者从未加入,请检查 Meet
|
||||
拨入号码、PIN 和 `--dtmf-sequence`。电话通话可能是正常的,
|
||||
但会议会拒绝或忽略错误的 DTMF 序列。
|
||||
如果 Voice Call 为绿色但 Meet 参与者始终未加入,请检查 Meet 拨入号码、PIN 和 `--dtmf-sequence`。电话通话可能正常,但会议会拒绝或忽略错误的 DTMF 序列。
|
||||
|
||||
Google Meet 会将 Meet DTMF 序列和介绍文本传递给 `voicecall.start`。
|
||||
对于 Twilio 通话,Voice Call 会先提供 DTMF TwiML,重定向回
|
||||
webhook,然后打开实时媒体流,以便在电话参与者加入会议后生成已保存的介绍。
|
||||
Google Meet 会将 Meet DTMF 序列和介绍文本传递给 `voicecall.start`。对于 Twilio 通话,Voice Call 会先提供 DTMF TwiML,重定向回 webhook,然后打开实时媒体流,以便在电话参与者加入会议后生成保存的介绍语。
|
||||
|
||||
使用 `openclaw logs --follow` 查看实时阶段跟踪。健康的 Twilio Meet
|
||||
加入会按此顺序记录日志:
|
||||
使用 `openclaw logs --follow` 查看实时阶段追踪。健康的 Twilio Meet 加入会按此顺序记录日志:
|
||||
|
||||
- Google Meet 将 Twilio 加入委托给 Voice Call。
|
||||
- Voice Call 存储连接前 DTMF TwiML。
|
||||
- Voice Call 存储接通前 DTMF TwiML。
|
||||
- Twilio 初始 TwiML 会在实时处理前被消费并提供。
|
||||
- Voice Call 为 Twilio 通话提供实时 TwiML。
|
||||
- 实时桥接启动,并将初始问候语排队。
|
||||
- 实时桥接启动,并将初始问候语加入队列。
|
||||
|
||||
`openclaw voicecall tail` 仍会显示持久化的通话记录;它对通话状态和转录很有用,但并非每个 webhook/实时转换都会出现在其中。
|
||||
`openclaw voicecall tail` 仍会显示持久化通话记录;它对通话状态和转录很有用,但并非每个 webhook/实时转换都会出现在其中。
|
||||
|
||||
### 实时通话没有语音
|
||||
|
||||
确认仅启用一种音频模式。`realtime.enabled` 和
|
||||
`streaming.enabled` 不能同时为 true。
|
||||
确认只启用了一种音频模式。`realtime.enabled` 和 `streaming.enabled` 不能同时为 true。
|
||||
|
||||
对于实时 Twilio 通话,还要验证:
|
||||
|
||||
- 已加载并注册实时提供商插件。
|
||||
- `realtime.provider` 未设置,或命名了已注册的提供商。
|
||||
- 提供商 API key 可供 Gateway 网关进程使用。
|
||||
- `openclaw logs --follow` 显示已提供实时 TwiML、实时桥接已启动,
|
||||
并且初始问候语已排队。
|
||||
- 提供商 API key 对 Gateway 网关进程可用。
|
||||
- `openclaw logs --follow` 显示已提供实时 TwiML、实时桥接已启动,并且初始问候语已加入队列。
|
||||
|
||||
## 相关
|
||||
|
||||
- [对话模式](/zh-CN/nodes/talk)
|
||||
- [Talk 模式](/zh-CN/nodes/talk)
|
||||
- [文本转语音](/zh-CN/tools/tts)
|
||||
- [语音唤醒](/zh-CN/nodes/voicewake)
|
||||
|
||||
@ -2,32 +2,32 @@
|
||||
read_when:
|
||||
- 你希望 OpenClaw 支持 Zalo Personal(非官方)
|
||||
- 你正在配置或开发 zalouser 插件
|
||||
summary: Zalo Personal 插件:通过原生 zca-js 实现二维码登录和消息收发(插件安装 + 渠道配置 + 工具)
|
||||
summary: Zalo Personal 插件:通过原生 zca-js 进行二维码登录 + 消息发送(插件安装 + 渠道配置 + 工具)
|
||||
title: Zalo 个人插件
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T21:05:30Z"
|
||||
generated_at: "2026-05-02T21:57:51Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0649c95317c09fc8316ec371a357d7d41d8bf801d0d9e500a29de13388421973
|
||||
source_hash: b8bcead1a6425587a2cae40e4e817c45b9adf8afbfce6dc673065cc98353f844
|
||||
source_path: plugins/zalouser.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# Zalo Personal(插件)
|
||||
|
||||
通过插件为 OpenClaw 提供 Zalo Personal 支持,使用原生 `zca-js` 自动化普通 Zalo 用户账号。
|
||||
通过插件为 OpenClaw 提供 Zalo Personal 支持,使用原生 `zca-js` 自动化普通 Zalo 用户账户。
|
||||
|
||||
<Warning>
|
||||
非官方自动化可能导致账号被暂停或封禁。使用风险自负。
|
||||
非官方自动化可能导致账户暂停或封禁。你需自行承担风险。
|
||||
</Warning>
|
||||
|
||||
## 命名
|
||||
|
||||
渠道 id 是 `zalouser`,用于明确表示它自动化的是**个人 Zalo 用户账号**(非官方)。我们保留 `zalo`,用于未来可能的官方 Zalo API 集成。
|
||||
渠道 ID 为 `zalouser`,用于明确表示它自动化的是**个人 Zalo 用户账户**(非官方)。我们保留 `zalo`,用于未来可能的官方 Zalo API 集成。
|
||||
|
||||
## 运行位置
|
||||
|
||||
此插件运行在 **Gateway 网关进程内部**。
|
||||
此插件运行在 **Gateway 网关进程内**。
|
||||
|
||||
如果你使用远程 Gateway 网关,请在**运行 Gateway 网关的机器**上安装/配置它,然后重启 Gateway 网关。
|
||||
|
||||
@ -41,7 +41,7 @@ x-i18n:
|
||||
openclaw plugins install @openclaw/zalouser
|
||||
```
|
||||
|
||||
当你使用 OpenClaw beta 渠道且 npmjs 显示 `beta` 领先于 `latest` 时,请使用 `@openclaw/zalouser@beta`。
|
||||
使用裸包名以跟随当前官方发布标签。仅在需要可复现安装时才固定精确版本。
|
||||
|
||||
之后重启 Gateway 网关。
|
||||
|
||||
@ -86,9 +86,9 @@ openclaw directory peers list --channel zalouser --query "name"
|
||||
|
||||
操作:`send`、`image`、`link`、`friends`、`groups`、`me`、`status`
|
||||
|
||||
渠道消息操作还支持 `react` 用于消息回应。
|
||||
渠道消息操作还支持用于消息回应的 `react`。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [构建插件](/zh-CN/plugins/building-plugins)
|
||||
- [社区插件](/zh-CN/plugins/community)
|
||||
|
||||
@ -5,15 +5,15 @@ read_when:
|
||||
summary: 使用 LM Studio 运行 OpenClaw
|
||||
title: LM Studio
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T05:17:38Z"
|
||||
generated_at: "2026-05-02T21:58:08Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 3971bc471e5d8b0f142394b7b1897f8fdb2be283082245fbb2cf744d06143292
|
||||
source_hash: 814117ecbdc52cf67e921d0f0d67c4219f8bdc15fb8cf34b983cda775cba9b9e
|
||||
source_path: providers/lmstudio.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
LM Studio 是一款友好且强大的应用,可在你自己的硬件上运行开放权重模型。它让你可以运行 llama.cpp(GGUF)或 MLX 模型(Apple Silicon)。它提供 GUI 软件包或无头守护进程(`llmster`)。产品和设置文档见 [lmstudio.ai](https://lmstudio.ai/)。
|
||||
LM Studio 是一款友好且强大的应用,可在你自己的硬件上运行开放权重模型。它可以运行 llama.cpp (GGUF) 或 MLX 模型 (Apple Silicon)。提供 GUI 软件包或无头守护进程 (`llmster`)。产品和设置文档请参阅 [lmstudio.ai](https://lmstudio.ai/)。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -35,17 +35,17 @@ lms daemon up
|
||||
lms server start --port 1234
|
||||
```
|
||||
|
||||
如果你使用应用,请确保已启用 JIT,以获得流畅体验。请阅读 [LM Studio JIT 和 TTL 指南](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)了解详情。
|
||||
如果你使用的是应用,请确保已启用 JIT,以获得流畅体验。请在 [LM Studio JIT 和 TTL 指南](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)中了解更多。
|
||||
|
||||
3. 如果已启用 LM Studio 身份验证,请设置 `LM_API_TOKEN`:
|
||||
3. 如果启用了 LM Studio 认证,请设置 `LM_API_TOKEN`:
|
||||
|
||||
```bash
|
||||
export LM_API_TOKEN="your-lm-studio-api-token"
|
||||
```
|
||||
|
||||
如果已禁用 LM Studio 身份验证,你可以在交互式 OpenClaw 设置期间将 API key 留空。
|
||||
如果禁用了 LM Studio 认证,你可以在交互式 OpenClaw 设置期间将 API key 留空。
|
||||
|
||||
有关 LM Studio 身份验证设置详情,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
|
||||
有关 LM Studio 认证设置详情,请参阅 [LM Studio 认证](https://lmstudio.ai/docs/developer/core/authentication)。
|
||||
|
||||
4. 运行新手引导并选择 `LM Studio`:
|
||||
|
||||
@ -61,11 +61,13 @@ openclaw onboard
|
||||
openclaw models set lmstudio/qwen/qwen3.5-9b
|
||||
```
|
||||
|
||||
LM Studio 模型键遵循 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`)。OpenClaw 模型引用会添加提供商名称前缀:`lmstudio/qwen/qwen3.5-9b`。你可以运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段,找到模型的确切键。
|
||||
LM Studio 模型键采用 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`)。OpenClaw
|
||||
模型引用会在前面加上提供商名称:`lmstudio/qwen/qwen3.5-9b`。你可以通过运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段来找到
|
||||
模型的确切键。
|
||||
|
||||
## 非交互式新手引导
|
||||
|
||||
当你想通过脚本设置(CI、预配、远程引导)时,请使用非交互式新手引导:
|
||||
当你想编写设置脚本(CI、预配、远程引导)时,请使用非交互式新手引导:
|
||||
|
||||
```bash
|
||||
openclaw onboard \
|
||||
@ -86,25 +88,30 @@ openclaw onboard \
|
||||
--custom-model-id qwen/qwen3.5-9b
|
||||
```
|
||||
|
||||
`--custom-model-id` 使用 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含 `lmstudio/` 提供商前缀。
|
||||
`--custom-model-id` 接收 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含
|
||||
`lmstudio/` 提供商前缀。
|
||||
|
||||
对于已启用身份验证的 LM Studio 服务器,传入 `--lmstudio-api-key` 或设置 `LM_API_TOKEN`。
|
||||
对于未启用身份验证的 LM Studio 服务器,省略该键;OpenClaw 会存储一个本地非密钥标记。
|
||||
对于启用认证的 LM Studio 服务器,请传入 `--lmstudio-api-key` 或设置 `LM_API_TOKEN`。
|
||||
对于未启用认证的 LM Studio 服务器,请省略该键;OpenClaw 会存储一个本地非机密标记。
|
||||
|
||||
`--custom-api-key` 仍受支持以保持兼容性,但对于 LM Studio,建议使用 `--lmstudio-api-key`。
|
||||
`--custom-api-key` 仍受支持以保持兼容性,但对于 LM Studio,首选 `--lmstudio-api-key`。
|
||||
|
||||
这会写入 `models.providers.lmstudio`,并将默认模型设置为 `lmstudio/<custom-model-id>`。当你提供 API key 时,设置还会写入 `lmstudio:default` 身份验证配置文件。
|
||||
这会写入 `models.providers.lmstudio`,并将默认模型设置为
|
||||
`lmstudio/<custom-model-id>`。当你提供 API key 时,设置还会写入
|
||||
`lmstudio:default` 认证配置文件。
|
||||
|
||||
交互式设置可以提示输入可选的首选加载上下文长度,并将其应用到保存进配置的已发现 LM Studio 模型。
|
||||
LM Studio 插件配置会信任已配置的 LM Studio 端点来处理模型请求,包括 loopback、LAN 和 tailnet 主机。你可以通过设置 `models.providers.lmstudio.request.allowPrivateNetwork: false` 选择退出。
|
||||
LM Studio 插件配置会信任已配置的 LM Studio 端点用于模型请求,包括 loopback、LAN 和 tailnet 主机。你可以通过设置 `models.providers.lmstudio.request.allowPrivateNetwork: false` 来退出。
|
||||
|
||||
## 配置
|
||||
|
||||
### 流式用量兼容性
|
||||
### 流式 usage 兼容性
|
||||
|
||||
LM Studio 兼容流式用量。当它未发出 OpenAI 形态的 `usage` 对象时,OpenClaw 会改为从 llama.cpp 风格的 `timings.prompt_n` / `timings.predicted_n` 元数据恢复 token 计数。
|
||||
LM Studio 兼容流式 usage。当它未发出 OpenAI 形态的
|
||||
`usage` 对象时,OpenClaw 会改为从 llama.cpp 风格的
|
||||
`timings.prompt_n` / `timings.predicted_n` 元数据中恢复令牌计数。
|
||||
|
||||
相同的流式用量行为适用于这些 OpenAI 兼容的本地后端:
|
||||
相同的流式 usage 行为也适用于这些 OpenAI 兼容的本地后端:
|
||||
|
||||
- vLLM
|
||||
- SGLang
|
||||
@ -116,7 +123,14 @@ LM Studio 兼容流式用量。当它未发出 OpenAI 形态的 `usage` 对象
|
||||
|
||||
### 思考兼容性
|
||||
|
||||
当 LM Studio 的 `/api/v1/models` 设备发现报告模型特定的推理选项时,OpenClaw 会在模型兼容性元数据中保留这些原生值。对于声明 `allowed_options: ["off", "on"]` 的二元思考模型,OpenClaw 会将禁用思考映射为 `off`,并将启用的 `/think` 级别映射为 `on`,而不是发送仅适用于 OpenAI 的值,例如 `low` 或 `medium`。
|
||||
当 LM Studio 的 `/api/v1/models` 发现报告模型特定的推理
|
||||
选项时,OpenClaw 会在模型兼容性元数据中公开匹配的 OpenAI 兼容 `reasoning_effort`
|
||||
值。当前 LM Studio 构建可以公布二进制
|
||||
UI 选项,例如 `allowed_options: ["off", "on"]`,但在
|
||||
`/v1/chat/completions` 上拒绝这些值;OpenClaw 会在发送请求前将该二进制发现形态规范化为
|
||||
`none`、`minimal`、`low`、`medium`、`high` 和 `xhigh`。
|
||||
包含 `off`/`on` 推理映射的较旧已保存 LM Studio 配置会在目录加载时
|
||||
以同样方式规范化。
|
||||
|
||||
### 显式配置
|
||||
|
||||
@ -149,30 +163,30 @@ LM Studio 兼容流式用量。当它未发出 OpenAI 形态的 `usage` 对象
|
||||
|
||||
### 未检测到 LM Studio
|
||||
|
||||
确保 LM Studio 正在运行。如果已启用身份验证,也请设置 `LM_API_TOKEN`:
|
||||
确保 LM Studio 正在运行。如果启用了认证,也请设置 `LM_API_TOKEN`:
|
||||
|
||||
```bash
|
||||
# Start via desktop app, or headless:
|
||||
lms server start --port 1234
|
||||
```
|
||||
|
||||
验证 API 是否可访问:
|
||||
验证 API 可访问:
|
||||
|
||||
```bash
|
||||
curl http://localhost:1234/api/v1/models
|
||||
```
|
||||
|
||||
### 身份验证错误(HTTP 401)
|
||||
### 认证错误 (HTTP 401)
|
||||
|
||||
如果设置报告 HTTP 401,请验证你的 API key:
|
||||
|
||||
- 检查 `LM_API_TOKEN` 是否与 LM Studio 中配置的键一致。
|
||||
- 有关 LM Studio 身份验证设置详情,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
|
||||
- 如果你的服务器不需要身份验证,请在设置期间将键留空。
|
||||
- 检查 `LM_API_TOKEN` 是否匹配 LM Studio 中配置的键。
|
||||
- 有关 LM Studio 认证设置详情,请参阅 [LM Studio 认证](https://lmstudio.ai/docs/developer/core/authentication)。
|
||||
- 如果你的服务器不要求认证,请在设置期间将键留空。
|
||||
|
||||
### 即时模型加载
|
||||
|
||||
LM Studio 支持即时(JIT)模型加载,即模型会在首次请求时加载。OpenClaw 默认通过 LM Studio 的原生加载端点预加载模型,这在禁用 JIT 时很有用。若要让 LM Studio 的 JIT、空闲 TTL 和自动驱逐行为负责模型生命周期,请禁用 OpenClaw 的预加载步骤:
|
||||
LM Studio 支持即时 (JIT) 模型加载,即模型会在首次请求时加载。OpenClaw 默认通过 LM Studio 的原生加载端点预加载模型,这在禁用 JIT 时很有帮助。若要让 LM Studio 的 JIT、空闲 TTL 和自动驱逐行为接管模型生命周期,请禁用 OpenClaw 的预加载步骤:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -191,7 +205,7 @@ LM Studio 支持即时(JIT)模型加载,即模型会在首次请求时加
|
||||
|
||||
### LAN 或 tailnet LM Studio 主机
|
||||
|
||||
使用 LM Studio 主机的可达地址,保留 `/v1`,并确保该机器上的 LM Studio 绑定到 loopback 之外的地址:
|
||||
使用 LM Studio 主机的可达地址,保留 `/v1`,并确保 LM Studio 在该机器上绑定到 loopback 之外的地址:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -208,7 +222,7 @@ LM Studio 支持即时(JIT)模型加载,即模型会在首次请求时加
|
||||
}
|
||||
```
|
||||
|
||||
与通用 OpenAI 兼容提供商不同,`lmstudio` 会自动信任其已配置的本地/私有端点,用于受保护的模型请求。自定义 loopback 提供商 ID(例如 `localhost` 或 `127.0.0.1`)也会自动受信任;对于 LAN、tailnet 或私有 DNS 自定义提供商 ID,请显式设置 `models.providers.<id>.request.allowPrivateNetwork: true`。
|
||||
与通用 OpenAI 兼容提供商不同,`lmstudio` 会自动信任其配置的本地/私有端点,用于受保护的模型请求。自定义 loopback 提供商 ID(例如 `localhost` 或 `127.0.0.1`)也会自动受信任;对于 LAN、tailnet 或私有 DNS 自定义提供商 ID,请显式设置 `models.providers.<id>.request.allowPrivateNetwork: true`。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user