forked from hangshuo652/aurak
0a9588abb7
- Add pagination support to findAll (page, limit query params) - Add findByTemplateId method to service - Add GET /by-template/:templateId endpoint to controller - Service already includes CRUD for QuestionBank and QuestionBankItem
13 KiB
13 KiB
Feishu WebSocket Integration - Design Document
Date: 2026-03-17 Author: Sisyphus AI Agent Status: Draft for Review
Executive Summary
Add WebSocket long-connection support for Feishu bot integration, enabling internal network deployment without requiring public domain or internet-facing endpoints. The system will support both existing webhook mode and new WebSocket mode, allowing users to choose their preferred connection method.
1. Architecture Overview
Current Architecture (Webhook Mode)
Feishu Cloud → Public Domain → NAT/Firewall → Internal Server
└→ POST /api/feishu/webhook/:appId
Limitations:
- Requires public domain with SSL certificate
- Requires NAT/firewall port forwarding or reverse proxy
- Not suitable for pure internal network deployment
New Architecture (WebSocket Mode)
Feishu Cloud ←──────── WebSocket (wss://open.feishu.cn) ──────── Internal Server
↑
Feishu Cloud → Webhook (optional backup) → Internal Server
Advantages:
- No public domain required
- No NAT/firewall configuration needed
- Direct connection from internal network to Feishu cloud
- Real-time message delivery (milliseconds vs minutes)
- Connection复用,资源效率更高
Architecture Diagram
┌─────────────────────────────────────────────────────────────┐
│ Feishu Open Platform │
│ (WebSocket Event Subscription) │
└───────────────────────┬─────────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
┌─────▼──────┐ ┌──────▼─────┐
│ Bot A │ │ Bot B │
│ ws://.../A │ │ ws://.../B │
└─────┬──────┘ └──────┬─────┘
│ │
┌─────▼──────────────────────────▼──────┐
│ AuraK Server │
│ ┌──────────────────────────────────┐ │
│ │ FeishuModule │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ FeishuWsManager │ │ │
│ │ │ - per-bot connections │ │ │
│ │ │ - auto-reconnect │ │ │
│ │ │ - message routing │ │ │
│ │ └────────────────────────────┘ │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ FeishuService │ │ │
│ │ │ - existing logic │ │ │
│ │ │ - new ws connect/disconnect│ │ │
│ │ └────────────────────────────┘ │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ FeishuController │ │ │
│ │ │ - webhook endpoints │ │ │
│ │ │ - ws management APIs │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
└──────────────────────────────────────────┘
2. Implementation Plan
2.1 New Components
2.1.1 FeishuWsManager
Purpose: Manage WebSocket connections for each bot
Responsibilities:
- Establish and maintain WebSocket connections
- Handle connection lifecycle (connect, disconnect, reconnect)
- Route incoming messages to appropriate bot handlers
- Manage connection state per bot
Location: server/src/feishu/feishu-ws.manager.ts
Key Methods:
class FeishuWsManager {
// Start WebSocket connection for a bot
async connect(bot: FeishuBot): Promise<void>
// Stop WebSocket connection for a bot
async disconnect(botId: string): Promise<void>
// Get connection status
getStatus(botId: string): ConnectionStatus
// Get all active connections
getAllConnections(): Map<string, ConnectionStatus>
}
2.1.2 ConnectionStatus Type
enum ConnectionState {
DISCONNECTED = 'disconnected',
CONNECTING = 'connecting',
CONNECTED = 'connected',
ERROR = 'error'
}
interface ConnectionStatus {
botId: string
state: ConnectionState
connectedAt?: Date
lastHeartbeat?: Date
error?: string
}
2.2 Modified Components
2.2.1 FeishuService
New Methods:
class FeishuService {
// Start WebSocket connection for a bot
async startWsConnection(botId: string): Promise<void>
// Stop WebSocket connection for a bot
async stopWsConnection(botId: string): Promise<void>
// Get connection status
async getWsStatus(botId: string): Promise<ConnectionStatus>
// List all connection statuses
async getAllWsStatuses(): Promise<ConnectionStatus[]>
}
2.2.2 FeishuController
New Endpoints:
// POST /feishu/bots/:id/ws/connect - Start WebSocket connection
// POST /feishu/bots/:id/ws/disconnect - Stop WebSocket connection
// GET /feishu/bots/:id/ws/status - Get connection status
// GET /feishu/ws/status - Get all connection statuses
Modified Endpoints:
- Keep existing webhook endpoints unchanged
- Add WebSocket status indicator in bot list response
2.2.3 FeishuBot Entity
New Fields:
@Entity('feishu_bots')
export class FeishuBot {
// ... existing fields ...
@Column({ default: false })
useWebSocket: boolean
@Column({ nullable: true })
wsConnectionState: string
}
2.3 Feishu SDK Integration
Package: @larksuiteoapi/node-sdk
Installation:
cd server && yarn add @larksuiteoapi/node-sdk
Configuration:
import { EventDispatcher, Conf } from '@larksuiteoapi/node-sdk'
const client = new EventDispatcher({
appId: bot.appId,
appSecret: bot.appSecret,
verificationToken: bot.verificationToken,
}, {
logger: console
})
2.4 Event Handling
Flow for WebSocket Mode:
Feishu Cloud ──WebSocket──> FeishuWsManager.on('message')
│
▼
Parse event type
│
┌───────────────┼───────────────┐
│ │ │
im.message. im.message. other
receive_v1 p2p_msg_received
│ │
▼ ▼
FeishuService.processChatMessage()
│
▼
Send response via
FeishuService.sendTextMessage()
2.5 Configuration Changes
Feishu Open Platform:
Users need to configure in Feishu developer console:
- Go to "Event Subscription" (事件与回调)
- Select "Use long connection to receive events" (使用长连接接收事件)
- Add event:
im.message.receive_v1 - Important: Must start local WebSocket client first before saving
3. Data Flow
WebSocket Message Flow
1. User triggers connect API
│
▼
2. FeishuController.connect(botId)
│
▼
3. FeishuService.startWsConnection(botId)
│
▼
4. FeishuWsManager.connect(bot)
│
▼
5. SDK establishes WebSocket to open.feishu.cn
│
▼
6. Connection established, events flow:
│
├─> on('message') ──> _processEvent() ──> _handleMessage()
│ │
│ ▼
│ FeishuService.processChatMessage()
│ │
│ ▼
│ FeishuService.sendTextMessage() (via SDK)
│
├─> on('error') ──> log error ──> trigger reconnect
│
└─> on('close') ──> trigger auto-reconnect
4. Error Handling
Connection Errors
| Error Type | Handling |
|---|---|
| Network timeout | Retry with exponential backoff (max 5 attempts) |
| Invalid credentials | Mark bot as error state, notify user |
| Token expired | Refresh token, reconnect |
| Feishu server error | Wait 30s, retry |
Auto-Reconnect Strategy
Initial delay: 1 second
Max delay: 60 seconds
Backoff multiplier: 2x
Max attempts: 5
Reset on successful connection
5. API Design
5.1 Connect WebSocket
POST /api/feishu/bots/:id/ws/connect
Response 200:
{
"success": true,
"botId": "bot_xxx",
"status": "connecting"
}
Response 400:
{
"success": false,
"error": "Bot not found or disabled"
}
5.2 Disconnect WebSocket
POST /api/feishu/bots/:id/ws/disconnect
Response 200:
{
"success": true,
"botId": "bot_xxx",
"status": "disconnected"
}
5.3 Get Connection Status
GET /api/feishu/bots/:id/ws/status
Response 200:
{
"botId": "bot_xxx",
"state": "connected",
"connectedAt": "2026-03-17T10:00:00Z",
"lastHeartbeat": "2026-03-17T10:05:00Z"
}
5.4 Get All Statuses
GET /api/feishu/ws/status
Response 200:
{
"connections": [
{
"botId": "bot_xxx",
"state": "connected",
"connectedAt": "2026-03-17T10:00:00Z"
},
{
"botId": "bot_yyy",
"state": "disconnected"
}
]
}
6. Security Considerations
- Credential Storage: App ID and App Secret stored encrypted in database
- Connection Validation: Verify bot belongs to authenticated user before connect
- Rate Limiting: Implement per-bot message rate limiting
- Connection Limits: Max 10 concurrent WebSocket connections per server instance
7. Testing Strategy
Unit Tests
- FeishuWsManager connection lifecycle
- Message routing logic
- Error handling and reconnection
Integration Tests
- Full WebSocket connection flow
- Message send/receive cycle
- Reconnection after network failure
Manual Testing
- Local development without ngrok
- Verify webhook still works alongside WebSocket
8. Backward Compatibility
- Existing webhook endpoints: Unchanged, continue to work
- Bot configuration: Existing bots keep webhook mode by default
- Migration path: Users can switch to WebSocket anytime via API
- Dual mode: Both modes can run simultaneously for different bots
9. Migration Guide
For Existing Users
- Update AuraK to new version (with WebSocket support)
- Install Feishu SDK:
yarn add @larksuiteoapi/node-sdk - In Feishu Developer Console:
- Start local WebSocket server
- Change event subscription to "Use long connection"
- Call
POST /api/feishu/bots/:id/ws/connectto activate
10. Limitations
- Outbound Network Required: Server must be able to reach
open.feishu.cnvia WebSocket - Single Connection Per Bot: Each bot needs its own WebSocket connection
- Feishu SDK Required: Must install official SDK, cannot use raw WebSocket
- Private Feishu: Does not support Feishu private deployment (自建飞书)
11. File Changes Summary
New Files
server/src/feishu/feishu-ws.manager.ts- WebSocket connection managerserver/src/feishu/dto/ws-status.dto.ts- WebSocket status DTOs
Modified Files
server/src/feishu/feishu.service.ts- Add WS methodsserver/src/feishu/feishu.controller.ts- Add WS endpointsserver/src/feishu/entities/feishu-bot.entity.ts- Add WS fieldsserver/src/feishu/feishu.module.ts- Register new manager
Dependencies
- Add:
@larksuiteoapi/node-sdk
12. Success Criteria
- Server can establish WebSocket connection to Feishu
- Messages received via WebSocket are processed correctly
- Responses sent back to Feishu via SDK
- Auto-reconnect works after network interruption
- Webhook mode continues to work unchanged
- Both modes can coexist for different bots
- Internal network deployment works without public domain