yz-yuki-plugin 2.0.4-3 → 2.0.4-5

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/CHANGELOG.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # 2.0.4
2
+ * 优化B站风控相关,新增bili_tiket参数
2
3
  * fix Repeated Instantiation Puppeteer
3
4
  * 优化获取B站登录ck
4
5
  * 添加截图列队,优化配置文件注释
@@ -1,7 +1,7 @@
1
1
  import axios from 'axios';
2
2
  import lodash from 'lodash';
3
3
  import { BiliApi } from './bilibili.api.js';
4
- import { readSyncCookie, readSavedCookieItems, readSavedCookieOtherItems } from './bilibili.models.js';
4
+ import { readSyncCookie, cookieWithBiliTicket, readSavedCookieItems, readSavedCookieOtherItems } from './bilibili.models.js';
5
5
  import { getWbiSign } from './bilibili.wbi.js';
6
6
 
7
7
  class BiliGetWebData {
@@ -11,6 +11,7 @@ class BiliGetWebData {
11
11
  async getBiliDynamicListDataByUid(uid) {
12
12
  const url = BiliApi.BILIBIL_API.biliDynamicInfoList;
13
13
  let { cookie } = await readSyncCookie();
14
+ cookie = await cookieWithBiliTicket(cookie);
14
15
  const data = {
15
16
  offset: '',
16
17
  host_mid: uid,
@@ -40,6 +41,7 @@ class BiliGetWebData {
40
41
  async getBilibiUserInfoByUid(uid) {
41
42
  const url = BiliApi.BILIBIL_API.biliSpaceUserInfoWbi;
42
43
  let { cookie } = await readSyncCookie();
44
+ cookie = await cookieWithBiliTicket(cookie);
43
45
  const data = {
44
46
  mid: uid,
45
47
  jsonp: 'jsonp',
@@ -62,6 +64,7 @@ class BiliGetWebData {
62
64
  async searchBiliUserInfoByKeyword(keyword) {
63
65
  const url = BiliApi.BILIBIL_API.biliSearchUpWbi;
64
66
  let { cookie } = await readSyncCookie();
67
+ cookie = await cookieWithBiliTicket(cookie);
65
68
  const data = {
66
69
  keyword: keyword,
67
70
  page: 1,
@@ -55,3 +55,9 @@ export declare function postGateway(cookie: string): Promise<import("axios").Axi
55
55
  * @param {string} uuid
56
56
  */
57
57
  export declare function get_buvid_fp(cookie: string): Promise<string>;
58
+ /**
59
+ * 获取有效bili_ticket并添加到cookie
60
+ * @param {string} cookie
61
+ * @returns {Promise<{ cookie: string; }>} 返回包含最新有效的bili_ticket的cookie
62
+ */
63
+ export declare function cookieWithBiliTicket(cookie: string): Promise<string>;
@@ -10,6 +10,7 @@ import { Segment, Bot, Redis } from 'yunzai';
10
10
  import { renderPage } from '../../utils/image.js';
11
11
  import { _paths } from '../../utils/paths.js';
12
12
  import { BiliApi } from './bilibili.api.js';
13
+ import { getBiliTicket } from './bilibili.ticket.js';
13
14
 
14
15
  /**
15
16
  * *******************************************************************
@@ -362,11 +363,11 @@ async function getNewTempCk() {
362
363
  let newTempCk = `${uuid}${buvid3_buvid4}${b_lsid}`; //${buvid_fp}`;
363
364
  await saveTempCk(newTempCk);
364
365
  const result = await postGateway(newTempCk);
365
- const { code, data } = await result.data; // 解析校验结果
366
- if (code !== 0) {
367
- logger?.mark(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
366
+ const data = await result.data; // 解析校验结果
367
+ if (data?.code !== 0) {
368
+ logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
368
369
  }
369
- else if (code === 0) {
370
+ else if (data?.code === 0) {
370
371
  logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
371
372
  }
372
373
  }
@@ -526,19 +527,20 @@ async function getPayload(cookie) {
526
527
  * @returns 返回POST请求的结果
527
528
  */
528
529
  async function postGateway(cookie) {
529
- const payload = getPayload(cookie);
530
+ const data = { payload: await getPayload(cookie) };
530
531
  const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
531
- const headers = lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
532
- 'Cookie': cookie,
533
- 'Content-type': 'Application/json',
534
- 'Charset': 'UTF-8',
535
- }, {
536
- 'Host': 'api.bilibili.com',
537
- 'Origin': 'https://www.bilibili.com',
538
- 'Referer': 'https://www.bilibili.com/',
539
- });
532
+ const config = {
533
+ headers: lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
534
+ 'Cookie': cookie,
535
+ 'Content-type': 'application/json;charset=UTF-8',
536
+ }, {
537
+ 'Host': 'api.bilibili.com',
538
+ 'Origin': 'https://www.bilibili.com',
539
+ 'Referer': 'https://www.bilibili.com/',
540
+ })
541
+ };
540
542
  try {
541
- const res = await axios.post(requestUrl, { payload }, { headers });
543
+ const res = await axios.post(requestUrl, data, config);
542
544
  return res;
543
545
  }
544
546
  catch (error) {
@@ -546,5 +548,30 @@ async function postGateway(cookie) {
546
548
  throw error;
547
549
  }
548
550
  }
551
+ /**
552
+ * 获取有效bili_ticket并添加到cookie
553
+ * @param {string} cookie
554
+ * @returns {Promise<{ cookie: string; }>} 返回包含最新有效的bili_ticket的cookie
555
+ */
556
+ async function cookieWithBiliTicket(cookie) {
557
+ const BiliJctKey = "Yz:yuki:bili:bili_ticket";
558
+ cookie = await readSavedCookieItems(cookie, ['bili_ticket'], true);
559
+ const biliTicket = await Redis.get(BiliJctKey);
560
+ if (!biliTicket) {
561
+ try {
562
+ const csrf = await readSavedCookieItems(cookie, ['bili_jct'], false);
563
+ const { ticket, ttl } = await getBiliTicket(csrf);
564
+ await Redis.set(BiliJctKey, ticket, { EX: ttl });
565
+ return cookie + `;bili_ticket=${ticket};`;
566
+ }
567
+ catch (error) {
568
+ logger?.error(`${error}`);
569
+ return cookie;
570
+ }
571
+ }
572
+ else {
573
+ return cookie + `;bili_ticket=${biliTicket};`;
574
+ }
575
+ }
549
576
 
550
- export { applyLoginQRCode, checkBiliLogin, exitBiliLogin, genUUID, gen_b_lsid, getNewTempCk, pollLoginQRCode, postGateway, readSavedCookieItems, readSavedCookieOtherItems, readSyncCookie, readTempCk, saveLocalBiliCk, saveLoginCookie, saveTempCk };
577
+ export { applyLoginQRCode, checkBiliLogin, cookieWithBiliTicket, exitBiliLogin, genUUID, gen_b_lsid, getNewTempCk, pollLoginQRCode, postGateway, readSavedCookieItems, readSavedCookieOtherItems, readSyncCookie, readTempCk, saveLocalBiliCk, saveLoginCookie, saveTempCk };
@@ -1,6 +1,6 @@
1
1
  import moment from 'moment';
2
2
  import { Bot, Segment } from 'yunzai';
3
- import { readSyncCookie } from './bilibili.models.js';
3
+ import { readSyncCookie, cookieWithBiliTicket } from './bilibili.models.js';
4
4
  import { BiliApi } from './bilibili.api.js';
5
5
  import axios from 'axios';
6
6
  import lodash from 'lodash';
@@ -229,10 +229,11 @@ class BiliQuery {
229
229
  * @returns {Json} 完整的B站文章内容json数据
230
230
  */
231
231
  static async getFullArticleContent(postUrl) {
232
- const Cookie = await readSyncCookie();
232
+ let { cookie } = await readSyncCookie();
233
+ cookie = await cookieWithBiliTicket(cookie);
233
234
  try {
234
235
  const response = await axios.get(postUrl, {
235
- headers: lodash.merge(BiliApi.BILIBILI_ARTICLE_HEADERS, { "Cookie": `${Cookie}`, "Host": "www.bilibili.com" }),
236
+ headers: lodash.merge(BiliApi.BILIBILI_ARTICLE_HEADERS, { "Cookie": `${cookie}`, "Host": "www.bilibili.com" }),
236
237
  responseType: 'text'
237
238
  });
238
239
  const text = response.data;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Get Bilibili web ticket
3
+ * @param {string | null} csrf CSRF token, can be empty or null, or the cookie's bili_jct value
4
+ * @returns {Promise<{ code: number, ticket: string, created_at: number, ttl: number }>}
5
+ * Promise that resolves to an object containing code, ticket, created_at, and ttl values
6
+ */
7
+ export declare function getBiliTicket(csrf: string | null): Promise<{
8
+ code?: number;
9
+ ticket?: string;
10
+ created_at?: number;
11
+ ttl?: number;
12
+ }>;
@@ -0,0 +1,59 @@
1
+ import { createHmac } from 'crypto';
2
+ import { BiliApi } from './bilibili.api.js';
3
+
4
+ /**
5
+ * Generate HMAC-SHA256 signature
6
+ * @param {string} key The key string to use for the HMAC-SHA256 hash
7
+ * @param {string} message The message string to hash
8
+ * @returns {string} The HMAC-SHA256 signature as a hex string
9
+ */
10
+ function hmacSha256(key, message) {
11
+ return createHmac('sha256', key).update(message).digest('hex');
12
+ }
13
+ /**
14
+ * Get Bilibili web ticket
15
+ * @param {string | null} csrf CSRF token, can be empty or null, or the cookie's bili_jct value
16
+ * @returns {Promise<{ code: number, ticket: string, created_at: number, ttl: number }>}
17
+ * Promise that resolves to an object containing code, ticket, created_at, and ttl values
18
+ */
19
+ async function getBiliTicket(csrf) {
20
+ const ts = Math.floor(Date.now() / 1000);
21
+ const hexSign = hmacSha256('XgwSnGZ1p', `ts${ts}`);
22
+ const url = 'https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket';
23
+ const params = new URLSearchParams({
24
+ key_id: 'ec02',
25
+ hexsign: hexSign,
26
+ 'context[ts]': String(ts),
27
+ csrf: csrf ?? '' // 使用空字符串代替null
28
+ });
29
+ try {
30
+ const response = await fetch(`${url}?${params}`, {
31
+ method: 'POST',
32
+ headers: {
33
+ 'User-Agent': BiliApi.BILIBILI_HEADERS['User-Agent']
34
+ }
35
+ });
36
+ if (!response.ok) {
37
+ throw new Error(`get bili_jct HTTP error! status: ${response.status}`);
38
+ }
39
+ const data = await response.json();
40
+ if (data.code !== 0) {
41
+ if (data.code === 400) {
42
+ throw new Error(`get bili_jct Parameter error! ${data.message}`);
43
+ }
44
+ throw new Error(`Failed to retrieve bili ticket: ${data.message}`);
45
+ }
46
+ // 返回所需的对象结构
47
+ return {
48
+ code: data.code,
49
+ ticket: data.data?.ticket,
50
+ created_at: data.data?.created_at,
51
+ ttl: data.data?.ttl
52
+ };
53
+ }
54
+ catch (error) {
55
+ throw new Error(`Failed to fetch Bilibili ticket: ${error instanceof Error ? error.message : String(error)}`);
56
+ }
57
+ }
58
+
59
+ export { getBiliTicket };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yz-yuki-plugin",
3
- "version": "2.0.4-3",
3
+ "version": "2.0.4-5",
4
4
  "description": "优纪插件,yunzaijs 关于 微博推送、B站推送 等功能的拓展插件",
5
5
  "author": "snowtafir",
6
6
  "type": "module",