# Telegram Bot 智能通知与交互系统 PRD **项目代号**: NaughtyMan **文档版本**: v2.1 **最后更新**: 2025年10月24日 *** ## 一、产品概述 ### 1.1 产品定位 构建一个企业级 Telegram Bot 系统,集成消息通知、智能提醒、管理功能和 AI 助手,为 ProjectOctopus(服务器监控)和 ProjectTonyStack(金融监控)提供统一的实时通知中枢与交互管理平台。 ### 1.2 核心价值 - **智能分级推送**: 根据事件紧急程度自动调度通知时间和模板 - **安全可控**: 白名单 + 动态 Token 双重鉴权机制 - **高可用性**: 内置速率控制器保障稳定运行 - **AI增强**: OpenRouter API 集成提供智能上下文响应 - **全面管理**: 用户群组管理与机器人功能动态配置 ### 1.3 技术栈 - **后端框架**: Gin (Go 语言) - **Bot SDK**: 原生 Telegram Bot API - **AI SDK**: OpenAI Go SDK (对接OpenRouter) - **数据持久化**: SQLite - **网络代理**: 支持 SOCKS5/HTTP *** ## 二、功能模块详细设计 ### 2.1 核心模块:消息通知系统 [P0-高优先级] #### 2.1.1 接口设计 **API 端点结构** ```go POST /api/v1/auth/handshake # 握手获取临时Token POST /api/v1/auth/token # 换取正式Token POST /api/v1/message/send # 发送消息 GET /api/v1/message/status # 查询消息状态 POST /api/v1/message/send-plain # 发送普通消息(非模板) POST /api/v1/message/send-markdown # 发送Markdown消息 ``` **Token 安全机制** 1. **双阶段认证流程**: - 阶段一: 客户端携带 API Key 请求握手,服务端返回 challenge 码(60秒有效期) - 阶段二: 客户端用 challenge+API Secret 生成签名,换取 Access Token(6小时有效期) 2. **Token 刷新策略**: - Token过期前30分钟允许静默续期 - 每个API Key同时只允许一个有效Token - Token中包含加密的白名单用户ID/群组ID **请求体示例** ```json { "target_type": "user|group", "target_id": "123456789", "level": "info|warning|critical", "project": "octopus|tonystack", "content": { "title": "服务器CPU告警", "body": "服务器CPU使用率达85%", "metadata": { "server": "prod-web-01", "timestamp": "2025-10-21T10:23:00Z" } } } ``` #### 2.1.2 消息分级与模板 **等级定义** | 等级 | 触发条件 | 推送时段 | 响应时效 | 模板标识 | | :-- | :-- | :-- | :-- | :-- | | INFO | 常规事件日志 | 08:00-23:00 | 批量推送(5分钟汇总) | 📘 蓝色图标 | | WARNING | 异常但可运行 | 08:00-23:00 | 即时推送 | ⚠️ 黄色图标 | | CRITICAL | 严重故障 | 全天候 | 即时推送+重试 | 🚨 红色图标 | **模板配置** *ProjectOctopus (服务器监控模板)* ``` 🖥️ [{{level}}] {{title}} 📍 服务器: {{metadata.server}} 📊 详情: {{body}} ⏰ 时间: {{timestamp}} #服务器监控 #{{level}} ``` *ProjectTonyStack (金融监控模板)* ``` 💹 [{{level}}] {{title}} 💰 标的: {{metadata.symbol}} 📈 数值: {{body}} ⏰ 时间: {{timestamp}} #金融监控 #{{level}} ``` #### 2.1.3 消息发送器包装 **普通消息发送器** 用于发送非模板类的纯文本消息: ```go type PlainMessageSender struct { rateLimiter *RateLimiter whitelist *WhitelistChecker } func (s *PlainMessageSender) Send(chatID int64, text string) error { // 白名单验证 // 速率限制 // 发送消息 } ``` **AI消息发送器** 专门处理Markdown格式的AI回复: ```go type AIMessageSender struct { baseSender *PlainMessageSender } func (s *AIMessageSender) SendMarkdown(chatID int64, markdown string) error { // 转换Markdown格式 // 使用ParseMode: "MarkdownV2" // 调用baseSender发送 } ``` #### 2.1.4 速率限制器设计 **Telegram官方限速规则** - 不同聊天: 30消息/秒 - 同一私聊: 1消息/秒 - 同一群聊: 20消息/分钟 - editMessageText: 共享发送额度 **限制器实现** ```go // 单例模式令牌桶算法 type RateLimiter struct { globalBucket *TokenBucket // 全局30/s chatBuckets sync.Map // 每个chat独立限流 editBucket *TokenBucket // 编辑消息单独限流 } // 消息排队机制 type MessageQueue struct { priority PriorityQueue // CRITICAL优先 retryQueue []Message // 失败重试队列(指数退避) deadLetterBox []Message // 3次失败转死信队列 } ``` *** ### 2.2 机器人预定义功能 [P1-中优先级] #### 2.2.1 定时提醒功能 **指令**: `/notify` **交互流程** 利用 Telegram InlineKeyboard 实现多步交互: ``` 用户输入 /notify ↓ Bot返回主界面: ┌─────────────────────────┐ │ 📅 日期 🕐 时间 🔁 重复 │ ├─────────────────────────┤ │ 📝 提醒内容: │ │ [在此输入...] │ ├─────────────────────────┤ │ ✅ 创建提醒 │ └─────────────────────────┘ ``` **回调数据结构** ```json { "action": "notify_date|notify_time|notify_repeat|notify_submit", "state": { "date": "2025-10-25", "time": "09:00", "repeat": "daily|weekly|biweekly|monthly|custom:[1,3,5]", "content": "团队站会" } } ``` **日期选择器实现** 使用 editMessageText 动态更新消息: - 日历视图: 显示当前月份,支持上/下月翻页 - 时间选择: 时/分滚动选择器(步长15分钟) - 重复规则: 预设+自定义(RRULE格式) #### 2.2.2 提醒管理功能 **指令**: `/notify_list` **列表展示** ``` 📋 您的提醒事项 (3) 🔁 每日 | 09:00 | 团队站会 [🗑️ 删除] 📅 10-25 | 14:30 | 客户电话会议 [🗑️ 删除] 📅 10-30 | 全天 | 项目交付DDL [🗑️ 删除] ``` **删除确认机制** 点击删除后 editMessageText 更新为确认界面: ``` ⚠️ 确认删除提醒? 🔁 每日 | 09:00 | 团队站会 [❌ 取消] [✅ 确认删除] ``` #### 2.2.3 数据持久化 **SQLite 表结构** ```sql CREATE TABLE reminders ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id BIGINT NOT NULL, chat_id BIGINT NOT NULL, content TEXT NOT NULL, trigger_time DATETIME NOT NULL, repeat_rule TEXT, -- RRULE格式 next_trigger DATETIME, status INTEGER DEFAULT 1, -- 1:活动 0:已删除 created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_next_trigger (next_trigger, status) ); ``` *** ### 2.3 Telegram管理功能 [P1-中优先级] **[新增]** #### 2.3.1 用户群组管理 **API端点** ```go GET /api/v1/admin/users # 查看所有用户ID GET /api/v1/admin/groups # 查看所有群组ID GET /api/v1/admin/user/:id # 查询用户详细信息 POST /api/v1/admin/user/:id/update # 更新用户信息 ``` **用户信息存储** ```sql CREATE TABLE user_profiles ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id BIGINT UNIQUE NOT NULL, username TEXT, first_name TEXT, last_name TEXT, phone_number TEXT, language_code TEXT, is_bot INTEGER DEFAULT 0, last_interaction DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE group_profiles ( id INTEGER PRIMARY KEY AUTOINCREMENT, group_id BIGINT UNIQUE NOT NULL, title TEXT, type TEXT, -- group, supergroup, channel member_count INTEGER, last_interaction DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` **功能特性** - 自动记录所有与Bot交互的用户/群组信息 - 支持通过API查询用户完整档案 - 持久化保存用户交互历史 #### 2.3.2 机器人功能管理 **动态指令注册系统** ```go type BotCommand struct { Command string // 指令名称 (如 "notify") Description string // 指令描述 Handler string // 处理器标识 IsEnabled bool // 是否启用 Scope string // user/group/all } ``` **API端点** ```go GET /api/v1/admin/commands # 查看所有注册指令 POST /api/v1/admin/commands # 注册新指令 PUT /api/v1/admin/commands/:cmd # 修改指令 DELETE /api/v1/admin/commands/:cmd # 删除指令 POST /api/v1/admin/commands/sync # 同步到Telegram ``` **数据表设计** ```sql CREATE TABLE bot_commands ( id INTEGER PRIMARY KEY AUTOINCREMENT, command TEXT UNIQUE NOT NULL, description TEXT, handler_name TEXT NOT NULL, is_enabled INTEGER DEFAULT 1, scope TEXT DEFAULT 'all', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` **预定义功能注册** 系统启动时自动注册核心指令: - `/notify` - 创建定时提醒 - `/notify_list` - 查看提醒列表 - `/help` - 帮助信息 - `/start` - 开始对话 *** ### 2.4 AI智能体功能 [P1-中优先级] #### 2.4.1 触发机制 **[更新]** **双模式触发** - **私聊模式**: 直接回复用户发送至Bot的所有消息 - **群聊模式**: 仅响应@机器人的消息 ```go func shouldRespondToMessage(msg *Message) bool { // 私聊模式: 所有消息都响应 if msg.Chat.Type == "private" { return true } // 群聊模式: 检查是否@了机器人 if msg.Chat.Type == "group" || msg.Chat.Type == "supergroup" { for _, entity := range msg.Entities { if entity.Type == "mention" && entity.IsBotMention { return true } } } return false } ``` #### 2.4.2 上下文管理 **消息引用策略** ``` 触发消息(被@的消息或私聊消息) ↓ 引用 前3条历史消息 ↓ 拼接 发送给AI API ``` **上下文窗口** ```json { "messages": [ {"role": "system", "content": "你是Telegram群助手..."}, {"role": "user", "content": "历史消息1", "name": "user123"}, {"role": "user", "content": "历史消息2", "name": "user456"}, {"role": "user", "content": "历史消息3", "name": "user123"}, {"role": "user", "content": "当前触发消息", "name": "user789"} ] } ``` #### 2.4.3 AI集成实现 **[更新]** **首选方案: OpenRouter** 使用OpenAI Go SDK对接OpenRouter API: ```go import ( "github.com/sashabaranov/go-openai" ) func initAIClient() *openai.Client { config := openai.DefaultConfig(os.Getenv("OPENROUTER_API_KEY")) config.BaseURL = "https://openrouter.ai/api/v1" return openai.NewClientWithConfig(config) } ``` **模型选择建议** | 提供商 | 推荐模型 | 特性 | | :-- | :-- | :-- | | OpenRouter | anthropic/claude-3.5-sonnet | 思考链支持 | | OpenRouter | google/gemini-pro-1.5 | 长上下文 | | OpenRouter | openai/gpt-4-turbo | 通用平衡 | **流式响应处理** ```go 1. 发送初始消息"🤔 正在思考..." 2. 创建流式请求到OpenRouter 3. 累积AI响应分片(每500字符或5秒) 4. 使用AIMessageSender.SendMarkdown更新消息 5. 遵守编辑速率限制(复用全局限流器) 6. 完成后添加"✅ 回答完成"标识 ``` **思考过程展示** ``` 🤔 思考中... 【推理步骤1】分析问题... 【推理步骤2】检索知识... 💡 回答: [AI生成的完整答复] ✅ 回答完成 | 用时3.2s ``` #### 2.4.4 交互日志记录 **[新增]** **日志输出格式** ```go type AIInteractionLog struct { Timestamp time.Time UserID int64 Username string PhoneNumber string // 可能为空 GroupID int64 // 私聊时为0 GroupName string // 私聊时为空 MessageText string AIResponse string Duration time.Duration } ``` **日志输出示例** ``` [2025-10-24 15:23:45] AI交互记录 用户ID: 123456789 | 用户名: @john_doe | 手机号: +1234567890 群组ID: 987654321 | 群组名: 开发团队讨论组 消息: 今天天气怎么样? AI回复: 我无法获取实时天气信息... 耗时: 2.3s ``` *** ## 三、基础架构设计 ### 3.1 安全控制 **白名单机制** ```sql CREATE TABLE whitelist ( id INTEGER PRIMARY KEY, type TEXT CHECK(type IN ('user', 'group')), entity_id BIGINT UNIQUE NOT NULL, alias TEXT, added_by BIGINT, added_at DATETIME DEFAULT CURRENT_TIMESTAMP, status INTEGER DEFAULT 1 ); ``` **中间件验证逻辑** ```go func WhitelistMiddleware() gin.HandlerFunc { return func(c *gin.Context) { update := c.MustGet("telegram_update") // 提取user_id和chat_id if !IsInWhitelist(userID, chatID) { bot.SendMessage(chatID, "⚠️ 未授权访问") c.Abort() return } c.Next() } } ``` ### 3.2 网络代理配置 **环境变量** ```shell TELEGRAM_PROXY_TYPE=socks5|http TELEGRAM_PROXY_HOST=127.0.0.1 TELEGRAM_PROXY_PORT=1080 TELEGRAM_PROXY_USER=optional_username TELEGRAM_PROXY_PASS=optional_password ``` **代理客户端初始化** ```go proxyURL, _ := url.Parse( fmt.Sprintf("%s://%s:%s@%s:%d", proxyType, user, pass, host, port)) httpClient := &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyURL(proxyURL), }, } bot, _ := tgbotapi.NewBotAPIWithClient(token, httpClient) ``` ### 3.3 数据持久化 **存储路径规范** - Windows: `%USERPROFILE%\naughty_man\bot.db` - Linux: `/usr/local/etc/naughty_man/bot.db` **核心表设计** ```sql -- Token管理 CREATE TABLE api_tokens ( id INTEGER PRIMARY KEY, api_key TEXT NOT NULL, access_token TEXT UNIQUE, challenge TEXT, challenge_expire DATETIME, token_expire DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 消息日志 CREATE TABLE message_log ( id INTEGER PRIMARY KEY, message_id TEXT, chat_id BIGINT, level TEXT, project TEXT, content TEXT, status TEXT, -- pending|sent|failed retry_count INTEGER DEFAULT 0, sent_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- AI交互日志 CREATE TABLE ai_interaction_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id BIGINT NOT NULL, username TEXT, phone_number TEXT, group_id BIGINT, group_name TEXT, message_text TEXT, ai_response TEXT, duration_ms INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### 3.4 配置文件 **统一配置管理** 所有可变参数通过`config.yaml`加载: ```yaml database: path: "./data/bot.db" proxy: enabled: true type: "socks5" host: "127.0.0.1" port: 1080 ai: provider: "openrouter" api_key: "${OPENROUTER_API_KEY}" model: "anthropic/claude-3.5-sonnet" auth: token_secret: "${TOKEN_SECRET}" token_expire_hours: 6 notification: normal_hours: "08:00-23:00" ``` *** ## 四、非功能性需求 ### 4.1 性能指标 - API响应延迟: P95 < 200ms - 消息发送成功率: > 99.5% - 定时提醒误差: ±30秒 - AI响应首字延迟: < 3秒 ### 4.2 可靠性 - 消息队列持久化避免丢失 - 失败消息自动重试(指数退避,最多3次) - 死信队列人工介入机制 - 定时任务崩溃恢复(启动时扫描pending任务) ### 4.3 可观测性 **日志分级** - ERROR: 消息发送失败、数据库错误 - WARN: 触及速率限制、Token即将过期 - INFO: API调用、定时任务触发、AI交互记录 - DEBUG: 消息队列状态、AI流式分片 **监控指标** - 消息发送QPS - 令牌桶剩余容量 - 数据库连接池状态 - AI API调用耗时分布 - 用户活跃度统计 *** ## 五、实施计划 ### 阶段一:基础设施 (2周) - 速率限制器实现与测试 - 数据库表结构设计(包含新增管理表) - 白名单+Token认证系统 - 代理支持与连接测试 ### 阶段二:核心功能 (3周) - 消息通知API开发 - 分级模板渲染引擎 - 普通/AI消息发送器包装 - 消息队列与重试机制 - 定时提醒CRUD功能 ### 阶段三:管理功能 (2周) **[新增]** - 用户群组信息采集与存储 - 管理API接口开发 - 动态指令注册系统 - 预定义功能自动注册 ### 阶段四:AI功能 (3周) - OpenRouter API集成(使用OpenAI SDK) - 私聊/群聊双模式触发 - 流式响应处理 - AI交互日志记录 - InlineKeyboard交互流程 ### 阶段五:上线准备 (1周) - 集成测试与修复 - 文档编写 - 监控告警配置 - 灰度发布 *** ## 六、风险与对策 | 风险项 | 影响 | 对策 | | :-- | :-- | :-- | | Telegram API限流 | 消息延迟/丢失 | 令牌桶+优先级队列+重试机制 | | OpenRouter服务中断 | 智能体不可用 | 降级提示+本地缓存回复 | | SQLite并发写入 | 数据竞争 | WAL模式+写操作串行化 | | 网络代理不稳定 | Bot离线 | 心跳检测+自动重连+备用代理 | | 用户隐私泄露 | 合规风险 | 手机号加密存储+API鉴权 | *** ## 七、后续演进方向 1. **多厂商AI支持**: 完整实现OpenAI/Gemini/Grok切换 2. **多Bot实例**: 分布式部署+消息路由中心 3. **富媒体支持**: 图片、文件、语音消息通知 4. **自定义指令**: 用户自定义快捷命令 5. **数据看板**: 消息统计、AI使用分析、用户活跃度 6. **Webhook模式**: 替代Long Polling提升实时性 *** ## 八、文档变更记录 **v2.1 (2025-10-24)** - 新增Telegram管理功能模块(用户群组管理/机器人功能管理) - AI智能体触发机制扩展至私聊模式 - 明确AI实现为OpenRouter优先,使用OpenAI Go SDK - 新增AI消息通知发送器包装 - 新增AI交互日志记录要求 - 术语更新:"机器人功能"改为"机器人预定义功能" **v2.0 (2025-10-21)** - 初始PRD文档发布