koishi-plugin-bilibili-notify 3.0.0-alpha.9 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/biliAPI.js CHANGED
@@ -9,60 +9,58 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- /* eslint-disable @typescript-eslint/ban-types */
13
- /* eslint-disable @typescript-eslint/no-namespace */
14
- /* eslint-disable @typescript-eslint/no-explicit-any */
15
12
  const koishi_1 = require("koishi");
16
13
  const md5_1 = __importDefault(require("md5"));
17
- const crypto_1 = __importDefault(require("crypto"));
14
+ const node_crypto_1 = __importDefault(require("node:crypto"));
18
15
  const axios_1 = __importDefault(require("axios"));
19
16
  const tough_cookie_1 = require("tough-cookie");
20
17
  const axios_cookiejar_support_1 = require("axios-cookiejar-support");
21
18
  const jsdom_1 = require("jsdom");
22
- const luxon_1 = require("luxon");
23
- const retry_1 = __importDefault(require("./utils/retry"));
19
+ const utils_1 = require("./utils");
24
20
  const mixinKeyEncTab = [
25
21
  46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
26
- 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
27
- 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
28
- 36, 20, 34, 44, 52
22
+ 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61,
23
+ 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36,
24
+ 20, 34, 44, 52,
29
25
  ];
30
26
  // 在getUserInfo中检测到番剧出差的UID时,要传回的数据:
31
- const bangumiTripData = { "code": 0, "data": { "live_room": { "roomid": 931774 } } };
32
- const GET_USER_SPACE_DYNAMIC_LIST = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space';
33
- const GET_ALL_DYNAMIC_LIST = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all';
34
- const HAS_NEW_DYNAMIC = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all/update';
35
- const GET_COOKIES_INFO = 'https://passport.bilibili.com/x/passport-login/web/cookie/info';
36
- const GET_USER_INFO = 'https://api.bilibili.com/x/space/wbi/acc/info';
37
- const GET_MYSELF_INFO = 'https://api.bilibili.com/x/member/web/account';
38
- const GET_LOGIN_QRCODE = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate';
39
- const GET_LOGIN_STATUS = 'https://passport.bilibili.com/x/passport-login/web/qrcode/poll';
40
- const GET_LIVE_ROOM_INFO = 'https://api.live.bilibili.com/room/v1/Room/get_info';
41
- const GET_MASTER_INFO = 'https://api.live.bilibili.com/live_user/v1/Master/info';
42
- const GET_TIME_NOW = 'https://api.bilibili.com/x/report/click/now';
43
- const GET_SERVER_UTC_TIME = 'https://interface.bilibili.com/serverdate.js';
27
+ const bangumiTripData = { code: 0, data: { live_room: { roomid: 931774 } } };
28
+ const GET_USER_SPACE_DYNAMIC_LIST = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space";
29
+ const GET_ALL_DYNAMIC_LIST = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all";
30
+ const HAS_NEW_DYNAMIC = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all/update";
31
+ const GET_COOKIES_INFO = "https://passport.bilibili.com/x/passport-login/web/cookie/info";
32
+ const GET_USER_INFO = "https://api.bilibili.com/x/space/wbi/acc/info";
33
+ const GET_MYSELF_INFO = "https://api.bilibili.com/x/member/web/account";
34
+ const GET_LOGIN_QRCODE = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
35
+ const GET_LOGIN_STATUS = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll";
36
+ const GET_LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info";
37
+ const GET_MASTER_INFO = "https://api.live.bilibili.com/live_user/v1/Master/info";
38
+ const GET_TIME_NOW = "https://api.bilibili.com/x/report/click/now";
39
+ const GET_SERVER_UTC_TIME = "https://interface.bilibili.com/serverdate.js";
44
40
  // 最近更新UP
45
- const GET_LATEST_UPDATED_UPS = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/portal';
41
+ const GET_LATEST_UPDATED_UPS = "https://api.bilibili.com/x/polymer/web-dynamic/v1/portal";
46
42
  // 操作
47
- const MODIFY_RELATION = 'https://api.bilibili.com/x/relation/modify';
48
- const CREATE_GROUP = 'https://api.bilibili.com/x/relation/tag/create';
49
- const MODIFY_GROUP_MEMBER = 'https://api.bilibili.com/x/relation/tags/addUsers';
50
- const GET_ALL_GROUP = 'https://api.bilibili.com/x/relation/tags';
51
- const COPY_USER_TO_GROUP = 'https://api.bilibili.com/x/relation/tags/copyUsers';
52
- const GET_RELATION_GROUP_DETAIL = 'https://api.bilibili.com/x/relation/tag';
43
+ const MODIFY_RELATION = "https://api.bilibili.com/x/relation/modify";
44
+ const CREATE_GROUP = "https://api.bilibili.com/x/relation/tag/create";
45
+ const MODIFY_GROUP_MEMBER = "https://api.bilibili.com/x/relation/tags/addUsers";
46
+ const GET_ALL_GROUP = "https://api.bilibili.com/x/relation/tags";
47
+ const COPY_USER_TO_GROUP = "https://api.bilibili.com/x/relation/tags/copyUsers";
48
+ const GET_RELATION_GROUP_DETAIL = "https://api.bilibili.com/x/relation/tag";
53
49
  // 直播
54
- const GET_LIVE_ROOM_INFO_STREAM_KEY = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo';
50
+ const GET_LIVE_ROOM_INFO_STREAM_KEY = "https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo";
55
51
  class BiliAPI extends koishi_1.Service {
56
- static inject = ['database', 'notifier'];
52
+ static inject = ["database", "notifier"];
57
53
  jar;
54
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
58
55
  client;
59
56
  apiConfig;
57
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
60
58
  loginData;
61
59
  loginNotifier;
62
60
  refreshCookieTimer;
63
61
  loginInfoIsLoaded = false;
64
62
  constructor(ctx, config) {
65
- super(ctx, 'ba');
63
+ super(ctx, "ba");
66
64
  this.apiConfig = config;
67
65
  }
68
66
  start() {
@@ -79,7 +77,9 @@ class BiliAPI extends koishi_1.Service {
79
77
  .slice(0, 32);
80
78
  // 为请求参数进行 wbi 签名
81
79
  encWbi(params, img_key, sub_key) {
82
- const mixin_key = this.getMixinKey(img_key + sub_key), curr_time = Math.round(Date.now() / 1000), chr_filter = /[!'()*]/g;
80
+ const mixin_key = this.getMixinKey(img_key + sub_key);
81
+ const curr_time = Math.round(Date.now() / 1000);
82
+ const chr_filter = /[!'()*]/g;
83
83
  Object.assign(params, { wts: curr_time }); // 添加 wts 字段
84
84
  // 按照 key 重排参数
85
85
  const query = Object.keys(params)
@@ -91,34 +91,38 @@ class BiliAPI extends koishi_1.Service {
91
91
  })
92
92
  .join("&");
93
93
  const wbi_sign = (0, md5_1.default)(query + mixin_key); // 计算 w_rid
94
- return query + "&w_rid=" + wbi_sign;
94
+ return `${query}&w_rid=${wbi_sign}`;
95
95
  }
96
96
  async getWbi(params) {
97
97
  const web_keys = await this.getWbiKeys();
98
- const img_key = web_keys.img_key, sub_key = web_keys.sub_key;
98
+ const img_key = web_keys.img_key;
99
+ const sub_key = web_keys.sub_key;
99
100
  const query = this.encWbi(params, img_key, sub_key);
100
101
  return query;
101
102
  }
102
103
  encrypt(text) {
103
- const iv = crypto_1.default.randomBytes(16);
104
- const cipher = crypto_1.default.createCipheriv('aes-256-cbc', Buffer.from(this.apiConfig.key), iv);
104
+ const iv = node_crypto_1.default.randomBytes(16);
105
+ const cipher = node_crypto_1.default.createCipheriv("aes-256-cbc", Buffer.from(this.apiConfig.key), iv);
105
106
  const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
106
- return iv.toString('hex') + ':' + encrypted.toString('hex');
107
+ return `${iv.toString("hex")}:${encrypted.toString("hex")}`;
107
108
  }
108
109
  decrypt(text) {
109
- const textParts = text.split(':');
110
- const iv = Buffer.from(textParts.shift(), 'hex');
111
- const encryptedText = Buffer.from(textParts.join(':'), 'hex');
112
- const decipher = crypto_1.default.createDecipheriv('aes-256-cbc', Buffer.from(this.apiConfig.key), iv);
113
- const decrypted = Buffer.concat([decipher.update(encryptedText), decipher.final()]);
110
+ const textParts = text.split(":");
111
+ const iv = Buffer.from(textParts.shift(), "hex");
112
+ const encryptedText = Buffer.from(textParts.join(":"), "hex");
113
+ const decipher = node_crypto_1.default.createDecipheriv("aes-256-cbc", Buffer.from(this.apiConfig.key), iv);
114
+ const decrypted = Buffer.concat([
115
+ decipher.update(encryptedText),
116
+ decipher.final(),
117
+ ]);
114
118
  return decrypted.toString();
115
119
  }
116
120
  // BA API
117
121
  async getTheUserWhoIsLiveStreaming() {
118
122
  // 获取直播间信息流密钥
119
- const { data: { live_users } } = await this.client.get(GET_LATEST_UPDATED_UPS);
123
+ const { data } = await this.client.get(GET_LATEST_UPDATED_UPS);
120
124
  // 返回data
121
- return live_users;
125
+ return data;
122
126
  }
123
127
  async getLiveRoomInfoStreamKey(roomId) {
124
128
  // 获取直播间信息流密钥
@@ -134,9 +138,7 @@ class BiliAPI extends koishi_1.Service {
134
138
  const timestamp = new Function(`return Date.UTC(${match[1]})`)();
135
139
  return timestamp / 1000;
136
140
  }
137
- else {
138
- throw new Error('解析服务器时间失败!');
139
- }
141
+ throw new Error("解析服务器时间失败!");
140
142
  }
141
143
  async getTimeNow() {
142
144
  const { data } = await this.client.get(GET_TIME_NOW);
@@ -153,11 +155,11 @@ class BiliAPI extends koishi_1.Service {
153
155
  const { data } = await this.client.post(MODIFY_GROUP_MEMBER, {
154
156
  fids: mid,
155
157
  tagids: 0,
156
- csrf
158
+ csrf,
157
159
  }, {
158
160
  headers: {
159
- 'Content-Type': 'application/x-www-form-urlencoded',
160
- }
161
+ "Content-Type": "application/x-www-form-urlencoded",
162
+ },
161
163
  });
162
164
  return data;
163
165
  }
@@ -168,11 +170,11 @@ class BiliAPI extends koishi_1.Service {
168
170
  const { data } = await this.client.post(COPY_USER_TO_GROUP, {
169
171
  fids: mid,
170
172
  tagids: groupId,
171
- csrf
173
+ csrf,
172
174
  }, {
173
175
  headers: {
174
- 'Content-Type': 'application/x-www-form-urlencoded',
175
- }
176
+ "Content-Type": "application/x-www-form-urlencoded",
177
+ },
176
178
  });
177
179
  return data;
178
180
  }
@@ -183,17 +185,19 @@ class BiliAPI extends koishi_1.Service {
183
185
  async createGroup(tag) {
184
186
  const { data } = await this.client.post(CREATE_GROUP, {
185
187
  tag,
186
- csrf: this.getCSRF()
188
+ csrf: this.getCSRF(),
187
189
  }, {
188
190
  headers: {
189
- 'Content-Type': 'application/x-www-form-urlencoded',
190
- }
191
+ "Content-Type": "application/x-www-form-urlencoded",
192
+ },
191
193
  });
192
194
  return data;
193
195
  }
194
196
  async getAllDynamic(updateBaseline) {
195
197
  let url = GET_ALL_DYNAMIC_LIST;
196
- updateBaseline && (url += `?update_baseline=${updateBaseline}`);
198
+ if (updateBaseline) {
199
+ url += `?update_baseline=${updateBaseline}`;
200
+ }
197
201
  const { data } = await this.client.get(url);
198
202
  return data;
199
203
  }
@@ -206,11 +210,11 @@ class BiliAPI extends koishi_1.Service {
206
210
  fid,
207
211
  act: 1,
208
212
  re_src: 11,
209
- csrf: this.getCSRF()
213
+ csrf: this.getCSRF(),
210
214
  }, {
211
215
  headers: {
212
- 'Content-Type': 'application/x-www-form-urlencoded',
213
- }
216
+ "Content-Type": "application/x-www-form-urlencoded",
217
+ },
214
218
  });
215
219
  return data;
216
220
  }
@@ -235,11 +239,11 @@ class BiliAPI extends koishi_1.Service {
235
239
  }
236
240
  // 获取最新的 img_key 和 sub_key
237
241
  async getWbiKeys() {
238
- const { data } = await this.client.get('https://api.bilibili.com/x/web-interface/nav');
242
+ const { data } = await this.client.get("https://api.bilibili.com/x/web-interface/nav");
239
243
  const { data: { wbi_img: { img_url, sub_url }, }, } = data;
240
244
  return {
241
- img_key: img_url.slice(img_url.lastIndexOf('/') + 1, img_url.lastIndexOf('.')),
242
- sub_key: sub_url.slice(sub_url.lastIndexOf('/') + 1, sub_url.lastIndexOf('.'))
245
+ img_key: img_url.slice(img_url.lastIndexOf("/") + 1, img_url.lastIndexOf(".")),
246
+ sub_key: sub_url.slice(sub_url.lastIndexOf("/") + 1, sub_url.lastIndexOf(".")),
243
247
  };
244
248
  }
245
249
  async getMyselfInfo() {
@@ -262,15 +266,17 @@ class BiliAPI extends koishi_1.Service {
262
266
  const { data } = await this.client.get(`${GET_MASTER_INFO}?uid=${mid}`);
263
267
  return data;
264
268
  }
265
- disposeNotifier() { if (this.loginNotifier)
266
- this.loginNotifier.dispose(); }
269
+ disposeNotifier() {
270
+ if (this.loginNotifier)
271
+ this.loginNotifier.dispose();
272
+ }
267
273
  getRandomUserAgent() {
268
274
  const userAgents = [
269
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
270
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
271
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
272
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0',
273
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
275
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
276
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
277
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
278
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0",
279
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
274
280
  ];
275
281
  const index = Math.floor(Math.random() * userAgents.length);
276
282
  return userAgents[index];
@@ -280,17 +286,16 @@ class BiliAPI extends koishi_1.Service {
280
286
  this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
281
287
  jar: this.jar,
282
288
  headers: {
283
- 'Content-Type': 'application/json',
284
- 'User-Agent': this.apiConfig.userAgent !== 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' ?
285
- this.apiConfig.userAgent : this.getRandomUserAgent(),
286
- 'Origin': 'https://www.bilibili.com',
287
- 'Referer': 'https://www.bilibili.com/'
288
- }
289
+ "Content-Type": "application/json",
290
+ "User-Agent": this.apiConfig.userAgent !==
291
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
292
+ ? this.apiConfig.userAgent
293
+ : this.getRandomUserAgent(),
294
+ Origin: "https://www.bilibili.com",
295
+ Referer: "https://www.bilibili.com/",
296
+ },
289
297
  }));
290
298
  }
291
- getTimeOfUTC8() {
292
- return Math.floor(luxon_1.DateTime.now().setZone('UTC+8').toSeconds());
293
- }
294
299
  getCookies() {
295
300
  const cookies = JSON.stringify(this.jar.serializeSync().cookies);
296
301
  return cookies;
@@ -301,8 +306,8 @@ class BiliAPI extends koishi_1.Service {
301
306
  const cookies = this.jar.serializeSync().cookies;
302
307
  // 将每个 cookie 对象转换为 "key=value" 形式,并用 "; " 连接起来
303
308
  const cookieHeader = cookies
304
- .map(cookie => `${cookie.key}=${cookie.value}`)
305
- .join('; ');
309
+ .map((cookie) => `${cookie.key}=${cookie.value}`)
310
+ .join("; ");
306
311
  return cookieHeader;
307
312
  }
308
313
  catch (e) {
@@ -315,18 +320,19 @@ class BiliAPI extends koishi_1.Service {
315
320
  }
316
321
  async getLoginInfoFromDB() {
317
322
  // 读取数据库获取cookies
318
- const data = (await this.ctx.database.get('loginBili', 1))[0];
323
+ const data = (await this.ctx.database.get("loginBili", 1))[0];
319
324
  // 判断是否登录
320
- if (data === undefined) { // 没有数据则直接返回
325
+ if (data === undefined) {
326
+ // 没有数据则直接返回
321
327
  // 未登录,在控制台提示
322
328
  this.loginNotifier = this.ctx.notifier.create({
323
- type: 'warning',
324
- content: '您尚未登录,将无法使用插件提供的指令'
329
+ type: "warning",
330
+ content: "您尚未登录,将无法使用插件提供的指令",
325
331
  });
326
332
  // 返回空值
327
333
  return {
328
334
  cookies: null,
329
- refresh_token: null
335
+ refresh_token: null,
330
336
  };
331
337
  }
332
338
  // 尝试解密
@@ -340,27 +346,29 @@ class BiliAPI extends koishi_1.Service {
340
346
  // 返回值
341
347
  return {
342
348
  cookies,
343
- refresh_token: decryptedRefreshToken
349
+ refresh_token: decryptedRefreshToken,
344
350
  };
345
351
  }
346
352
  catch (e) {
347
353
  // 数据库被篡改,在控制台提示
348
354
  this.loginNotifier = this.ctx.notifier.create({
349
- type: 'warning',
350
- content: '数据库被篡改,请重新登录'
355
+ type: "warning",
356
+ content: "数据库被篡改,请重新登录",
351
357
  });
352
358
  // 解密或解析失败,删除数据库登录信息
353
- await this.ctx.database.remove('loginBili', [1]);
359
+ await this.ctx.database.remove("loginBili", [1]);
354
360
  // 返回空值
355
361
  return {
356
362
  cookies: null,
357
- refresh_token: null
363
+ refresh_token: null,
358
364
  };
359
365
  }
360
366
  }
361
367
  getCSRF() {
362
368
  // 获取csrf
363
- return this.jar.serializeSync().cookies.find(cookie => cookie.key === 'bili_jct').value;
369
+ return this.jar
370
+ .serializeSync()
371
+ .cookies.find((cookie) => cookie.key === "bili_jct").value;
364
372
  }
365
373
  async loadCookiesFromDatabase() {
366
374
  // Get login info from db
@@ -372,10 +380,16 @@ class BiliAPI extends koishi_1.Service {
372
380
  return;
373
381
  }
374
382
  // 定义CSRF Token
375
- let csrf, expires, domain, path, secure, httpOnly, sameSite;
376
- cookies.forEach(cookieData => {
383
+ let csrf;
384
+ let expires;
385
+ let domain;
386
+ let path;
387
+ let secure;
388
+ let httpOnly;
389
+ let sameSite;
390
+ for (const cookieData of cookies) {
377
391
  // 获取key为bili_jct的值
378
- if (cookieData.key === 'bili_jct') {
392
+ if (cookieData.key === "bili_jct") {
379
393
  csrf = cookieData.value;
380
394
  expires = new Date(cookieData.expires);
381
395
  domain = cookieData.domain;
@@ -393,22 +407,22 @@ class BiliAPI extends koishi_1.Service {
393
407
  path: cookieData.path,
394
408
  secure: cookieData.secure,
395
409
  httpOnly: cookieData.httpOnly,
396
- sameSite: cookieData.sameSite
410
+ sameSite: cookieData.sameSite,
397
411
  });
398
- this.jar.setCookieSync(cookie, `http${cookie.secure ? 's' : ''}://${cookie.domain}${cookie.path}`, {});
399
- });
412
+ this.jar.setCookieSync(cookie, `http${cookie.secure ? "s" : ""}://${cookie.domain}${cookie.path}`, {});
413
+ }
400
414
  // 对于某些 IP 地址,需要在 Cookie 中提供任意非空的 buvid3 字段
401
415
  const buvid3Cookie = new tough_cookie_1.Cookie({
402
- key: 'buvid3',
403
- value: 'some_non_empty_value', // 设置任意非空值
416
+ key: "buvid3",
417
+ value: "some_non_empty_value", // 设置任意非空值
404
418
  expires, // 设置过期时间
405
419
  domain, // 设置域名
406
420
  path, // 设置路径
407
421
  secure, // 设置是否为安全 cookie
408
422
  httpOnly, // 设置是否为 HttpOnly cookie
409
- sameSite // 设置 SameSite 属性
423
+ sameSite, // 设置 SameSite 属性
410
424
  });
411
- this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? 's' : ''}://${buvid3Cookie.domain}${buvid3Cookie.path}`, {});
425
+ this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? "s" : ""}://${buvid3Cookie.domain}${buvid3Cookie.path}`, {});
412
426
  // Login info is loaded
413
427
  this.loginInfoIsLoaded = true;
414
428
  // restart plugin check
@@ -422,15 +436,16 @@ class BiliAPI extends koishi_1.Service {
422
436
  this.refreshCookieTimer();
423
437
  // Open scheduled tasks and check if token need refresh
424
438
  this.refreshCookieTimer = this.ctx.setInterval(async () => {
439
+ // 每12小时检测一次
425
440
  // 从数据库获取登录信息
426
441
  const { cookies, refresh_token } = await this.getLoginInfoFromDB();
427
442
  // 判断是否有值
428
443
  if (!cookies || !refresh_token)
429
444
  return;
430
445
  // 获取csrf
431
- const csrf = cookies.find(cookie => {
446
+ const csrf = cookies.find((cookie) => {
432
447
  // 判断key是否为bili_jct
433
- if (cookie.key === 'bili_jct')
448
+ if (cookie.key === "bili_jct")
434
449
  return true;
435
450
  }).value;
436
451
  // 检查是否需要更新
@@ -442,8 +457,8 @@ class BiliAPI extends koishi_1.Service {
442
457
  const notifyAndError = (info) => {
443
458
  // 设置控制台通知
444
459
  this.loginNotifier = this.ctx.notifier.create({
445
- type: 'warning',
446
- content: info
460
+ type: "warning",
461
+ content: info,
447
462
  });
448
463
  // 重置为未登录状态
449
464
  this.createNewClient();
@@ -470,7 +485,7 @@ class BiliAPI extends koishi_1.Service {
470
485
  // 如果请求失败,有可能是404,直接刷新cookie
471
486
  }
472
487
  // 定义Key
473
- const publicKey = await crypto_1.default.subtle.importKey("jwk", {
488
+ const publicKey = await node_crypto_1.default.subtle.importKey("jwk", {
474
489
  kty: "RSA",
475
490
  n: "y4HdjgJHBlbaBN04VERG4qNBIFHP6a3GozCl75AihQloSWCXC5HDNgyinEnhaQ_4-gaMud_GF50elYXLlCToR9se9Z8z433U3KjM-3Yx7ptKkmQNAMggQwAVKgq3zYAoidNEWuxpkY_mAitTSRLnsJW-NCTa0bqBFF6Wm1MxgfE",
476
491
  e: "AQAB",
@@ -478,7 +493,7 @@ class BiliAPI extends koishi_1.Service {
478
493
  // 定义获取CorrespondPath方法
479
494
  async function getCorrespondPath(timestamp) {
480
495
  const data = new TextEncoder().encode(`refresh_${timestamp}`);
481
- const encrypted = new Uint8Array(await crypto_1.default.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
496
+ const encrypted = new Uint8Array(await node_crypto_1.default.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
482
497
  return encrypted.reduce((str, c) => str + c.toString(16).padStart(2, "0"), "");
483
498
  }
484
499
  // 获取CorrespondPath
@@ -489,69 +504,73 @@ class BiliAPI extends koishi_1.Service {
489
504
  // 创建一个虚拟的DOM元素
490
505
  const { document } = new jsdom_1.JSDOM(refreshCsrfHtml).window;
491
506
  // 提取标签name为1-name的内容
492
- const targetElement = document.getElementById('1-name');
507
+ const targetElement = document.getElementById("1-name");
493
508
  const refresh_csrf = targetElement ? targetElement.textContent : null;
494
509
  // 发送刷新请求
495
- const { data: refreshData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/cookie/refresh', {
510
+ const { data: refreshData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/cookie/refresh", {
496
511
  csrf,
497
512
  refresh_csrf,
498
- source: 'main_web',
499
- refresh_token: refreshToken
513
+ source: "main_web",
514
+ refresh_token: refreshToken,
500
515
  }, {
501
516
  headers: {
502
- 'Content-Type': 'application/x-www-form-urlencoded',
503
- }
517
+ "Content-Type": "application/x-www-form-urlencoded",
518
+ },
504
519
  });
505
520
  // 检查是否有其他问题
506
521
  switch (refreshData.code) {
507
522
  // 账号未登录
508
- case -101: return this.createNewClient();
523
+ case -101:
524
+ return this.createNewClient();
509
525
  case -111: {
510
- await this.ctx.database.remove('loginBili', [1]);
511
- notifyAndError('csrf 校验错误,请重新登录');
526
+ await this.ctx.database.remove("loginBili", [1]);
527
+ notifyAndError("csrf 校验错误,请重新登录");
512
528
  break;
513
529
  }
514
530
  case 86095: {
515
- await this.ctx.database.remove('loginBili', [1]);
516
- notifyAndError('refresh_csrf 错误或 refresh_token 与 cookie 不匹配,请重新登录');
531
+ await this.ctx.database.remove("loginBili", [1]);
532
+ notifyAndError("refresh_csrf 错误或 refresh_token 与 cookie 不匹配,请重新登录");
517
533
  }
518
534
  }
519
535
  // 更新 新的cookies和refresh_token
520
536
  const encryptedCookies = this.encrypt(this.getCookies());
521
537
  const encryptedRefreshToken = this.encrypt(refreshData.data.refresh_token);
522
- await this.ctx.database.upsert('loginBili', [{
538
+ await this.ctx.database.upsert("loginBili", [
539
+ {
523
540
  id: 1,
524
541
  bili_cookies: encryptedCookies,
525
- bili_refresh_token: encryptedRefreshToken
526
- }]);
542
+ bili_refresh_token: encryptedRefreshToken,
543
+ },
544
+ ]);
527
545
  // Get new csrf from cookies
528
- const newCsrf = this.jar.serializeSync().cookies.find(cookie => {
529
- if (cookie.key === 'bili_jct')
546
+ const newCsrf = this.jar.serializeSync().cookies.find((cookie) => {
547
+ if (cookie.key === "bili_jct")
530
548
  return true;
531
549
  }).value;
532
550
  // Accept update
533
- const { data: aceeptData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/confirm/refresh', {
551
+ const { data: aceeptData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/confirm/refresh", {
534
552
  csrf: newCsrf,
535
- refresh_token: refreshToken
553
+ refresh_token: refreshToken,
536
554
  }, {
537
555
  headers: {
538
- 'Content-Type': 'application/x-www-form-urlencoded',
539
- }
556
+ "Content-Type": "application/x-www-form-urlencoded",
557
+ },
540
558
  });
541
559
  // 检查是否有其他问题
542
560
  switch (aceeptData.code) {
543
561
  case -111: {
544
- await this.ctx.database.remove('loginBili', [1]);
545
- notifyAndError('csrf 校验失败,请重新登录');
562
+ await this.ctx.database.remove("loginBili", [1]);
563
+ notifyAndError("csrf 校验失败,请重新登录");
546
564
  break;
547
565
  }
548
- case -400: throw new Error('请求错误');
566
+ case -400:
567
+ throw new Error("请求错误");
549
568
  }
550
569
  // 没有问题,cookies已更新完成
551
570
  }
552
571
  }
553
572
  __decorate([
554
- (0, retry_1.default)({
573
+ (0, utils_1.Retry)({
555
574
  attempts: 3,
556
575
  onFailure(error, attempts) {
557
576
  this.logger.error(`getTheUserWhoIsLiveStreaming() 第${attempts}次失败: ${error.message}`);
@@ -559,7 +578,7 @@ __decorate([
559
578
  })
560
579
  ], BiliAPI.prototype, "getTheUserWhoIsLiveStreaming", null);
561
580
  __decorate([
562
- (0, retry_1.default)({
581
+ (0, utils_1.Retry)({
563
582
  attempts: 3,
564
583
  onFailure(error, attempts) {
565
584
  this.logger.error(`getLiveRoomInfoStreamKey() 第${attempts}次失败: ${error.message}`);
@@ -567,7 +586,7 @@ __decorate([
567
586
  })
568
587
  ], BiliAPI.prototype, "getLiveRoomInfoStreamKey", null);
569
588
  __decorate([
570
- (0, retry_1.default)({
589
+ (0, utils_1.Retry)({
571
590
  attempts: 3,
572
591
  onFailure(error, attempts) {
573
592
  this.logger.error(`getServerUTCTime() 第${attempts}次失败: ${error.message}`);
@@ -575,7 +594,7 @@ __decorate([
575
594
  })
576
595
  ], BiliAPI.prototype, "getServerUTCTime", null);
577
596
  __decorate([
578
- (0, retry_1.default)({
597
+ (0, utils_1.Retry)({
579
598
  attempts: 3,
580
599
  onFailure(error, attempts) {
581
600
  this.logger.error(`getTimeNow() 第${attempts}次失败: ${error.message}`);
@@ -583,7 +602,7 @@ __decorate([
583
602
  })
584
603
  ], BiliAPI.prototype, "getTimeNow", null);
585
604
  __decorate([
586
- (0, retry_1.default)({
605
+ (0, utils_1.Retry)({
587
606
  attempts: 3,
588
607
  onFailure(error, attempts) {
589
608
  this.logger.error(`getAllGroup() 第${attempts}次失败: ${error.message}`);
@@ -591,7 +610,7 @@ __decorate([
591
610
  })
592
611
  ], BiliAPI.prototype, "getAllGroup", null);
593
612
  __decorate([
594
- (0, retry_1.default)({
613
+ (0, utils_1.Retry)({
595
614
  attempts: 3,
596
615
  onFailure(error, attempts) {
597
616
  this.logger.error(`removeUserFromGroup() 第${attempts}次失败: ${error.message}`);
@@ -599,7 +618,7 @@ __decorate([
599
618
  })
600
619
  ], BiliAPI.prototype, "removeUserFromGroup", null);
601
620
  __decorate([
602
- (0, retry_1.default)({
621
+ (0, utils_1.Retry)({
603
622
  attempts: 3,
604
623
  onFailure(error, attempts) {
605
624
  this.logger.error(`copyUserToGroup() 第${attempts}次失败: ${error.message}`);
@@ -607,7 +626,7 @@ __decorate([
607
626
  })
608
627
  ], BiliAPI.prototype, "copyUserToGroup", null);
609
628
  __decorate([
610
- (0, retry_1.default)({
629
+ (0, utils_1.Retry)({
611
630
  attempts: 3,
612
631
  onFailure(error, attempts) {
613
632
  this.logger.error(`getUserSpaceDynamic() 第${attempts}次失败: ${error.message}`);
@@ -615,7 +634,7 @@ __decorate([
615
634
  })
616
635
  ], BiliAPI.prototype, "getUserSpaceDynamic", null);
617
636
  __decorate([
618
- (0, retry_1.default)({
637
+ (0, utils_1.Retry)({
619
638
  attempts: 3,
620
639
  onFailure(error, attempts) {
621
640
  this.logger.error(`createGroup() 第${attempts}次失败: ${error.message}`);
@@ -623,7 +642,7 @@ __decorate([
623
642
  })
624
643
  ], BiliAPI.prototype, "createGroup", null);
625
644
  __decorate([
626
- (0, retry_1.default)({
645
+ (0, utils_1.Retry)({
627
646
  attempts: 3,
628
647
  onFailure(error, attempts) {
629
648
  this.logger.error(`getAllDynamic() 第${attempts}次失败: ${error.message}`);
@@ -631,7 +650,7 @@ __decorate([
631
650
  })
632
651
  ], BiliAPI.prototype, "getAllDynamic", null);
633
652
  __decorate([
634
- (0, retry_1.default)({
653
+ (0, utils_1.Retry)({
635
654
  attempts: 3,
636
655
  onFailure(error, attempts) {
637
656
  this.logger.error(`hasNewDynamic() 第${attempts}次失败: ${error.message}`);
@@ -639,7 +658,7 @@ __decorate([
639
658
  })
640
659
  ], BiliAPI.prototype, "hasNewDynamic", null);
641
660
  __decorate([
642
- (0, retry_1.default)({
661
+ (0, utils_1.Retry)({
643
662
  attempts: 3,
644
663
  onFailure(error, attempts) {
645
664
  this.logger.error(`follow() 第${attempts}次失败: ${error.message}`);
@@ -647,7 +666,7 @@ __decorate([
647
666
  })
648
667
  ], BiliAPI.prototype, "follow", null);
649
668
  __decorate([
650
- (0, retry_1.default)({
669
+ (0, utils_1.Retry)({
651
670
  attempts: 3,
652
671
  onFailure(error, attempts) {
653
672
  this.logger.error(`getRelationGroupDetail() 第${attempts}次失败: ${error.message}`);
@@ -655,7 +674,7 @@ __decorate([
655
674
  })
656
675
  ], BiliAPI.prototype, "getRelationGroupDetail", null);
657
676
  __decorate([
658
- (0, retry_1.default)({
677
+ (0, utils_1.Retry)({
659
678
  attempts: 3,
660
679
  onFailure(error, attempts) {
661
680
  this.logger.error(`getCookieInfo() 第${attempts}次失败: ${error.message}`);
@@ -663,7 +682,7 @@ __decorate([
663
682
  })
664
683
  ], BiliAPI.prototype, "getCookieInfo", null);
665
684
  __decorate([
666
- (0, retry_1.default)({
685
+ (0, utils_1.Retry)({
667
686
  attempts: 3,
668
687
  onFailure(error, attempts) {
669
688
  this.logger.error(`getUserInfo() 第${attempts}次失败: ${error.message}`);
@@ -671,7 +690,7 @@ __decorate([
671
690
  })
672
691
  ], BiliAPI.prototype, "getUserInfo", null);
673
692
  __decorate([
674
- (0, retry_1.default)({
693
+ (0, utils_1.Retry)({
675
694
  attempts: 3,
676
695
  onFailure(error, attempts) {
677
696
  this.logger.error(`getWbiKeys() 第${attempts}次失败: ${error.message}`);
@@ -679,7 +698,7 @@ __decorate([
679
698
  })
680
699
  ], BiliAPI.prototype, "getWbiKeys", null);
681
700
  __decorate([
682
- (0, retry_1.default)({
701
+ (0, utils_1.Retry)({
683
702
  attempts: 3,
684
703
  onFailure(error, attempts) {
685
704
  this.logger.error(`getMyselfInfo() 第${attempts}次失败: ${error.message}`);
@@ -687,7 +706,7 @@ __decorate([
687
706
  })
688
707
  ], BiliAPI.prototype, "getMyselfInfo", null);
689
708
  __decorate([
690
- (0, retry_1.default)({
709
+ (0, utils_1.Retry)({
691
710
  attempts: 3,
692
711
  onFailure(error, attempts) {
693
712
  this.logger.error(`getLoginQRCode() 第${attempts}次失败: ${error.message}`);
@@ -695,7 +714,7 @@ __decorate([
695
714
  })
696
715
  ], BiliAPI.prototype, "getLoginQRCode", null);
697
716
  __decorate([
698
- (0, retry_1.default)({
717
+ (0, utils_1.Retry)({
699
718
  attempts: 3,
700
719
  onFailure(error, attempts) {
701
720
  this.logger.error(`getLoginStatus() 第${attempts}次失败: ${error.message}`);
@@ -703,7 +722,7 @@ __decorate([
703
722
  })
704
723
  ], BiliAPI.prototype, "getLoginStatus", null);
705
724
  __decorate([
706
- (0, retry_1.default)({
725
+ (0, utils_1.Retry)({
707
726
  attempts: 3,
708
727
  onFailure(error, attempts) {
709
728
  this.logger.error(`getLiveRoomInfo() 第${attempts}次失败: ${error.message}`);
@@ -711,7 +730,7 @@ __decorate([
711
730
  })
712
731
  ], BiliAPI.prototype, "getLiveRoomInfo", null);
713
732
  __decorate([
714
- (0, retry_1.default)({
733
+ (0, utils_1.Retry)({
715
734
  attempts: 3,
716
735
  onFailure(error, attempts) {
717
736
  this.logger.error(`getMasterInfo() 第${attempts}次失败: ${error.message}`);
@@ -723,7 +742,7 @@ __decorate([
723
742
  userAgent: koishi_1.Schema.string(),
724
743
  key: koishi_1.Schema.string()
725
744
  .pattern(/^[0-9a-f]{32}$/)
726
- .required()
745
+ .required(),
727
746
  });
728
747
  })(BiliAPI || (BiliAPI = {}));
729
748
  exports.default = BiliAPI;