294 lines
9.2 KiB
Markdown
294 lines
9.2 KiB
Markdown
# 🤖 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 7:Web 面板升级
|
||
- 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
|