Files
Cyrene/docs/debug_log/2026-05-23-phase4-multi-platform.md
T

234 lines
10 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.
# 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
```