You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
7.3 KiB

## 一、整体设计
```mermaid
flowchart TB
subgraph Platforms [外部平台]
FS[飞书]
DT[钉钉]
WC[企业微信(开发中)]
TG[Telegram开发中]
More[更多平台...]
end
subgraph BotModule [bot/ 模块]
WH[Webhook Server]
Adapters[平台适配器]
Dispatcher[命令分发器]
Commands[命令处理器]
end
subgraph Core [现有核心模块]
AS[AnalysisService]
MA[MarketAnalyzer]
NS[NotificationService]
end
FS -->|POST /bot/feishu| WH
DT -->|POST /bot/dingtalk| WH
WC -->|POST /bot/wecom| WH
TG -->|POST /bot/telegram| WH
WH --> Adapters
Adapters -->|统一消息格式| Dispatcher
Dispatcher --> Commands
Commands --> AS
Commands --> MA
Commands --> NS
```
## 二、目录结构
在项目根目录新建 `bot/` 目录:
```
bot/
├── __init__.py # 模块入口,导出主要类
├── models.py # 统一的消息/响应模型
├── dispatcher.py # 命令分发器(核心)
├── commands/ # 命令处理器
│ ├── __init__.py
│ ├── base.py # 命令抽象基类
│ ├── analyze.py # /analyze 股票分析
│ ├── market.py # /market 大盘复盘
│ ├── help.py # /help 帮助信息
│ └── status.py # /status 系统状态
└── platforms/ # 平台适配器
├── __init__.py
├── base.py # 平台抽象基类
├── feishu.py # 飞书机器人
├── dingtalk.py # 钉钉机器人
├── dingtalk_stream.py # 钉钉机器人Stream
├── wecom.py # 企业微信机器人 (开发中)
└── telegram.py # Telegram 机器人 (开发中)
```
## 三、核心抽象设计
### 3.1 统一消息模型 (`bot/models.py`)
```python
@dataclass
class BotMessage:
"""统一的机器人消息模型"""
platform: str # 平台标识: feishu/dingtalk/wecom/telegram
user_id: str # 发送者 ID
user_name: str # 发送者名称
chat_id: str # 会话 ID群聊或私聊
chat_type: str # 会话类型: group/private
content: str # 消息文本内容
raw_data: Dict # 原始请求数据(平台特定)
timestamp: datetime # 消息时间
mentioned: bool = False # 是否@了机器人
@dataclass
class BotResponse:
"""统一的机器人响应模型"""
text: str # 回复文本
markdown: bool = False # 是否为 Markdown
at_user: bool = True # 是否@发送者
```
### 3.2 平台适配器基类 (`bot/platforms/base.py`)
```python
class BotPlatform(ABC):
"""平台适配器抽象基类"""
@property
@abstractmethod
def platform_name(self) -> str:
"""平台标识名称"""
pass
@abstractmethod
def verify_request(self, headers: Dict, body: bytes) -> bool:
"""验证请求签名(安全校验)"""
pass
@abstractmethod
def parse_message(self, data: Dict) -> Optional[BotMessage]:
"""解析平台消息为统一格式"""
pass
@abstractmethod
def format_response(self, response: BotResponse) -> Dict:
"""将统一响应转换为平台格式"""
pass
```
### 3.3 命令基类 (`bot/commands/base.py`)
```python
class BotCommand(ABC):
"""命令处理器抽象基类"""
@property
@abstractmethod
def name(self) -> str:
"""命令名称 (如 'analyze')"""
pass
@property
@abstractmethod
def aliases(self) -> List[str]:
"""命令别名 (如 ['a', '分析'])"""
pass
@property
@abstractmethod
def description(self) -> str:
"""命令描述"""
pass
@property
@abstractmethod
def usage(self) -> str:
"""使用说明"""
pass
@abstractmethod
async def execute(self, message: BotMessage, args: List[str]) -> BotResponse:
"""执行命令"""
pass
```
### 3.4 命令分发器 (`bot/dispatcher.py`)
```python
class CommandDispatcher:
"""命令分发器 - 单例模式"""
def __init__(self):
self._commands: Dict[str, BotCommand] = {}
self._aliases: Dict[str, str] = {}
def register(self, command: BotCommand) -> None:
"""注册命令"""
self._commands[command.name] = command
for alias in command.aliases:
self._aliases[alias] = command.name
def dispatch(self, message: BotMessage) -> BotResponse:
"""分发消息到对应命令"""
# 1. 解析命令和参数
# 2. 查找命令处理器
# 3. 执行并返回响应
```
## 四、已支持的命令
| 命令 | 别名 | 说明 | 示例 |
|------|------|------|------|
| /analyze | /a, 分析 | 分析指定股票 | `/analyze 600519` |
| /market | /m, 大盘 | 大盘复盘 | `/market` |
| /batch | /b, 批量 | 批量分析自选股 | `/batch` |
| /help | /h, 帮助 | 显示帮助信息 | `/help` |
| /status | /s, 状态 | 系统状态 | `/status` |
## 五、Webhook 路由
在 [api/v1/router.py](../api/v1/router.py) 中注册路由:
```python
# Webhook 路由
/bot/feishu # POST - 飞书事件回调
/bot/dingtalk # POST - 钉钉事件回调
/bot/wecom # POST - 企业微信事件回调 (开发中)
/bot/telegram # POST - Telegram 更新回调 (开发中)
```
## 配置
在 [config.py](../config.py) 中新增机器人配置:
```python
# === 机器人配置 ===
bot_enabled: bool = False # 是否启用机器人
bot_command_prefix: str = "/" # 命令前缀
# 飞书机器人(事件订阅)
feishu_app_id: str # 已有
feishu_app_secret: str # 已有
feishu_verification_token: str # 新增:事件校验 Token
feishu_encrypt_key: str # 新增:加密密钥
# 钉钉机器人(应用)
dingtalk_app_key: str # 新增
dingtalk_app_secret: str # 新增
# 企业微信机器人(开发中)
wecom_token: str # 新增:回调 Token
wecom_encoding_aes_key: str # 新增EncodingAESKey
# Telegram 机器人(开发中)
telegram_bot_token: str # 已有
telegram_webhook_secret: str # 新增Webhook 密钥
```
## 扩展说明
### 怎样新增一个通知平台
1.`bot/platforms/` 创建新文件
2. 继承 `BotPlatform` 基类
3. 实现 `verify_request`, `parse_message`, `format_response`
4. 在路由中注册 Webhook 端点
### 怎样新增新增命令
1.`bot/commands/` 创建新文件
2. 继承 `BotCommand` 基类
3. 实现 `execute` 方法
4. 在分发器中注册命令
## 安全相关配置
- 支持命令频率限制(防刷)
- 敏感操作(如批量分析)可设置权限白名单
在 [config.py](../config.py) 中新增机器人安全配置:
```python
bot_rate_limit_requests: int = 10 # 频率限制:窗口内最大请求数
bot_rate_limit_window: int = 60 # 频率限制:窗口时间(秒)
bot_admin_users: List[str] = field(default_factory=list) # 管理员用户 ID 列表,限制敏感操作
```