18 KiB
18 KiB
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 端点结构
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 安全机制
- 双阶段认证流程:
- 阶段一: 客户端携带 API Key 请求握手,服务端返回 challenge 码(60秒有效期)
- 阶段二: 客户端用 challenge+API Secret 生成签名,换取 Access Token(6小时有效期)
- Token 刷新策略:
- Token过期前30分钟允许静默续期
- 每个API Key同时只允许一个有效Token
- Token中包含加密的白名单用户ID/群组ID
请求体示例
{
"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 消息发送器包装
普通消息发送器
用于发送非模板类的纯文本消息:
type PlainMessageSender struct {
rateLimiter *RateLimiter
whitelist *WhitelistChecker
}
func (s *PlainMessageSender) Send(chatID int64, text string) error {
// 白名单验证
// 速率限制
// 发送消息
}
AI消息发送器
专门处理Markdown格式的AI回复:
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: 共享发送额度
限制器实现
// 单例模式令牌桶算法
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返回主界面:
┌─────────────────────────┐
│ 📅 日期 🕐 时间 🔁 重复 │
├─────────────────────────┤
│ 📝 提醒内容: │
│ [在此输入...] │
├─────────────────────────┤
│ ✅ 创建提醒 │
└─────────────────────────┘
回调数据结构
{
"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 表结构
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端点
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 # 更新用户信息
用户信息存储
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 机器人功能管理
动态指令注册系统
type BotCommand struct {
Command string // 指令名称 (如 "notify")
Description string // 指令描述
Handler string // 处理器标识
IsEnabled bool // 是否启用
Scope string // user/group/all
}
API端点
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
数据表设计
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的所有消息
- 群聊模式: 仅响应@机器人的消息
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
上下文窗口
{
"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:
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 | 通用平衡 |
流式响应处理
1. 发送初始消息"🤔 正在思考..."
2. 创建流式请求到OpenRouter
3. 累积AI响应分片(每500字符或5秒)
4. 使用AIMessageSender.SendMarkdown更新消息
5. 遵守编辑速率限制(复用全局限流器)
6. 完成后添加"✅ 回答完成"标识
思考过程展示
🤔 思考中...
【推理步骤1】分析问题...
【推理步骤2】检索知识...
💡 回答:
[AI生成的完整答复]
✅ 回答完成 | 用时3.2s
2.4.4 交互日志记录 [新增]
日志输出格式
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 安全控制
白名单机制
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
);
中间件验证逻辑
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 网络代理配置
环境变量
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
代理客户端初始化
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
核心表设计
-- 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加载:
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鉴权 |
七、后续演进方向
- 多厂商AI支持: 完整实现OpenAI/Gemini/Grok切换
- 多Bot实例: 分布式部署+消息路由中心
- 富媒体支持: 图片、文件、语音消息通知
- 自定义指令: 用户自定义快捷命令
- 数据看板: 消息统计、AI使用分析、用户活跃度
- Webhook模式: 替代Long Polling提升实时性
八、文档变更记录
v2.1 (2025-10-24)
- 新增Telegram管理功能模块(用户群组管理/机器人功能管理)
- AI智能体触发机制扩展至私聊模式
- 明确AI实现为OpenRouter优先,使用OpenAI Go SDK
- 新增AI消息通知发送器包装
- 新增AI交互日志记录要求
- 术语更新:"机器人功能"改为"机器人预定义功能"
v2.0 (2025-10-21)
- 初始PRD文档发布