Skip to content

Commit a75859f

Browse files
committed
feat: 除番剧集外,其余API的Puppeteer支持
1 parent b9d332a commit a75859f

File tree

13 files changed

+337
-67
lines changed

13 files changed

+337
-67
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
2323
"build": "tsc"
2424
},
2525
"dependencies": {
26+
"@koishijs/plugin-http": "^0.6.3",
2627
"handlebars": "^4.7.8",
2728
"koishi": "^4.17.5",
29+
"koishi-plugin-puppeteer": "^3.9.0",
2830
"numbro": "^2.5.0"
2931
},
3032
"peerDependencies": {
33+
"@koishijs/plugin-http": "^0.6.3",
3134
"handlebars": "^4.7.8",
3235
"koishi": "^4.17.5",
36+
"koishi-plugin-puppeteer": "^3.9.0",
3337
"numbro": "^2.5.0"
3438
},
3539
"devDependencies": {
@@ -61,4 +65,4 @@
6165
"zh"
6266
]
6367
}
64-
}
68+
}

readme.md

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ A koishi plugin use to parse bilibili links.
77

88
一个能够解析 BiliBili 链接的 Koishi 插件。
99

10-
## Depends/前置依赖
10+
## 前置依赖
1111

1212
- [handlebars](https://www.npmjs.com/package/handlebars)
1313
- [numbro](https://www.npmjs.com/package/numbro)
1414

15-
## Usage/使用方法
15+
## 使用方法
1616
### Video/视频
17-
When regex match `bilibili\.com\/video\/([ab]v[0-9a-zA-Z]+)`, reply
18-
1917
当正则表达式符合 `bilibili\.com\/video\/([ab]v[0-9a-zA-Z]+)`,回复
2018

2119
```
@@ -30,8 +28,6 @@ https://www.bilibili.com/video/{{bvid}}
3028
```
3129

3230
### Live/直播
33-
When regex match `live\.bilibili\.com(?:\/h5)?\/(\d+)`, reply
34-
3531
当正则表达式符合 `live\.bilibili\.com(?:\/h5)?\/(\d+)`,回复
3632

3733
```
@@ -43,8 +39,6 @@ https://live.bilibili.com/{{room_id}}
4339
```
4440

4541
### Bangumi/番剧
46-
When regex match `bilibili\.com\/bangumi\/play\/((ep|ss)(\d+))`, `bilibili\.com\/bangumi\/media\/(md(\d+))`, reply
47-
4842
当正则表达式符合 `bilibili\.com\/bangumi\/play\/((ep|ss)(\d+))``bilibili\.com\/bangumi\/media\/(md(\d+))`,回复
4943

5044
```
@@ -68,9 +62,26 @@ https://www.bilibili.com/bangumi/media/md{{media_id}}
6862
https://www.bilibili.com/bangumi/play/ep{{getCurrentEpisode "ep_id"}}
6963
```
7064

71-
### Article/专栏
72-
When regex match `bilibili\.com\/read\/cv(\d+)`, `bilibili\.com\/read\/mobile(?:\?id=|\/)(\d+)`, reply
65+
### Space/空间
66+
当正则表达式符合 `space\.bilibili\.com\/(\d+)`,回复
7367

68+
```
69+
{{module_author.name}}
70+
<img src=\"{{module_author.face}}\" />
71+
https://space.bilibili.com/{{module_author.mid}}
72+
```
73+
74+
### Opus/动态
75+
当正则表达式符合 `bilibili\.com\/opus\/(\d+)`,回复
76+
77+
```
78+
{{item.modules.module_author.name}}的动态
79+
<img src=\"{{item.modules.module_dynamic.additional.goods.items.[0].cover}}\" />
80+
{{item.modules.module_dynamic.desc.text}}
81+
转发:{{formatNumber item.modules.module_stat.forward.count}} | 评论:{{formatNumber item.modules.module_stat.comment.count}} | 点赞:{{formatNumber item.modules.module_stat.like.count}}
82+
```
83+
84+
### Article/专栏
7485
当正则表达式符合 `bilibili\.com\/read\/cv(\d+)``bilibili\.com\/read\/mobile(?:\?id=|\/)(\d+)`,回复
7586

7687
```
@@ -83,8 +94,6 @@ https://www.bilibili.com/read/{{getArticleID}}
8394
```
8495

8596
### Audio/音乐
86-
When regex match `bilibili\.com\/audio\/au(\d+)`, reply
87-
8897
当正则表达式符合 `bilibili\.com\/audio\/au(\d+)`,回复
8998

9099
```
@@ -97,8 +106,6 @@ https://www.bilibili.com/audio/au{{id}}
97106
```
98107

99108
### Audio Menu/歌单
100-
When regex match `bilibili\.com\/audio\/am(\d+)`, reply
101-
102109
当正则表达式符合 `bilibili\.com\/audio\/am(\d+)`,回复
103110

104111
```
@@ -110,37 +117,10 @@ UP主:{{uname}}
110117
https://www.bilibili.com/audio/am{{menuId}}
111118
```
112119

113-
### Opus/动态
114-
When regex match `bilibili\.com\/opus\/(\d+)`, reply
115-
116-
当正则表达式符合 `bilibili\.com\/opus\/(\d+)`,回复
117-
118-
```
119-
{{item.modules.module_author.name}}的动态
120-
<img src=\"{{item.modules.module_dynamic.additional.goods.items.[0].cover}}\" />
121-
{{item.modules.module_dynamic.desc.text}}
122-
转发:{{formatNumber item.modules.module_stat.forward.count}} | 评论:{{formatNumber item.modules.module_stat.comment.count}} | 点赞:{{formatNumber item.modules.module_stat.like.count}}
123-
```
124-
125-
### Space/空间
126-
When regex match `space\.bilibili\.com\/(\d+)`, reply
127-
128-
当正则表达式符合 `space\.bilibili\.com\/(\d+)`,回复
129-
130-
```
131-
{{module_author.name}}
132-
<img src=\"{{module_author.face}}\" />
133-
https://space.bilibili.com/{{module_author.mid}}
134-
```
135-
136120
### Short link/短链接
137-
When regex match `b23\.tv\/([0-9a-zA-Z]+)`, `bili(?:22|23|33)\.cn\/([0-9a-zA-Z]+)`, reply
138-
139121
当正则表达式符合 `b23\.tv\/([0-9a-zA-Z]+)``bili(?:22|23|33)\.cn\/([0-9a-zA-Z]+)`,会先解析回原链接,之后会自动交给以上方法处理。
140122

141123
### Light App/小程序
142-
When regex match `https:\\\/\\\/b23.tv\\\/(.+)\?`, reply
143-
144124
当正则表达式符合 `https:\\\/\\\/b23.tv\\\/(.+)\?`,会先解析回原链接,之后会自动交给以上方法处理。
145125

146126
## 自定义文本预设
@@ -159,7 +139,7 @@ logger:
159139
2. 发送一个视频链接给 Bot。此时日志会输出从 API 中获取来的 Json 数据。例:
160140
161141
```Json
162-
bVideo api return: {
142+
Video api return: {
163143
"name": "SummonHIM",
164144
"id": "11223344",
165145
"dict": {
@@ -173,6 +153,8 @@ bVideo api return: {
173153
}
174154
```
175155

156+
(推荐前去 [bilibili-API-collect](https://github.com/SocialSisterYi/bilibili-API-collect) 参阅更详细的 BiliBili API 介绍)
157+
176158
3. 根据以上 Json 数据来编写自定义的文本预设占位符。
177159

178160
```

src/api/bili/article.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { runtime } from "../..";
1010
*/
1111
export async function fetch_api(id: string): Promise<BiliAPI<Dict>> {
1212
const ret: BiliAPI<Dict> = await runtime.ctx.http.get<BiliAPI<Dict>>(
13-
`https://api.bilibili.com/x/article/viewinfo?id=${id.replace(/^cv/, "")}`,
13+
`https://api.bilibili.com/x/article/viewinfo?id=${id}`,
1414
{
1515
headers: {
1616
Host: "api.bilibili.com",
@@ -21,6 +21,11 @@ export async function fetch_api(id: string): Promise<BiliAPI<Dict>> {
2121
return ret;
2222
}
2323

24+
/**
25+
* 使用 Puppeteer 获取专栏基本信息
26+
* @param id 专栏 ID
27+
* @returns API 内容
28+
*/
2429
export async function puppeteer_fetch_api(id: string) {
2530
if (!runtime.ctx.puppeteer)
2631
throw new Error("Please enable puppeteer service.");
@@ -34,13 +39,12 @@ export async function puppeteer_fetch_api(id: string) {
3439

3540
let ret: BiliAPI<Dict>;
3641
try {
37-
await page.goto("https://www.bilibili.com/404", {
42+
await page.goto(`https://www.bilibili.com/read/cv${id}`, {
43+
waitUntil: "networkidle2",
44+
});
45+
await page.goto(`https://api.bilibili.com/x/article/viewinfo?id=${id}`, {
3846
waitUntil: "networkidle2",
3947
});
40-
await page.goto(
41-
`https://api.bilibili.com/x/article/viewinfo?id=${id.replace(/^cv/, "")}`,
42-
{ waitUntil: "networkidle2" },
43-
);
4448

4549
ret = await page.evaluate(() => {
4650
return JSON.parse(document.body.innerText);

src/api/bili/audio.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,77 @@ export async function fetch_am_api(id: string): Promise<BiliAPI<Dict>> {
3838
);
3939
return ret;
4040
}
41+
42+
/**
43+
* 使用 Puppeteer 获取音乐基本信息
44+
* @param id 音乐 ID
45+
* @returns API 内容
46+
*/
47+
export async function puppeteer_fetch_api(id: string) {
48+
if (!runtime.ctx.puppeteer)
49+
throw new Error("Please enable puppeteer service.");
50+
51+
const browser = runtime.ctx.puppeteer.browser;
52+
const context = await browser.createBrowserContext();
53+
const page = await context.newPage();
54+
if (runtime.config.userAgent) {
55+
await page.setUserAgent(runtime.config.userAgent);
56+
}
57+
58+
let ret: BiliAPI<Dict>;
59+
try {
60+
await page.goto(`https://www.bilibili.com/audio/au${id}`, {
61+
waitUntil: "networkidle2",
62+
});
63+
await page.goto(
64+
`https://www.bilibili.com/audio/music-service-c/web/song/info?sid=${id}`,
65+
{ waitUntil: "networkidle2" },
66+
);
67+
68+
ret = await page.evaluate(() => {
69+
return JSON.parse(document.body.innerText);
70+
});
71+
} finally {
72+
await page.close();
73+
await context.close();
74+
}
75+
76+
return ret;
77+
}
78+
79+
/**
80+
* 使用 Puppeteer 获取歌单基本信息
81+
* @param id 歌单 ID
82+
* @returns API 内容
83+
*/
84+
export async function puppeteer_fetch_am_api(id: string) {
85+
if (!runtime.ctx.puppeteer)
86+
throw new Error("Please enable puppeteer service.");
87+
88+
const browser = runtime.ctx.puppeteer.browser;
89+
const context = await browser.createBrowserContext();
90+
const page = await context.newPage();
91+
if (runtime.config.userAgent) {
92+
await page.setUserAgent(runtime.config.userAgent);
93+
}
94+
95+
let ret: BiliAPI<Dict>;
96+
try {
97+
await page.goto(`https://www.bilibili.com/audio/am${id}`, {
98+
waitUntil: "networkidle2",
99+
});
100+
await page.goto(
101+
`https://www.bilibili.com/audio/music-service-c/web/menu/info?sid=${id}`,
102+
{ waitUntil: "networkidle2" },
103+
);
104+
105+
ret = await page.evaluate(() => {
106+
return JSON.parse(document.body.innerText);
107+
});
108+
} finally {
109+
await page.close();
110+
await context.close();
111+
}
112+
113+
return ret;
114+
}

src/api/bili/bangumi.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Dict } from "koishi";
22

3-
import { logger, runtime } from "../..";
3+
import { runtime } from "../..";
44
import { BiliAPI } from ".";
55

66
interface BGMType {
@@ -54,7 +54,6 @@ export async function fetch_web_api(id: string): Promise<BiliAPI<Dict>> {
5454
throw new Error(`No such bangumi type: ${bgm.type}`);
5555
}
5656

57-
logger.debug(url);
5857
const ret = await runtime.ctx.http.get<BiliAPI<Dict>>(url, {
5958
headers: {
6059
Host: "api.bilibili.com",

src/api/bili/live.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function getStatusText(statusCode: number) {
2323

2424
/**
2525
* 获取直播间基本信息
26-
* @param id 直播 ID
26+
* @param id 直播间 ID
2727
* @returns API 内容
2828
*/
2929
export async function fetch_api(id: string): Promise<BiliAPI<Dict>> {
@@ -38,3 +38,40 @@ export async function fetch_api(id: string): Promise<BiliAPI<Dict>> {
3838
);
3939
return ret;
4040
}
41+
42+
/**
43+
* 使用 Puppeteer 获取直播基本信息
44+
* @param id 直播间 ID
45+
* @returns API 内容
46+
*/
47+
export async function puppeteer_fetch_api(id: string) {
48+
if (!runtime.ctx.puppeteer)
49+
throw new Error("Please enable puppeteer service.");
50+
51+
const browser = runtime.ctx.puppeteer.browser;
52+
const context = await browser.createBrowserContext();
53+
const page = await context.newPage();
54+
if (runtime.config.userAgent) {
55+
await page.setUserAgent(runtime.config.userAgent);
56+
}
57+
58+
let ret: BiliAPI<Dict>;
59+
try {
60+
await page.goto("https://www.bilibili.com/404", {
61+
waitUntil: "networkidle2",
62+
});
63+
await page.goto(
64+
`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${id}`,
65+
{ waitUntil: "networkidle2" },
66+
);
67+
68+
ret = await page.evaluate(() => {
69+
return JSON.parse(document.body.innerText);
70+
});
71+
} finally {
72+
await page.close();
73+
await context.close();
74+
}
75+
76+
return ret;
77+
}

src/api/bili/opus.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,40 @@ export async function fetch_api(id: string): Promise<BiliAPI<Dict>> {
2020
);
2121
return ret;
2222
}
23+
24+
/**
25+
* 使用 Puppeteer 获取动态基本信息
26+
* @param id 动态 ID
27+
* @returns API 内容
28+
*/
29+
export async function puppeteer_fetch_api(id: string) {
30+
if (!runtime.ctx.puppeteer)
31+
throw new Error("Please enable puppeteer service.");
32+
33+
const browser = runtime.ctx.puppeteer.browser;
34+
const context = await browser.createBrowserContext();
35+
const page = await context.newPage();
36+
if (runtime.config.userAgent) {
37+
await page.setUserAgent(runtime.config.userAgent);
38+
}
39+
40+
let ret: BiliAPI<Dict>;
41+
try {
42+
await page.goto(`https://www.bilibili.com/opus/${id}`, {
43+
waitUntil: "networkidle2",
44+
});
45+
await page.goto(
46+
`https://api.bilibili.com/x/polymer/web-dynamic/v1/detail?id=${id}`,
47+
{ waitUntil: "networkidle2" },
48+
);
49+
50+
ret = await page.evaluate(() => {
51+
return JSON.parse(document.body.innerText);
52+
});
53+
} finally {
54+
await page.close();
55+
await context.close();
56+
}
57+
58+
return ret;
59+
}

0 commit comments

Comments
 (0)