yz-yuki-plugin 2.0.5-8 → 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.
- package/CHANGELOG.md +6 -0
- package/defaultConfig/bilibili/config.yaml +6 -0
- package/lib/apps/bilibili.js +17 -14
- package/lib/index.js +1 -1
- package/lib/models/bilibili/bilibili.main.api.js +402 -0
- package/lib/models/bilibili/{bilibili.get.web.data.js → bilibili.main.get.web.data.js} +16 -8
- package/lib/models/bilibili/{bilibili.models.js → bilibili.main.models.js} +64 -238
- package/lib/models/bilibili/{bilibili.query.js → bilibili.main.query.js} +24 -23
- package/lib/models/bilibili/{bilibili.task.js → bilibili.main.task.js} +18 -11
- package/lib/models/bilibili/bilibili.risk.buid.fp.js +282 -0
- package/lib/models/bilibili/{bilibili.dm.img.js → bilibili.risk.dm.img.js} +4 -2
- package/lib/models/bilibili/{bilibili.ticket.js → bilibili.risk.ticket.js} +1 -1
- package/lib/models/bilibili/bilibili.risk.w_webid.js +43 -0
- package/lib/models/bilibili/bilibili.risk.wbi.js +102 -0
- package/lib/models/weibo/weibo.query.js +17 -19
- package/lib/models/weibo/weibo.task.js +12 -5
- package/package.json +12 -11
- package/lib/models/bilibili/bilibili.api.js +0 -77
- package/lib/models/bilibili/bilibili.buid.fp.js +0 -77
- package/lib/models/bilibili/bilibili.wbi.js +0 -61
|
@@ -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
|
|
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
|
|
65
|
-
throw new Error(`获取B站登录二维码失败: ${res.data
|
|
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
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
368
|
-
|
|
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
|
|
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
|
|
616
|
-
|
|
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
|
|
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') : ''}
|
|
392
|
-
Segment.image(desc?.cover)
|
|
391
|
+
`时间:${author ? moment(author.pub_ts * 1000).format('YYYY年MM月DD日 HH:mm:ss') : ''}`
|
|
393
392
|
];
|
|
394
|
-
|
|
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') : ''}
|
|
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') : ''}
|
|
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
|
-
|
|
528
|
-
|
|
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
|
|
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
|
-
...
|
|
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}
|
|
555
|
-
|
|
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;
|
|
@@ -22,7 +22,7 @@ class BiliTask {
|
|
|
22
22
|
const resjson = await resp.data;
|
|
23
23
|
if (!resjson || resjson.code !== 0 || resjson.code === -352) {
|
|
24
24
|
await postGateway(cookie);
|
|
25
|
-
if (count <
|
|
25
|
+
if (count < 2) {
|
|
26
26
|
await this.randomDelay(2000, 8000); // 随机延时2-8秒
|
|
27
27
|
await this.hendleEventDynamicData(uid, count + 1);
|
|
28
28
|
logger.error(`获取 ${uid} 动态,Gateway count:${String(count)}`);
|
|
@@ -78,11 +78,11 @@ class BiliTask {
|
|
|
78
78
|
dynamicList[subInfoOfup.uid] = dynamicData;
|
|
79
79
|
}
|
|
80
80
|
else if (resp.code === -352) {
|
|
81
|
-
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:-352
|
|
82
|
-
|
|
81
|
+
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:-352,请待下次任务自动重试`);
|
|
82
|
+
return;
|
|
83
83
|
}
|
|
84
84
|
else if (resp.code !== 0) {
|
|
85
|
-
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:${resp.code}
|
|
85
|
+
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:${resp.code},请待下次任务自动重试`);
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -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 *
|
|
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 *
|
|
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
|
}
|