yz-yuki-plugin 2.0.6-8 → 2.0.7-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 +8 -1
- package/README.md +1 -1
- package/defaultConfig/bilibili/config.yaml +33 -15
- package/defaultConfig/weibo/config.yaml +23 -8
- package/lib/apps/bilibili.js +139 -38
- package/lib/apps/weibo.js +8 -8
- package/lib/components/dynamic/Footer.js +2 -2
- package/lib/components/help/Help.js +1 -1
- package/lib/components/version/Version.js +1 -1
- package/lib/index.js +3 -3
- package/lib/models/bilibili/bilibili.main.api.js +7 -1
- package/lib/models/bilibili/bilibili.main.get.web.data.js +57 -8
- package/lib/models/bilibili/bilibili.main.models.js +17 -3
- package/lib/models/bilibili/bilibili.main.query.js +5 -5
- package/lib/models/bilibili/bilibili.main.task.js +139 -77
- package/lib/models/weibo/weibo.main.api.js +43 -17
- package/lib/models/weibo/weibo.main.get.web.data.js +12 -9
- package/lib/models/weibo/weibo.main.query.js +8 -8
- package/lib/models/weibo/weibo.main.task.js +117 -40
- package/lib/utils/image.js +4 -4
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
# 2.0.7
|
|
2
|
+
* 新增B站视频解析
|
|
3
|
+
|
|
1
4
|
# 2.0.6
|
|
5
|
+
* 优化屏蔽关键词功能
|
|
6
|
+
* 新增 weibo User-Agent 配置项
|
|
7
|
+
* 优化api请求
|
|
8
|
+
* 优化消息发送
|
|
2
9
|
* 优化文字动态图片资源的发送
|
|
3
10
|
* 依赖升级
|
|
4
11
|
* 新增哔哩直播动态@全体成员功能,开启前请检查机器人管理员权限和所在聊天类型是否支持
|
|
5
12
|
|
|
6
13
|
# 2.0.5
|
|
7
14
|
* 优化ck
|
|
8
|
-
* 新增 User-Agent 配置项
|
|
15
|
+
* 新增 bili User-Agent 配置项
|
|
9
16
|
* 优化获取动态数据
|
|
10
17
|
* 新增获取B站up数据的随机延迟配置项
|
|
11
18
|
* 新增puppeteer渲染图片测试脚本
|
package/README.md
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
# b站推送,1 开启 0 关闭,保留添加的相关数据,但是不再推送
|
|
2
2
|
pushStatus: 1
|
|
3
3
|
|
|
4
|
-
# 检测b站动态的冷却时间 CD,Cron表达式,作用域共6位,具体方法浏览器搜索 “node-schedule cron
|
|
4
|
+
# 检测b站动态的冷却时间 CD,Cron表达式,作用域共6位,具体方法浏览器搜索 “node-schedule cron表达式”,
|
|
5
|
+
# 示例:
|
|
5
6
|
# "*/15 * * * *" #每15min检测一次
|
|
6
7
|
# "*/31 * * * *" #每31min检测一次
|
|
7
8
|
# "0 5,35 * * * *" #每小时固定第5分0秒、第35分0秒检测一次,共2次/h
|
|
8
9
|
# "0 5,35,51 * * * *" #每小时固定第5分0秒、第35分0秒、第51分0秒检测一次,共3次/h
|
|
9
|
-
|
|
10
|
+
# ❀动态发布通常习惯整点发布,触发检测时比发布时间点稍晚几分钟即可,基本可以命中。
|
|
11
|
+
# ❀请勿设置周期过短比如小于10分钟,以免触发风控。
|
|
12
|
+
checkDynamicCD: '*/23 * * * *'
|
|
10
13
|
|
|
11
|
-
# 请求头 User-Agent 列表。如出现 -352
|
|
14
|
+
# 请求头 User-Agent 列表。如出现 -352 风控,可尝试更换请求头,请根据需要自行添加或修改。
|
|
15
|
+
# 可设置多个请求头,每次重启后会随机选择一个。获取方法请浏览器自行搜索。
|
|
12
16
|
userAgentList:
|
|
13
|
-
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
14
|
-
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:
|
|
15
|
-
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
17
|
+
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
|
|
18
|
+
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0
|
|
19
|
+
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0
|
|
16
20
|
|
|
17
|
-
#
|
|
18
|
-
|
|
21
|
+
# 筛选何时发布的动态,单位为秒,默认7200秒即2小时,即以当前时间为基准,筛选过去2小时内的发布动态,并推送。
|
|
22
|
+
# 取值范围:3600-36000秒,即过去的1-10h。应大于checkDynamicCD的周期。
|
|
23
|
+
dynamicTimeRange: 7200
|
|
19
24
|
|
|
20
|
-
# 顺序检测相邻up主的动态并获取数据的最大随机间隔时间,单位为毫秒,默认 8000,即 8000 毫秒(8
|
|
25
|
+
# 顺序检测相邻up主的动态并获取数据的最大随机间隔时间,单位为毫秒,默认 8000,即 8000 毫秒(8秒),
|
|
26
|
+
# 即获取该up的动态数据后,随机等待2(内置值)-8秒后再获取下一位up的动态数据。取值范围:4000 ≦ x < checkDynamicCD的周期,单位为毫秒。
|
|
21
27
|
# 该数值大小影响风控概率, 请谨慎调整,建议不要设置过小,否则可能被风控导致动态获取失败。
|
|
22
28
|
getDataRandomDelay: 8000
|
|
23
29
|
|
|
24
|
-
# 全部订阅的转发动态是否推送: 默认 1 - 开启推送, 0 - 关闭推送。
|
|
30
|
+
# 全部订阅的转发动态是否推送: 默认 1 - 开启推送, 0 - 关闭推送。
|
|
31
|
+
# 如果仅仅需要关闭单个订阅的转发动态推送,使用分类订阅指令不包含 转发 分类即可,无需修改此配置。
|
|
25
32
|
pushTransmit: 1
|
|
26
33
|
|
|
27
34
|
# 推送文字和图文动态时,限制发送多少张图片
|
|
@@ -44,13 +51,16 @@ banWords:
|
|
|
44
51
|
# 设置B站动态消息模式 0 文字模式 1 图片模式
|
|
45
52
|
pushMsgMode: 1
|
|
46
53
|
|
|
47
|
-
# 文字模式时,文字消息与图片附件是否合并在一起发送,默认 1 合并,0
|
|
54
|
+
# 文字模式时,文字消息与图片附件是否合并在一起发送,默认 1 合并,0 不合并。
|
|
55
|
+
# 如果合并时图片过多导致发送失败,可设置为 0 单独发送图片。
|
|
48
56
|
mergeTextPic: 1
|
|
49
57
|
|
|
50
|
-
# 是否启用九宫格样式:默认 1 启用,0
|
|
58
|
+
# 是否启用九宫格样式:默认 1 启用,0 不启用。
|
|
59
|
+
# 此为最高优先级,九宫格为动态模式,特定大小/长宽比的图片资源将会动态启用九宫格/四宫格/无宫格样式。
|
|
51
60
|
boxGrid: 1
|
|
52
61
|
|
|
53
|
-
# B站动态卡片分片截图模式:默认 1 启用 0
|
|
62
|
+
# B站动态卡片分片截图模式:默认 1 启用 0 不启用。
|
|
63
|
+
# 启用,将会推送每条动态的全部内容;不启用,动态内容过长时候将只推送noSplitHeight长度的动态卡片,需关闭宫格模式。
|
|
54
64
|
isSplit: 1
|
|
55
65
|
|
|
56
66
|
# 动态卡片非分片模式下的截图高度,默认7500px(仅填数字,无需填入单位),请勿设置过大或过小。关闭分片截图时生效。
|
|
@@ -59,12 +69,20 @@ noSplitHeight: 7500
|
|
|
59
69
|
# 动态卡片分页截图高度,默认8000px(仅填数字,无需填入单位),请勿设置过大或过小。启用分片截图时生效。
|
|
60
70
|
splitHeight: 8000
|
|
61
71
|
|
|
62
|
-
# 直播动态是否@全体成员,默认 0 关闭,1
|
|
72
|
+
# 直播动态是否@全体成员,默认 0 关闭,1 开启。
|
|
73
|
+
# 开启前请检查 <机器人> 是否有 [管理员权限] 或 [聊天平台是否支持],某些聊天平台或类型不支持@全体成员,如qq官方机器人等。
|
|
63
74
|
liveAtAll: 0
|
|
64
75
|
|
|
65
76
|
# 直播动态@全体成员的群组/聊天/私聊列表,默认为空即不在任何群于推送直播动态中执行@全体成员。开启liveAtAll后才会生效。
|
|
66
77
|
liveAtAllGroupList:
|
|
67
78
|
- 1234567890 # 示例群号
|
|
68
79
|
|
|
69
|
-
# 直播动态@全体成员的共享冷却时间CD,单位秒,默认 1800 秒(30
|
|
80
|
+
# 直播动态@全体成员的共享冷却时间CD,单位秒,默认 1800 秒(30分钟),
|
|
81
|
+
# 即每个群聊30分钟内不论多少条直播动态,只会@一次。注意,qq群有 @全体成员 10次/日 的限制,所以请合理设置。
|
|
70
82
|
liveAtAllCD: 1800
|
|
83
|
+
|
|
84
|
+
# 直播动态@全体成员失败时是否发送错误消息,默认 1 发送,0 不发送。开启liveAtAll后才会生效。
|
|
85
|
+
liveAtAllErrMsg: 1
|
|
86
|
+
|
|
87
|
+
#视频链接解析开关 默认 1 开启 0 关闭
|
|
88
|
+
parseVideoLink: 1
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
# 微博推送,1 开启 0 关闭,保留添加的相关数据,但是不再推送
|
|
2
2
|
pushStatus: 1
|
|
3
3
|
|
|
4
|
-
# 检测微博动态的冷却时间 CD,Cron表达式,作用域共6位,具体方法浏览器搜索 “node-schedule cron
|
|
4
|
+
# 检测微博动态的冷却时间 CD,Cron表达式,作用域共6位,具体方法浏览器搜索 “node-schedule cron表达式”,
|
|
5
|
+
# 示例:
|
|
5
6
|
# "*/15 * * * *" #每15min检测一次
|
|
6
7
|
# "*/31 * * * *" #每31min检测一次
|
|
7
8
|
# "0 5,35 * * * *" #每小时固定第5分0秒、第35分0秒检测一次,共2次/h
|
|
8
9
|
# "0 5,35,51 * * * *" #每小时固定第5分0秒、第35分0秒、第51分0秒检测一次,共3次/h
|
|
9
|
-
|
|
10
|
+
# ❀动态发布通常习惯整点发布,触发检测时比发布时间点稍晚几分钟即可,基本可以命中。
|
|
11
|
+
# ❀请勿设置周期过短比如小于10分钟,以免触发访问限制。
|
|
12
|
+
checkDynamicCD: '*/23 * * * *'
|
|
10
13
|
|
|
11
|
-
#
|
|
12
|
-
|
|
14
|
+
# 请求头 User-Agent 列表。请根据需要自行添加或修改。
|
|
15
|
+
# 可设置多个请求头,每次重启后会随机选择一个。获取方法请浏览器自行搜索。
|
|
16
|
+
userAgentList:
|
|
17
|
+
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
|
|
18
|
+
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0
|
|
19
|
+
#- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0
|
|
13
20
|
|
|
14
|
-
#
|
|
21
|
+
# 筛选何时发布的动态,单位为秒,默认7200秒即2小时,即以当前时间为基准,筛选过去2小时内发布的动态,并推送。
|
|
22
|
+
# 取值范围:3600-36000秒,即过去的1-10h。应大于checkDynamicCD的周期。
|
|
23
|
+
dynamicTimeRange: 7200
|
|
24
|
+
|
|
25
|
+
# 全部订阅的转发动态是否推送: 默认 1 - 开启推送, 0 - 关闭推送。
|
|
26
|
+
# 如果仅仅需要关闭单个订阅的转发动态推送,使用分类订阅指令不包含 转发 分类即可,无需修改此配置。
|
|
15
27
|
pushTransmit: 1
|
|
16
28
|
|
|
17
29
|
# 推送动态时,限制发送多少张图片
|
|
@@ -34,13 +46,16 @@ banWords:
|
|
|
34
46
|
# 设置微博动态消息模式 0 文字模式 1 图片模式
|
|
35
47
|
pushMsgMode: 1
|
|
36
48
|
|
|
37
|
-
# 文字模式时,文字消息与图片附件是否合并在一起发送,默认 1 合并,0
|
|
49
|
+
# 文字模式时,文字消息与图片附件是否合并在一起发送,默认 1 合并,0 不合并。
|
|
50
|
+
# 如果合并时图片过多导致发送失败,可设置为 0 单独发送图片。
|
|
38
51
|
mergeTextPic: 1
|
|
39
52
|
|
|
40
|
-
# 是否启用九宫格样式:默认 1 启用,0
|
|
53
|
+
# 是否启用九宫格样式:默认 1 启用,0 不启用。
|
|
54
|
+
# 此为最高优先级,九宫格为动态模式,特定大小/长宽比的图片资源将会动态启用九宫格/四宫格/无宫格样式。
|
|
41
55
|
boxGrid: 1
|
|
42
56
|
|
|
43
|
-
# 微博动态卡片分片截图模式:默认 1 启用 0
|
|
57
|
+
# 微博动态卡片分片截图模式:默认 1 启用 0 不启用。
|
|
58
|
+
# 启用,将会推送每条动态的全部内容;不启用,动态内容过长时候将只推送noSplitHeight长度的动态卡片,需关闭宫格模式。
|
|
44
59
|
isSplit: 1
|
|
45
60
|
|
|
46
61
|
# 动态卡片非分片模式下的截图高度,默认7500px(仅填数字,无需填入单位),请勿设置过大或过小。关闭分片截图时生效。
|
package/lib/apps/bilibili.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import JSON from 'json5';
|
|
2
2
|
import lodash from 'lodash';
|
|
3
|
-
import
|
|
3
|
+
import moment from 'moment';
|
|
4
|
+
import { Messages, Redis, Segment } from 'yunzaijs';
|
|
4
5
|
import { BiliQuery } from '../models/bilibili/bilibili.main.query.js';
|
|
5
6
|
import { BiliTask } from '../models/bilibili/bilibili.main.task.js';
|
|
6
7
|
import Config from '../utils/config.js';
|
|
7
|
-
import {
|
|
8
|
-
import { applyLoginQRCode, pollLoginQRCode, saveLoginCookie, postGateway, exitBiliLogin, checkBiliLogin, readSavedCookieItems, saveLocalBiliCk, readSyncCookie, getNewTempCk, saveTempCk } from '../models/bilibili/bilibili.main.models.js';
|
|
8
|
+
import { BilibiliWebDataFetcher } from '../models/bilibili/bilibili.main.get.web.data.js';
|
|
9
|
+
import { readLoginCookie, applyLoginQRCode, pollLoginQRCode, saveLoginCookie, postGateway, exitBiliLogin, checkBiliLogin, readSavedCookieItems, saveLocalBiliCk, readSyncCookie, getNewTempCk, saveTempCk } from '../models/bilibili/bilibili.main.models.js';
|
|
9
10
|
|
|
10
11
|
const message = new Messages('message');
|
|
11
12
|
let biliPushData = Config.getConfigData('config', 'bilibili', 'push');
|
|
13
|
+
let biliConfigData = Config.getConfigData('config', 'bilibili', 'config');
|
|
12
14
|
/** 推送任务 函数 */
|
|
13
15
|
async function biliNewPushTask(e) {
|
|
14
16
|
await new BiliTask(e).runTask();
|
|
@@ -52,8 +54,8 @@ message.use(async (e) => {
|
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
56
|
// 获取 Bilibili 动态信息
|
|
55
|
-
const res = await new
|
|
56
|
-
if (res
|
|
57
|
+
const res = await new BilibiliWebDataFetcher(e).getBiliDynamicListDataByUid(uid);
|
|
58
|
+
if (res?.statusText !== 'OK') {
|
|
57
59
|
e.reply('出了点网络问题,等会再试试吧~');
|
|
58
60
|
return false;
|
|
59
61
|
}
|
|
@@ -66,8 +68,8 @@ message.use(async (e) => {
|
|
|
66
68
|
let infoName = '';
|
|
67
69
|
if (code === 0 && has_more === false) {
|
|
68
70
|
e.reply(`检测到该uid的主页空间动态内容为空,\n执行uid:${uid} 校验...`);
|
|
69
|
-
const resp = await new
|
|
70
|
-
if (resp
|
|
71
|
+
const resp = await new BilibiliWebDataFetcher(e).getBilibiUserInfoByUid(uid);
|
|
72
|
+
if (resp?.statusText !== 'OK') {
|
|
71
73
|
e.reply('出了点网络问题,发起uid校验失败,等会再试试吧~');
|
|
72
74
|
return false;
|
|
73
75
|
}
|
|
@@ -167,39 +169,45 @@ message.use(async (e) => {
|
|
|
167
169
|
}, [/^(#|\/)(yuki|优纪)?(取消|删除|del|DEL)(b站|B站|bili|bilibili|哔哩|哔哩哔哩)推送\s*(视频\s*|图文\s*|文章\s*|转发\s*|直播\s*)*.*$/]);
|
|
168
170
|
/** 扫码登录B站 */
|
|
169
171
|
message.use(async (e) => {
|
|
170
|
-
if (e.isMaster) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
172
|
+
if (!e.isMaster) {
|
|
173
|
+
e.reply('未取得bot主人身份,无权限配置B站登录ck');
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const LoginCk = await readLoginCookie();
|
|
177
|
+
if (LoginCk) {
|
|
178
|
+
e.reply(`当前已有B站登录ck,请勿重复扫码!\n如需更换,请先删除当前登录再扫码:\n#yuki删除B站登录`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
try {
|
|
182
|
+
const token = await applyLoginQRCode(e);
|
|
183
|
+
if (token) {
|
|
184
|
+
let biliLoginCk = await pollLoginQRCode(e, token);
|
|
185
|
+
if (biliLoginCk) {
|
|
186
|
+
if (lodash.trim(biliLoginCk).length != 0) {
|
|
187
|
+
await saveLoginCookie(e, biliLoginCk);
|
|
188
|
+
e.reply(`get bilibili LoginCk:成功!`);
|
|
189
|
+
const result = await postGateway(biliLoginCk); //激活ck
|
|
190
|
+
const { code, data } = await result.data; // 解析校验结果
|
|
191
|
+
switch (code) {
|
|
192
|
+
case 0:
|
|
193
|
+
global?.logger?.mark(`优纪插件:获取biliLoginCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
global?.logger?.mark(`优纪插件:获取biliLoginCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
e.reply(`get bilibili LoginCk:失败X﹏X`);
|
|
188
202
|
}
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
e.reply(`get bilibili LoginCk:失败X﹏X`);
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
catch (Error) {
|
|
207
|
+
global?.logger?.info(`yuki-plugin Login bilibili Failed:${Error}`);
|
|
208
|
+
}
|
|
198
209
|
}
|
|
199
210
|
}
|
|
200
|
-
else {
|
|
201
|
-
e.reply('未取得bot主人身份,无权限配置B站登录ck');
|
|
202
|
-
}
|
|
203
211
|
}, [/^(#|\/)(yuki|优纪)?(扫码|添加|ADD|add)(b站|B站|bili|bilibili|哔哩|哔哩哔哩)登录$/]);
|
|
204
212
|
/** 删除登陆的B站ck */
|
|
205
213
|
message.use(async (e) => {
|
|
@@ -432,8 +440,8 @@ message.use(async (e) => {
|
|
|
432
440
|
/**通过uid获取up主信息 */
|
|
433
441
|
message.use(async (e) => {
|
|
434
442
|
let uid = e.msg.replace(/^(#|\/)(yuki|优纪)?(b站|B站|bili|bilibili|哔哩|哔哩哔哩)(up|UP)主/g, '').trim();
|
|
435
|
-
const res = await new
|
|
436
|
-
if (res
|
|
443
|
+
const res = await new BilibiliWebDataFetcher(e).getBilibiUserInfoByUid(uid);
|
|
444
|
+
if (res?.statusText !== 'OK') {
|
|
437
445
|
e.reply('诶嘿,出了点网络问题,等会再试试吧~');
|
|
438
446
|
return;
|
|
439
447
|
}
|
|
@@ -460,8 +468,8 @@ message.use(async (e) => {
|
|
|
460
468
|
/** 根据名称搜索up的uid*/
|
|
461
469
|
message.use(async (e) => {
|
|
462
470
|
let keyword = e.msg.replace(/^(#|\/)(yuki|优纪)?搜索(b站|B站|bili|bilibili|哔哩|哔哩哔哩)(up|UP)主/g, '').trim();
|
|
463
|
-
const res = await new
|
|
464
|
-
if (res
|
|
471
|
+
const res = await new BilibiliWebDataFetcher(e).searchBiliUserInfoByKeyword(keyword);
|
|
472
|
+
if (res?.statusText !== 'OK') {
|
|
465
473
|
e.reply('诶嘿,出了点网络问题,等会再试试吧~');
|
|
466
474
|
return;
|
|
467
475
|
}
|
|
@@ -489,6 +497,99 @@ message.use(async (e) => {
|
|
|
489
497
|
}
|
|
490
498
|
e.reply(messages.join('\n'));
|
|
491
499
|
}, [/^(#|\/)(yuki|优纪)?搜索(b站|B站|bili|bilibili|哔哩|哔哩哔哩)(up|UP)主.*$/]);
|
|
500
|
+
/** 根据名称搜索up的uid*/
|
|
501
|
+
message.use(async (e) => {
|
|
502
|
+
if (biliConfigData?.parseVideoLink && !!biliConfigData.parseVideoLink === false) {
|
|
503
|
+
logger?.info(`优纪B站视频链接解析配置文件已设置关闭,解析终止。`);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const VideoIDStr = e.msg
|
|
507
|
+
.match(/(b23\.tv\/[a-zA-Z0-9]+)|(www\.bilibili\.com\/video\/)?(av\d+|BV[a-zA-Z0-9]+)/)?.[0]
|
|
508
|
+
.replace(/^www\.bilibili\.com\/video\//, '');
|
|
509
|
+
let vedioID;
|
|
510
|
+
if (VideoIDStr && new RegExp(/^b23\.tv\/[a-zA-Z0-9]+/).test(VideoIDStr)) {
|
|
511
|
+
const tvUrlID = VideoIDStr.replace(/^b23\.tv\//g, '');
|
|
512
|
+
const bvidStr = await new BilibiliWebDataFetcher(e).getBVIDByShortUrl(tvUrlID);
|
|
513
|
+
vedioID = { bvid: bvidStr };
|
|
514
|
+
}
|
|
515
|
+
else if (VideoIDStr && new RegExp(/^av\d+/).test(VideoIDStr)) {
|
|
516
|
+
const aid = VideoIDStr.replace(/^av/g, '');
|
|
517
|
+
vedioID = { aid: Number(aid) };
|
|
518
|
+
}
|
|
519
|
+
else if (VideoIDStr && new RegExp(/|^BV[a-zA-Z0-9]+/).test(VideoIDStr)) {
|
|
520
|
+
vedioID = { bvid: VideoIDStr };
|
|
521
|
+
}
|
|
522
|
+
e.reply('优纪酱解析中,请稍后~');
|
|
523
|
+
const res = await new BilibiliWebDataFetcher(e).getBiliVideoInfoByAid_BV(vedioID);
|
|
524
|
+
if (res?.statusText !== 'OK') {
|
|
525
|
+
e.reply('诶嘿,出了点网络问题,等会再试试吧~');
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
const { code, data } = (await res.data) || {};
|
|
529
|
+
function formatNumber(num) {
|
|
530
|
+
if (num >= 10000) {
|
|
531
|
+
return `${(num / 10000).toFixed(1)}万`;
|
|
532
|
+
}
|
|
533
|
+
return num.toString();
|
|
534
|
+
}
|
|
535
|
+
function formatDuration(seconds) {
|
|
536
|
+
const hours = Math.floor(seconds / 3600);
|
|
537
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
538
|
+
const secs = seconds % 60;
|
|
539
|
+
const mm = minutes.toString().padStart(2, '0');
|
|
540
|
+
const ss = secs.toString().padStart(2, '0');
|
|
541
|
+
return `${hours}:${mm}:${ss}`;
|
|
542
|
+
}
|
|
543
|
+
if (code === -400) {
|
|
544
|
+
e.reply('视频解析请求错误~');
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
else if (code === -403) {
|
|
548
|
+
e.reply(`权限不足,视频解析失败。`);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
else if (code === -404) {
|
|
552
|
+
e.reply('解析的视频不存在。');
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
else if (code === 62002) {
|
|
556
|
+
e.reply('解析的视频稿件不可见。');
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
else if (code === 62004) {
|
|
560
|
+
e.reply('解析的视频稿件审核中。');
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
else if (code === 62012) {
|
|
564
|
+
e.reply('解析的视频稿件仅up主可见。');
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
else if (code === 0) {
|
|
568
|
+
const message = [
|
|
569
|
+
`${data?.title}\n`,
|
|
570
|
+
Segment.image(data.pic),
|
|
571
|
+
`\nbvid:${data?.bvid}`,
|
|
572
|
+
`\n--------------------`,
|
|
573
|
+
`\n分区:${data?.tname_v2} (${data?.tname})`,
|
|
574
|
+
`\n投稿:${moment(data?.ctime * 1000).format('YYYY年MM月DD日 HH:mm:ss')}`,
|
|
575
|
+
`\n发布:${moment(data?.pubdate * 1000).format('YYYY年MM月DD日 HH:mm:ss')}`,
|
|
576
|
+
`\n时长:${formatDuration(data?.duration)}`,
|
|
577
|
+
`\n创作:${data?.copyright === 1 ? '原创' : '转载'}`,
|
|
578
|
+
`\n--------------------`,
|
|
579
|
+
`\nUP主:${data?.owner?.name}`,
|
|
580
|
+
`\nUID:${data?.owner?.mid}`,
|
|
581
|
+
//`\n作者头像:${Segment.image(data?.owner?.face)}`,
|
|
582
|
+
`\n--------------------`,
|
|
583
|
+
`\n视频简介:`,
|
|
584
|
+
`\n${data?.desc}`,
|
|
585
|
+
`\n--------------------`,
|
|
586
|
+
`\n${formatNumber(data?.stat?.view)}播放 • ${formatNumber(data?.stat?.danmaku)}弹幕 • ${formatNumber(data?.stat?.reply)}评论 `,
|
|
587
|
+
`\n${formatNumber(data?.stat?.like)}点赞 • ${formatNumber(data?.stat?.coin)}投币 • ${formatNumber(data?.stat?.favorite)}收藏`,
|
|
588
|
+
`\n${formatNumber(data?.stat?.share)}分享`
|
|
589
|
+
];
|
|
590
|
+
e.reply(message);
|
|
591
|
+
}
|
|
592
|
+
}, [/(b23\.tv\/[a-zA-Z0-9]+)|(www\.bilibili\.com\/video\/)?(av\d+|BV[a-zA-Z0-9]+)/]);
|
|
492
593
|
const YukiBli = message.ok;
|
|
493
594
|
|
|
494
595
|
export { YukiBli };
|
package/lib/apps/weibo.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Messages } from 'yunzaijs';
|
|
|
2
2
|
import { WeiboQuery } from '../models/weibo/weibo.main.query.js';
|
|
3
3
|
import { WeiboTask } from '../models/weibo/weibo.main.task.js';
|
|
4
4
|
import Config from '../utils/config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { WeiboWebDataFetcher } from '../models/weibo/weibo.main.get.web.data.js';
|
|
6
6
|
|
|
7
7
|
const message = new Messages('message');
|
|
8
8
|
let weiboPushData = Config.getConfigData('config', 'weibo', 'push');
|
|
@@ -46,8 +46,8 @@ message.use(async (e) => {
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
// 获取 微博 博主信息
|
|
49
|
-
const res = await new
|
|
50
|
-
if (res
|
|
49
|
+
const res = await new WeiboWebDataFetcher(e).getBloggerInfo(uid);
|
|
50
|
+
if (res?.statusText !== 'OK') {
|
|
51
51
|
e.reply('出了点网络问题,等会再试试吧~');
|
|
52
52
|
return false;
|
|
53
53
|
}
|
|
@@ -58,7 +58,7 @@ message.use(async (e) => {
|
|
|
58
58
|
}
|
|
59
59
|
const userInfo = data.userInfo || {};
|
|
60
60
|
let name = uid;
|
|
61
|
-
if (userInfo.length !== 0) {
|
|
61
|
+
if (userInfo && userInfo.length !== 0) {
|
|
62
62
|
name = userInfo.screen_name || uid;
|
|
63
63
|
}
|
|
64
64
|
// 添加新的推送数据
|
|
@@ -211,8 +211,8 @@ message.use(async (e) => {
|
|
|
211
211
|
/**通过uid获取up主信息 */
|
|
212
212
|
message.use(async (e) => {
|
|
213
213
|
let uid = e.msg.replace(/^(#|\/)(yuki|优纪)?(微博|weibo|WEIBO)(博|bo|BO)主/g, '').trim();
|
|
214
|
-
const res = await new
|
|
215
|
-
if (res
|
|
214
|
+
const res = await new WeiboWebDataFetcher(e).getBloggerInfo(uid);
|
|
215
|
+
if (res?.statusText !== 'OK') {
|
|
216
216
|
e.reply('诶嘿,出了点网络问题,等会再试试吧~');
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
@@ -240,8 +240,8 @@ message.use(async (e) => {
|
|
|
240
240
|
/** 根据昵称搜索博主信息*/
|
|
241
241
|
message.use(async (e) => {
|
|
242
242
|
let keyword = e.msg.replace(/^(#|\/)(yuki|优纪)?搜索(微博|weibo|WEIBO)(博|bo|BO)主/g, '').trim();
|
|
243
|
-
const res = await new
|
|
244
|
-
if (res
|
|
243
|
+
const res = await new WeiboWebDataFetcher(e).searchBloggerInfo(keyword);
|
|
244
|
+
if (res?.statusText !== 'OK') {
|
|
245
245
|
e.reply('诶嘿,出了点网络问题,等会再试试吧~');
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { BOT_NAME, ConfigController } from 'yunzaijs';
|
|
3
3
|
import Config from '../../utils/config.js';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { createRequire, _paths } from '../../utils/paths.js';
|
|
6
6
|
|
|
7
7
|
// Footer.tsx
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { BOT_NAME, ConfigController } from 'yunzaijs';
|
|
3
3
|
import Config from '../../utils/config.js';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { createRequire, _paths } from '../../utils/paths.js';
|
|
6
6
|
|
|
7
7
|
//help.tsx
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { BOT_NAME, ConfigController } from 'yunzaijs';
|
|
3
3
|
import Config from '../../utils/config.js';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { createRequire, _paths } from '../../utils/paths.js';
|
|
6
6
|
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
8
|
const botVersion = ConfigController.package?.version;
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { applicationOptions,
|
|
2
|
+
import { applicationOptions, useEvent, setBotTask } from 'yunzaijs';
|
|
3
3
|
import Config from './utils/config.js';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { _paths } from './utils/paths.js';
|
|
@@ -55,7 +55,7 @@ var index = () => {
|
|
|
55
55
|
catch (err) {
|
|
56
56
|
console.error('B站动态推送定时任务', err);
|
|
57
57
|
}
|
|
58
|
-
}, biliConfigData.pushStatus ? biliConfigData.
|
|
58
|
+
}, !!biliConfigData.pushStatus ? (biliConfigData.checkDynamicCD ? biliConfigData.checkDynamicCD : ' */23 * * * *') : '');
|
|
59
59
|
/** 微博动态推送定时任务 */
|
|
60
60
|
setBotTask(async (Bot) => {
|
|
61
61
|
try {
|
|
@@ -67,7 +67,7 @@ var index = () => {
|
|
|
67
67
|
catch (err) {
|
|
68
68
|
console.error('微博动态推送定时任务', err);
|
|
69
69
|
}
|
|
70
|
-
}, weiboConfigData.pushStatus ? weiboConfigData.
|
|
70
|
+
}, !!weiboConfigData.pushStatus ? (weiboConfigData.checkDynamicCD ? weiboConfigData.checkDynamicCD : ' */23 * * * *') : '');
|
|
71
71
|
},
|
|
72
72
|
async mounted(e) {
|
|
73
73
|
// 存储
|
|
@@ -8,7 +8,7 @@ class BiliApi {
|
|
|
8
8
|
this.USER_AGENT = BiliApi.BILIBILI_USER_AGENT;
|
|
9
9
|
this.initialize();
|
|
10
10
|
}
|
|
11
|
-
static BILIBILI_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
11
|
+
static BILIBILI_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36';
|
|
12
12
|
//初始化User-Agent
|
|
13
13
|
async initialize() {
|
|
14
14
|
await this.initUserAgent();
|
|
@@ -37,6 +37,12 @@ class BiliApi {
|
|
|
37
37
|
biliSearchUp: `https://api.bilibili.com/x/web-interface/search/type`,
|
|
38
38
|
//通过关键词${upKeyword}搜索up主 parama = { keyword: 'upKeyword', page: 1, search_type: 'bili_user', order: 'totalrank' },需要wbi签名
|
|
39
39
|
biliSearchUpWbi: `https://api.bilibili.com/x/web-interface/wbi/search/type`,
|
|
40
|
+
// 获取视频详情无wbi parama = { aid: avid } 或 { bvid: bvid }
|
|
41
|
+
biliVideoInfo: `https://api.bilibili.com/x/web-interface/view`,
|
|
42
|
+
// 获取视频详情 wbi parama = { aid: avid } 或 { bvid: bvid }
|
|
43
|
+
biliVideoInfoWbi: `https://api.bilibili.com/x/web-interface/wbi/view`,
|
|
44
|
+
//短链
|
|
45
|
+
biliShortVideoUrl: `https://b23.tv/`,
|
|
40
46
|
biliLiveStatus: 'https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids',
|
|
41
47
|
biliCard: 'https://api.bilibili.com/x/web-interface/card',
|
|
42
48
|
biliStat: 'https://api.bilibili.com/x/relation/stat',
|
|
@@ -6,7 +6,8 @@ import { getWbiSign } from './bilibili.risk.wbi.js';
|
|
|
6
6
|
import { getDmImg } from './bilibili.risk.dm.img.js';
|
|
7
7
|
import { getWebId } from './bilibili.risk.w_webid.js';
|
|
8
8
|
|
|
9
|
-
class
|
|
9
|
+
class BilibiliWebDataFetcher {
|
|
10
|
+
e;
|
|
10
11
|
constructor(e) { }
|
|
11
12
|
/**通过uid获取up动态数据表*/
|
|
12
13
|
async getBiliDynamicListDataByUid(uid) {
|
|
@@ -32,9 +33,10 @@ class BiliGetWebData {
|
|
|
32
33
|
w_rid: w_rid,
|
|
33
34
|
wts: time_stamp
|
|
34
35
|
};
|
|
35
|
-
const res = await axios
|
|
36
|
+
const res = await axios(url, {
|
|
37
|
+
method: 'GET',
|
|
36
38
|
params,
|
|
37
|
-
timeout:
|
|
39
|
+
timeout: 15000,
|
|
38
40
|
headers: lodash.merge(BiliApi.BILIBILI_HEADERS, {
|
|
39
41
|
Cookie: `${cookie}`,
|
|
40
42
|
Host: `api.bilibili.com`,
|
|
@@ -67,9 +69,10 @@ class BiliGetWebData {
|
|
|
67
69
|
w_rid: w_rid,
|
|
68
70
|
wts: time_stamp
|
|
69
71
|
};
|
|
70
|
-
const res = await axios
|
|
72
|
+
const res = await axios(url, {
|
|
73
|
+
method: 'GET',
|
|
71
74
|
params,
|
|
72
|
-
timeout:
|
|
75
|
+
timeout: 10000,
|
|
73
76
|
headers: lodash.merge(BiliApi.BILIBILI_HEADERS, {
|
|
74
77
|
Cookie: `${cookie}`,
|
|
75
78
|
Host: `api.bilibili.com`,
|
|
@@ -97,9 +100,10 @@ class BiliGetWebData {
|
|
|
97
100
|
w_rid: w_rid,
|
|
98
101
|
wts: time_stamp
|
|
99
102
|
};
|
|
100
|
-
const res = await axios
|
|
103
|
+
const res = await axios(url, {
|
|
104
|
+
method: 'GET',
|
|
101
105
|
params,
|
|
102
|
-
timeout:
|
|
106
|
+
timeout: 10000,
|
|
103
107
|
headers: lodash.merge(BiliApi.BILIBILI_HEADERS, {
|
|
104
108
|
Cookie: `${cookie}`,
|
|
105
109
|
Host: `api.bilibili.com`,
|
|
@@ -109,6 +113,51 @@ class BiliGetWebData {
|
|
|
109
113
|
});
|
|
110
114
|
return res;
|
|
111
115
|
}
|
|
116
|
+
/*通过aid/bvid获取视频信息*/
|
|
117
|
+
async getBiliVideoInfoByAid_BV(vedioID) {
|
|
118
|
+
const url = BiliApi.BILIBIL_API.biliVideoInfoWbi;
|
|
119
|
+
let { cookie } = await readSyncCookie();
|
|
120
|
+
cookie = await cookieWithBiliTicket(cookie);
|
|
121
|
+
let referer = vedioID?.bvid ? `https://www.bilibili.com/video/${vedioID.bvid}` : `https://www.bilibili.com/video/av${vedioID.aid}`;
|
|
122
|
+
let data = vedioID?.bvid ? { bvid: vedioID.bvid } : { aid: vedioID.aid };
|
|
123
|
+
let signCookie = (await readSavedCookieItems(cookie, ['SESSDATA'], false)) || (await readSavedCookieOtherItems(cookie, ['SESSDATA']));
|
|
124
|
+
const { w_rid, time_stamp } = await getWbiSign(data, BiliApi.BILIBILI_HEADERS, signCookie);
|
|
125
|
+
const params = {
|
|
126
|
+
...data,
|
|
127
|
+
w_rid: w_rid,
|
|
128
|
+
wts: time_stamp
|
|
129
|
+
};
|
|
130
|
+
const res = await axios(url, {
|
|
131
|
+
method: 'GET',
|
|
132
|
+
params,
|
|
133
|
+
timeout: 5000,
|
|
134
|
+
headers: lodash.merge(BiliApi.BILIBILI_HEADERS, {
|
|
135
|
+
Cookie: `${cookie}`,
|
|
136
|
+
Host: `api.bilibili.com`,
|
|
137
|
+
Origin: 'https://www.bilibili.com',
|
|
138
|
+
Referer: referer
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
return res;
|
|
142
|
+
}
|
|
143
|
+
/*通过视频短链url获取bvid*/
|
|
144
|
+
async getBVIDByShortUrl(tvUrlID) {
|
|
145
|
+
const ShortVideoUrlApi = BiliApi.BILIBIL_API.biliShortVideoUrl;
|
|
146
|
+
const url = `${ShortVideoUrlApi}${tvUrlID}`;
|
|
147
|
+
let { cookie } = await readSyncCookie();
|
|
148
|
+
cookie = await cookieWithBiliTicket(cookie);
|
|
149
|
+
const res = await axios(url, {
|
|
150
|
+
method: 'GET',
|
|
151
|
+
timeout: 5000,
|
|
152
|
+
headers: lodash.merge(BiliApi.BILIBILI_DYNAMIC_SPACE_HEADERS, {
|
|
153
|
+
Cookie: `${cookie}`
|
|
154
|
+
})
|
|
155
|
+
});
|
|
156
|
+
const htmlContent = await res.data;
|
|
157
|
+
const htmlContentRegex = /itemprop="url"\s*content="https:\/\/www.bilibili.com\/video\/(BV[a-zA-Z0-9]+)\/">/;
|
|
158
|
+
const BVID = htmlContent.match(htmlContentRegex)?.[1];
|
|
159
|
+
return `${BVID}`;
|
|
160
|
+
}
|
|
112
161
|
}
|
|
113
162
|
|
|
114
|
-
export {
|
|
163
|
+
export { BilibiliWebDataFetcher };
|