yz-yuki-plugin 2.0.5-9 → 2.0.6-0

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.
@@ -9,9 +9,9 @@ import YAML from 'yaml';
9
9
  import { Segment, Bot, Redis } from 'yunzaijs';
10
10
  import { renderPage } from '../../utils/image.js';
11
11
  import { _paths } from '../../utils/paths.js';
12
- import { BiliApi } from './bilibili.api.js';
13
- import { gen_buvid_fp } from './bilibili.buid.fp.js';
14
- import { getBiliTicket } from './bilibili.ticket.js';
12
+ import BiliApi from './bilibili.main.api.js';
13
+ import { gen_buvid_fp } from './bilibili.risk.buid.fp.js';
14
+ import { getBiliTicket } from './bilibili.risk.ticket.js';
15
15
 
16
16
  /**
17
17
  * *******************************************************************
@@ -61,8 +61,8 @@ async function applyLoginQRCode(e) {
61
61
  return qrcodeKey;
62
62
  }
63
63
  else {
64
- e.reply(`获取B站登录二维码失败: ${res.data?.message}`);
65
- throw new Error(`获取B站登录二维码失败: ${res.data?.message}`);
64
+ e.reply(`获取B站登录二维码失败: ${JSON.stringify(res.data)}`);
65
+ throw new Error(`获取B站登录二维码失败: ${JSON.stringify(res.data)}`);
66
66
  }
67
67
  }
68
68
  /**处理扫码结果 */
@@ -81,8 +81,17 @@ async function pollLoginQRCode(e, qrcodeKey) {
81
81
  if (data.data.code === 0) {
82
82
  // 登录成功,获取 cookie
83
83
  const LoginCookie = response.headers.get('set-cookie');
84
+ let loginCk = '';
85
+ try {
86
+ const nomalCk = await getNewTempCk();
87
+ loginCk = `${nomalCk}${LoginCookie}`;
88
+ }
89
+ catch (error) {
90
+ loginCk = LoginCookie;
91
+ logger.debug(`优纪插件: 获取B站登录ck缺失部分: ${error}`);
92
+ }
84
93
  e.reply(`~B站登陆成功~`);
85
- return LoginCookie;
94
+ return loginCk;
86
95
  }
87
96
  else if (data.data.code === 86101) {
88
97
  // 未扫码
@@ -115,26 +124,33 @@ async function pollLoginQRCode(e, qrcodeKey) {
115
124
  /**查看app扫码登陆获取的ck的有效状态*/
116
125
  async function checkBiliLogin(e) {
117
126
  const LoginCookie = await readLoginCookie();
118
- const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
119
- method: 'GET',
120
- headers: lodash.merge(BiliApi.BIlIBILI_LOGIN_HEADERS, { 'User-agent': BiliApi.BILIBILI_HEADERS['User-Agent'] }, { Cookie: `${LoginCookie}` }),
121
- redirect: 'follow'
122
- });
123
- const resData = await res.json();
124
- Bot.logger?.debug(`B站验证登录状态:${JSON.stringify(resData)}`);
125
- if (resData.code === 0) {
126
- let uname = resData.data?.uname;
127
- let mid = resData.data?.mid;
128
- let money = resData.data?.money;
129
- let level_info = resData.data?.level_info;
130
- let current_level = level_info?.current_level;
131
- let current_exp = level_info?.current_exp;
132
- let next_exp = level_info?.next_exp;
133
- e.reply(`~B站账号已登陆~\n昵称:${uname}\nuid:${mid}\n硬币:${money}\n经验等级:${current_level}\n当前经验值exp:${current_exp}\n下一等级所需exp:${next_exp}`);
127
+ if (String(LoginCookie).trim().length < 10) {
128
+ e.reply('啊咧?B站登录CK呢?哦,没 #扫码B站登录# 或失效了啊,那没事了。');
129
+ return;
134
130
  }
135
131
  else {
136
- // 处理其他情况
137
- return;
132
+ const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
133
+ method: 'GET',
134
+ headers: lodash.merge(BiliApi.BIlIBILI_LOGIN_HEADERS, { 'User-agent': BiliApi.BILIBILI_HEADERS['User-Agent'] }, { Cookie: `${LoginCookie}` }),
135
+ redirect: 'follow'
136
+ });
137
+ const resData = await res.json();
138
+ Bot?.logger?.debug(`B站验证登录状态:${JSON.stringify(resData)}`);
139
+ if (resData.code === 0) {
140
+ let uname = resData.data?.uname;
141
+ let mid = resData.data?.mid;
142
+ let money = resData.data?.money;
143
+ let level_info = resData.data?.level_info;
144
+ let current_level = level_info?.current_level;
145
+ let current_exp = level_info?.current_exp;
146
+ let next_exp = level_info?.next_exp;
147
+ e.reply(`~B站账号已登陆~\n昵称:${uname}\nuid:${mid}\n硬币:${money}\n经验等级:${current_level}\n当前经验值exp:${current_exp}\n下一等级所需exp:${next_exp}`);
148
+ }
149
+ else {
150
+ // 处理其他情况
151
+ e.reply('意外情况,未能成功获取登录ck的有效状态');
152
+ return;
153
+ }
138
154
  }
139
155
  }
140
156
  /**退出B站账号登录,将会删除redis缓存的LoginCK,并在服务器注销该登录 Token (SESSDATA)*/
@@ -245,7 +261,22 @@ async function saveLocalBiliCk(data) {
245
261
  async function readTempCk() {
246
262
  const CK_KEY = 'Yz:yuki:bili:tempCookie';
247
263
  const tempCk = await Redis.get(CK_KEY);
248
- return tempCk ?? '';
264
+ if (!tempCk) {
265
+ const newTempCk = await getNewTempCk();
266
+ await saveTempCk(newTempCk);
267
+ const result = await postGateway(newTempCk);
268
+ const data = await result.data; // 解析校验结果
269
+ if (data?.code !== 0) {
270
+ logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
271
+ }
272
+ else if (data?.code === 0) {
273
+ logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
274
+ }
275
+ return newTempCk;
276
+ }
277
+ else {
278
+ return tempCk;
279
+ }
249
280
  }
250
281
  /**保存tempCK*/
251
282
  async function saveTempCk(newTempCk) {
@@ -362,231 +393,26 @@ async function getBuvid3_4(uuid) {
362
393
  /**获取新的tempCK*/
363
394
  async function getNewTempCk() {
364
395
  const uuid = await genUUID();
396
+ const b_nut = `b_nut=${Date.now() / 1000};`;
365
397
  const buvid3_buvid4 = await getBuvid3_4(uuid);
366
398
  const b_lsid = await gen_b_lsid();
367
- //const buvid_fp = await get_buvid_fp(uuid);
368
- let newTempCk = `${uuid}${buvid3_buvid4}${b_lsid}`; //${buvid_fp}`;
369
- await saveTempCk(newTempCk);
370
- const result = await postGateway(newTempCk);
371
- const data = await result.data; // 解析校验结果
372
- if (data?.code !== 0) {
373
- logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
374
- }
375
- else if (data?.code === 0) {
376
- logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
377
- }
399
+ const buvid_fp = await get_buvid_fp(uuid);
400
+ return `${uuid}${buvid3_buvid4}${b_lsid}${buvid_fp}${b_nut}`;
378
401
  }
379
402
  /**
380
403
  * *******************************************************************
381
404
  * 风控相关函数
382
405
  * *******************************************************************
383
406
  */
384
- /**获取GatWay payload */
385
- async function getPayload(cookie) {
386
- const payloadOriginData = {
387
- '3064': 1, // ptype, mobile => 2, others => 1
388
- '5062': `${Date.now()}`, // timestamp
389
- '03bf': 'https://www.bilibili.com/', // url accessed
390
- '39c8': '333.999.fp.risk',
391
- '34f1': '', // target_url, default empty now
392
- 'd402': '', // screenx, default empty
393
- '654a': '', // screeny, default empty
394
- '6e7c': '878x1066', // browser_resolution, window.innerWidth || document.body && document.body.clientWidth + "x" + window.innerHeight || document.body && document.body.clientHeight
395
- '3c43': {
396
- // 3c43 => msg
397
- '2673': 0, // hasLiedResolution, window.screen.width < window.screen.availWidth || window.screen.height < window.screen.availHeight
398
- '5766': 24, // colorDepth, window.screen.colorDepth
399
- '6527': 0, // addBehavior, !!window.HTMLElement.prototype.addBehavior, html5 api
400
- '7003': 1, // indexedDb, !!window.indexedDB, html5 api
401
- '807e': 1, // cookieEnabled, navigator.cookieEnabled
402
- 'b8ce': BiliApi.BILIBILI_HEADERS['User-Agent'], // ua "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
403
- '641c': 0, // webdriver, navigator.webdriver, like Selenium
404
- '07a4': 'zh-CN', // language
405
- '1c57': 'not available', // deviceMemory in GB, navigator.deviceMemory
406
- '0bd0': 16, // hardwareConcurrency, navigator.hardwareConcurrency
407
- '748e': [1920, 1200], // window.screen.width window.screen.height
408
- 'd61f': [1920, 1152], // window.screen.availWidth window.screen.availHeight
409
- 'fc9d': -480, // timezoneOffset, (new Date).getTimezoneOffset()
410
- '6aa9': 'Asia/Shanghai', //Intl.DateTimeFormat().resolvedOptions().timeZone, // timezone, (new window.Intl.DateTimeFormat).resolvedOptions().timeZone
411
- '75b8': 1, // sessionStorage, window.sessionStorage, html5 api
412
- '3b21': 1, // localStorage, window.localStorage, html5 api
413
- '8a1c': 0, // openDatabase, window.openDatabase, html5 api
414
- 'd52f': 'not available', // cpuClass, navigator.cpuClass
415
- 'adca': BiliApi.BILIBILI_HEADERS['User-Agent'].includes('Windows') ? 'Win32' : 'Linux', // platform, navigator.platform
416
- '80c9': [
417
- [
418
- 'PDF Viewer',
419
- 'Portable Document Format',
420
- [
421
- ['application/pdf', 'pdf'],
422
- ['text/pdf', 'pdf']
423
- ]
424
- ],
425
- [
426
- 'Chrome PDF Viewer',
427
- 'Portable Document Format',
428
- [
429
- ['application/pdf', 'pdf'],
430
- ['text/pdf', 'pdf']
431
- ]
432
- ],
433
- [
434
- 'Chromium PDF Viewer',
435
- 'Portable Document Format',
436
- [
437
- ['application/pdf', 'pdf'],
438
- ['text/pdf', 'pdf']
439
- ]
440
- ],
441
- [
442
- 'Microsoft Edge PDF Viewer',
443
- 'Portable Document Format',
444
- [
445
- ['application/pdf', 'pdf'],
446
- ['text/pdf', 'pdf']
447
- ]
448
- ],
449
- [
450
- 'WebKit built-in PDF',
451
- 'Portable Document Format',
452
- [
453
- ['application/pdf', 'pdf'],
454
- ['text/pdf', 'pdf']
455
- ]
456
- ]
457
- ], // plugins
458
- '13ab': 'f3YAAAAASUVORK5CYII=', // canvas fingerprint
459
- 'bfe9': 'kABYpRAGAVYzWJooB9Bf4P+UortSvxRY0AAAAASUVORK5CYII=', // webgl_str
460
- 'a3c1': [
461
- 'extensions:ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_sRGB;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_provoking_vertex',
462
- 'webgl aliased line width range:[1, 1]',
463
- 'webgl aliased point size range:[1, 1024]',
464
- 'webgl alpha bits:8',
465
- 'webgl antialiasing:yes',
466
- 'webgl blue bits:8',
467
- 'webgl depth bits:24',
468
- 'webgl green bits:8',
469
- 'webgl max anisotropy:16',
470
- 'webgl max combined texture image units:32',
471
- 'webgl max cube map texture size:16384',
472
- 'webgl max fragment uniform vectors:1024',
473
- 'webgl max render buffer size:16384',
474
- 'webgl max texture image units:16',
475
- 'webgl max texture size:16384',
476
- 'webgl max varying vectors:30',
477
- 'webgl max vertex attribs:16',
478
- 'webgl max vertex texture image units:16',
479
- 'webgl max vertex uniform vectors:4096',
480
- 'webgl max viewport dims:[32767, 32767]',
481
- 'webgl red bits:8',
482
- 'webgl renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
483
- 'webgl shading language version:WebGL GLSL ES 1.0',
484
- 'webgl stencil bits:0',
485
- 'webgl vendor:Mozilla',
486
- 'webgl version:WebGL 1.0',
487
- 'webgl unmasked vendor:Google Inc. (Intel)',
488
- 'webgl unmasked renderer:ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar',
489
- 'webgl vertex shader high float precision:23',
490
- 'webgl vertex shader high float precision rangeMin:127',
491
- 'webgl vertex shader high float precision rangeMax:127',
492
- 'webgl vertex shader medium float precision:23',
493
- 'webgl vertex shader medium float precision rangeMin:127',
494
- 'webgl vertex shader medium float precision rangeMax:127',
495
- 'webgl vertex shader low float precision:23',
496
- 'webgl vertex shader low float precision rangeMin:127',
497
- 'webgl vertex shader low float precision rangeMax:127',
498
- 'webgl fragment shader high float precision:23',
499
- 'webgl fragment shader high float precision rangeMin:127',
500
- 'webgl fragment shader high float precision rangeMax:127',
501
- 'webgl fragment shader medium float precision:23',
502
- 'webgl fragment shader medium float precision rangeMin:127',
503
- 'webgl fragment shader medium float precision rangeMax:127',
504
- 'webgl fragment shader low float precision:23',
505
- 'webgl fragment shader low float precision rangeMin:127',
506
- 'webgl fragment shader low float precision rangeMax:127',
507
- 'webgl vertex shader high int precision:0',
508
- 'webgl vertex shader high int precision rangeMin:31',
509
- 'webgl vertex shader high int precision rangeMax:30',
510
- 'webgl vertex shader medium int precision:0',
511
- 'webgl vertex shader medium int precision rangeMin:31',
512
- 'webgl vertex shader medium int precision rangeMax:30',
513
- 'webgl vertex shader low int precision:0',
514
- 'webgl vertex shader low int precision rangeMin:31',
515
- 'webgl vertex shader low int precision rangeMax:30',
516
- 'webgl fragment shader high int precision:0',
517
- 'webgl fragment shader high int precision rangeMin:31',
518
- 'webgl fragment shader high int precision rangeMax:30',
519
- 'webgl fragment shader medium int precision:0',
520
- 'webgl fragment shader medium int precision rangeMin:31',
521
- 'webgl fragment shader medium int precision rangeMax:30',
522
- 'webgl fragment shader low int precision:0',
523
- 'webgl fragment shader low int precision rangeMin:31',
524
- 'webgl fragment shader low int precision rangeMax:30'
525
- ], // webgl_params, cab be set to [] if webgl is not supported
526
- '6bc5': 'Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics Direct3D11 vs_5_0 ps_5_0), or similar', // webglVendorAndRenderer
527
- 'ed31': 0,
528
- '72bd': 0,
529
- '097b': 0,
530
- '52cd': [0, 0, 0],
531
- 'a658': [
532
- 'Arial',
533
- 'Arial Black',
534
- 'Calibri',
535
- 'Cambria',
536
- 'Cambria Math',
537
- 'Comic Sans MS',
538
- 'Consolas',
539
- 'Courier',
540
- 'Courier New',
541
- 'Georgia',
542
- 'Helvetica',
543
- 'Impact',
544
- 'Lucida Console',
545
- 'Lucida Sans Unicode',
546
- 'Microsoft Sans Serif',
547
- 'MS Gothic',
548
- 'MS PGothic',
549
- 'MS Sans Serif',
550
- 'MS Serif',
551
- 'Palatino Linotype',
552
- 'Segoe Print',
553
- 'Segoe Script',
554
- 'Segoe UI',
555
- 'Segoe UI Light',
556
- 'Segoe UI Symbol',
557
- 'Tahoma',
558
- 'Times',
559
- 'Times New Roman',
560
- 'Trebuchet MS',
561
- 'Verdana',
562
- 'Wingdings'
563
- ],
564
- 'd02f': '35.749972093850374'
565
- },
566
- '54ef': {
567
- 'in_new_ab ': true,
568
- 'ab_version ': {
569
- 'waterfall_article ': 'SHOW '
570
- },
571
- 'ab_split_num ': {
572
- 'waterfall_article ': 0
573
- }
574
- },
575
- '8b94': '',
576
- 'df35': `${await readSavedCookieItems(cookie, ['_uuid'], false)}`, // _uuid, set from cookie, generated by client side(algorithm remains unknown)
577
- '07a4': 'zh-CN',
578
- '5f45': null,
579
- 'db46': 0
580
- };
581
- return JSON.stringify(payloadOriginData);
582
- }
583
407
  /**
584
408
  * 请求参数POST接口(ExClimbWuzhi)过校验
585
409
  * @param cookie 请求所需的cookie
586
410
  * @returns 返回POST请求的结果
587
411
  */
588
412
  async function postGateway(cookie) {
589
- const data = { payload: await getPayload(cookie) };
413
+ const _uuid = await readSavedCookieItems(cookie, ['_uuid'], false);
414
+ const payloadJsonData = await BiliApi.BILIBILI_BROWSER_DATA(_uuid);
415
+ const data = { payload: JSON.stringify(payloadJsonData) };
590
416
  const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
591
417
  const config = {
592
418
  headers: lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
@@ -612,8 +438,8 @@ async function postGateway(cookie) {
612
438
  */
613
439
  async function get_buvid_fp(cookie) {
614
440
  const uuid = await readSavedCookieItems(cookie, ['_uuid'], false);
615
- const seedget = Math.floor(Math.random() * (60 - 1 + 1) + 1);
616
- let buvidFp = gen_buvid_fp(uuid, seedget);
441
+ const fingerprintData = BiliApi.BILIBILI_FINGERPRINT_DATA(uuid);
442
+ const buvidFp = gen_buvid_fp(fingerprintData);
617
443
  return `buvid_fp=${buvidFp};`;
618
444
  }
619
445
  /**
@@ -1,7 +1,7 @@
1
1
  import moment from 'moment';
2
2
  import { Bot, Segment } from 'yunzaijs';
3
- import { readSyncCookie, cookieWithBiliTicket } from './bilibili.models.js';
4
- import { BiliApi } from './bilibili.api.js';
3
+ import { readSyncCookie, cookieWithBiliTicket } from './bilibili.main.models.js';
4
+ import BiliApi from './bilibili.main.api.js';
5
5
  import axios from 'axios';
6
6
  import lodash from 'lodash';
7
7
 
@@ -26,7 +26,7 @@ class BiliQuery {
26
26
  desc = data?.modules?.module_dynamic?.major?.archive || {};
27
27
  formatData.data.title = desc?.title;
28
28
  formatData.data.content = this.parseRichTextNodes(desc?.desc);
29
- formatData.data.url = this.formatUrl(desc?.jump_url);
29
+ formatData.data.url = this.formatUrl(desc?.jump_url) || '';
30
30
  formatData.data.pubTime = author.pub_time;
31
31
  formatData.data.pubTs = moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss');
32
32
  formatData.data.category = '视频动态';
@@ -146,7 +146,7 @@ class BiliQuery {
146
146
  formatData.data.pics = pics;
147
147
  formatData.data.content = '';
148
148
  }
149
- formatData.data.url = this.formatUrl(desc?.jump_url);
149
+ formatData.data.url = this.formatUrl(desc?.jump_url) || '';
150
150
  formatData.data.pubTime = author.pub_time;
151
151
  formatData.data.pubTs = moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss');
152
152
  formatData.data.category = '文章动态';
@@ -272,7 +272,7 @@ class BiliQuery {
272
272
  }
273
273
  catch (err) {
274
274
  logger?.error(`优纪插件:获取B站完整文章内容失败 [ ${postUrl} ] : ${err}`);
275
- return null;
275
+ return { readInfo: null, articleType: null };
276
276
  }
277
277
  }
278
278
  /**解析旧版完整文章内容 */
@@ -372,7 +372,7 @@ class BiliQuery {
372
372
  */
373
373
  static async formatTextDynamicData(upName, data, isForward, setData) {
374
374
  const BiliDrawDynamicLinkUrl = 'https://m.bilibili.com/dynamic/';
375
- let desc, msg, pics, author, majorType, content, dynamicTitle;
375
+ let desc, msg = [], pics = [], author, majorType, content, dynamicTitle;
376
376
  let title = `B站【${upName}】动态推送:\n`;
377
377
  switch (data.type) {
378
378
  case 'DYNAMIC_TYPE_AV':
@@ -388,10 +388,10 @@ class BiliQuery {
388
388
  `标题:${desc.title}\n`,
389
389
  `${desc.desc}\n`,
390
390
  `链接:${this.formatUrl(desc.jump_url)}\n`,
391
- `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}\n`,
392
- Segment.image(desc?.cover)
391
+ `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
393
392
  ];
394
- return msg;
393
+ pics = [Segment.image(desc?.cover)];
394
+ return { msg, pics };
395
395
  case 'DYNAMIC_TYPE_WORD':
396
396
  // 处理文字动态
397
397
  author = data?.modules?.module_author;
@@ -421,7 +421,7 @@ class BiliQuery {
421
421
  `链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
422
422
  `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
423
423
  ];
424
- return msg;
424
+ return { msg, pics };
425
425
  case 'DYNAMIC_TYPE_DRAW':
426
426
  // 处理图文动态
427
427
  author = data?.modules?.module_author;
@@ -465,10 +465,9 @@ class BiliQuery {
465
465
  `-----------------------------\n`,
466
466
  `${this.dynamicContentLimit(content, setData)}\n`,
467
467
  `链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
468
- `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}\n`,
469
- ...pics
468
+ `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
470
469
  ];
471
- return msg;
470
+ return { msg, pics };
472
471
  case 'DYNAMIC_TYPE_ARTICLE':
473
472
  // 处理文章动态
474
473
  author = data?.modules?.module_author;
@@ -509,10 +508,9 @@ class BiliQuery {
509
508
  `-----------------------------\n`,
510
509
  `标题:${dynamicTitle}\n`,
511
510
  `链接:${this.formatUrl(desc.jump_url)}\n`,
512
- `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}\n`,
513
- ...pics
511
+ `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
514
512
  ];
515
- return msg;
513
+ return { msg, pics };
516
514
  case 'DYNAMIC_TYPE_FORWARD':
517
515
  // 处理转发动态
518
516
  author = data?.modules?.module_author;
@@ -524,11 +522,13 @@ class BiliQuery {
524
522
  return;
525
523
  isForward = true;
526
524
  let orig = await this.formatTextDynamicData(upName, data.orig, isForward, setData);
527
- if (orig && orig.length) {
528
- orig = orig.slice(2);
525
+ let origContent = [];
526
+ if (orig && typeof orig === 'object') {
527
+ origContent = orig.msg.slice(2);
528
+ pics = orig.pics;
529
529
  }
530
530
  else {
531
- return false;
531
+ return 'continue';
532
532
  }
533
533
  title = `B站【${upName}】转发动态推送:\n`;
534
534
  msg = [
@@ -538,9 +538,9 @@ class BiliQuery {
538
538
  `链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
539
539
  `时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}\n`,
540
540
  '\n---以下为转发内容---\n',
541
- ...orig
541
+ ...origContent
542
542
  ];
543
- return msg;
543
+ return { msg, pics };
544
544
  case 'DYNAMIC_TYPE_LIVE_RCMD':
545
545
  // 处理直播动态
546
546
  desc = data?.modules?.module_dynamic?.major?.live_rcmd?.content;
@@ -551,8 +551,9 @@ class BiliQuery {
551
551
  if (!desc)
552
552
  return;
553
553
  title = `B站【${upName}】直播动态推送:\n`;
554
- msg = [title, `-----------------------------\n`, `标题:${desc.title}\n`, `链接:https:${desc.link}\n`, Segment.image(desc.cover)];
555
- return msg;
554
+ msg = [title, `-----------------------------\n`, `标题:${desc.title}\n`, `链接:https:${desc.link}`];
555
+ pics = [Segment.image(desc.cover)];
556
+ return { msg, pics };
556
557
  default:
557
558
  // 处理未定义的动态类型
558
559
  (Bot.logger ?? logger)?.mark(`未处理的B站推送【${upName}】:${data.type}`);
@@ -2,9 +2,9 @@ import QRCode from 'qrcode';
2
2
  import { Redis, Bot, Segment } from 'yunzaijs';
3
3
  import Config from '../../utils/config.js';
4
4
  import { renderPage } from '../../utils/image.js';
5
- import { BiliGetWebData } from './bilibili.get.web.data.js';
6
- import { readSyncCookie, postGateway } from './bilibili.models.js';
7
- import { BiliQuery } from './bilibili.query.js';
5
+ import { BiliGetWebData } from './bilibili.main.get.web.data.js';
6
+ import { readSyncCookie, postGateway } from './bilibili.main.models.js';
7
+ import { BiliQuery } from './bilibili.main.query.js';
8
8
 
9
9
  class BiliTask {
10
10
  taskName;
@@ -191,7 +191,7 @@ class BiliTask {
191
191
  let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
192
192
  if (!imgs)
193
193
  return;
194
- Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 10 }); // 设置已发送标记
194
+ Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 72 }); // 设置已发送标记
195
195
  (logger ?? Bot.logger)?.mark('优纪插件:B站动态执行推送');
196
196
  for (let i = 0; i < imgs.length; i++) {
197
197
  const image = imgs[i];
@@ -202,17 +202,24 @@ class BiliTask {
202
202
  }
203
203
  else {
204
204
  const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData); // 构建图文动态消息
205
- Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 10 }); // 设置已发送标记
205
+ Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 72 }); // 设置已发送标记
206
206
  if (dynamicMsg == 'continue') {
207
207
  return 'return'; // 如果动态消息构建失败,则直接返回
208
208
  }
209
209
  if (biliConfigData.banWords.length > 0) {
210
210
  const banWords = new RegExp(biliConfigData.banWords.join('|'), 'g'); // 构建屏蔽关键字正则表达式
211
- if (banWords.test(dynamicMsg.join(''))) {
211
+ if (banWords.test(dynamicMsg.msg.join(''))) {
212
212
  return 'return'; // 如果动态消息包含屏蔽关键字,则直接返回
213
213
  }
214
214
  }
215
- await this.sendMessage(chatId, bot_id, chatType, dynamicMsg);
215
+ await this.sendMessage(chatId, bot_id, chatType, dynamicMsg.msg);
216
+ const pics = dynamicMsg.pics;
217
+ if (pics && pics.length > 0) {
218
+ for (let i = 0; i < pics.length; i++) {
219
+ await this.sendMessage(chatId, bot_id, chatType, pics[i]);
220
+ await this.randomDelay(1000, 2000); // 随机延时1-2秒
221
+ }
222
+ }
216
223
  await new Promise(resolve => setTimeout(resolve, 1000));
217
224
  }
218
225
  }