Skip to content

Commit 38931df

Browse files
committed
Last Sync: 2026-05-16 22:48 (Mobile)
1 parent fc7b9f8 commit 38931df

9 files changed

Lines changed: 546 additions & 0 deletions

File tree

main/plugins/QQ点歌/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## 更新日志
2+
- 修复了一些已知问题
3+
4+
## 指令列表
5+
- `点歌 歌名`(仅自己可用)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import okhttp3.*
2+
import java.time.Duration
3+
4+
client = new OkHttpClient.Builder()
5+
.connectTimeout(Duration.ofSeconds(30))
6+
.callTimeout(Duration.ofSeconds(30))
7+
.readTimeout(Duration.ofSeconds(30))
8+
.build()
9+
10+
addHeaders(builder, header) {
11+
if (!header?.isEmpty()) {
12+
for (Map.Entry entry : header.entrySet()) {
13+
key = "${entry.getKey()}"
14+
value = "${entry.getValue()}"
15+
builder.addHeader(key, value)
16+
}
17+
}
18+
}
19+
20+
doRequest(builder) {
21+
try {
22+
request = builder.build()
23+
response = client.newCall(request).execute()
24+
body = response?.body()?.string() ?: ""
25+
response.close()
26+
return body
27+
} catch (e) {
28+
return null
29+
}
30+
}
31+
32+
get(
33+
url, callback,
34+
header = null
35+
) {
36+
new Thread(() -> {
37+
builder = new Request.Builder().url(url).get()
38+
addHeaders(builder, header)
39+
result = doRequest(builder)
40+
callback?.onResult(result)
41+
}).start()
42+
}
43+
44+
post(
45+
url, data, callback,
46+
header = null
47+
) {
48+
new Thread(() -> {
49+
mediaType = "application/json"
50+
if (header?.containsKey("Content-Type")) {
51+
mediaType = String.valueOf(header.get("Content-Type"))
52+
}
53+
body = RequestBody.create(
54+
MediaType.parse(mediaType),
55+
data ?: ""
56+
)
57+
builder = new Request.Builder().url(url).post(body)
58+
addHeaders(builder, header)
59+
result = doRequest(builder)
60+
callback?.onResult(result)
61+
}).start()
62+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import com.alibaba.fastjson2.*
2+
3+
HEADERS = new HashMap()
4+
HEADERS.put("referer", "http://aqqmusic.tc.qq.com/")
5+
HEADERS.put("user-agent", "Mozilla/5.0 Chrome/92.0.4515.105 Safari/537.36")
6+
7+
BASE_URL = "http://aqqmusic.tc.qq.com/"
8+
API_URL = "http://u.y.qq.com/cgi-bin/musicu.fcg"
9+
PIC_URL = "http://y.gtimg.cn/music/photo_new/T002R500x500M000"
10+
LYRIC_URL = "http://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?format=json&nobase64=1"
11+
12+
search(name) {
13+
return """
14+
{"comm": {
15+
"ct": "19",
16+
"cv": "1882",
17+
"uin": "3449496653"
18+
}, "searchMusic": {
19+
"method": "DoSearchForQQMusicDesktop",
20+
"module": "music.search.SearchCgiService",
21+
"param": {
22+
"grp": 1,
23+
"num_per_page": 1,
24+
"page_num": 1,
25+
"query": "${name}",
26+
"search_type": 0
27+
}
28+
}
29+
}"""
30+
}
31+
32+
purl(id) {
33+
return """
34+
{"comm": {
35+
"ct": "11",
36+
"cv": "22060004",
37+
"tmeAppID": "ztelite",
38+
"OpenUDID": "nouid",
39+
"uid": "3449496653"
40+
}, "request": {
41+
"module": "music.qqmusiclite.MtLimitFreeSvr",
42+
"method": "Obtain",
43+
"param": {
44+
"songid": [${id}],
45+
"need_ppurl": true
46+
}
47+
}
48+
}"""
49+
}
50+
51+
getVkey(name, mid) {
52+
return """
53+
{"comm": {
54+
"ct": "11",
55+
"cv": "22060004",
56+
"tmeAppID": "ztelite",
57+
"OpenUDID": "nouid",
58+
"uid": "3449496653"
59+
}, "request": {
60+
"module": "music.vkey.GetVkey",
61+
"method": "UrlGetVkey",
62+
"param": {
63+
"guid": "yun",
64+
"songmid": ["${mid}"],
65+
"filename": ["M500${name}.mp3"]
66+
}
67+
}
68+
}"""
69+
}
70+
71+
vkey(mid, purl) {
72+
return """
73+
{"request": {
74+
"module": "music.vkey.GetVkey",
75+
"method": "CgiGetTempVkey",
76+
"param": {
77+
"guid": "yun",
78+
"songlist": [{
79+
"mediamid": "yun",
80+
"tempVkey": "${purl}",
81+
"songMID": "${mid}"
82+
}]
83+
}
84+
}
85+
}"""
86+
}
87+
88+
send_Music(talker, title, author, musicUrl, albumUrl, lyric) {
89+
sendCard(talker,
90+
"""<msg>
91+
<appmsg appid="wx1c37343fc2a86bc4">
92+
<title>${escape(title)}</title>
93+
<des>${escape(author)}</des>
94+
<action>view</action>
95+
<type>76</type>
96+
<url>${escape(musicUrl)}</url>
97+
<dataurl>${escape(musicUrl)}</dataurl>
98+
<songalbumurl>${escape(albumUrl)}</songalbumurl>
99+
<songlyric>${escape(lyric)}</songlyric>
100+
<musicShareItem>
101+
<mvCoverUrl>${escape(albumUrl)}</mvCoverUrl>
102+
<mvSingerName>${escape(author)}</mvSingerName>
103+
<mid>getlinkmid_</mid>
104+
</musicShareItem>
105+
</appmsg>
106+
</msg>""")
107+
}
108+
109+
escape(s) {
110+
if (s == null) return ""
111+
return s.replace("&", "&amp;")
112+
.replace("<", "&lt;")
113+
.replace(">", "&gt;")
114+
.replace("\"", "&quot;")
115+
.replace("'", "&apos;")
116+
}
117+
118+
music(talker, song) {
119+
get(API_URL + "?data=${search(song)}", resp -> {
120+
if (resp == null) return sendText(talker, "请求失败")
121+
search = JSON.parseObject(resp)
122+
if (search.getIntValue("code") != 0) return sendText(talker, "发生错误")
123+
music = JSONPath.eval(search, "$.searchMusic.data.body.song.list[0]")
124+
if (music == null) return sendText(talker, "未搜到")
125+
mid = music.getString("mid")
126+
id = music.getString("id")
127+
name = music.getString("name")
128+
singer = JSONPath.eval(music, "$.singer[0].name")
129+
mediamid = JSONPath.eval(music, "$.file.media_mid")
130+
pic = PIC_URL + JSONPath.eval(music, "$.album.pmid") + ".jpg"
131+
post(API_URL, "${purl(id)}", resp -> {
132+
if (resp == null) return
133+
result = JSON.parseObject(resp)
134+
pUrl = JSONPath.eval(result, "$.request.data.tracks[0].control.ppurl")
135+
get(LYRIC_URL + "&songmid=${mid}", resp -> {
136+
lyric = JSONPath.eval(resp, "$.lyric")
137+
if (!pUrl.isEmpty()) {
138+
post(API_URL, "${vkey(mid, pUrl)}", resp -> {
139+
url = JSONPath.eval(resp, "$.request.data.data.yun.purl")
140+
send_Music(talker, name, singer, url, pic, lyric)
141+
})
142+
} else
143+
post(API_URL, "${getVkey(mediamid, mid)}", resp -> {
144+
url = JSONPath.eval(resp, "$.request.data.midurlinfo[0].flowurl")
145+
if (!url.isEmpty()) {
146+
send_Music(talker, name, singer, BASE_URL + url, pic, lyric)
147+
} else sendText(talker, "该曲可能是数字专辑")
148+
})
149+
}, HEADERS)
150+
})
151+
}, HEADERS)
152+
}

main/plugins/QQ点歌/info.prop

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#Wed May 06 17:56:02 GMT+08:00 2026
2+
author=雲上升
3+
name=QQ点歌
4+
version=1.0.7
5+
desc=为微信添加点歌服务

main/plugins/QQ点歌/main.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
loadJava("api/http")
2+
loadJava("api/music")
3+
4+
onMsg(msg) {
5+
content = msg.content
6+
if (msg.sendTalker.equals(myWxId)) {
7+
if (content.startsWith("点歌")) {
8+
music(msg.talker, content.substring(2))
9+
}
10+
}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| 功能属性 | 说明信息 |
2+
| :--- | :--- |
3+
| **支持平台** | 抖音、快手、小红书、哔哩哔哩 |
4+
| **使用方式** | 直接输入/发送视频链接即可 |
5+
| **权限说明** | 仅限个人专属调用 |
309 KB
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#Wed Apr 29 12:07:29 GMT+08:00 2026
2+
author=\u96F2\u4E0A\u5347
3+
name=\u89C6\u9891\u89E3\u6790
4+
version=1.0.3
5+
desc=解析视频链接并发送文件

0 commit comments

Comments
 (0)