koishi-plugin-bilibili-notify 3.0.0-alpha.12 → 3.0.0-alpha.14

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.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Context, Schema, Service } from "koishi";
2
- import { CookieJar } from 'tough-cookie';
3
- import { Notifier } from "@koishijs/plugin-notifier";
4
- declare module 'koishi' {
1
+ import { type Context, Schema, Service } from "koishi";
2
+ import { CookieJar } from "tough-cookie";
3
+ import type { Notifier } from "@koishijs/plugin-notifier";
4
+ declare module "koishi" {
5
5
  interface Context {
6
6
  ba: BiliAPI;
7
7
  }
@@ -13,7 +13,7 @@ declare class BiliAPI extends Service {
13
13
  apiConfig: BiliAPI.Config;
14
14
  loginData: any;
15
15
  loginNotifier: Notifier;
16
- refreshCookieTimer: Function;
16
+ refreshCookieTimer: () => void;
17
17
  loginInfoIsLoaded: boolean;
18
18
  constructor(ctx: Context, config: BiliAPI.Config);
19
19
  protected start(): void | Promise<void>;
package/lib/biliAPI.js CHANGED
@@ -9,12 +9,9 @@ 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");
@@ -23,46 +20,48 @@ const luxon_1 = require("luxon");
23
20
  const retry_1 = __importDefault(require("./utils/retry"));
24
21
  const mixinKeyEncTab = [
25
22
  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
23
+ 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61,
24
+ 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36,
25
+ 20, 34, 44, 52,
29
26
  ];
30
27
  // 在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';
28
+ const bangumiTripData = { code: 0, data: { live_room: { roomid: 931774 } } };
29
+ const GET_USER_SPACE_DYNAMIC_LIST = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space";
30
+ const GET_ALL_DYNAMIC_LIST = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all";
31
+ const HAS_NEW_DYNAMIC = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all/update";
32
+ const GET_COOKIES_INFO = "https://passport.bilibili.com/x/passport-login/web/cookie/info";
33
+ const GET_USER_INFO = "https://api.bilibili.com/x/space/wbi/acc/info";
34
+ const GET_MYSELF_INFO = "https://api.bilibili.com/x/member/web/account";
35
+ const GET_LOGIN_QRCODE = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
36
+ const GET_LOGIN_STATUS = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll";
37
+ const GET_LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info";
38
+ const GET_MASTER_INFO = "https://api.live.bilibili.com/live_user/v1/Master/info";
39
+ const GET_TIME_NOW = "https://api.bilibili.com/x/report/click/now";
40
+ const GET_SERVER_UTC_TIME = "https://interface.bilibili.com/serverdate.js";
44
41
  // 最近更新UP
45
- const GET_LATEST_UPDATED_UPS = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/portal';
42
+ const GET_LATEST_UPDATED_UPS = "https://api.bilibili.com/x/polymer/web-dynamic/v1/portal";
46
43
  // 操作
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';
44
+ const MODIFY_RELATION = "https://api.bilibili.com/x/relation/modify";
45
+ const CREATE_GROUP = "https://api.bilibili.com/x/relation/tag/create";
46
+ const MODIFY_GROUP_MEMBER = "https://api.bilibili.com/x/relation/tags/addUsers";
47
+ const GET_ALL_GROUP = "https://api.bilibili.com/x/relation/tags";
48
+ const COPY_USER_TO_GROUP = "https://api.bilibili.com/x/relation/tags/copyUsers";
49
+ const GET_RELATION_GROUP_DETAIL = "https://api.bilibili.com/x/relation/tag";
53
50
  // 直播
54
- const GET_LIVE_ROOM_INFO_STREAM_KEY = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo';
51
+ const GET_LIVE_ROOM_INFO_STREAM_KEY = "https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo";
55
52
  class BiliAPI extends koishi_1.Service {
56
- static inject = ['database', 'notifier'];
53
+ static inject = ["database", "notifier"];
57
54
  jar;
55
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
58
56
  client;
59
57
  apiConfig;
58
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
60
59
  loginData;
61
60
  loginNotifier;
62
61
  refreshCookieTimer;
63
62
  loginInfoIsLoaded = false;
64
63
  constructor(ctx, config) {
65
- super(ctx, 'ba');
64
+ super(ctx, "ba");
66
65
  this.apiConfig = config;
67
66
  }
68
67
  start() {
@@ -79,7 +78,9 @@ class BiliAPI extends koishi_1.Service {
79
78
  .slice(0, 32);
80
79
  // 为请求参数进行 wbi 签名
81
80
  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;
81
+ const mixin_key = this.getMixinKey(img_key + sub_key);
82
+ const curr_time = Math.round(Date.now() / 1000);
83
+ const chr_filter = /[!'()*]/g;
83
84
  Object.assign(params, { wts: curr_time }); // 添加 wts 字段
84
85
  // 按照 key 重排参数
85
86
  const query = Object.keys(params)
@@ -91,32 +92,36 @@ class BiliAPI extends koishi_1.Service {
91
92
  })
92
93
  .join("&");
93
94
  const wbi_sign = (0, md5_1.default)(query + mixin_key); // 计算 w_rid
94
- return query + "&w_rid=" + wbi_sign;
95
+ return `${query}&w_rid=${wbi_sign}`;
95
96
  }
96
97
  async getWbi(params) {
97
98
  const web_keys = await this.getWbiKeys();
98
- const img_key = web_keys.img_key, sub_key = web_keys.sub_key;
99
+ const img_key = web_keys.img_key;
100
+ const sub_key = web_keys.sub_key;
99
101
  const query = this.encWbi(params, img_key, sub_key);
100
102
  return query;
101
103
  }
102
104
  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);
105
+ const iv = node_crypto_1.default.randomBytes(16);
106
+ const cipher = node_crypto_1.default.createCipheriv("aes-256-cbc", Buffer.from(this.apiConfig.key), iv);
105
107
  const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
106
- return iv.toString('hex') + ':' + encrypted.toString('hex');
108
+ return `${iv.toString("hex")}:${encrypted.toString("hex")}`;
107
109
  }
108
110
  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()]);
111
+ const textParts = text.split(":");
112
+ const iv = Buffer.from(textParts.shift(), "hex");
113
+ const encryptedText = Buffer.from(textParts.join(":"), "hex");
114
+ const decipher = node_crypto_1.default.createDecipheriv("aes-256-cbc", Buffer.from(this.apiConfig.key), iv);
115
+ const decrypted = Buffer.concat([
116
+ decipher.update(encryptedText),
117
+ decipher.final(),
118
+ ]);
114
119
  return decrypted.toString();
115
120
  }
116
121
  // BA API
117
122
  async getTheUserWhoIsLiveStreaming() {
118
123
  // 获取直播间信息流密钥
119
- const { data: { live_users } } = await this.client.get(GET_LATEST_UPDATED_UPS);
124
+ const { data: { live_users }, } = await this.client.get(GET_LATEST_UPDATED_UPS);
120
125
  // 返回data
121
126
  return live_users;
122
127
  }
@@ -134,9 +139,7 @@ class BiliAPI extends koishi_1.Service {
134
139
  const timestamp = new Function(`return Date.UTC(${match[1]})`)();
135
140
  return timestamp / 1000;
136
141
  }
137
- else {
138
- throw new Error('解析服务器时间失败!');
139
- }
142
+ throw new Error("解析服务器时间失败!");
140
143
  }
141
144
  async getTimeNow() {
142
145
  const { data } = await this.client.get(GET_TIME_NOW);
@@ -153,11 +156,11 @@ class BiliAPI extends koishi_1.Service {
153
156
  const { data } = await this.client.post(MODIFY_GROUP_MEMBER, {
154
157
  fids: mid,
155
158
  tagids: 0,
156
- csrf
159
+ csrf,
157
160
  }, {
158
161
  headers: {
159
- 'Content-Type': 'application/x-www-form-urlencoded',
160
- }
162
+ "Content-Type": "application/x-www-form-urlencoded",
163
+ },
161
164
  });
162
165
  return data;
163
166
  }
@@ -168,11 +171,11 @@ class BiliAPI extends koishi_1.Service {
168
171
  const { data } = await this.client.post(COPY_USER_TO_GROUP, {
169
172
  fids: mid,
170
173
  tagids: groupId,
171
- csrf
174
+ csrf,
172
175
  }, {
173
176
  headers: {
174
- 'Content-Type': 'application/x-www-form-urlencoded',
175
- }
177
+ "Content-Type": "application/x-www-form-urlencoded",
178
+ },
176
179
  });
177
180
  return data;
178
181
  }
@@ -183,17 +186,19 @@ class BiliAPI extends koishi_1.Service {
183
186
  async createGroup(tag) {
184
187
  const { data } = await this.client.post(CREATE_GROUP, {
185
188
  tag,
186
- csrf: this.getCSRF()
189
+ csrf: this.getCSRF(),
187
190
  }, {
188
191
  headers: {
189
- 'Content-Type': 'application/x-www-form-urlencoded',
190
- }
192
+ "Content-Type": "application/x-www-form-urlencoded",
193
+ },
191
194
  });
192
195
  return data;
193
196
  }
194
197
  async getAllDynamic(updateBaseline) {
195
198
  let url = GET_ALL_DYNAMIC_LIST;
196
- updateBaseline && (url += `?update_baseline=${updateBaseline}`);
199
+ if (updateBaseline) {
200
+ url += `?update_baseline=${updateBaseline}`;
201
+ }
197
202
  const { data } = await this.client.get(url);
198
203
  return data;
199
204
  }
@@ -206,11 +211,11 @@ class BiliAPI extends koishi_1.Service {
206
211
  fid,
207
212
  act: 1,
208
213
  re_src: 11,
209
- csrf: this.getCSRF()
214
+ csrf: this.getCSRF(),
210
215
  }, {
211
216
  headers: {
212
- 'Content-Type': 'application/x-www-form-urlencoded',
213
- }
217
+ "Content-Type": "application/x-www-form-urlencoded",
218
+ },
214
219
  });
215
220
  return data;
216
221
  }
@@ -235,11 +240,11 @@ class BiliAPI extends koishi_1.Service {
235
240
  }
236
241
  // 获取最新的 img_key 和 sub_key
237
242
  async getWbiKeys() {
238
- const { data } = await this.client.get('https://api.bilibili.com/x/web-interface/nav');
243
+ const { data } = await this.client.get("https://api.bilibili.com/x/web-interface/nav");
239
244
  const { data: { wbi_img: { img_url, sub_url }, }, } = data;
240
245
  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('.'))
246
+ img_key: img_url.slice(img_url.lastIndexOf("/") + 1, img_url.lastIndexOf(".")),
247
+ sub_key: sub_url.slice(sub_url.lastIndexOf("/") + 1, sub_url.lastIndexOf(".")),
243
248
  };
244
249
  }
245
250
  async getMyselfInfo() {
@@ -262,15 +267,17 @@ class BiliAPI extends koishi_1.Service {
262
267
  const { data } = await this.client.get(`${GET_MASTER_INFO}?uid=${mid}`);
263
268
  return data;
264
269
  }
265
- disposeNotifier() { if (this.loginNotifier)
266
- this.loginNotifier.dispose(); }
270
+ disposeNotifier() {
271
+ if (this.loginNotifier)
272
+ this.loginNotifier.dispose();
273
+ }
267
274
  getRandomUserAgent() {
268
275
  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'
276
+ "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",
277
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
278
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
279
+ "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",
280
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
274
281
  ];
275
282
  const index = Math.floor(Math.random() * userAgents.length);
276
283
  return userAgents[index];
@@ -280,16 +287,18 @@ class BiliAPI extends koishi_1.Service {
280
287
  this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
281
288
  jar: this.jar,
282
289
  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
- }
290
+ "Content-Type": "application/json",
291
+ "User-Agent": this.apiConfig.userAgent !==
292
+ "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"
293
+ ? this.apiConfig.userAgent
294
+ : this.getRandomUserAgent(),
295
+ Origin: "https://www.bilibili.com",
296
+ Referer: "https://www.bilibili.com/",
297
+ },
289
298
  }));
290
299
  }
291
300
  getTimeOfUTC8() {
292
- return Math.floor(luxon_1.DateTime.now().setZone('UTC+8').toSeconds());
301
+ return Math.floor(luxon_1.DateTime.now().setZone("UTC+8").toSeconds());
293
302
  }
294
303
  getCookies() {
295
304
  const cookies = JSON.stringify(this.jar.serializeSync().cookies);
@@ -301,8 +310,8 @@ class BiliAPI extends koishi_1.Service {
301
310
  const cookies = this.jar.serializeSync().cookies;
302
311
  // 将每个 cookie 对象转换为 "key=value" 形式,并用 "; " 连接起来
303
312
  const cookieHeader = cookies
304
- .map(cookie => `${cookie.key}=${cookie.value}`)
305
- .join('; ');
313
+ .map((cookie) => `${cookie.key}=${cookie.value}`)
314
+ .join("; ");
306
315
  return cookieHeader;
307
316
  }
308
317
  catch (e) {
@@ -315,18 +324,19 @@ class BiliAPI extends koishi_1.Service {
315
324
  }
316
325
  async getLoginInfoFromDB() {
317
326
  // 读取数据库获取cookies
318
- const data = (await this.ctx.database.get('loginBili', 1))[0];
327
+ const data = (await this.ctx.database.get("loginBili", 1))[0];
319
328
  // 判断是否登录
320
- if (data === undefined) { // 没有数据则直接返回
329
+ if (data === undefined) {
330
+ // 没有数据则直接返回
321
331
  // 未登录,在控制台提示
322
332
  this.loginNotifier = this.ctx.notifier.create({
323
- type: 'warning',
324
- content: '您尚未登录,将无法使用插件提供的指令'
333
+ type: "warning",
334
+ content: "您尚未登录,将无法使用插件提供的指令",
325
335
  });
326
336
  // 返回空值
327
337
  return {
328
338
  cookies: null,
329
- refresh_token: null
339
+ refresh_token: null,
330
340
  };
331
341
  }
332
342
  // 尝试解密
@@ -340,27 +350,29 @@ class BiliAPI extends koishi_1.Service {
340
350
  // 返回值
341
351
  return {
342
352
  cookies,
343
- refresh_token: decryptedRefreshToken
353
+ refresh_token: decryptedRefreshToken,
344
354
  };
345
355
  }
346
356
  catch (e) {
347
357
  // 数据库被篡改,在控制台提示
348
358
  this.loginNotifier = this.ctx.notifier.create({
349
- type: 'warning',
350
- content: '数据库被篡改,请重新登录'
359
+ type: "warning",
360
+ content: "数据库被篡改,请重新登录",
351
361
  });
352
362
  // 解密或解析失败,删除数据库登录信息
353
- await this.ctx.database.remove('loginBili', [1]);
363
+ await this.ctx.database.remove("loginBili", [1]);
354
364
  // 返回空值
355
365
  return {
356
366
  cookies: null,
357
- refresh_token: null
367
+ refresh_token: null,
358
368
  };
359
369
  }
360
370
  }
361
371
  getCSRF() {
362
372
  // 获取csrf
363
- return this.jar.serializeSync().cookies.find(cookie => cookie.key === 'bili_jct').value;
373
+ return this.jar
374
+ .serializeSync()
375
+ .cookies.find((cookie) => cookie.key === "bili_jct").value;
364
376
  }
365
377
  async loadCookiesFromDatabase() {
366
378
  // Get login info from db
@@ -372,10 +384,16 @@ class BiliAPI extends koishi_1.Service {
372
384
  return;
373
385
  }
374
386
  // 定义CSRF Token
375
- let csrf, expires, domain, path, secure, httpOnly, sameSite;
376
- cookies.forEach(cookieData => {
387
+ let csrf;
388
+ let expires;
389
+ let domain;
390
+ let path;
391
+ let secure;
392
+ let httpOnly;
393
+ let sameSite;
394
+ for (const cookieData of cookies) {
377
395
  // 获取key为bili_jct的值
378
- if (cookieData.key === 'bili_jct') {
396
+ if (cookieData.key === "bili_jct") {
379
397
  csrf = cookieData.value;
380
398
  expires = new Date(cookieData.expires);
381
399
  domain = cookieData.domain;
@@ -393,22 +411,22 @@ class BiliAPI extends koishi_1.Service {
393
411
  path: cookieData.path,
394
412
  secure: cookieData.secure,
395
413
  httpOnly: cookieData.httpOnly,
396
- sameSite: cookieData.sameSite
414
+ sameSite: cookieData.sameSite,
397
415
  });
398
- this.jar.setCookieSync(cookie, `http${cookie.secure ? 's' : ''}://${cookie.domain}${cookie.path}`, {});
399
- });
416
+ this.jar.setCookieSync(cookie, `http${cookie.secure ? "s" : ""}://${cookie.domain}${cookie.path}`, {});
417
+ }
400
418
  // 对于某些 IP 地址,需要在 Cookie 中提供任意非空的 buvid3 字段
401
419
  const buvid3Cookie = new tough_cookie_1.Cookie({
402
- key: 'buvid3',
403
- value: 'some_non_empty_value', // 设置任意非空值
420
+ key: "buvid3",
421
+ value: "some_non_empty_value", // 设置任意非空值
404
422
  expires, // 设置过期时间
405
423
  domain, // 设置域名
406
424
  path, // 设置路径
407
425
  secure, // 设置是否为安全 cookie
408
426
  httpOnly, // 设置是否为 HttpOnly cookie
409
- sameSite // 设置 SameSite 属性
427
+ sameSite, // 设置 SameSite 属性
410
428
  });
411
- this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? 's' : ''}://${buvid3Cookie.domain}${buvid3Cookie.path}`, {});
429
+ this.jar.setCookieSync(buvid3Cookie, `http${buvid3Cookie.secure ? "s" : ""}://${buvid3Cookie.domain}${buvid3Cookie.path}`, {});
412
430
  // Login info is loaded
413
431
  this.loginInfoIsLoaded = true;
414
432
  // restart plugin check
@@ -422,15 +440,16 @@ class BiliAPI extends koishi_1.Service {
422
440
  this.refreshCookieTimer();
423
441
  // Open scheduled tasks and check if token need refresh
424
442
  this.refreshCookieTimer = this.ctx.setInterval(async () => {
443
+ // 每12小时检测一次
425
444
  // 从数据库获取登录信息
426
445
  const { cookies, refresh_token } = await this.getLoginInfoFromDB();
427
446
  // 判断是否有值
428
447
  if (!cookies || !refresh_token)
429
448
  return;
430
449
  // 获取csrf
431
- const csrf = cookies.find(cookie => {
450
+ const csrf = cookies.find((cookie) => {
432
451
  // 判断key是否为bili_jct
433
- if (cookie.key === 'bili_jct')
452
+ if (cookie.key === "bili_jct")
434
453
  return true;
435
454
  }).value;
436
455
  // 检查是否需要更新
@@ -442,8 +461,8 @@ class BiliAPI extends koishi_1.Service {
442
461
  const notifyAndError = (info) => {
443
462
  // 设置控制台通知
444
463
  this.loginNotifier = this.ctx.notifier.create({
445
- type: 'warning',
446
- content: info
464
+ type: "warning",
465
+ content: info,
447
466
  });
448
467
  // 重置为未登录状态
449
468
  this.createNewClient();
@@ -470,7 +489,7 @@ class BiliAPI extends koishi_1.Service {
470
489
  // 如果请求失败,有可能是404,直接刷新cookie
471
490
  }
472
491
  // 定义Key
473
- const publicKey = await crypto_1.default.subtle.importKey("jwk", {
492
+ const publicKey = await node_crypto_1.default.subtle.importKey("jwk", {
474
493
  kty: "RSA",
475
494
  n: "y4HdjgJHBlbaBN04VERG4qNBIFHP6a3GozCl75AihQloSWCXC5HDNgyinEnhaQ_4-gaMud_GF50elYXLlCToR9se9Z8z433U3KjM-3Yx7ptKkmQNAMggQwAVKgq3zYAoidNEWuxpkY_mAitTSRLnsJW-NCTa0bqBFF6Wm1MxgfE",
476
495
  e: "AQAB",
@@ -478,7 +497,7 @@ class BiliAPI extends koishi_1.Service {
478
497
  // 定义获取CorrespondPath方法
479
498
  async function getCorrespondPath(timestamp) {
480
499
  const data = new TextEncoder().encode(`refresh_${timestamp}`);
481
- const encrypted = new Uint8Array(await crypto_1.default.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
500
+ const encrypted = new Uint8Array(await node_crypto_1.default.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data));
482
501
  return encrypted.reduce((str, c) => str + c.toString(16).padStart(2, "0"), "");
483
502
  }
484
503
  // 获取CorrespondPath
@@ -489,63 +508,67 @@ class BiliAPI extends koishi_1.Service {
489
508
  // 创建一个虚拟的DOM元素
490
509
  const { document } = new jsdom_1.JSDOM(refreshCsrfHtml).window;
491
510
  // 提取标签name为1-name的内容
492
- const targetElement = document.getElementById('1-name');
511
+ const targetElement = document.getElementById("1-name");
493
512
  const refresh_csrf = targetElement ? targetElement.textContent : null;
494
513
  // 发送刷新请求
495
- const { data: refreshData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/cookie/refresh', {
514
+ const { data: refreshData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/cookie/refresh", {
496
515
  csrf,
497
516
  refresh_csrf,
498
- source: 'main_web',
499
- refresh_token: refreshToken
517
+ source: "main_web",
518
+ refresh_token: refreshToken,
500
519
  }, {
501
520
  headers: {
502
- 'Content-Type': 'application/x-www-form-urlencoded',
503
- }
521
+ "Content-Type": "application/x-www-form-urlencoded",
522
+ },
504
523
  });
505
524
  // 检查是否有其他问题
506
525
  switch (refreshData.code) {
507
526
  // 账号未登录
508
- case -101: return this.createNewClient();
527
+ case -101:
528
+ return this.createNewClient();
509
529
  case -111: {
510
- await this.ctx.database.remove('loginBili', [1]);
511
- notifyAndError('csrf 校验错误,请重新登录');
530
+ await this.ctx.database.remove("loginBili", [1]);
531
+ notifyAndError("csrf 校验错误,请重新登录");
512
532
  break;
513
533
  }
514
534
  case 86095: {
515
- await this.ctx.database.remove('loginBili', [1]);
516
- notifyAndError('refresh_csrf 错误或 refresh_token 与 cookie 不匹配,请重新登录');
535
+ await this.ctx.database.remove("loginBili", [1]);
536
+ notifyAndError("refresh_csrf 错误或 refresh_token 与 cookie 不匹配,请重新登录");
517
537
  }
518
538
  }
519
539
  // 更新 新的cookies和refresh_token
520
540
  const encryptedCookies = this.encrypt(this.getCookies());
521
541
  const encryptedRefreshToken = this.encrypt(refreshData.data.refresh_token);
522
- await this.ctx.database.upsert('loginBili', [{
542
+ await this.ctx.database.upsert("loginBili", [
543
+ {
523
544
  id: 1,
524
545
  bili_cookies: encryptedCookies,
525
- bili_refresh_token: encryptedRefreshToken
526
- }]);
546
+ bili_refresh_token: encryptedRefreshToken,
547
+ },
548
+ ]);
527
549
  // Get new csrf from cookies
528
- const newCsrf = this.jar.serializeSync().cookies.find(cookie => {
529
- if (cookie.key === 'bili_jct')
550
+ const newCsrf = this.jar.serializeSync().cookies.find((cookie) => {
551
+ if (cookie.key === "bili_jct")
530
552
  return true;
531
553
  }).value;
532
554
  // Accept update
533
- const { data: aceeptData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/confirm/refresh', {
555
+ const { data: aceeptData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/confirm/refresh", {
534
556
  csrf: newCsrf,
535
- refresh_token: refreshToken
557
+ refresh_token: refreshToken,
536
558
  }, {
537
559
  headers: {
538
- 'Content-Type': 'application/x-www-form-urlencoded',
539
- }
560
+ "Content-Type": "application/x-www-form-urlencoded",
561
+ },
540
562
  });
541
563
  // 检查是否有其他问题
542
564
  switch (aceeptData.code) {
543
565
  case -111: {
544
- await this.ctx.database.remove('loginBili', [1]);
545
- notifyAndError('csrf 校验失败,请重新登录');
566
+ await this.ctx.database.remove("loginBili", [1]);
567
+ notifyAndError("csrf 校验失败,请重新登录");
546
568
  break;
547
569
  }
548
- case -400: throw new Error('请求错误');
570
+ case -400:
571
+ throw new Error("请求错误");
549
572
  }
550
573
  // 没有问题,cookies已更新完成
551
574
  }
@@ -723,7 +746,7 @@ __decorate([
723
746
  userAgent: koishi_1.Schema.string(),
724
747
  key: koishi_1.Schema.string()
725
748
  .pattern(/^[0-9a-f]{32}$/)
726
- .required()
749
+ .required(),
727
750
  });
728
751
  })(BiliAPI || (BiliAPI = {}));
729
752
  exports.default = BiliAPI;
@@ -1,6 +1,6 @@
1
- import { Bot, Context, FlatPick, Logger, Schema, Session } from "koishi";
2
- import { Notifier } from "@koishijs/plugin-notifier";
3
- import { LoginBili } from "./database";
1
+ import { type Bot, type Context, type FlatPick, type Logger, Schema, type Session } from "koishi";
2
+ import type { Notifier } from "@koishijs/plugin-notifier";
3
+ import type { LoginBili } from "./database";
4
4
  declare enum LiveType {
5
5
  NotLiveBroadcast = 0,
6
6
  StartBroadcasting = 1,
@@ -34,7 +34,7 @@ declare class ComRegister {
34
34
  qqRelatedBotList: Array<string>;
35
35
  logger: Logger;
36
36
  config: ComRegister.Config;
37
- loginTimer: Function;
37
+ loginTimer: () => void;
38
38
  num: number;
39
39
  rebootCount: number;
40
40
  subNotifier: Notifier;
@@ -42,8 +42,8 @@ declare class ComRegister {
42
42
  subManager: SubManager;
43
43
  loginDBData: FlatPick<LoginBili, "dynamic_group_id">;
44
44
  privateBot: Bot<Context>;
45
- dynamicDispose: Function;
46
- liveDispose: Function;
45
+ dynamicDispose: () => void;
46
+ liveDispose: () => void;
47
47
  sendMsgFunc: (bot: Bot<Context, any>, channelId: string, content: any) => Promise<void>;
48
48
  constructor(ctx: Context, config: ComRegister.Config);
49
49
  init(config: ComRegister.Config): Promise<void>;
@@ -111,7 +111,7 @@ declare namespace ComRegister {
111
111
  };
112
112
  unlockSubLimits: boolean;
113
113
  automaticResend: boolean;
114
- liveDetectMode: 'API' | 'WS';
114
+ liveDetectMode: "API" | "WS";
115
115
  restartPush: boolean;
116
116
  pushTime: number;
117
117
  liveLoopTime: number;