Files
dukang/docs/企微API插件-配置手册.md
T

483 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 企微 API / MCP 插件 · 配置手册
> 面向运营/技术:在企微后台「智能机器人 → 添加插件」填表。
> 后端前缀:`/api/v1/wecom/plugin` · MCP:`/api/v1/wecom/plugin/mcp` · 鉴权 Header `X-Api-Key` · 与 HQ 长连接 Bot **独立**。
> 密钥与权限在 HQ **企微机器人 → API 插件** 维护(v3.5.17+;MCP 端点 v3.5.18)。
---
## 1. 推荐流程(MCP 插件)
企微 5.0.6+ 支持 **MCP 插件**:自动 `tools/list` 拉工具,不必手填、也不必导入 OpenAPI。REST API 插件仍保留,已配好的机器人不用改。
1. HQ → **企微机器人 → API 插件** → 新建实例,勾选工具权限,复制 **Key**(只显示一次)。
2. 企微工作台 → 智能机器人 → **插件** → **添加 MCP 插件**:
- **插件 URL**:见下表(必须是企业域名,localhost 无法注入成员身份)
- **传输协议**:Streamable HTTP
- **授权方式**:Service token / API key
- **位置**:Header
- **Parameter name**:`X-Api-Key`
- **Service token**:该实例 Key
3. 企微会自动拉取已授权工具;把插件挂到「运营查询」类智能机器人即可。
4. 白名单会话试问:「查一下今日经营指标」「订单 DK…」。HQ **日志 → 智能机器人日志** 应出现 `botKey=plugin:{id}`。
| 企微表单字段 | 测试环境 | 生产环境 |
|-------------|---------|---------|
| **MCP 插件 URL** | `https://api-test.dukanghaoke.com/api/v1/wecom/plugin/mcp` | `https://api.dukanghaoke.com/api/v1/wecom/plugin/mcp` |
| **传输协议** | Streamable HTTP | 同左 |
| **Header** | `X-Api-Key` | 同左 |
**自检(JSON-RPC,无 `{code,message,data}` 信封):**
```bash
# 无 Key → 401
curl -sS -o /dev/null -w '%{http_code}\n' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' \
"https://api-test.dukanghaoke.com/api/v1/wecom/plugin/mcp"
# 带 Key:initialize
curl -sS -H "X-Api-Key: <你的Key>" -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' \
"https://api-test.dukanghaoke.com/api/v1/wecom/plugin/mcp"
# 带 Key:tools/list(仅含本实例已勾选权限)
curl -sS -H "X-Api-Key: <你的Key>" -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
"https://api-test.dukanghaoke.com/api/v1/wecom/plugin/mcp"
```
若「添加插件」拉不到工具,再试传输协议 **SSE**(需运维给 `/api/v1/wecom/plugin/mcp` 关 `proxy_buffering`);第一期默认 Streamable HTTP 无状态即可。
---
## 2. 兼容流程(API 插件 + OpenAPI 导入)
**不要 17 个工具全手填。** API 插件推荐:
1. HQ 建实例并复制 Key(同上)。
2. 企微 **第 1 步**:填 API 插件 URL + Header Key(见 §3)。
3. 企微 **第 2 步**:**OpenAPI 导入**
- URL:`{Base URL}/openapi.json`
- **同样带 Header `X-Api-Key`**(与第 1 步相同 Key)
- 服务端按该 Key 的权限**只返回已授权路径**,与 HQ 勾选一致。
4. 导入后逐条核对 §4「全局规则」;类型不对时按 §6 手工修正。
手填仅适用于:导入失败,或只加 2~3 个高频工具。
---
## 3. 第 1 步:添加 API 插件
| 企微表单字段 | 测试环境 | 生产环境 |
|-------------|---------|---------|
| **插件 URL** | `https://api-test.dukanghaoke.com/api/v1/wecom/plugin` | `https://api.dukanghaoke.com/api/v1/wecom/plugin` |
| **授权方式** | Service token / API key | 同左 |
| **位置** | Header | Header |
| **Parameter name** | `X-Api-Key` | `X-Api-Key` |
| **Service token** | HQ 该实例 Key | 同左 |
**自检(应返回 `{ code, message, data }`,不是 401):**
```bash
curl -H "X-Api-Key: <你的Key>" \
"https://api-test.dukanghaoke.com/api/v1/wecom/plugin/metrics?kind=today"
```
HQ 页也会展示 Base URL 与 Header 名(不含密钥)。
---
## 4. 全局规则(调试不过先看这里)
| 项 | 正确 | 错误 |
|----|------|------|
| HTTP 方法 | 全部 **GET** | POST、Body |
| 入参位置 | **Query** 或 **Path** | Body、Form |
| 响应顶层 | **`code`(Integer) + `message`(String) + `data`(Object)** | 只配 `data` 内字段 |
| 状态字段 | `status`、`payStatus`、`auditStatus` 等 → **String** | Integer |
| 模型可见 | 业务入参 `q`、`kind`、`from`… → **是** | 隐藏 `q` 模型不会传 |
| 分页 | `page` 默认 1;`pageSize` 默认 5,**最大 10** | 过大 pageSize |
| 鉴权 | 插件级 Header 已配 Key | Query 再传 apiKey |
**统一响应信封(`openapi.json` 除外):**
```json
{
"code": 0,
"message": "ok",
"data": { }
}
```
企微「输出参数」:**先配顶层 `code` / `message` / `data`,再在 `data` 下配业务字段**。
---
## 5. HQ 权限与工具对照
只添加 HQ **已勾选**权限对应的工具;未授权 REST 返回 **403**,MCP 则不出现在 `tools/list`。
| HQ 权限 | REST 路径 | MCP 工具名 |
|---------|-----------|-----------|
| `metrics.read` | `/metrics` | `query_metrics` |
| `order.read` | `/orders` | `query_orders` |
| `user.read` | `/users` | `query_users` |
| `store.read` | `/stores` | `query_stores` |
| `redeem.read` | `/redeems` | `query_redeems` |
| `promo.read` | `/promo-codes`、`/promo-codes/{code}/stats` | `query_promo_codes`、`query_promo_code_stats` |
| `store.audit.read` | `/store-audits`、`/store-info-audits`、`/store-info-audits/{id}`、`/store-package-audits`、`/store-package-audits/{id}` | `query_store_audits` 等 5 个 |
| `partner.read` | `/partners`、`/partners/{partnerId}/users|stores|orders` | `query_partners` 等 4 个 |
| `dev_plan.read` | `/versions`、`/tasks` | `query_versions`、`query_tasks` |
**实例建议:**
| 场景 | HQ 勾选 |
|------|---------|
| 日常运营 | metrics + order + user + store + promo + redeem |
| 审核值班 | 上表 + store.audit.read |
| 合伙人分析 | 上表 + partner.read |
| 开发计划 | `dev_plan.read`(已有实例需在 HQ 补勾才会出现这两个工具) |
---
## 6. 第 2 步:工具参数明细
以下均为 **GET**。Base URL 与 §2 相同,路径为相对路径。
### 5.1 通用分页(有列表的工具)
| 参数 | 位置 | 类型 | 必填 | 默认 | 模型可见 | 说明 |
|------|------|------|------|------|----------|------|
| page | Query | Integer | 否 | 1 | 否 | 页码 |
| pageSize | Query | Integer | 否 | 5 | 否 | 每页条数,最大 10 |
**列表类 `data` 结构:**
| 字段 | 类型 | 说明 |
|------|------|------|
| total | Integer | 总条数 |
| items | Array | 结果列表 |
---
### 5.2 查询经营指标
| 项 | 值 |
|----|-----|
| 权限 | `metrics.read` |
| 路径 | `/metrics` |
**输入:**
| 参数 | 位置 | 类型 | 必填 | 默认 | 模型可见 | 说明 |
|------|------|------|------|------|----------|------|
| kind | Query | String | 否 | today | **是** | `today` / `daily` / `weekly` / `monthly` |
**输出 `data`:**
| 字段 | 类型 | 说明 |
|------|------|------|
| kind | String | 指标类型 |
| title | String | 标题 |
| rangeLabel | String | 统计区间 |
| incrementLabel | String | 如「今日新增」 |
| periodKey | String | 账期 key |
| stats | Object | 见下表 |
**`stats` 字段:**
| 字段 | 类型 | 说明 |
|------|------|------|
| usersTotal / usersIncrement | Integer | 用户存量/增量 |
| partnersTotal / partnersIncrement | Integer | 合伙人 |
| storesTotal / storesIncrement | Integer | 门店存量/增量 |
| **newStores** | Integer | **新增门店数**(与 storesIncrement 相同) |
| ordersTotal / ordersIncrement | Integer | 订单笔数(排除待支付 / 已取消 / 退款中) |
| orderAmountTotal / orderAmountIncrement | Number | 订单金额(已付 payAmount,排除待支付 / 已取消 / 退款中) |
| redeemsTotal / redeemsIncrement | Integer | 核销笔数 |
| redeemAmountTotal / redeemAmountIncrement | Number | 核销金额 |
口径与 HQ 企微经营报告一致;`today` 期末为当前时刻。
---
### 5.3 查询订单
| 权限 | `order.read` |
| 路径 | `/orders` |
| 参数 | 位置 | 类型 | 必填 | 模型可见 | 说明 |
|------|------|------|------|----------|------|
| q | Query | String | **是** | **是** | 订单号,如 `DK20260903xxxx` |
**`items[]`:** orderNo, status(String), payStatus(String), deliveryType, productName, quantity, payAmount(Number), user(Object), receiverName, receiverPhone, receiverCity, trackingNo, createdAt
---
### 5.4 查询用户
| 权限 | `user.read` |
| 路径 | `/users` |
| 参数 | 位置 | 类型 | 必填 | 模型可见 | 说明 |
|------|------|------|------|----------|------|
| q | Query | String | **是** | **是** | 用户号或 11 位手机号 |
**`items[]`:** userNo, nickname, phone(脱敏), status, orderCount, benefitBalance, createdAt
---
### 5.5 查询门店(含经营数据)
| 权限 | `store.read` |
| 路径 | `/stores` |
| 参数 | 位置 | 类型 | 必填 | 模型可见 | 说明 |
|------|------|------|------|----------|------|
| q | Query | String | **是** | **是** | 门店名称关键词 |
**`items[]`:** id, name, status(String), auditStatus(String), cityName, district, address, contactPhone, rating(Number), redeemCount, totalRedeemedBenefitAmount, partnerName, partnerId, createdAt
---
### 5.6 查询核销
| 权限 | `redeem.read` |
| 路径 | `/redeems` |
| 参数 | q=核销单号或门店名(Query,必填,模型可见)
**`items[]`:** redeemNo, amount, channel, storeName, createdAt
---
### 5.7 查询推广码
| 权限 | `promo.read` |
| 路径 | `/promo-codes` |
| 参数 | q=推广码 code 或名称(Query,必填,模型可见)
**`items[]`:** code, name, scene, status(String), scanCount, orderCount
---
### 5.8 推广码统计
| 权限 | `promo.read` |
| 路径 | `/promo-codes/{code}/stats` |
| 参数 | 位置 | 类型 | 必填 | 模型可见 |
|------|------|------|------|----------|
| code | **Path** | String | 是 | **是** |
**`data`:** code, name, status, stats(Object)
---
### 5.9 门店入驻审核
| 权限 | `store.audit.read` |
| 路径 | `/store-audits` |
| 参数 | 位置 | 类型 | 必填 | 默认 | 模型可见 | 说明 |
|------|------|------|------|------|----------|------|
| q | Query | String | 否 | — | 是 | 门店名称 |
| status | Query | String | 否 | PENDING | 是 | PENDING / APPROVED / REJECTED |
**`items[]`:** id, name, status, auditStatus, rejectReason, cityName, address, contactPhone, partnerName, partnerId, createdAt
---
### 5.10 门店信息变更审核列表
| 权限 | `store.audit.read` |
| 路径 | `/store-info-audits` |
| 参数 | status(Query,默认 PENDING)+ 分页
**`items[]`:** id, storeId, storeName, status, changedFields, changedFieldLabels, submitterType, createdAt
---
### 5.11 门店信息变更对比详情
| 权限 | `store.audit.read` |
| 路径 | `/store-info-audits/{id}` |
| 参数 | id → **Path**,String,必填,模型可见(从列表取 id)
**`data` 额外:** diffs[] → field, label, live, proposed
---
### 5.12 门店套餐审核列表
| 权限 | `store.audit.read` |
| 路径 | `/store-package-audits` |
| 参数 | status + 分页
**`items[]`:** id, storeId, storeName, status, packageCount, createdAt
---
### 5.13 门店套餐对比详情
| 权限 | `store.audit.read` |
| 路径 | `/store-package-audits/{id}` |
| 参数 | id → Path
**`data`:** proposedPackages(Array), livePackages(Array) — 含 name, price, dishes, usableTime, otherNotes
> 插件为**只读**;审核通过/驳回仍在 HQ 操作,不在插件内配置写接口。
---
### 5.14 查询合伙人
| 权限 | `partner.read` |
| 路径 | `/partners` |
| 参数 | q=姓名/公司名/手机号/ID(Query,必填,模型可见)
**`items[]`:** id, name, companyName, phone(脱敏), status, cityName, storeCount, userCount
---
### 5.15 合伙人关联用户 / 门店 / 订单
先 **查询合伙人** 取得 `id`,再调下列接口。
| 工具名 | 路径 |
|--------|------|
| 合伙人关联用户 | `/partners/{partnerId}/users` |
| 合伙人名下门店 | `/partners/{partnerId}/stores` |
| 合伙人相关订单 | `/partners/{partnerId}/orders` |
**Path:**
| 参数 | 类型 | 必填 | 模型可见 |
|------|------|------|----------|
| partnerId | String | 是 | **是** |
**Query(可选,建议模型可见):**
| 参数 | 类型 | 说明 |
|------|------|------|
| from | String | 起始日期 `YYYY-MM-DD` 或 ISO |
| to | String | 结束日期(含当天) |
| page / pageSize | Integer | 分页 |
**`data`:** partnerId, partnerName, total, items[]
- **users**:关联用户(assocPartnerAccountId)
- **stores**:名下门店 + 经营数据
- **orders**:佣金归属订单(partnerAccountIdAtPay)
---
### 5.16 查询开发版本
| 项 | 值 |
|----|-----|
| 权限 | `dev_plan.read` |
| 路径 | `/versions` |
| MCP | `query_versions` |
**输入(均可选):**
| 参数 | 位置 | 类型 | 模型可见 | 说明 |
|------|------|------|----------|------|
| q | Query | String | 是 | 版本号或说明,如 `v3.5.18` |
| status | Query | String | 是 | `PENDING` 待启动 / `IN_PROGRESS` 开发中 / `TESTING` 测试 / `RELEASED` 已上线 / `STOPPED` 已停止 |
| page / pageSize | Query | Integer | 否 | 分页 |
**`data.items[]`:** versionNo、content、status、statusLabel、createdAt、releasedAt
---
### 5.17 查询开发任务
| 项 | 值 |
|----|-----|
| 权限 | `dev_plan.read` |
| 路径 | `/tasks` |
| MCP | `query_tasks` |
按**任务状态**筛选。可同时用 `q`、`versionNo`。
**输入(均可选):**
| 参数 | 位置 | 类型 | 模型可见 | 说明 |
|------|------|------|----------|------|
| status | Query | String | **是** | `TODO` 待开发 / `IN_PROGRESS` 开发中 / `DEVELOPED` 已开发 / `RELEASED` 已上线 / `STOPPED` 已停止 |
| q | Query | String | 是 | 任务编号或内容 |
| versionNo | Query | String | 是 | 精确版本号,如 `v3.5.18`;传入则只返回该版本下任务 |
| page / pageSize | Query | Integer | 否 | 分页 |
**`data.items[]`:** taskNo、content、type、typeLabel、status、statusLabel、creatorName、supportTicketNo、versions[]、createdAt、completedAt。不含附件 URL。
---
## 7. OpenAPI 导入
| 项 | 值 |
|----|-----|
| 导入 URL | `{Base URL}/openapi.json` |
| Header | `X-Api-Key: <同实例 Key>` |
| 格式 | OpenAPI 3.0(**无** `{code,message,data}` 信封,原样 JSON) |
| 过滤 | 仅含当前 Key 已授权 paths |
示例:
```bash
curl -H "X-Api-Key: <Key>" \
"https://api-test.dukanghaoke.com/api/v1/wecom/plugin/openapi.json"
```
---
## 8. 调试检查清单
### MCP 插件
- [ ] 无 Key / 错 Key → 401
- [ ] `initialize` + `tools/list` 仅含 HQ 已勾选权限对应工具
- [ ] 企微后台能自动拉到工具(Streamable HTTP)
- [ ] 白名单会话能问到真实数据;HQ 日志 `botKey=plugin:{id}`
### API 插件(兼容)
- [ ] 第 1 步 Key 与 HQ 实例一致,实例 **已启用**
- [ ] curl 带 Key 返回 `code: 0`
- [ ] 工具为 **GET**,入参在 **Query/Path**,非 Body
- [ ] 输出含 **code / message / data**
- [ ] status 等枚举字段类型为 **String**
- [ ] 未导入 HQ 未授权工具(否则 403)
- [ ] 企微白名单会话试问:「查一下今日经营指标」「订单 DK…」
- [ ] HQ **日志 → 智能机器人日志** 出现 `botKey=plugin:{id}`
---
## 9. 多实例与分工
| 企微插件 | HQ 实例 | 说明 |
|----------|---------|------|
| 运营查询 | 全权限 Key | metrics + 审核 + 合伙人等 |
| 客服只读 | 部分权限 Key | order + user + store |
| URL | **相同** Base URL | 仅 Key 不同 |
---
## 10. 相关文档
- [杜康好客-v3.5.18-开发文档](./杜康好客-v3.5.18-开发文档.md) — MCP Streamable HTTP 端点
- [杜康好客-v3.5.17-开发文档](./杜康好客-v3.5.17-开发文档.md) — 表结构、Admin API、权限目录
- [杜康好客-v3.5.16-开发文档](./杜康好客-v3.5.16-开发文档.md) — 插件初版与 curl 示例
- [杜康好客-v3编码手册](./杜康好客-v3编码手册.md) — 编码验收一句