一个用于处理QQ合并转发消息的服务器,支持消息数据的上传、存储和展示,需要配合 nonebot-plugin-discord-message-bridge 使用。
- ✅ 合并转发消息数据的上传和存储
- ✅ 任意层级嵌套合并转发的递归展示
- ✅ 图片自动下载和本地存储
- ✅ 嵌套消息时间格式统一
- ✅ 消息数据的JSON格式化和展示
- ✅ RESTful API接口
- ✅ CORS跨域支持
- ✅ 固定 worker 队列后台下载图片,上传接口不等待网络请求
- ✅ 页面、映射、聊天数据和图片的 HTTP 公共缓存
- ✅ 完整的日志记录
forward_msg_server/
├── server.py # 主服务器程序
├── config.py # 配置文件
├── requirements.txt # 依赖包列表
├── README.md # 项目说明文档
└── uploads/ # 上传文件存储目录(自动创建)
├── images/ # 图片存储目录
├── data/ # 聊天数据存储目录
├── image_index.json # 图片索引文件
└── id_mapping.json # ID映射文件
- Python 3.10+
- pip
pip install -r requirements.txt在 config.py 中修改配置项。
python server.py服务器将在 http://0.0.0.0:3000 启动。
POST /upload/<ori_id>
- 描述: 上传合并转发消息数据
- 参数:
ori_id: 原始消息ID
- 请求体: JSON格式的消息数据
- 返回:
{ "status": "success", "chat_uuid": "生成的UUID", "message": "Chat data uploaded and processed successfully", "chat_data_url": "聊天数据访问URL" }
GET /mapping/<ori_id>
- 描述: 根据原始ID获取聊天记录UUID
- 参数:
ori_id: 原始消息ID
- 返回:
{ "status": "success", "ori_id": "原始ID", "chat_uuid": "对应的UUID", "chat_data_url": "聊天数据访问URL" }
GET /chat-data/<chat_uuid>.json
- 描述: 获取格式化的聊天数据
- 参数:
chat_uuid: 聊天记录UUID
- 返回: JSON格式的聊天数据数组
GET /image/<image_uuid>
- 描述: 获取存储的图片文件
- 参数:
image_uuid: 图片UUID
- 返回: 图片文件
{
"data": {
"messages": [
{
"message_id": 123456,
"sender": {
"user_id": "123456789",
"nickname": "用户昵称"
},
"time": 1632825600,
"message": [
{
"type": "text",
"data": {
"text": "文本内容"
}
},
{
"type": "image",
"data": {
"url": "图片URL"
}
}
]
}
]
}
}[
{
"id": "123456",
"nickname": "用户昵称",
"avatar": "QQ头像URL",
"message": [
{
"type": "text",
"data": {
"text": "文本内容"
}
},
{
"type": "image",
"data": {
"url": "本地图片URL"
}
}
],
"timestamp": "2025-08-24 12:00:00"
}
]- 自动下载消息(包括嵌套合并转发)中的图片到本地
- 支持多种图片格式(JPG、PNG、GIF、WebP)
- 使用UUID重命名图片文件,避免冲突
- 上传响应发送完成后才将图片任务放入内存队列,不等待任何图片网络请求
- 固定数量 worker 复用 HTTP 连接池,避免大量图片时创建大量线程
- 嵌套层级中的临时图片 URL 同样会替换为服务器本地 URL
- 使用JSON文件存储聊天数据
- 维护原始ID与UUID的映射关系
- 图片索引文件加速图片查找
- 完整的异常捕获和日志记录
- 图片下载失败时的优雅降级
- 网络超时保护
DEBUG: 详细的调试信息INFO: 一般信息WARNING: 警告信息ERROR: 错误信息
项目采用模块化设计,可以轻松添加新功能:
- 在
config.py中添加新的配置项 - 在
server.py中添加新的路由和处理函数 - 更新
requirements.txt添加新的依赖
- 确保服务器有足够的存储空间用于图片和数据文件
- 根据实际部署环境修改
config.py中的SERVER_URL - 生产环境建议使用 Nginx 等反向代理服务器
源站会为所有成功的公开 GET 响应返回:
Cache-Control: public, immutable
CDN-Cache-Control: public, max-age=31536000, immutable
Cloudflare-CDN-Cache-Control: public, max-age=31536000, immutable浏览器缓存头不设置时间上限;Cloudflare 边缘缓存使用一年 TTL,因为
Cloudflare 不支持真正无限的 Edge TTL。聊天数据使用 .json 后缀,同时
继续兼容历史无后缀 URL;图片格式由真实下载结果决定,不伪造扩展名。
Cloudflare 默认不会缓存 HTML 和部分动态路径。请在 Cloudflare 控制台创建
一条 Cache Rule,否则响应仍可能显示 CF-Cache-Status: DYNAMIC:
- 条件设置为请求方法等于
GET,并匹配/、/mapping/、/chat-data/或/image/。 - 将 Cache eligibility 设置为 Eligible for cache。
- Edge TTL 选择遵循源站缓存控制头,不要选择 Bypass cache。
- 保存并部署规则后,首次请求应为
MISS,再次请求应为HIT或REVALIDATED,而不是DYNAMIC。