Skip to content

Commit c162078

Browse files
committed
添加[QQ音乐]签到脚本
1 parent c680201 commit c162078

3 files changed

Lines changed: 287 additions & 0 deletions

File tree

qqmusic/README.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# QQ 音乐
2+
3+
> 代码已同时兼容 Surge & QuanX, 使用同一份签到脚本即可
4+
5+
> QuanX 需要 v1.0.6-build195 及以后版本
6+
7+
> QuanX 需要 v1.0.6-build195 及以后版本
8+
9+
> QuanX 需要 v1.0.6-build195 及以后版本
10+
11+
## 配置 (Surge)
12+
13+
```properties
14+
[MITM]
15+
*.y.qq.com
16+
17+
[Script]
18+
# 注意获取Cookie有两条脚本
19+
http-request ^https:\/\/u.y.qq.com\/cgi\-bin\/musicu.fcg requires-body=true,script-path=https://raw.githubusercontent.com/chavyleung/scripts/master/qqmusic/qqmusic.cookie.js
20+
http-response ^https:\/\/u.y.qq.com\/cgi\-bin\/musicu.fcg requires-body=true,script-path=https://raw.githubusercontent.com/chavyleung/scripts/master/qqmusic/qqmusic.cookie.js
21+
cron "10 0 0 * * *" script-path=https://raw.githubusercontent.com/chavyleung/scripts/master/qqmusic/qqmusic.js
22+
```
23+
24+
## 配置 (QuanX)
25+
26+
```properties
27+
[MITM]
28+
*.y.qq.com
29+
30+
[rewrite_local]
31+
# 195及以后版本 (注意获取Cookie有两条脚本)
32+
^https:\/\/u.y.qq.com\/cgi\-bin\/musicu.fcg url script-request-body qqmusic.cookie.js
33+
^https:\/\/u.y.qq.com\/cgi\-bin\/musicu.fcg url script-response-body qqmusic.cookie.js
34+
35+
[task_local]
36+
1 0 * * * qqmusic.js
37+
```
38+
39+
## 说明
40+
41+
1. 先把`*.y.qq.com`加到`[MITM]`
42+
2. 再配置重写规则:
43+
- Surge: 把两条远程脚本放到`[Script]`
44+
- QuanX: 把`qqmusic.cookie.js``qqmusic.js`传到`On My iPhone - Quantumult X - Scripts` (传到 iCloud 相同目录也可, 注意要打开 quanx 的 iCloud 开关)
45+
3. 打开 APP 然后手动签到 1 次
46+
4. 系统提示: `获取Cookie: 成功`
47+
5. 最后就可以把第 1 条脚本注释掉了
48+
6. 运行一次脚本, 如果提示重复签到, 那就算成功了!
49+
50+
> 第 1 条脚本是用来获取 cookie 的, 用浏览器访问一次获取 cookie 成功后就可以删掉或注释掉了, 但请确保在`登录成功`后再获取 cookie.
51+
52+
> 第 2 条脚本是签到脚本, 每天`00:00:10`执行一次.
53+
54+
## 常见问题
55+
56+
1. 无法写入 Cookie
57+
58+
- 检查 Surge 系统通知权限放开了没
59+
- 如果你用的是 Safari, 请尝试在浏览地址栏`手动输入网址`(不要用复制粘贴)
60+
61+
2. 写入 Cookie 成功, 但签到不成功
62+
63+
- 看看是不是在登录前就写入 Cookie 了
64+
- 如果是,请确保在登录成功后,再尝试写入 Cookie
65+
66+
3. 为什么有时成功有时失败
67+
68+
- 很正常,网络问题,哪怕你是手工签到也可能失败(凌晨签到容易拥堵就容易失败)
69+
- 暂时不考虑代码级的重试机制,但咱有配置级的(暴力美学):
70+
71+
- `Surge`配置:
72+
73+
```properties
74+
# 没有什么是一顿饭解决不了的:
75+
cron "10 0 0 * * *" script-path=xxx.js # 每天00:00:10执行一次
76+
# 如果有,那就两顿:
77+
cron "20 0 0 * * *" script-path=xxx.js # 每天00:00:20执行一次
78+
# 实在不行,三顿也能接受:
79+
cron "30 0 0 * * *" script-path=xxx.js # 每天00:00:30执行一次
80+
81+
# 再粗暴点,直接:
82+
cron "* */60 * * * *" script-path=xxx.js # 每60分执行一次
83+
```
84+
85+
- `QuanX`配置:
86+
87+
```properties
88+
[task_local]
89+
1 0 * * * xxx.js # 每天00:01执行一次
90+
2 0 * * * xxx.js # 每天00:02执行一次
91+
3 0 * * * xxx.js # 每天00:03执行一次
92+
93+
*/60 * * * * xxx.js # 每60分执行一次
94+
```
95+
96+
## 感谢
97+
98+
[@NobyDa](https://github.com/NobyDa)
99+
100+
[@lhie1](https://github.com/lhie1)
101+
102+
[@ConnersHua](https://github.com/ConnersHua)

qqmusic/qqmusic.cookie.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
const cookieName = 'QQ音乐'
2+
const signurlKey = 'chavy_signurl_qqmusic'
3+
const signheaderKey = 'chavy_header_qqmusic'
4+
const signbodyKey = 'chavy_body_qqmusic'
5+
const signFlagKey = 'chavy_flag_qqmusic'
6+
const chavy = init()
7+
8+
if ($request && $request.body) {
9+
// 每日签到: UserGrow.UserGrowScore receive_score
10+
// 每月签到: music.activeCenter.MonthLoginSvr MonthScore
11+
// 签到记录: UserGrow.UserGrowScore sign_record
12+
const is_receive_score = $request.body.indexOf(`receive_score`) >= 0
13+
const is_MonthScore = $request.body.indexOf(`MonthScore`) >= 0
14+
const is_sign_record = $request.body.indexOf(`sign_record`) >= 0
15+
if ($request.headers['Cookie'] && is_receive_score) {
16+
let signFlagVal = is_receive_score ? `receive_score` : ``
17+
signFlagVal = is_MonthScore ? `MonthScore` : signFlagVal
18+
signFlagVal = is_sign_record ? `sign_record` : signFlagVal
19+
const signurlVal = $request.url
20+
const signheaderVal = JSON.stringify($request.headers)
21+
const signbodyVal = $request.body
22+
if (signurlVal) chavy.setdata(signurlVal, signurlKey)
23+
if (signheaderVal) chavy.setdata(signheaderVal, signheaderKey)
24+
if (signbodyVal) chavy.setdata(signbodyVal, signbodyKey)
25+
if (signFlagVal) chavy.setdata(signFlagVal, signFlagKey)
26+
chavy.msg(`${cookieName}`, '获取Cookie: 成功', '')
27+
// chavy.log(`[${cookieName}] 获取Cookie: 成功, SignUrl: ${signurlVal}`)
28+
// chavy.log(`[${cookieName}] 获取Cookie: 成功, SignHeader: ${signheaderVal}`)
29+
// chavy.log(`[${cookieName}] 获取Cookie: 成功, SignBody: ${signbodyVal}`)
30+
}
31+
} else if ($response && $response.body && $request.url == chavy.getdata(signurlKey) && `receive_score` == chavy.getdata(signFlagKey)) {
32+
const respbodyObj = JSON.parse($response.body)
33+
if (respbodyObj && respbodyObj.req_0 && respbodyObj.req_0.data && respbodyObj.req_0.data.totalDays) {
34+
chavy.msg(`${cookieName}`, '手动签到: 成功 (每日签到)', `共签: ${respbodyObj.req_0.data.totalDays}天, 今天积分: +${respbodyObj.req_0.data.todayScore}, 明天积分: +${respbodyObj.req_0.data.tomrrowScore}`)
35+
chavy.log(`[${cookieName}] 手动签到: 成功 (每日签到), 共签: ${respbodyObj.req_0.data.totalDays}天, 今天积分: +${respbodyObj.req_0.data.todayScore}, 明天积分: +${respbodyObj.req_0.data.tomrrowScore}`)
36+
}
37+
} else if ($response && $response.body && $request.url == chavy.getdata(signurlKey) && `MonthScore` == chavy.getdata(signFlagKey)) {
38+
const respbodyObj = JSON.parse($response.body)
39+
if (respbodyObj && respbodyObj.req_0 && respbodyObj.req_0.data && respbodyObj.req_0.data.totalDays) {
40+
chavy.msg(`${cookieName}`, '手动签到: 成功 (每月首签)', `共签: ${respbodyObj.req_0.data.totalDays}天, 积分: +${respbodyObj.req_0.data.todayScore}`)
41+
chavy.log(`[${cookieName}] 手动签到: 成功 (每月首签), 说明: 共签: ${respbodyObj.req_0.data.totalDays}天, 积分: +${respbodyObj.req_0.data.todayScore}`)
42+
}
43+
} else if ($response && $response.body && $request.url == chavy.getdata(signurlKey) && `sign_record` == chavy.getdata(signFlagKey)) {
44+
const respbodyObj = JSON.parse($response.body)
45+
if (respbodyObj && respbodyObj.req_0 && respbodyObj.req_0.data && respbodyObj.req_0.data.totalDays) {
46+
chavy.msg(`${cookieName}`, '获取签到: 成功', `共签: ${respbodyObj.req_0.data.totalDays}天, 积分: +${respbodyObj.req_0.data.todayScore}`)
47+
chavy.log(`[${cookieName}] 获取签到: 成功, 说明: 共签: ${respbodyObj.req_0.data.totalDays}天, 积分: +${respbodyObj.req_0.data.todayScore}`)
48+
}
49+
}
50+
51+
function init() {
52+
isSurge = () => {
53+
return undefined === this.$httpClient ? false : true
54+
}
55+
isQuanX = () => {
56+
return undefined === this.$task ? false : true
57+
}
58+
getdata = (key) => {
59+
if (isSurge()) return $persistentStore.read(key)
60+
if (isQuanX()) return $prefs.valueForKey(key)
61+
}
62+
setdata = (key, val) => {
63+
if (isSurge()) return $persistentStore.write(key, val)
64+
if (isQuanX()) return $prefs.setValueForKey(key, val)
65+
}
66+
msg = (title, subtitle, body) => {
67+
if (isSurge()) $notification.post(title, subtitle, body)
68+
if (isQuanX()) $notify(title, subtitle, body)
69+
}
70+
log = (message) => console.log(message)
71+
get = (url, cb) => {
72+
if (isSurge()) {
73+
$httpClient.get(url, cb)
74+
}
75+
if (isQuanX()) {
76+
url.method = 'GET'
77+
$task.fetch(url).then((resp) => cb(null, {}, resp.body))
78+
}
79+
}
80+
post = (url, cb) => {
81+
if (isSurge()) {
82+
$httpClient.post(url, cb)
83+
}
84+
if (isQuanX()) {
85+
url.method = 'POST'
86+
$task.fetch(url).then((resp) => cb(null, {}, resp.body))
87+
}
88+
}
89+
done = (value = {}) => {
90+
$done(value)
91+
}
92+
return { isSurge, isQuanX, msg, log, getdata, setdata, get, post, done }
93+
}
94+
chavy.done()

qqmusic/qqmusic.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const cookieName = 'QQ音乐'
2+
const signurlKey = 'chavy_signurl_qqmusic'
3+
const signheaderKey = 'chavy_header_qqmusic'
4+
const signbodyKey = 'chavy_body_qqmusic'
5+
const chavy = init()
6+
const signurlVal = chavy.getdata(signurlKey)
7+
const signheaderVal = chavy.getdata(signheaderKey)
8+
const signbodyVal = chavy.getdata(signbodyKey)
9+
10+
sign()
11+
12+
function sign() {
13+
if (signurlVal && signheaderVal && signbodyVal) {
14+
const url = { url: signurlVal, headers: JSON.parse(signheaderVal), body: signbodyVal }
15+
chavy.post(url, (error, response, data) => {
16+
chavy.log(`${cookieName}, data: ${data}`)
17+
const title = `${cookieName}`
18+
let subTitle = ''
19+
let detail = ''
20+
let result = JSON.parse(data)
21+
if (result.code == 0 && result.req_0 && result.req_0.code == 0) {
22+
if (result.req_0.data.retCode == 0) {
23+
subTitle = `签到结果: 成功`
24+
detail = `共签: ${result.req_0.data.totalDays}天, 今天积分: +${result.req_0.data.todayScore}, 明天积分: +${result.req_0.data.tomrrowScore}`
25+
} else if (result.req_0.data.retCode == 40001) {
26+
subTitle = `签到结果: 成功 (重复签到)`
27+
detail = `说明: ${result.req_0.data.errMsg}`
28+
} else {
29+
subTitle = `签到结果: 失败`
30+
detail = `编码: ${result.req_0.data.retCode}, 说明: ${result.req_0.data.errMsg}`
31+
}
32+
} else {
33+
subTitle = `签到结果: 失败`
34+
detail = `说明: 详见日志`
35+
}
36+
chavy.msg(title, subTitle, detail)
37+
chavy.done()
38+
})
39+
} else {
40+
const title = `${cookieName}`
41+
const subTitle = '签到结果: 失败'
42+
const detail = `原因: 请先获取Cookie`
43+
chavy.msg(title, subTitle, detail)
44+
chavy.log(`${cookieName}, ${subTitle}, ${detail}`)
45+
chavy.done()
46+
}
47+
}
48+
49+
function init() {
50+
isSurge = () => {
51+
return undefined === this.$httpClient ? false : true
52+
}
53+
isQuanX = () => {
54+
return undefined === this.$task ? false : true
55+
}
56+
getdata = (key) => {
57+
if (isSurge()) return $persistentStore.read(key)
58+
if (isQuanX()) return $prefs.valueForKey(key)
59+
}
60+
setdata = (key, val) => {
61+
if (isSurge()) return $persistentStore.write(key, val)
62+
if (isQuanX()) return $prefs.setValueForKey(key, val)
63+
}
64+
msg = (title, subtitle, body) => {
65+
if (isSurge()) $notification.post(title, subtitle, body)
66+
if (isQuanX()) $notify(title, subtitle, body)
67+
}
68+
log = (message) => console.log(message)
69+
get = (url, cb) => {
70+
if (isSurge()) {
71+
$httpClient.get(url, cb)
72+
}
73+
if (isQuanX()) {
74+
url.method = 'GET'
75+
$task.fetch(url).then((resp) => cb(null, {}, resp.body))
76+
}
77+
}
78+
post = (url, cb) => {
79+
if (isSurge()) {
80+
$httpClient.post(url, cb)
81+
}
82+
if (isQuanX()) {
83+
url.method = 'POST'
84+
$task.fetch(url).then((resp) => cb(null, {}, resp.body))
85+
}
86+
}
87+
done = (value = {}) => {
88+
$done(value)
89+
}
90+
return { isSurge, isQuanX, msg, log, getdata, setdata, get, post, done }
91+
}

0 commit comments

Comments
 (0)