- 同一互动 uuid(平台重复推送)或同群同按钮 10 秒内只处理一次;连点 仍应答互动,关掉客户端 loading - 播放/下载结果以 msg_seq=2 补发(同一事件相同 msg_seq 的二次回复会被 QQ 拒绝) - 一并入库此前未提交的 /sources 平台发现(直链回退链按服务器能力动态 解析);uv.lock 随上游 qqbotsdk main 更新 sdist hash
musicbot
QQ 群点歌 bot,基于 qqbotsdk,两步点歌:
- 选歌菜单——
点歌 <歌名 [歌手]>(或斜杠指令/点歌 <歌名 [歌手]>)只负责选歌:Markdown 歌单(编号 + 歌名/歌手,默认 QQ 音乐源,搜不到自动聚合兜底),下方每行 5 个编号回调按钮 +[上一页][下一页](每页MENU_PAGE_SIZE首,默认 10,上限 20) - 歌曲卡片——点编号弹出卡片:专辑封面图 + 歌名/歌手/来源 +
[▶ 播放][⬇ 下载]回调按钮,再点才执行
- 专辑封面:卡片用 Markdown 图片语法
显示封面(QQ 后台会代理并缓存图片到客户端,不落库);封面来自 MusicServer 的img字段,tx/wy 有值,kw/kg 无(这些源卡片就不带图) - 回调按钮(type=1)点一下直接生效,无需再按发送;播放发语音、下载发文件或直链(见
SEND_MODE),失败回退直链文本;无 Markdown 权限自动回退文本 - 下载发送方式(
SEND_MODE,默认link):群文件上传仅限群主/管理员(40093005),故默认直接发直链;file则先尝试上传群文件、失败(含无权限)回退直链。播放始终发语音 - 直链候选源回退:tx 等源直链常受 CDN 风控抓不动(bot 抓不动时 QQ 服务器侧上传同样报 40093007),上传前先探测直链可抓性,不可抓则按 kw/wy/mg 逐个搜索换源
- 自动撤回(
WITHDRAW,默认开):翻页撤旧菜单、选歌后撤菜单、下载/播放点击后撤卡片(无论发送成败都撤,卡片是一次性 UI);关闭后所有消息都保留 - 回调防抖与先应答:按钮回调进门先回应互动(
PUT /interactions,几秒内不应答 QQ 客户端就报超时),同一互动 uuid(平台重复推送)或同群同按钮 10 秒内只处理一次;播放/下载先回「正在获取」占位消息再取直链,结果以递增的msg_seq补发(同一事件相同msg_seq的第二次回复会被 QQ 拒绝) - 日志:控制台 +
LOG_DIR/musicbot.log(按天轮转、保留 7 天),级别由LOG_LEVEL控制;目录不可写时自动退化为仅控制台 - 热重载(开发用):监控
musicbot/下的.py与intents.toml/.env,变更后重启 bot 子进程(重连一次 websocket)。默认关,uv run musicbot --reload(start.bat已带)或RELOAD=on开启 - 按钮回调需
intents.toml开启INTERACTION(本仓库已开启)
配置
复制 .env.example 为 .env,填入开放平台 APPID/APPSECRET。intents.toml 控制事件订阅。MusicServer(lx-music 聚合音源)需在本机或 MUSIC_SERVER_URL 指向处运行。
点歌相关开关:
| 变量 | 默认 | 说明 |
|---|---|---|
MENU_PAGE_SIZE |
10 |
选歌菜单每页候选数,1~20(内嵌键盘 5 行所限) |
WITHDRAW |
on |
自动撤回旧菜单/卡片;off 则全部保留 |
SEND_MODE |
link |
下载按钮:link 直接发直链 / file 先传群文件(需群主/管理员) |
LOG_LEVEL |
INFO |
日志级别 TRACE/DEBUG/INFO/SUCCESS/WARNING/ERROR/CRITICAL |
LOG_DIR |
logs |
日志目录(自动按天轮转、保留 7 天) |
RELOAD |
off |
热重载;on 等价于命令行 --reload(start.bat 已带) |
不 @ 机器人也能点歌
- 群侧开关:群主/管理员在 QQ 里打开机器人资料页,把消息接收切换为「接收群内全部消息」——三种取值为
all(全量)/only_mention(仅@)/mention_and_context(@+上下文),切换时平台会推GROUP_MSG_RECEIVE/GROUP_MSG_REJECT事件。未开启时网关不推送非 @ 消息,bot 行为与现在完全一致。当前群设置可用GET /v2/groups/{group_openid}/bot_state查(字段recv_msg_setting)。 intents.toml订阅GROUP_AND_C2C_EVENT(本仓库已开启)——@消息(GROUP_AT_MESSAGE_CREATE)与全量消息(GROUP_MESSAGE_CREATE)同属这一个分组,无需额外配置。
两个事件共用同一个 dataclass 与 handler,被动回复都用该消息的 msg_id(群聊 5 分钟内有效、每条最多回复 5 次)。全量事件不支持 event_id——官方 event_id 支持列表只有 INTERACTION_CREATE、GROUP_ADD_ROBOT、GROUP_MSG_RECEIVE。
斜杠指令(输入框 / 菜单)
群里输入框敲 / 唤出的「指令面板」由 bot 调接口自动注册(开放平台 2026-08 新增的 /v2/panels 系列接口):每次建连(READY)时把 点歌/歌词/帮助 三条指令同步上去——没有就创建(target_type=all 对全部群生效)、内容有变就更新、一致则跳过,重连即自愈;失败只记日志不影响运行。COMMAND_PANEL=off 可关闭,改在开放平台后台「功能配置 → 指令」手工配置。
指令消息以 /点歌 稻香 形式推给 bot(走 GROUP_AT_MESSAGE_CREATE,指令自动 @ 机器人),与文本命令共用同一套解析——_normalize 会剥掉开头的 / 与 @机器人 前缀,点歌 稻香、/点歌 稻香、@bot /点歌 稻香 三种写法等价。只敲命令不带参数(斜杠指令参数可为空)时回复用法提示。
「帮助」消息带 [🎤 点歌][📝 歌词] 指令按钮(action type=2):点击把 /点歌 填进输入框,补上歌名发送即可;键盘无权限时自动回退纯文本。
运行
uv sync
uv run musicbot # 正常启动
uv run musicbot --reload # 开发:改源码/配置自动重启
Windows 上双击 start.bat 即以热重载模式启动。
开发
uv run pytest
uv run ruff check musicbot tests conftest.py && uv run pyright