yz-yuki-plugin 2.0.1 → 2.0.2-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/CHANGELOG.md +4 -0
- package/README.md +8 -7
- package/lib/apps/bilibili.js +52 -20
- package/lib/apps/help.js +3 -0
- package/lib/apps/version.js +3 -0
- package/lib/apps/weibo.js +34 -16
- package/lib/components/dynamic/Account.js +2 -0
- package/lib/components/dynamic/Content.js +2 -0
- package/lib/components/dynamic/Footer.js +1 -0
- package/lib/components/dynamic/ForwardContent.js +2 -0
- package/lib/components/dynamic/LogoText.js +2 -0
- package/lib/components/dynamic/MainPage.js +1 -0
- package/lib/components/help/Help.js +1 -0
- package/lib/components/loginQrcode/Page.js +1 -0
- package/lib/index.js +53 -2
- package/lib/models/bilibili/bilibili.api.d.ts +3 -0
- package/lib/models/bilibili/bilibili.api.js +9 -0
- package/lib/models/bilibili/bilibili.get.web.data.d.ts +3 -0
- package/lib/models/bilibili/bilibili.get.web.data.js +4 -0
- package/lib/models/bilibili/bilibili.models.d.ts +37 -0
- package/lib/models/bilibili/bilibili.models.js +71 -19
- package/lib/models/bilibili/bilibili.query.d.ts +24 -0
- package/lib/models/bilibili/bilibili.query.js +69 -11
- package/lib/models/bilibili/bilibili.task.d.ts +41 -0
- package/lib/models/bilibili/bilibili.task.js +77 -34
- package/lib/models/bilibili/bilibili.wbi.d.ts +6 -0
- package/lib/models/bilibili/bilibili.wbi.js +16 -3
- package/lib/models/version/version.d.ts +10 -0
- package/lib/models/version/version.js +12 -1
- package/lib/models/weibo/weibo.api.d.ts +1 -0
- package/lib/models/weibo/weibo.api.js +2 -0
- package/lib/models/weibo/weibo.get.web.data.d.ts +3 -0
- package/lib/models/weibo/weibo.get.web.data.js +3 -0
- package/lib/models/weibo/weibo.query.d.ts +20 -0
- package/lib/models/weibo/weibo.query.js +63 -6
- package/lib/models/weibo/weibo.task.d.ts +49 -0
- package/lib/models/weibo/weibo.task.js +84 -34
- package/lib/utils/config.d.ts +50 -0
- package/lib/utils/config.js +55 -2
- package/lib/utils/image.d.ts +11 -0
- package/lib/utils/image.js +15 -0
- package/lib/utils/paths.js +7 -7
- package/lib/utils/puppeteer.render.d.ts +15 -0
- package/lib/utils/puppeteer.render.js +37 -15
- package/package.json +6 -5
package/lib/index.js
CHANGED
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { applicationOptions, useEvent } from 'yunzai';
|
|
2
|
+
import { applicationOptions, setBotTask, useEvent } from 'yunzai';
|
|
3
3
|
import Config from './utils/config.js';
|
|
4
4
|
import * as index$1 from './apps/index.js';
|
|
5
|
+
import { BiliTask } from './models/bilibili/bilibili.task.js';
|
|
6
|
+
import { WeiboTask } from './models/weibo/weibo.task.js';
|
|
5
7
|
|
|
8
|
+
let biliConfigData = Config.getConfigData("config", "bilibili", "config");
|
|
9
|
+
let weiboConfigData = Config.getConfigData("config", "weibo", "config");
|
|
10
|
+
/** B站动态任务 函数 */
|
|
11
|
+
async function biliNewPushTask(e) {
|
|
12
|
+
await new BiliTask(e).runTask();
|
|
13
|
+
}
|
|
14
|
+
/** 微博动态任务 函数 */
|
|
15
|
+
async function weiboNewPushTask(e) {
|
|
16
|
+
await new WeiboTask(e).runTask();
|
|
17
|
+
}
|
|
6
18
|
var index = () => {
|
|
19
|
+
// 预先存储
|
|
7
20
|
const rules = [];
|
|
21
|
+
// options
|
|
8
22
|
return applicationOptions({
|
|
9
23
|
create() {
|
|
24
|
+
// created
|
|
10
25
|
for (const key in index$1) {
|
|
26
|
+
// 推类型
|
|
11
27
|
const app = new index$1[key]();
|
|
28
|
+
// 用 reg 和 key 连接起来。
|
|
29
|
+
// 也可以进行自由排序
|
|
12
30
|
for (const rule of app.rule) {
|
|
13
31
|
rules.push({
|
|
14
32
|
reg: rule.reg,
|
|
@@ -23,12 +41,42 @@ var index = () => {
|
|
|
23
41
|
logger.info(chalk.rgb(255, 245, 255)(`https://github.com/snowtafir/yuki-plugin`));
|
|
24
42
|
logger.info(chalk.rgb(0, 190, 255)(`-----------------------------------------`));
|
|
25
43
|
logger.info(chalk.rgb(0, 190, 255)(`★ 优纪插件加载完成了喵~`));
|
|
44
|
+
/** B站动态推送定时任务 */
|
|
45
|
+
setBotTask(async (Bot) => {
|
|
46
|
+
try {
|
|
47
|
+
biliNewPushTask();
|
|
48
|
+
if (biliConfigData.pushTaskLog) {
|
|
49
|
+
Bot.logger.mark("yuki插件---B站动态推送定时任务");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.error('B站动态推送定时任务', err);
|
|
54
|
+
}
|
|
55
|
+
}, biliConfigData.pushStatus ? biliConfigData.pushTime : "");
|
|
56
|
+
/** 微博动态推送定时任务 */
|
|
57
|
+
setBotTask(async (Bot) => {
|
|
58
|
+
try {
|
|
59
|
+
await weiboNewPushTask();
|
|
60
|
+
if (weiboConfigData.pushTaskLog) {
|
|
61
|
+
Bot.logger.mark("yuki插件---微博动态推送定时任务");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error('微博动态推送定时任务', err);
|
|
66
|
+
}
|
|
67
|
+
}, weiboConfigData.pushStatus ? weiboConfigData.pushTime : "");
|
|
26
68
|
},
|
|
27
69
|
async mounted(e) {
|
|
70
|
+
// 存储
|
|
28
71
|
const data = [];
|
|
72
|
+
// 如果key不存在
|
|
29
73
|
const cache = {};
|
|
74
|
+
// 使用event以确保得到正常类型
|
|
30
75
|
await useEvent(e => {
|
|
31
76
|
for (const item of rules) {
|
|
77
|
+
// 匹配正则
|
|
78
|
+
// 存在key
|
|
79
|
+
// 第一次new
|
|
32
80
|
if (new RegExp(item.reg).test(e.msg) &&
|
|
33
81
|
index$1[item.key] &&
|
|
34
82
|
!cache[item.key]) {
|
|
@@ -36,7 +84,10 @@ var index = () => {
|
|
|
36
84
|
data.push(new index$1[item.key]());
|
|
37
85
|
}
|
|
38
86
|
}
|
|
39
|
-
},
|
|
87
|
+
},
|
|
88
|
+
// 推倒为message类型的event
|
|
89
|
+
[e, 'message']);
|
|
90
|
+
// back
|
|
40
91
|
return data;
|
|
41
92
|
}
|
|
42
93
|
});
|
|
@@ -12,6 +12,7 @@ export declare class BiliApi {
|
|
|
12
12
|
biliLiveUserInfo: string;
|
|
13
13
|
biliOpusDetail: string;
|
|
14
14
|
};
|
|
15
|
+
/**header */
|
|
15
16
|
static BILIBILI_HEADERS: {
|
|
16
17
|
Accept: string;
|
|
17
18
|
'Accept-Language': string;
|
|
@@ -32,6 +33,7 @@ export declare class BiliApi {
|
|
|
32
33
|
"Upgrade-Insecure-Requests": string;
|
|
33
34
|
'User-Agent': string;
|
|
34
35
|
};
|
|
36
|
+
/**Login header */
|
|
35
37
|
static BIlIBILI_LOGIN_HEADERS: {
|
|
36
38
|
Accept: string;
|
|
37
39
|
'Accept-Language': string;
|
|
@@ -45,6 +47,7 @@ export declare class BiliApi {
|
|
|
45
47
|
'Sec-Fetch-User': string;
|
|
46
48
|
TE: string;
|
|
47
49
|
};
|
|
50
|
+
/**FullArticle header */
|
|
48
51
|
static BILIBILI_ARTICLE_HEADERS: {
|
|
49
52
|
Accept: string;
|
|
50
53
|
'Accept-Language': string;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
class BiliApi {
|
|
2
2
|
static BILIBIL_API = {
|
|
3
|
+
//获取动态资源列表 wbi/无wbi parama = { host_mid: uid, timezone_offset: -480, platform: 'web', features: 'itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote', web_location: "333.999", ...getDmImg(), "x-bili-device-req-json": { "platform": "web", "device": "pc" }, "x-bili-web-req-json": { "spm_id": "333.999" }, w_rid, wts }
|
|
3
4
|
biliDynamicInfoList: `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space`,
|
|
5
|
+
//获取关注数与粉丝数 parama = { vmid: uid }
|
|
4
6
|
biliUpFollowFans: `https://api.bilibili.com/x/relation/stat`,
|
|
7
|
+
//通过uid获取up详情 parama = { mid: uid, jsonp: jsonp }
|
|
5
8
|
biliSpaceUserInfo: `https://api.bilibili.com/x/space/acc/info`,
|
|
9
|
+
//parama = { mid: uid, jsonp: jsonp }
|
|
6
10
|
biliSpaceUserInfoWbi: `https://api.bilibili.com/x/space/wbi/acc/info`,
|
|
11
|
+
//通过关键词${upKeyword}搜索up主 parama = { keyword: 'upKeyword', page: 1, search_type: 'bili_user', order: 'totalrank', pagesize: 5 }
|
|
7
12
|
biliSearchUp: `https://api.bilibili.com/x/web-interface/search/type`,
|
|
13
|
+
//通过关键词${upKeyword}搜索up主 parama = { keyword: 'upKeyword', page: 1, search_type: 'bili_user', order: 'totalrank' },需要wbi签名
|
|
8
14
|
biliSearchUpWbi: `https://api.bilibili.com/x/web-interface/wbi/search/type`,
|
|
9
15
|
biliLiveStatus: 'https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids',
|
|
10
16
|
biliCard: "https://api.bilibili.com/x/web-interface/card",
|
|
@@ -12,6 +18,7 @@ class BiliApi {
|
|
|
12
18
|
biliLiveUserInfo: "https://api.live.bilibili.com/live_user/v1/Master/info",
|
|
13
19
|
biliOpusDetail: "https://api.bilibili.com/x/polymer/web-dynamic/v1/opus/detail",
|
|
14
20
|
};
|
|
21
|
+
/**header */
|
|
15
22
|
static BILIBILI_HEADERS = {
|
|
16
23
|
'Accept': '*/*',
|
|
17
24
|
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
|
|
@@ -32,6 +39,7 @@ class BiliApi {
|
|
|
32
39
|
"Upgrade-Insecure-Requests": '1',
|
|
33
40
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
|
34
41
|
};
|
|
42
|
+
/**Login header */
|
|
35
43
|
static BIlIBILI_LOGIN_HEADERS = {
|
|
36
44
|
'Accept': '*/*',
|
|
37
45
|
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
|
|
@@ -45,6 +53,7 @@ class BiliApi {
|
|
|
45
53
|
'Sec-Fetch-User': '?1',
|
|
46
54
|
'TE': 'trailers',
|
|
47
55
|
};
|
|
56
|
+
/**FullArticle header */
|
|
48
57
|
static BILIBILI_ARTICLE_HEADERS = {
|
|
49
58
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8',
|
|
50
59
|
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare class BiliGetWebData {
|
|
2
2
|
constructor(e?: any);
|
|
3
|
+
/**通过uid获取up动态数据表*/
|
|
3
4
|
getBiliDynamicListDataByUid(uid: any): Promise<import("axios").AxiosResponse<any, any>>;
|
|
5
|
+
/**通过uid获取up详情*/
|
|
4
6
|
getBilibiUserInfoByUid(uid: any): Promise<import("axios").AxiosResponse<any, any>>;
|
|
7
|
+
/**通过关键词搜索up*/
|
|
5
8
|
searchBiliUserInfoByKeyword(keyword: string): Promise<import("axios").AxiosResponse<any, any>>;
|
|
6
9
|
}
|
|
@@ -7,6 +7,7 @@ import { getWbiSign } from './bilibili.wbi.js';
|
|
|
7
7
|
class BiliGetWebData {
|
|
8
8
|
constructor(e) {
|
|
9
9
|
}
|
|
10
|
+
/**通过uid获取up动态数据表*/
|
|
10
11
|
async getBiliDynamicListDataByUid(uid) {
|
|
11
12
|
const url = BiliApi.BILIBIL_API.biliDynamicInfoList;
|
|
12
13
|
let { cookie } = await readSyncCookie();
|
|
@@ -17,6 +18,7 @@ class BiliGetWebData {
|
|
|
17
18
|
platform: 'web',
|
|
18
19
|
features: "itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote",
|
|
19
20
|
web_location: "333.999",
|
|
21
|
+
//...getDmImg(),
|
|
20
22
|
"x-bili-device-req-json": { "platform": "web", "device": "pc" },
|
|
21
23
|
"x-bili-web-req-json": { "spm_id": "333.999" }
|
|
22
24
|
};
|
|
@@ -34,6 +36,7 @@ class BiliGetWebData {
|
|
|
34
36
|
});
|
|
35
37
|
return res;
|
|
36
38
|
}
|
|
39
|
+
/**通过uid获取up详情*/
|
|
37
40
|
async getBilibiUserInfoByUid(uid) {
|
|
38
41
|
const url = BiliApi.BILIBIL_API.biliSpaceUserInfoWbi;
|
|
39
42
|
let { cookie } = await readSyncCookie();
|
|
@@ -55,6 +58,7 @@ class BiliGetWebData {
|
|
|
55
58
|
});
|
|
56
59
|
return res;
|
|
57
60
|
}
|
|
61
|
+
/**通过关键词搜索up*/
|
|
58
62
|
async searchBiliUserInfoByKeyword(keyword) {
|
|
59
63
|
const url = BiliApi.BILIBIL_API.biliSearchUpWbi;
|
|
60
64
|
let { cookie } = await readSyncCookie();
|
|
@@ -1,20 +1,57 @@
|
|
|
1
1
|
import { EventType } from 'yunzai';
|
|
2
|
+
/**
|
|
3
|
+
* *******************************************************************
|
|
4
|
+
* Login 相关
|
|
5
|
+
* *******************************************************************
|
|
6
|
+
*/
|
|
7
|
+
/**申请登陆二维码(web端) */
|
|
2
8
|
export declare function applyLoginQRCode(e: EventType): Promise<any>;
|
|
9
|
+
/**处理扫码结果 */
|
|
3
10
|
export declare function pollLoginQRCode(e: EventType, qrcodeKey: string): Promise<string>;
|
|
11
|
+
/**查看app扫码登陆获取的ck的有效状态*/
|
|
4
12
|
export declare function checkBiliLogin(e: EventType): Promise<void>;
|
|
13
|
+
/**退出B站账号登录,将会删除redis缓存的LoginCK,并在服务器注销该登录 Token (SESSDATA)*/
|
|
5
14
|
export declare function exitBiliLogin(e: EventType): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* *******************************************************************
|
|
17
|
+
* cookie相关
|
|
18
|
+
* *******************************************************************
|
|
19
|
+
*/
|
|
20
|
+
/**保存扫码登录的loginCK*/
|
|
6
21
|
export declare function saveLoginCookie(e: EventType, biliLoginCk: string): Promise<void>;
|
|
22
|
+
/** 覆盖保存手动获取绑定的B站ck */
|
|
7
23
|
export declare function saveLocalBiliCk(data: any): Promise<void>;
|
|
24
|
+
/** 读取缓存的tempCK */
|
|
8
25
|
export declare function readTempCk(): Promise<string>;
|
|
26
|
+
/**保存tempCK*/
|
|
9
27
|
export declare function saveTempCk(newTempCk: any): Promise<void>;
|
|
28
|
+
/** 综合获取ck,返回优先级:localCK > loginCK > tempCK */
|
|
10
29
|
export declare function readSyncCookie(): Promise<{
|
|
11
30
|
cookie: any;
|
|
12
31
|
mark: string;
|
|
13
32
|
}>;
|
|
33
|
+
/**
|
|
34
|
+
* 综合读取、筛选 传入的或本地或redis存储的cookie的item
|
|
35
|
+
* @param {string} mark 读取存储的CK类型,'localCK' 'tempCK' 'loginCK' 或传入值 'xxx'并进行筛选
|
|
36
|
+
* @param {Array} items 选取获取CK的项 选全部值:items[0] = 'all' ,或选取其中的值 ['buvid3', 'buvid4', '_uuid', 'SESSDATA', 'DedeUserID', 'DedeUserID__ckMd5', 'bili_jct', 'b_nut', 'b_lsid']
|
|
37
|
+
* @param {boolean} isInverted 控制正取和反取,true为反取,false为正取
|
|
38
|
+
* @returns {string}
|
|
39
|
+
**/
|
|
14
40
|
export declare function readSavedCookieItems(mark: string, items: Array<string>, isInverted?: boolean): Promise<string>;
|
|
15
41
|
export declare function readSavedCookieOtherItems(mark: string, items: Array<string>): Promise<string>;
|
|
42
|
+
/** 生成 _uuid */
|
|
16
43
|
export declare function genUUID(): Promise<string>;
|
|
44
|
+
/**生成 b_lsid */
|
|
17
45
|
export declare function gen_b_lsid(): Promise<string>;
|
|
46
|
+
/**获取新的tempCK*/
|
|
18
47
|
export declare function getNewTempCk(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* 请求参数POST接口(ExClimbWuzhi)过校验
|
|
50
|
+
* @param cookie 请求所需的cookie
|
|
51
|
+
* @returns 返回POST请求的结果
|
|
52
|
+
*/
|
|
19
53
|
export declare function postGateway(cookie: string): Promise<import("axios").AxiosResponse<any, any>>;
|
|
54
|
+
/**生成buvid_fp
|
|
55
|
+
* @param {string} uuid
|
|
56
|
+
*/
|
|
20
57
|
export declare function get_buvid_fp(cookie: string): Promise<string>;
|
|
@@ -11,6 +11,12 @@ import Image from '../../utils/image.js';
|
|
|
11
11
|
import { _paths } from '../../utils/paths.js';
|
|
12
12
|
import { BiliApi } from './bilibili.api.js';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* *******************************************************************
|
|
16
|
+
* Login 相关
|
|
17
|
+
* *******************************************************************
|
|
18
|
+
*/
|
|
19
|
+
/**申请登陆二维码(web端) */
|
|
14
20
|
async function applyLoginQRCode(e) {
|
|
15
21
|
const url = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header';
|
|
16
22
|
const response = await fetch(url, {
|
|
@@ -49,6 +55,7 @@ async function applyLoginQRCode(e) {
|
|
|
49
55
|
throw new Error(`获取B站登录二维码失败: ${res.data.message}`);
|
|
50
56
|
}
|
|
51
57
|
}
|
|
58
|
+
/**处理扫码结果 */
|
|
52
59
|
async function pollLoginQRCode(e, qrcodeKey) {
|
|
53
60
|
const url = `https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=${qrcodeKey}&source=main-fe-header`;
|
|
54
61
|
const response = await fetch(url, {
|
|
@@ -59,20 +66,26 @@ async function pollLoginQRCode(e, qrcodeKey) {
|
|
|
59
66
|
const data = await response.json();
|
|
60
67
|
if (data.code === 0) {
|
|
61
68
|
if (data.data.code === 0) {
|
|
69
|
+
// 登录成功,获取 cookie
|
|
62
70
|
const LoginCookie = response.headers.get('set-cookie');
|
|
63
71
|
e.reply(`~B站登陆成功~`);
|
|
64
72
|
return LoginCookie;
|
|
65
73
|
}
|
|
66
74
|
else if (data.data.code === 86101) {
|
|
75
|
+
// 未扫码
|
|
76
|
+
// 继续轮询
|
|
67
77
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
68
78
|
(logger ?? Bot.logger)?.mark(`优纪插件:扫码B站登录:未扫码,轮询中...`);
|
|
69
79
|
return pollLoginQRCode(e, qrcodeKey);
|
|
70
80
|
}
|
|
71
81
|
else if (data.data.code === 86090) {
|
|
82
|
+
// 已扫码未确认
|
|
83
|
+
// 继续轮询
|
|
72
84
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
73
85
|
return pollLoginQRCode(e, qrcodeKey);
|
|
74
86
|
}
|
|
75
87
|
else if (data.data.code === 86038) {
|
|
88
|
+
// 二维码已失效
|
|
76
89
|
e.reply('B站登陆二维码已失效');
|
|
77
90
|
return null;
|
|
78
91
|
}
|
|
@@ -86,6 +99,7 @@ async function pollLoginQRCode(e, qrcodeKey) {
|
|
|
86
99
|
throw new Error(`处理扫码结果出错: ${data?.message}`);
|
|
87
100
|
}
|
|
88
101
|
}
|
|
102
|
+
/**查看app扫码登陆获取的ck的有效状态*/
|
|
89
103
|
async function checkBiliLogin(e) {
|
|
90
104
|
const LoginCookie = await readLoginCookie();
|
|
91
105
|
const res = await fetch("https://api.bilibili.com/x/web-interface/nav", {
|
|
@@ -106,9 +120,11 @@ async function checkBiliLogin(e) {
|
|
|
106
120
|
e.reply(`~B站账号已登陆~\n昵称:${uname}\nuid:${mid}\n硬币:${money}\n经验等级:${current_level}\n当前经验值exp:${current_exp}\n下一等级所需exp:${next_exp}`);
|
|
107
121
|
}
|
|
108
122
|
else {
|
|
123
|
+
// 处理其他情况
|
|
109
124
|
return;
|
|
110
125
|
}
|
|
111
126
|
}
|
|
127
|
+
/**退出B站账号登录,将会删除redis缓存的LoginCK,并在服务器注销该登录 Token (SESSDATA)*/
|
|
112
128
|
async function exitBiliLogin(e) {
|
|
113
129
|
const url = 'https://passport.bilibili.com/login/exit/v2';
|
|
114
130
|
const exitCk = await readLoginCookie();
|
|
@@ -160,6 +176,12 @@ async function exitBiliLogin(e) {
|
|
|
160
176
|
e.reply("退出登录请求出错,请稍后再试");
|
|
161
177
|
}
|
|
162
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* *******************************************************************
|
|
181
|
+
* cookie相关
|
|
182
|
+
* *******************************************************************
|
|
183
|
+
*/
|
|
184
|
+
/**保存扫码登录的loginCK*/
|
|
163
185
|
async function saveLoginCookie(e, biliLoginCk) {
|
|
164
186
|
if (biliLoginCk && biliLoginCk.length > 0) {
|
|
165
187
|
const LoginCkKey = "Yz:yuki:bili:loginCookie";
|
|
@@ -169,15 +191,17 @@ async function saveLoginCookie(e, biliLoginCk) {
|
|
|
169
191
|
e.reply("扫码超时");
|
|
170
192
|
}
|
|
171
193
|
}
|
|
194
|
+
/** 读取扫码登陆后缓存的cookie */
|
|
172
195
|
async function readLoginCookie() {
|
|
173
196
|
const CK_KEY = "Yz:yuki:bili:loginCookie";
|
|
174
197
|
const tempCk = await Redis.get(CK_KEY);
|
|
175
198
|
return tempCk ? tempCk : '';
|
|
176
199
|
}
|
|
200
|
+
/** 读取手动绑定的B站ck */
|
|
177
201
|
async function readLocalBiliCk() {
|
|
178
202
|
const dir = path.join(_paths.root, 'data/yuki-plugin/');
|
|
179
203
|
if (!fs__default.existsSync(dir)) {
|
|
180
|
-
fs__default.mkdirSync(dir, { recursive: true });
|
|
204
|
+
fs__default.mkdirSync(dir, { recursive: true }); // 创建目录,包括父目录
|
|
181
205
|
}
|
|
182
206
|
const files = fs__default.readdirSync(dir).filter((file) => file.endsWith('.yaml'));
|
|
183
207
|
const readFile = promisify(fs__default.readFile);
|
|
@@ -186,6 +210,7 @@ async function readLocalBiliCk() {
|
|
|
186
210
|
const Bck = contents.map((content) => YAML.parse(content));
|
|
187
211
|
return Bck[0];
|
|
188
212
|
}
|
|
213
|
+
/** 覆盖保存手动获取绑定的B站ck */
|
|
189
214
|
async function saveLocalBiliCk(data) {
|
|
190
215
|
const dirPath = path.join(_paths.root, 'data/yuki-plugin/');
|
|
191
216
|
const filePath = path.join(dirPath, 'biliCookie.yaml');
|
|
@@ -201,15 +226,18 @@ async function saveLocalBiliCk(data) {
|
|
|
201
226
|
fs__default.writeFileSync(filePath, yamlContent, 'utf8');
|
|
202
227
|
}
|
|
203
228
|
}
|
|
229
|
+
/** 读取缓存的tempCK */
|
|
204
230
|
async function readTempCk() {
|
|
205
231
|
const CK_KEY = "Yz:yuki:bili:tempCookie";
|
|
206
232
|
const tempCk = await Redis.get(CK_KEY);
|
|
207
233
|
return tempCk ?? '';
|
|
208
234
|
}
|
|
235
|
+
/**保存tempCK*/
|
|
209
236
|
async function saveTempCk(newTempCk) {
|
|
210
237
|
const CK_KEY = "Yz:yuki:bili:tempCookie";
|
|
211
238
|
await Redis.set(CK_KEY, newTempCk, { EX: 3600 * 24 * 180 });
|
|
212
239
|
}
|
|
240
|
+
/** 综合获取ck,返回优先级:localCK > loginCK > tempCK */
|
|
213
241
|
async function readSyncCookie() {
|
|
214
242
|
const localCk = await readLocalBiliCk();
|
|
215
243
|
const tempCk = await readTempCk();
|
|
@@ -228,6 +256,13 @@ async function readSyncCookie() {
|
|
|
228
256
|
return { cookie: '', mark: "ckIsEmpty" };
|
|
229
257
|
}
|
|
230
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* 综合读取、筛选 传入的或本地或redis存储的cookie的item
|
|
261
|
+
* @param {string} mark 读取存储的CK类型,'localCK' 'tempCK' 'loginCK' 或传入值 'xxx'并进行筛选
|
|
262
|
+
* @param {Array} items 选取获取CK的项 选全部值:items[0] = 'all' ,或选取其中的值 ['buvid3', 'buvid4', '_uuid', 'SESSDATA', 'DedeUserID', 'DedeUserID__ckMd5', 'bili_jct', 'b_nut', 'b_lsid']
|
|
263
|
+
* @param {boolean} isInverted 控制正取和反取,true为反取,false为正取
|
|
264
|
+
* @returns {string}
|
|
265
|
+
**/
|
|
231
266
|
async function readSavedCookieItems(mark, items, isInverted = false) {
|
|
232
267
|
let ckString;
|
|
233
268
|
switch (mark) {
|
|
@@ -252,16 +287,18 @@ async function readSavedCookieItems(mark, items, isInverted = false) {
|
|
|
252
287
|
}
|
|
253
288
|
const cookiePairs = String(Bck)
|
|
254
289
|
.trim()
|
|
255
|
-
.match(/(\w+)=([^;|,]+)/g)
|
|
290
|
+
.match(/(\w+)=([^;|,]+)/g) //正则 /(\w+)=([^;]+);/g 匹配 a=b 的内容,并分组为 [^;|,]+ 来匹配值,其中 [^;|,] 表示除了分号和,以外的任意字符
|
|
256
291
|
?.map(match => match.split('='))
|
|
257
292
|
.filter(([key, value]) => (isInverted ? !items.includes(key) : items.includes(key)) && value !== '')
|
|
258
293
|
.map(([key, value]) => `${key}=${value}`)
|
|
259
294
|
.join(';') || '';
|
|
260
295
|
return cookiePairs;
|
|
261
296
|
}
|
|
297
|
+
// 取反读取ck、筛选 传入的或本地或redis存储的cookie的item
|
|
262
298
|
async function readSavedCookieOtherItems(mark, items) {
|
|
263
299
|
return await readSavedCookieItems(mark, items, true);
|
|
264
300
|
}
|
|
301
|
+
/** 生成 _uuid */
|
|
265
302
|
async function genUUID() {
|
|
266
303
|
const generatePart = (length) => Array.from({ length }, () => Math.floor(16 * Math.random()))
|
|
267
304
|
.map(num => num.toString(16).toUpperCase())
|
|
@@ -276,6 +313,7 @@ async function genUUID() {
|
|
|
276
313
|
const uuid = `_uuid=${e}-${t}-${r}-${n}-${o}${padLeft((i % 1e5).toString(), 5)}infoc;`;
|
|
277
314
|
return uuid;
|
|
278
315
|
}
|
|
316
|
+
/**生成 b_lsid */
|
|
279
317
|
async function gen_b_lsid() {
|
|
280
318
|
function get_random_str(length) {
|
|
281
319
|
return Array.from({ length }, () => Math.floor(Math.random() * 16).toString(16).toUpperCase()).join('');
|
|
@@ -285,6 +323,7 @@ async function gen_b_lsid() {
|
|
|
285
323
|
const timestampHex = timestamp.toString(16).toUpperCase();
|
|
286
324
|
return `b_lsid=${randomPart}_${timestampHex};`;
|
|
287
325
|
}
|
|
326
|
+
/** 获取 buvid3 和 buvid4 */
|
|
288
327
|
async function getBuvid3_4(uuid) {
|
|
289
328
|
const url = 'https://api.bilibili.com/x/frontend/finger/spi/';
|
|
290
329
|
const headers = lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
|
|
@@ -303,14 +342,16 @@ async function getBuvid3_4(uuid) {
|
|
|
303
342
|
return '';
|
|
304
343
|
}
|
|
305
344
|
}
|
|
345
|
+
/**获取新的tempCK*/
|
|
306
346
|
async function getNewTempCk() {
|
|
307
347
|
const uuid = await genUUID();
|
|
308
348
|
const buvid3_buvid4 = await getBuvid3_4(uuid);
|
|
309
349
|
const b_lsid = await gen_b_lsid();
|
|
310
|
-
|
|
350
|
+
//const buvid_fp = await get_buvid_fp(uuid);
|
|
351
|
+
let newTempCk = `${uuid}${buvid3_buvid4}${b_lsid}`; //${buvid_fp}`;
|
|
311
352
|
await saveTempCk(newTempCk);
|
|
312
353
|
const result = await postGateway(newTempCk);
|
|
313
|
-
const { code, data } = await result.data;
|
|
354
|
+
const { code, data } = await result.data; // 解析校验结果
|
|
314
355
|
if (code !== 0) {
|
|
315
356
|
logger?.mark(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
316
357
|
}
|
|
@@ -318,23 +359,29 @@ async function getNewTempCk() {
|
|
|
318
359
|
logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
319
360
|
}
|
|
320
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* *******************************************************************
|
|
364
|
+
* 风控相关函数
|
|
365
|
+
* *******************************************************************
|
|
366
|
+
*/
|
|
367
|
+
/**获取GatWay payload */
|
|
321
368
|
async function getPayload(cookie) {
|
|
322
369
|
const payloadOriginData = {
|
|
323
|
-
"3064": 1,
|
|
324
|
-
"5062": `${Date.now()}`,
|
|
325
|
-
"03bf": "https://www.bilibili.com/",
|
|
370
|
+
"3064": 1, // ptype, mobile => 2, others => 1
|
|
371
|
+
"5062": `${Date.now()}`, // timestamp
|
|
372
|
+
"03bf": "https://www.bilibili.com/", // url accessed
|
|
326
373
|
"39c8": "333.999.fp.risk",
|
|
327
|
-
"34f1": "",
|
|
328
|
-
"d402": "",
|
|
329
|
-
"654a": "",
|
|
330
|
-
"6e7c": "878x1066",
|
|
374
|
+
"34f1": "", // target_url, default empty now
|
|
375
|
+
"d402": "", // screenx, default empty
|
|
376
|
+
"654a": "", // screeny, default empty
|
|
377
|
+
"6e7c": "878x1066", // browser_resolution, window.innerWidth || document.body && document.body.clientWidth + "x" + window.innerHeight || document.body && document.body.clientHeight
|
|
331
378
|
"3c43": {
|
|
332
|
-
"2673": 0,
|
|
333
|
-
"5766": 24,
|
|
334
|
-
"6527": 0,
|
|
335
|
-
"7003": 1,
|
|
336
|
-
"807e": 1,
|
|
337
|
-
"b8ce": BiliApi.BILIBILI_HEADERS['User-Agent'],
|
|
379
|
+
"2673": 0, // hasLiedResolution, window.screen.width < window.screen.availWidth || window.screen.height < window.screen.availHeight
|
|
380
|
+
"5766": 24, // colorDepth, window.screen.colorDepth
|
|
381
|
+
"6527": 0, // addBehavior, !!window.HTMLElement.prototype.addBehavior, html5 api
|
|
382
|
+
"7003": 1, // indexedDb, !!window.indexedDB, html5 api
|
|
383
|
+
"807e": 1, // cookieEnabled, navigator.cookieEnabled
|
|
384
|
+
"b8ce": BiliApi.BILIBILI_HEADERS['User-Agent'], // ua "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
|
|
338
385
|
"641c": 0,
|
|
339
386
|
"07a4": "zh-CN",
|
|
340
387
|
"1c57": "not available",
|
|
@@ -347,7 +394,7 @@ async function getPayload(cookie) {
|
|
|
347
394
|
"3b21": 1,
|
|
348
395
|
"8a1c": 0,
|
|
349
396
|
"d52f": "not available",
|
|
350
|
-
"adca": BiliApi.BILIBILI_HEADERS['User-Agent'].includes('Windows') ? 'Win32' : 'Linux',
|
|
397
|
+
"adca": BiliApi.BILIBILI_HEADERS['User-Agent'].includes('Windows') ? 'Win32' : 'Linux', // platform, navigator.platform
|
|
351
398
|
"80c9": [
|
|
352
399
|
["PDF Viewer", "Portable Document Format", [
|
|
353
400
|
["application/pdf", "pdf"],
|
|
@@ -455,13 +502,18 @@ async function getPayload(cookie) {
|
|
|
455
502
|
}
|
|
456
503
|
},
|
|
457
504
|
"8b94": "",
|
|
458
|
-
"df35": `${await readSavedCookieItems(cookie, ['_uuid'], false)}`,
|
|
505
|
+
"df35": `${await readSavedCookieItems(cookie, ['_uuid'], false)}`, // _uuid, set from cookie, generated by client side(algorithm remains unknown)
|
|
459
506
|
"07a4": "zh-CN",
|
|
460
507
|
"5f45": null,
|
|
461
508
|
"db46": 0
|
|
462
509
|
};
|
|
463
510
|
return JSON.stringify(payloadOriginData);
|
|
464
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* 请求参数POST接口(ExClimbWuzhi)过校验
|
|
514
|
+
* @param cookie 请求所需的cookie
|
|
515
|
+
* @returns 返回POST请求的结果
|
|
516
|
+
*/
|
|
465
517
|
async function postGateway(cookie) {
|
|
466
518
|
const payload = getPayload(cookie);
|
|
467
519
|
const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
|
|
@@ -1,15 +1,39 @@
|
|
|
1
1
|
export declare class BiliQuery {
|
|
2
|
+
/**
|
|
3
|
+
* 序列化动态数据
|
|
4
|
+
* @param data - 动态数据对象
|
|
5
|
+
* @returns 序列化后的动态数据对象
|
|
6
|
+
*/
|
|
2
7
|
static formatDynamicData(data: any): Promise<{
|
|
3
8
|
uid: any;
|
|
4
9
|
data: {
|
|
5
10
|
[key: string]: any;
|
|
6
11
|
};
|
|
7
12
|
}>;
|
|
13
|
+
/**
|
|
14
|
+
* 动态内容富文本节点解析
|
|
15
|
+
* @param nodes - 动态内容富文本节点
|
|
16
|
+
* @returns 解析后的动态内容富文本
|
|
17
|
+
*/
|
|
8
18
|
static parseRichTextNodes: (nodes: any[] | string | any) => any;
|
|
19
|
+
/**获取完整B站文章内容
|
|
20
|
+
* @param postId - 文章ID
|
|
21
|
+
* @returns {Json}完整的B站文章内容json数据
|
|
22
|
+
*/
|
|
9
23
|
static getFullArticleContent(postUrl: string): Promise<any>;
|
|
24
|
+
/**解析完整文章内容 */
|
|
10
25
|
static praseFullArticleContent(content: string): string;
|
|
11
26
|
static formatUrl(url: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* 生成动态消息文字内容
|
|
29
|
+
* @param upName - UP主名称
|
|
30
|
+
* @param formatData - 动态数据
|
|
31
|
+
* @param isForward - 是否为转发动态
|
|
32
|
+
* @param setData - 设置数据
|
|
33
|
+
* @returns 生成的动态消息文字内容
|
|
34
|
+
*/
|
|
12
35
|
static formatTextDynamicData(upName: string, data: any, isForward: boolean, setData: any): Promise<any>;
|
|
13
36
|
static dynamicContentLimit(content: string, setData: any): string;
|
|
37
|
+
/**根据关键字更新 up 的动态类型 */
|
|
14
38
|
static typeHandle(up: any, msg: string, type: string): unknown[];
|
|
15
39
|
}
|