---
title: 企微 Webhook Relay 本地 Skill 接入指南
updated: 2026-07-27
project: claude-code-qiwe-assistant
scope: local-skill-integration
---

# 企微 Webhook Relay 本地 Skill 接入指南

本地 Skill 不暴露 Webhook 端口。企微事件先进入中央 Relay，本地通过长轮询领取属于当前租户和设备的事件。

## 一、正式链路

```text
企微消息
  -> Token 级全局回调 /api/webhook/ingest
  -> Relay 按消息体真实 guid 找到租户
  -> 加密、去重并进入租户队列
  -> 本地 Relay Client 长轮询
  -> 解密、落盘、业务处理并 ACK
```

企微上游的回调配置对服务 Token 全局生效，不是每个客户或设备一条。因此回调地址固定为：

```text
{RELAY_BASE_URL}/api/webhook/ingest
```

不要把回调设置成 `/api/webhook/ingest/{tenantId}/{guid}`。最后一次设置会覆盖此前客户，造成消息错投或中断。

## 二、首次接入

1. 配置 Fmode 鉴权 Token。
2. 启动登录页并完成企业微信扫码登录。
3. Skill 自动注册 Relay 租户，并把真实设备 `guid` 注册到该租户。
4. Skill 调用 Fmode 专用接口：

```http
POST {QIWEI_API_BASE}/relay/connect
Authorization: Bearer <Fmode Token>
Content-Type: application/json

{"uid":"本地设备 uid"}
```

5. Fmode 服务端校验订阅和设备后，使用服务端保存的回调地址与签名密钥调用企微 `/client/setCallback`。
6. MCP/Skill 自动确保本地 Relay 消费守护进程运行；无需启动 Dashboard。手工诊断时仍可执行：

```bash
npm run relay
```

客户端请求中只能出现 `uid`，不能提交任意回调 URL、签名密钥、上游 Token 或设备 `guid`。

## 三、Fmode 服务端配置

Future Server 需要由运维设置以下环境变量：

```text
QIWEI_RELAY_CALLBACK_URL=http://8.138.37.248:4000/api/webhook/ingest
QIWEI_RELAY_CALLBACK_SECRET=<服务端全局回调签名密钥>
```

签名密钥只保存在 Future Server 和 Relay 服务端，不能进入 Skill、浏览器、npm 包、日志或客户配置文件。

## 四、本地凭据

本地 Relay Client 只保存本租户的领取和解密凭据：

```text
RELAY_BASE_URL
TENANT_ID
TENANT_API_KEY
TENANT_API_SECRET
RELAY_PRIVATE_KEY
RELAY_DEVICE_GUID
```

这些内容写入 `.env.local`，不得提交 Git 或打进 npm 包。`RELAY_PRIVATE_KEY` 使用 `\n` 表示 PEM 换行。

## 五、验证

1. `qiwei_webhook_status` 显示 `relayRunning=true`；默认服务端队列保留 7 天，处理成功后才 ACK。
2. 让另一个企微账号给当前登录账号发送一条新的真实消息。
3. Relay 服务日志应出现全局入口的接收记录和对应 `guid` 路由。
4. 本地客户端应完成 poll、解密、业务处理和 ACK。
5. 4320 工作台应只在正确客户或群聊会话中出现该消息。

历史消息不通过回调补采，产品口径为“从接入完成后开始接收”。

## 六、故障排查

| 现象 | 检查项 |
|---|---|
| `/relay/connect` 返回未配置 | Future Server 是否设置两项 Relay 环境变量并重启 |
| Relay 收到消息但本地没有 | 设备 `guid` 是否属于当前租户，Relay Client 是否在线 |
| 本地能 poll 但不能解密 | 本地私钥是否属于当前租户，PEM 换行是否正确 |
| 消息进入错误客户会话 | 检查事件真实 `guid`、会话 ID 和群/私聊类型，禁止按当前页面会话兜底 |
| 回调突然中断 | 排查是否有个人进程再次调用 `/client/setCallback` 覆盖全局地址 |

## 七、隔离部署

客户自有服务器的独立服务 Token 可以使用自定义回调，但必须显式开启：

```text
QIWEI_ALLOW_DIRECT_CALLBACK=true
```

共享 Token 环境禁止开启。默认关闭是为了避免个人版或本地测试覆盖企业版全局回调。
