feat: Phase 4 多平台接入 — Platform Bridge + 6平台适配器 + 身份权限系统 (22文件, 2129行)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# Phase 4: 多平台接入 — 开发报告
|
||||
|
||||
> **报告日期**:2026-05-23
|
||||
> **分支**:`dev`
|
||||
> **阶段**:Phase 4 — 多平台接入
|
||||
> **总计修改文件数**:18 个 (新增 15 个, 修改 3 个)
|
||||
> **总代码行数**:1852 行 (Go) + 配置文件
|
||||
> **编译状态**:platform-bridge ✅ / ai-core ⚠️ 网络不可用 (预存在问题)
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
Phase 3 完成了插件与工具系统。Phase 4 的目标是建立统一的多平台消息接入层,让昔涟能够通过 QQ、Telegram、Webhook 等多种渠道与用户交互。
|
||||
|
||||
### 核心目标
|
||||
|
||||
| 任务 | 说明 |
|
||||
|------|------|
|
||||
| 统一消息模型 | 所有平台消息转换为统一的 UnifiedMessage/UnifiedResponse |
|
||||
| 身份映射 | 平台用户 UID → Cyrene 用户的身份映射与权限管理 |
|
||||
| QQ OBv11 适配器 | 反向 WebSocket 连接,QQ 机器人协议适配 |
|
||||
| Telegram 适配器 | Bot API Webhook 模式,消息收发 + 输入状态 |
|
||||
| 通用 Webhook | 标准 HTTP POST 接收任意平台消息 |
|
||||
| 权限检查器 | admin/full/basic/restricted 四级权限,工具/设备白名单 |
|
||||
| WeChat/Feishu/Discord 桩 | 预留接口,待后续接入外部 SDK |
|
||||
|
||||
---
|
||||
|
||||
## 二、架构概览
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ Platform Bridge (port 8095) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ QQ OBv11 │ │ Telegram │ │ Webhook │ ... 6 适配器│
|
||||
│ │ (WS 8096)│ │ (Bot API)│ │ (通用) │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ │ │ │
|
||||
│ ┌────▼──────────────▼──────────────▼────┐ │
|
||||
│ │ Platform Router │ │
|
||||
│ │ ┌────────────┐ ┌─────────────────┐ │ │
|
||||
│ │ │ Identity │ │ Permission │ │ │
|
||||
│ │ │ Mapper │ │ Checker │ │ │
|
||||
│ │ └────────────┘ └────────┬────────┘ │ │
|
||||
│ └───────────────────────────┴────────────┘ │
|
||||
│ │ │
|
||||
│ forwardToAICore() │
|
||||
│ │ │
|
||||
│ ┌───────▼────────┐ │
|
||||
│ │ AI-Core │ │
|
||||
│ │ (port 8081) │ │
|
||||
│ └────────────────┘ │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 消息流程
|
||||
|
||||
```
|
||||
外部平台消息 → Adapter.ToUnified() → 统一消息 → IdentityMapper.Resolve()
|
||||
→ Permission Check → forwardToAICore() → 统一响应 → Adapter.FromUnified()
|
||||
→ 平台消息发送
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、文件清单
|
||||
|
||||
### 3.1 核心类型 (internal/bridge/)
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `unified.go` | 76 | UnifiedMessage, UnifiedResponse, ResponseMessage, PlatformCapabilities, PlatformMessage, Attachment, PlatformHints |
|
||||
| `adapter.go` | 24 | PlatformAdapter 接口 (PlatformName, ToUnified, FromUnified, Capabilities, Connect, Disconnect, IsConnected, HealthCheck) + MessageHandler 类型 |
|
||||
| `mapper.go` | 73 | IdentityMapper — platform:platformUID → CyreneUser 映射注册/查询/列表 |
|
||||
| `router.go` | 168 | PlatformRouter — 适配器注册、消息路由、通道上下文管理、响应发送 |
|
||||
|
||||
### 3.2 权限系统 (internal/permissions/)
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `permissions.go` | 115 | PlatformIdentity 结构体 + Checker 权限检查器 (四级权限: admin/full/basic/restricted)、工具白名单、IoT 设备白名单 |
|
||||
|
||||
### 3.3 平台适配器 (internal/adapter/)
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `qq/protocol.go` | 75 | OBv11 协议类型 (OBv11Message, OBv11Sender, OBv11SendMsg 等) |
|
||||
| `qq/adapter.go` | 394 | QQ 适配器 — 反向 WebSocket 服务器, ToUnified/FromUnified, SendMessage, ReadMessages 事件循环, markdown→QQ 格式转换 |
|
||||
| `telegram/adapter.go` | 251 | Telegram 适配器 — Bot API Webhook, ToUnified 支持结构化/map 两种输入, SendMessage, SendChatAction (typing 指示器) |
|
||||
| `webhook/adapter.go` | 121 | 通用 Webhook 适配器 — WebhookPayload/WebhookResponse 标准格式 |
|
||||
| `wechat/stub.go` | 50 | 微信桩 (待 WeChatFerry / 企业微信 SDK) |
|
||||
| `feishu/stub.go` | 50 | 飞书桩 (待 Lark Go SDK) |
|
||||
| `discord/stub.go` | 50 | Discord 桩 (待 discordgo) |
|
||||
|
||||
### 3.4 REST API (internal/handler/)
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `bridge_handler.go` | 149 | 路由注册, /health, /api/v1/platforms, /api/v1/identities, /api/v1/webhook/telegram, /api/v1/webhook/{platform} |
|
||||
|
||||
### 3.5 配置与入口
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `config/config.go` | 52 | 环境变量加载 (PORT, AI_CORE_URL, QQ_BOT_PORT, TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_URL) |
|
||||
| `cmd/main.go` | 204 | 服务入口 — 创建 mapper/checker/router, 注册 6 个适配器, 设置消息处理器, QQ 消息读取循环, 身份种子数据 |
|
||||
|
||||
### 3.6 DevTools 集成 (修改)
|
||||
|
||||
| 文件 | 变更 | 说明 |
|
||||
|------|------|------|
|
||||
| `devtools/src/config.js` | +33 行 | 添加 plugin-manager 和 platform-bridge 服务配置 |
|
||||
| `devtools/src/process-manager.js` | +2/-2 | 添加新服务到启动顺序和 DB 检查列表 |
|
||||
| `backend/go.work` | +1 | 添加 platform-bridge 模块 |
|
||||
|
||||
---
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
### 4.1 导入循环解决
|
||||
|
||||
原始设计中 `adapter` 包定义了 `PlatformAdapter` 接口,`bridge` 包的 `router.go` 引用它,但 `adapter` 实现文件又引用 `bridge` 的类型。产生了循环依赖:
|
||||
|
||||
```
|
||||
adapter ↔ bridge (import cycle)
|
||||
```
|
||||
|
||||
**解决方案**:将 `PlatformAdapter` 接口和 `MessageHandler` 类型从 `internal/adapter/` 移到 `internal/bridge/adapter.go`,与它们引用的类型 (`UnifiedMessage`, `UnifiedResponse`) 放在同一包中。
|
||||
|
||||
同理,`permissions ↔ bridge` 循环通过将 `PlatformIdentity` 从 `bridge/mapper.go` 移到 `permissions/permissions.go` 解决。
|
||||
|
||||
### 4.2 QQ 适配器的反向 WebSocket
|
||||
|
||||
QQ 使用 OneBot v11 协议,采用反向 WebSocket 模式:
|
||||
- **平台桥接启动 WebSocket 服务器** (端口 8096)
|
||||
- **QQ 机器人框架主动连接到此端口**
|
||||
- 消息通过 WebSocket 双向传递
|
||||
|
||||
```go
|
||||
// Connect 非阻塞:在 goroutine 中启动 HTTP Server
|
||||
mux.HandleFunc("/ws/qq", func(w, r) { upgrade(w, r) })
|
||||
go srv.ListenAndServe()
|
||||
```
|
||||
|
||||
### 4.3 Telegram Webhook 模式
|
||||
|
||||
Telegram 适配器使用 Bot API webhook:
|
||||
- **启动时**调用 `setWebhook` 注册回调 URL
|
||||
- **运行时**被动接收 Telegram 服务器推送的 Update
|
||||
- **ToUnified** 同时支持结构化 `*TelegramUpdate` 和原始 `map[string]interface{}`,避免 HTTP handler 与适配器类型耦合
|
||||
|
||||
### 4.4 桩适配器策略
|
||||
|
||||
WeChat、Feishu、Discord 目前为桩实现。它们实现了完整的 `PlatformAdapter` 接口但返回错误信息,提示需要哪个 SDK。这样做的好处:
|
||||
- 路由注册和平台列表正常工作
|
||||
- 当获取到对应的 SDK 和凭据后,只需替换桩实现即可
|
||||
- Auth 系统可通过 API 查看所有平台状态
|
||||
|
||||
### 4.5 权限模型
|
||||
|
||||
```
|
||||
admin → 所有权限 (聊天/IoT操控/查询/记忆管理/系统管理/全部工具/全部设备)
|
||||
full → 聊天 + IoT操控 + IoT查询 + 记忆访问
|
||||
basic → 聊天 + IoT查询
|
||||
restricted → 仅聊天
|
||||
```
|
||||
|
||||
权限检查器支持细粒度的工具白名单和设备白名单,admin 自动拥有所有权限。
|
||||
|
||||
---
|
||||
|
||||
## 五、API 端点
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/health` | 健康检查,返回平台列表 |
|
||||
| GET | `/api/v1/platforms` | 列出所有平台及其能力 |
|
||||
| GET | `/api/v1/platforms/{name}` | 单个平台详情 |
|
||||
| GET | `/api/v1/identities` | 列出所有身份映射 |
|
||||
| POST | `/api/v1/webhook/telegram` | 接收 Telegram Bot API Update |
|
||||
| POST | `/api/v1/webhook/{platform}` | 接收通用 Webhook 消息 |
|
||||
|
||||
---
|
||||
|
||||
## 六、环境变量
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `PORT` | 8095 | 桥接服务 HTTP 端口 |
|
||||
| `AI_CORE_URL` | http://localhost:8081 | AI-Core 地址 |
|
||||
| `QQ_BOT_PORT` | 8096 | QQ OBv11 WebSocket 监听端口 |
|
||||
| `TELEGRAM_BOT_TOKEN` | (空) | Telegram Bot API Token |
|
||||
| `TELEGRAM_WEBHOOK_URL` | (空) | Telegram Webhook 回调 URL |
|
||||
| `QQ_ADMIN_UID` | (空) | QQ 管理员 UID (种子身份) |
|
||||
| `TELEGRAM_ADMIN_UID` | (空) | Telegram 管理员 UID (种子身份) |
|
||||
|
||||
---
|
||||
|
||||
## 七、已知限制
|
||||
|
||||
1. **WeChat/Feishu/Discord 为桩** — 需要对应的 SDK 和凭据后才能启用
|
||||
2. **QQ 适配器未实现心跳** — OBv11 协议中 bot 需要定期发送心跳包维持连接
|
||||
3. **Telegram 未处理 callback_query** — 目前仅处理 message 类型的 Update
|
||||
4. **平台桥接与 Gateway 之间无内部认证** — `forwardToAICore` 直接调用 AI-Core,绕过 Gateway。后续若需要 Gateway 统一管理会话,应通过 Gateway 的 HTTP API 而非 WebSocket
|
||||
|
||||
---
|
||||
|
||||
## 八、验证指南
|
||||
|
||||
```bash
|
||||
# 1. 编译 platform-bridge
|
||||
cd backend/platform-bridge
|
||||
GOWORK=off go build ./cmd/main.go
|
||||
|
||||
# 2. 启动服务
|
||||
./main
|
||||
|
||||
# 3. 健康检查
|
||||
curl http://localhost:8095/health
|
||||
|
||||
# 4. 查看注册的平台
|
||||
curl http://localhost:8095/api/v1/platforms
|
||||
|
||||
# 5. 测试通用 Webhook
|
||||
curl -X POST http://localhost:8095/api/v1/webhook/webhook \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"user_id":"test_user","user_name":"测试用户","content":"你好昔涟","channel_id":"test_channel"}'
|
||||
|
||||
# 6. 查看身份映射
|
||||
curl http://localhost:8095/api/v1/identities
|
||||
```
|
||||
Reference in New Issue
Block a user