Files
tg-spam-guard/PLAN.md
T
2026-07-06 19:26:00 +08:00

294 lines
9.2 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.
# 🤖 TG 群管机器人 v2 — 重构规划
## 📌 项目信息
| 项 | 值 |
|----|-----|
| 项目路径 | `/vol3/1000/Code/tg-spam-guard/` |
| Git 仓库 | GitHub `ngfchl/tg-spam-guard` |
| 运行环境 | Python 3.12 + Docker |
| Web 框架 | FastAPI + uvicorn |
| ORM | Tortoise ORM + aerich |
| 数据库 | PostgreSQL (`192.168.123.5:15432`) |
| Bot | python-telegram-bot ≥ 22 |
| AI | Ollama (`qwen3:8b`) |
| 知识库 | sentence-transformers + BGE-zh + numpy |
| 前端 | Element UI 单页 |
---
## 🏗️ 项目结构
```
tg-spam-guard/
├── main.py # 入口:启动 FastAPI + Bot
├── config.py # 全局配置(从环境变量/配置文件读取)
├── db/ # 数据库层
│ ├── __init__.py # Tortoise 初始化
│ ├── models.py # 所有 ORM 模型
│ └── migrate.py # aerich 迁移配置
├── handlers/ # Telegram 消息处理器
│ ├── __init__.py
│ ├── welcome.py # 入群欢迎/退群告别
│ ├── verify.py # 入群验证
│ ├── spam.py # 垃圾检测+封禁
│ ├── night_mode.py # 夜间模式
│ ├── knowledge.py # /ask 知识库问答
│ ├── fun.py # 气氛组 + 小游戏
│ ├── bind.py # 账号绑定
│ └── admin.py # /ban /unban /warn /mute /kick /stats /purge
├── services/ # 业务逻辑层
│ ├── __init__.py
│ ├── spam_detector.py # 多层垃圾检测引擎
│ ├── knowledge_base.py # RAG 检索(当前 knowledge/ 模块)
│ ├── verify_service.py # 验证逻辑
│ ├── night_scheduler.py # APScheduler 定时任务
│ ├── game_service.py # 小游戏逻辑
│ └── bind_service.py # go-harvest-server verify 对接
├── web/ # Web 管理面板
│ ├── api.py # FastAPI 路由
│ └── static/
│ └── index.html # Element UI 前端
├── knowledge/ # 知识库(保持现有)
│ ├── __init__.py
│ ├── __main__.py
│ ├── index/
│ └── models/
├── templates/ # 消息模板
│ ├── welcome.md
│ ├── verify.md
│ └── night_mode.md
├── wheels/ # 本地 wheel 缓存(torch 等)
├── logs/ # 日志目录(运行时生成)
├── docker-compose.yaml
├── Dockerfile
├── requirements.txt
├── pyproject.toml
├── aerich.toml # aerich 迁移配置
├── .env.example # 环境变量示例
└── .gitignore
```
---
## 📦 数据库设计(PostgreSQL
### 核心表
```sql
-- 消息记录
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
msg_id BIGINT,
chat_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
username VARCHAR(255),
first_name VARCHAR(255),
text TEXT,
is_spam BOOLEAN DEFAULT FALSE,
spam_reason VARCHAR(255),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_messages_user_id ON messages(user_id);
CREATE INDEX idx_messages_created_at ON messages(created_at);
CREATE INDEX idx_messages_is_spam ON messages(is_spam);
-- 封禁记录
CREATE TABLE bans (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
username VARCHAR(255),
first_name VARCHAR(255),
reason VARCHAR(500),
method VARCHAR(50), -- 'auto' / 'command' / 'verify_fail'
duration_minutes INTEGER,
auto_unban BOOLEAN DEFAULT TRUE,
unban_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_bans_user_id ON bans(user_id);
-- 操作日志(入群/退群/删除/解封/警告等)
CREATE TABLE actions (
id BIGSERIAL PRIMARY KEY,
action VARCHAR(50) NOT NULL, -- JOIN/LEAVE/DELETE/UNBAN/WARN/MUTE/KICK
user_id BIGINT,
username VARCHAR(255),
operator_id BIGINT, -- 执行操作的管理员
details JSONB, -- 扩展字段
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_actions_action ON actions(action);
CREATE INDEX idx_actions_created_at ON actions(created_at);
-- 入队验证
CREATE TABLE verify_queue (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
username VARCHAR(255),
question VARCHAR(500),
answer VARCHAR(500),
attempts INTEGER DEFAULT 0,
status VARCHAR(20) DEFAULT 'pending', -- pending/verified/failed/expired
created_at TIMESTAMPTZ DEFAULT NOW(),
verified_at TIMESTAMPTZ
);
CREATE INDEX idx_verify_user_id ON verify_queue(user_id);
-- 账号绑定(TG ↔ Harvest
CREATE TABLE user_bindings (
id BIGSERIAL PRIMARY KEY,
tg_user_id BIGINT UNIQUE NOT NULL,
tg_username VARCHAR(255),
harvest_uid VARCHAR(255),
harvest_token VARCHAR(500),
bound_at TIMESTAMPTZ DEFAULT NOW()
);
-- 警告记录
CREATE TABLE warnings (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
username VARCHAR(255),
reason VARCHAR(500),
issued_by BIGINT,
active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_warnings_user_id ON warnings(user_id);
CREATE INDEX idx_warnings_active ON warnings(active);
-- 游戏积分
CREATE TABLE game_scores (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
username VARCHAR(255),
game_type VARCHAR(50),
score INTEGER DEFAULT 0,
wins INTEGER DEFAULT 0,
total INTEGER DEFAULT 0,
streak INTEGER DEFAULT 0,
last_played TIMESTAMPTZ,
UNIQUE(user_id, game_type)
);
-- 群组配置
CREATE TABLE group_config (
key VARCHAR(100) PRIMARY KEY,
value JSONB,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
---
## 📋 功能清单(去掉 PT 专属)
| # | 模块 | 优先级 | 说明 |
|---|------|--------|------|
| 1 | 🛡️ 垃圾信息阻挡 | ✅ 已有 | 三级检测:缓存→正则→AI,保留优化 |
| 2 | ⚡ 防刷屏 | 🔴 P0 | 令牌桶限速,超阈值删除多余消息 |
| 3 | 🔒 新人限制 | 🔴 P0 | 入群 N 分钟内禁止发链接/图片/文件/贴纸 |
| 4 | 👋 入群欢迎 | 🔴 P0 | 自定义欢迎卡片 + 群规 + 60s 自动删 |
| 5 | ✅ 入群验证 | 🔴 P0 | 新人答题/点按钮,超时踢出 |
| 6 | 🔗 账号绑定 | 🔴 P0 | TG ↔ Harvest 授权绑定 |
| 7 | 🌙 夜间模式 | 🟡 P1 | 定时全员禁言,管理员不受影响 |
| 8 | 🔨 管理工具 | 🟡 P1 | /warn /mute /kick /purge /slowmode /stats |
| 9 | 📊 操作审计 | 🟡 P1 | 所有管理员操作记录到 DB |
| 10 | 👥 退群告别 | 🟡 P1 | 可选,默认关闭 |
| 11 | 📚 知识库问答 | ✅ 已有 | /ask + RAG,保持 |
| 12 | 🎉 气氛组 | 🟢 P2 | 关键词触发表情、连击、撒花、里程碑 |
| 13 | 🎮 小游戏 | 🟢 P2 | 答题/签到/积分排行/抽奖 |
| 14 | 🎂 生日祝福 | 🟢 P3 | 记录生日,当天自动祝福 |
---
## 🔄 开发阶段
### Phase 1:基建(SQLite→PG + 重构 + Git
- 初始化 Git 仓库
- 项目目录结构搭建
- config.py(环境变量管理)
- db/Tortoise ORM 模型 + aerich 初始化)
- docker-compose.yaml(接入 PostgreSQL 网络)
- requirements.txt / pyproject.toml 更新
- main.py 瘦身:只保留启动逻辑
### Phase 2:核心安全(P0
- handlers/spam.py + services/spam_detector.py(从旧 main.py 提取)
- handlers/admin.py/ban /unban /warn /mute /kick /stats /purge
- 防刷屏中间件
- 新人限制(禁止链接/图片/文件)
### Phase 3:入群流程(P0
- handlers/welcome.py(入群欢迎/退群告别)
- handlers/verify.py + services/verify_service.py(入群验证)
- templates/(消息模板)
### Phase 4:账号绑定(P0
- handlers/bind.py + services/bind_service.py
- 对接 go-harvest-server verify 接口
- /bind /unbind 命令
### Phase 5:夜间模式 + 管理增强(P1)
- handlers/night_mode.py + services/night_scheduler.py
- APScheduler 集成
- 操作审计
### Phase 6:社交 + 游戏(P2-P3
- handlers/fun.py + services/game_service.py
- 气氛组(关键词触发、连击、撒花)
- 小游戏(答题、签到、积分)
- 生日祝福
### Phase 7Web 面板升级
- web/api.py(所有 API 路由)
- web/static/index.html(适配新数据结构)
- SSE 实时推送适配
---
## ⚙️ 环境变量(.env
```env
# Telegram
TG_BOT_TOKEN=your_telegram_bot_token
TG_CHAT_ID=-1001515287526
# PostgreSQL
DATABASE_URL=postgresql://user:password@192.168.123.5:15432/tg_spam_guard
# Ollama
OLLAMA_URL=http://127.0.0.1:11434
OLLAMA_MODEL=qwen3:8b
# Proxy
PROXY_URL=http://192.168.123.10:11055
# Web
WEB_PORT=8766
SITE_URL=https://ptools.fun
# Harvest
HARVEST_SERVER_URL=https://ptools.fun
```
---
## 📝 备忘
- 旧数据迁移:JSON → PostgreSQL(一次性脚本,放在 scripts/migrate_json_to_pg.py
- docker-compose 需要加入 `1panel-network` 网络
- aerich 配置写在 aerich.toml,用 `aerich init` / `aerich migrate` 管理
- wheels/ 目录保留(torch 等大包不走网络)
- 知识库模块(knowledge/)保持独立,不改动
- 旧 main.py 备份为 main.py.bak