mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79c50c6f29 |
+46
-22
@@ -153,29 +153,41 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
|
|
||||||
async getQrCode(): Promise<QrCodeResult> {
|
async getQrCode(): Promise<QrCodeResult> {
|
||||||
const res = await this.api.get("/getQQLoginQr");
|
const res = await this.api.get("/getQQLoginQr");
|
||||||
|
const qrsig = res.data?.qrsig ?? "";
|
||||||
|
const ptqrtoken = res.data?.ptqrtoken ?? "";
|
||||||
|
// @sansenjian/qq-music-api's checkQQLoginQr requires BOTH qrsig and
|
||||||
|
// ptqrtoken, so encode both into the opaque key the caller polls with.
|
||||||
return {
|
return {
|
||||||
qrUrl: "",
|
qrUrl: "",
|
||||||
qrImg: res.data?.img ?? "",
|
qrImg: res.data?.img ?? "",
|
||||||
key: res.data?.qrsig ?? res.data?.ptqrtoken ?? "",
|
key: qrsig && ptqrtoken ? `${qrsig}|${ptqrtoken}` : "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkQrCodeStatus(
|
async checkQrCodeStatus(
|
||||||
key: string
|
key: string
|
||||||
): Promise<"waiting" | "scanned" | "confirmed" | "expired"> {
|
): Promise<"waiting" | "scanned" | "confirmed" | "expired"> {
|
||||||
const res = await this.api.get("/checkQQLoginQr", {
|
const [qrsig, ptqrtoken] = key.split("|");
|
||||||
params: { qrsig: key },
|
if (!qrsig || !ptqrtoken) return "expired";
|
||||||
});
|
try {
|
||||||
const code = res.data?.code ?? res.data?.response?.code;
|
// /checkQQLoginQr is POST, and the success body is
|
||||||
if (code === 0) {
|
// { isOk, refresh, message, session: { cookie, ... } }
|
||||||
if (res.data?.cookie) {
|
const res = await this.api.post("/checkQQLoginQr", null, {
|
||||||
this.cookie = res.data.cookie;
|
params: { qrsig, ptqrtoken },
|
||||||
|
});
|
||||||
|
if (res.data?.isOk) {
|
||||||
|
const cookie = res.data?.session?.cookie;
|
||||||
|
if (cookie) {
|
||||||
|
this.cookie = cookie;
|
||||||
|
}
|
||||||
|
return "confirmed";
|
||||||
}
|
}
|
||||||
return "confirmed";
|
if (res.data?.refresh) return "expired";
|
||||||
|
// The upstream lib does not distinguish "scanned" from "waiting"
|
||||||
|
return "waiting";
|
||||||
|
} catch {
|
||||||
|
return "expired";
|
||||||
}
|
}
|
||||||
if (code === 1) return "scanned";
|
|
||||||
if (code === 2) return "waiting";
|
|
||||||
return "expired";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setCookie(cookie: string): void {
|
setCookie(cookie: string): void {
|
||||||
@@ -188,20 +200,32 @@ export class QQMusicProvider implements MusicProvider {
|
|||||||
|
|
||||||
async getAuthStatus(): Promise<AuthStatus> {
|
async getAuthStatus(): Promise<AuthStatus> {
|
||||||
if (!this.cookie) return { loggedIn: false };
|
if (!this.cookie) return { loggedIn: false };
|
||||||
|
|
||||||
|
// @sansenjian/qq-music-api does not expose a dedicated "am I logged in"
|
||||||
|
// endpoint. /user/getUserAvatar only builds a static avatar URL from a
|
||||||
|
// uin and never talks to QQ, so it cannot be used to validate a cookie.
|
||||||
|
// Instead, parse the uin from the cookie and round-trip it through
|
||||||
|
// /user/getUserPlaylists, which actually hits QQ Music's servers using
|
||||||
|
// the provided cookie. A successful response (code=0) means the cookie
|
||||||
|
// is still valid.
|
||||||
|
const uinMatch = this.cookie.match(/(?:^|;\s*)uin=([^;]+)/);
|
||||||
|
const uin = uinMatch?.[1];
|
||||||
|
if (!uin) return { loggedIn: false };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await this.api.get("/getUserAvatar", {
|
const res = await this.api.get("/user/getUserPlaylists", {
|
||||||
params: { ...this.cookieParams },
|
params: { uin, limit: 1, ...this.cookieParams },
|
||||||
});
|
});
|
||||||
if (res.data?.response?.data) {
|
if (res.data?.response?.code !== 0) {
|
||||||
return {
|
return { loggedIn: false };
|
||||||
loggedIn: true,
|
|
||||||
nickname: res.data.response.data.nickname,
|
|
||||||
avatarUrl: res.data.response.data.headpic,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
loggedIn: true,
|
||||||
|
nickname: `QQ ${uin}`,
|
||||||
|
avatarUrl: `https://q.qlogo.cn/headimg_dl?dst_uin=${uin}&spec=140`,
|
||||||
|
};
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
return { loggedIn: false };
|
||||||
}
|
}
|
||||||
return { loggedIn: false };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user