Files
chatrebot_aireply_plug/scripts/qq_resolve_name.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

200 lines
6.4 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 号/群号 ↔ 用户名/群名 转换脚本
将数字 ID 转为可读的名称。通过 NapCat (OneBot) HTTP API 查询。
用法:
# 解析单个 QQ 号
python3 qq_resolve_name.py --uid YOUR_ADMIN_QQ
python3 qq_resolve_name.py --uid YOUR_ADMIN_QQ --json
# 解析单个群号
python3 qq_resolve_name.py --gid YOUR_GROUP_ID
python3 qq_resolve_name.py --gid YOUR_GROUP_ID --json
# 批量解析
python3 qq_resolve_name.py --uid YOUR_ADMIN_QQ --uid 12345678 --gid YOUR_GROUP_ID
python3 qq_resolve_name.py --uid YOUR_ADMIN_QQ --gid YOUR_GROUP_ID --json
# 从文件读取待解析的 ID每行一个uid:123456 或 gid:YOUR_GROUP_ID
python3 qq_resolve_name.py --from-file /tmp/ids.txt
python3 qq_resolve_name.py --from-file /tmp/ids.txt --json
"""
import json
import sys
import argparse
import requests
CQHTTP_URL = "http://YOUR_NAPCAT_HOST:25570"
def get_stranger_info(user_id):
"""通过 OneBot API 获取陌生人/好友信息"""
url = f"{CQHTTP_URL}/get_stranger_info"
payload = {"user_id": int(user_id), "no_cache": True}
resp = requests.post(url, json=payload, timeout=10)
data = resp.json()
if data.get("status") == "ok":
return data.get("data", {})
return None
def get_group_info(group_id):
"""通过 OneBot API 获取群信息"""
url = f"{CQHTTP_URL}/get_group_info"
payload = {"group_id": int(group_id), "no_cache": True}
resp = requests.post(url, json=payload, timeout=10)
data = resp.json()
if data.get("status") == "ok":
return data.get("data", {})
return None
def format_user_info(info, uid):
"""格式化用户信息"""
if not info:
return f"{uid} → 未找到(可能不是好友或不存在)"
uid = info.get("user_id", uid)
nickname = info.get("nickname", "?")
remark = info.get("remark", "")
level = info.get("level", 0)
sex = {"male": "", "female": "", "unknown": "未知"}.get(info.get("sex", ""), "?")
age = info.get("age", "?")
remark_str = f"(备注:{remark}" if remark else ""
return f"{nickname} ({uid}){remark_str} [{sex}/{age}岁/等级{level}]"
def format_group_info(info, gid):
"""格式化群信息"""
if not info:
return f"{gid} → 未找到(群不存在或 bot 未加入)"
gid = info.get("group_id", gid)
name = info.get("group_name", "?")
member_count = info.get("member_count", "?")
max_member = info.get("max_member_count", "?")
level = info.get("group_level", 0)
owner = info.get("owner_id", "?")
return f"{name} ({gid}) — {member_count}/{max_member} 人 | 群主:{owner} | 等级:{level}"
def resolve_uids(uids):
"""批量解析多个 QQ 号"""
results = {"users": []}
for uid in uids:
info = get_stranger_info(uid)
results["users"].append({
"user_id": uid,
"nickname": info.get("nickname", "?") if info else None,
"remark": info.get("remark", "") if info else None,
"found": info is not None,
"raw": info
})
return results
def resolve_gids(gids):
"""批量解析多个群号"""
results = {"groups": []}
for gid in gids:
info = get_group_info(gid)
results["groups"].append({
"group_id": gid,
"group_name": info.get("group_name", "?") if info else None,
"found": info is not None,
"raw": info
})
return results
def parse_id_line(line):
"""解析行格式 uid:123456 或 gid:123456"""
line = line.strip()
if not line or line.startswith("#"):
return None
if ":" in line:
kind, val = line.split(":", 1)
return kind.strip().lower(), val.strip()
# 纯数字行:默认当作 uid
if line.isdigit():
return "uid", line
return None
def main():
parser = argparse.ArgumentParser(description="QQ 号/群号 ↔ 用户名/群名 转换")
parser.add_argument("--uid", action="append", type=str, dest="uids",
help="待解析的 QQ 号(可多次使用)")
parser.add_argument("--gid", action="append", type=str, dest="gids",
help="待解析的群号(可多次使用)")
parser.add_argument("--from-file", type=str,
help="从文件读取 ID每行 uid:123456 或 gid:123456")
parser.add_argument("--json", action="store_true", help="输出 JSON 格式")
args = parser.parse_args()
uids = args.uids or []
gids = args.gids or []
if args.from_file:
with open(args.from_file, "r") as f:
for line in f:
parsed = parse_id_line(line)
if parsed:
kind, val = parsed
if kind in ("uid", "user", "qq"):
uids.append(val)
elif kind in ("gid", "group"):
gids.append(val)
if not uids and not gids:
print("❌ 请指定 --uid 或 --gid 或 --from-file")
sys.exit(1)
try:
results = {}
if uids:
results["users"] = []
for uid in uids:
info = get_stranger_info(uid)
results["users"].append({
"user_id": uid,
"info": info
})
if gids:
results["groups"] = []
for gid in gids:
info = get_group_info(gid)
results["groups"].append({
"group_id": gid,
"info": info
})
if args.json:
print(json.dumps(results, ensure_ascii=False, indent=2))
else:
lines = []
if "users" in results:
lines.append("📋 用户信息:")
for item in results["users"]:
lines.append(format_user_info(item["info"], item["user_id"]))
if "groups" in results:
if lines:
lines.append("")
lines.append("📋 群信息:")
for item in results["groups"]:
lines.append(format_group_info(item["info"], item["group_id"]))
print("\n".join(lines))
except requests.exceptions.ConnectionError:
print(f"❌ 连接失败: 无法连接到 NapCat ({CQHTTP_URL})")
sys.exit(1)
except Exception as e:
print(f"❌ 查询失败: {e}")
sys.exit(1)
if __name__ == "__main__":
main()