Files
chatrebot_aireply_plug/scripts/qq_get_file.py
root 9dff73e7bc fix: 通过本地完整测试发现的 11 个 bug
🔴 致命(5个):
- Bug1: onebot11.json 格式错误(旧 {http:{},ws:{}} → network.httpServers/httppClients)
- Bug2: 端口映射错位(WebUI 6099, OneBot API 6097 独立端口)
- Bug3: 变量名含空格 NAP CAT_HOST → NAPCAT_HOST(14脚本+2SKILL+README)
- Bug4: heredoc 单引号阻止变量展开
- Bug5: process.py 缺失 _get_high_risk_words() 方法

🟡 重要(3个):
- Bug6: onebot11.json 默认不存在(cat > 而非 edit)
- Bug7: API 须登录后才响应(新增扫码引导步骤)
- Bug8: qqrebot systemd 依赖 napcat 服务

🟢 中等(3个):
- Bug9: Skills 占位符缺 YOUR_NAPCAT_HOST sed 覆盖
- Bug10: venv 不可用需降级方案
- Bug11: 端口 25580 冲突处理
已验证全链路:NapCat + qqrebot + 插件 + OpenClaw Gateway + AI 回复
2026-05-04 19:47:26 +08:00

104 lines
3.1 KiB
Python
Raw Permalink 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.

#!/usr/bin/env python3
"""
从 QQ 接收文件/图片 - 通过 NapCat (OneBot) HTTP API
自动下载到 qqagent 工作区的 files/ 目录,供 agent 直接使用。
用法:
python3 qq_get_file.py --file <file_id>
→ 下载到 files/ 目录
→ 输出保存路径、文件名、大小、类型
python3 qq_get_file.py --file <file_id> --info --json
→ 只查文件信息(不下)
"""
import json
import sys
import os
import argparse
import requests
CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570"
FILES_DIR = "YOUR_WORKSPACE_PATH/files"
def get_file(file_id: str) -> dict:
resp = requests.post(
f"{CQHTTP_URL}/get_file",
json={"file_id": file_id},
timeout=15
)
resp.raise_for_status()
data = resp.json()
if data.get("status") != "ok":
raise Exception(f"API error: {data}")
return data["data"]
def save_file(file_info: dict) -> tuple[str, str]:
"""下载文件到 FILES_DIR返回 (本地路径, 文件名)"""
os.makedirs(FILES_DIR, exist_ok=True)
filename = file_info.get("file_name", "unknown")
local_path = os.path.join(FILES_DIR, filename)
if file_info.get("base64"):
import base64
with open(local_path, "wb") as f:
f.write(base64.b64decode(file_info["base64"]))
else:
url = file_info.get("url", "")
if not url:
raise Exception("No base64 or url available")
resp = requests.get(url, timeout=30)
resp.raise_for_status()
with open(local_path, "wb") as f:
f.write(resp.content)
return local_path, filename
def detect_type(filename: str) -> str:
ext = filename.lower().rsplit(".", 1)[-1] if "." in filename else ""
image_exts = {"jpg", "jpeg", "png", "gif", "bmp", "webp"}
return "图片" if ext in image_exts else "文件"
def main():
parser = argparse.ArgumentParser(description="从 QQ 接收文件")
parser.add_argument("--file", required=True, help="文件 IDfile_id")
parser.add_argument("--output", help="保存目录(默认 files/")
parser.add_argument("--info", action="store_true", help="只查文件信息,不下")
parser.add_argument("--json", action="store_true", help="JSON 格式输出")
args = parser.parse_args()
try:
file_info = get_file(args.file)
if args.info or args.json:
info = {
"file_id": args.file,
"name": file_info.get("file_name"),
"size": file_info.get("file_size"),
"has_base64": bool(file_info.get("base64")),
}
print(json.dumps(info, ensure_ascii=False, indent=2))
return
save_dir = args.output or FILES_DIR
local_path, filename = save_file(file_info)
ftype = detect_type(filename)
print(f"✅ 已保存到 {local_path}")
print(f" 文件名: {filename}")
print(f" 大小: {file_info.get('file_size')} bytes")
print(f" 类型: {ftype}")
except Exception as e:
print(f"❌ 错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()