mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-01 20:42:50 +08:00
Repoints the `@sansenjian/qq-music-api` dependency from the public npm
release to a local fork at ../qq-music-api, which ships a corrected
getMusicPlay that:
- drops the hardcoded-sign GET path (no longer honored by QQ's vkey
server for VIP entitlement lookups)
- POSTs JSON directly to u.y.qq.com/cgi-bin/musicu.fcg (mirroring
the library's own getLyric.ts pattern)
- extracts qqmusic_key from the forwarded cookie and passes it as
`comm.authst` — the inline auth field the jsososo/QQMusicApi
reference implementation sets
- uses `ct: 19` (was 24) to match the community reference
For accounts that actually have entitlement to a given track, this
now returns the real VIP URL. For accounts that don't, QQ's vkey
server still returns result=104003 with empty purl — this is correct
server-side behavior and not a bug. Verified by observing the real
QQ Music web player on y.qq.com fall back to the same 30-second
preview on a logged-in account that lacks the specific track tier.
Supporting changes:
src/music/api-server.ts
The fork (v2.2.11) stopped auto-starting a Koa server on import —
it only listens when run as `require.main`. Explicitly import the
default Koa app and call .listen() with a server handle we can
clean up on shutdown. Without this fix, port 3200 silently fails
to bind and every QQ endpoint 502s.
src/music/qq.ts (getSongDetail)
The library's /getSongInfo endpoint returns upstream code 500001
because its param format no longer matches QQ's current API.
resolveAndPlay only needs `id` + `platform` to fetch a play URL,
so fall through to a minimal stub on /getSongInfo failure. This
unblocks /play-by-id and /add-by-id for QQ — they had been
returning "Song not found" for every QQ track regardless of
entitlement.
scripts/qq_browser_login.py
Visible-browser diagnostic tool that opens Chromium at y.qq.com,
auto-detects login via uin cookie poll, captures the full
post-login cookie set, tests it against /getMusicPlay for 稻香,
and writes the cookie to data/cookies/qq.json only if VIP
actually unlocks. On failure, dumps the full cookie to
data/cookies/qq.browser-capture.json for OAuth-vs-browser diff.
scripts/qq_verify_entitlement.py
Companion diagnostic: opens the real QQ Music web player at a
specific song's detail page so the user can manually click play
and verify whether their account has entitlement — independent
of any code path in this project. If the browser plays the full
song, HTTP 104003 is a request-signing issue; if the browser
also falls back to a 30-second preview, the account lacks the
tier/album purchase and no code fix can change that.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
46 lines
1.2 KiB
JSON
46 lines
1.2 KiB
JSON
{
|
|
"name": "tsmusicbot",
|
|
"version": "0.1.0",
|
|
"description": "TeamSpeak music bot with NetEase Cloud Music and QQ Music support",
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "tsx watch src/index.ts",
|
|
"build": "tsc && npm run build:web",
|
|
"build:web": "cd web && npm run build",
|
|
"start": "node dist/index.js",
|
|
"play": "node dist/index.js",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest"
|
|
},
|
|
"license": "MIT",
|
|
"dependencies": {
|
|
"@discordjs/opus": "^0.10.0",
|
|
"@honeybbq/teamspeak-client": "^0.2.1",
|
|
"@koa/router": "^15.4.0",
|
|
"@sansenjian/qq-music-api": "file:../qq-music-api",
|
|
"axios": "^1.14.0",
|
|
"better-sqlite3": "^12.8.0",
|
|
"chalk": "^5.6.2",
|
|
"express": "^5.2.1",
|
|
"ffmpeg-static": "^5.3.0",
|
|
"koa": "^3.2.0",
|
|
"koa-bodyparser": "^4.4.1",
|
|
"koa-static": "^5.0.0",
|
|
"NeteaseCloudMusicApi": "^4.30.0",
|
|
"pino": "^10.3.1",
|
|
"ts3-nodejs-library": "^3.5.1",
|
|
"tweetnacl": "^1.0.3",
|
|
"ws": "^8.20.0",
|
|
"yt-dlp-wrap": "^2.3.12"
|
|
},
|
|
"devDependencies": {
|
|
"@types/better-sqlite3": "^7.6.13",
|
|
"@types/express": "^5.0.6",
|
|
"@types/node": "^25.5.0",
|
|
"@types/ws": "^8.18.1",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^6.0.2",
|
|
"vitest": "^4.1.2"
|
|
}
|
|
}
|