yz-yuki-plugin 1.0.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 +7 -0
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/defaultConfig/bilibili/config.yaml +41 -0
- package/defaultConfig/bilibili/push.yaml +0 -0
- package/defaultConfig/help/help.yaml +86 -0
- package/defaultConfig/weibo/config.yaml +41 -0
- package/defaultConfig/weibo/push.yaml +0 -0
- package/lib/apps/bilibili.js +402 -0
- package/lib/apps/help.js +37 -0
- package/lib/apps/index.js +4 -0
- package/lib/apps/version.js +34 -0
- package/lib/apps/weibo.js +252 -0
- package/lib/components/dynamic/Account.js +26 -0
- package/lib/components/dynamic/Content.js +118 -0
- package/lib/components/dynamic/Footer.js +36 -0
- package/lib/components/dynamic/ForwardContent.js +15 -0
- package/lib/components/dynamic/LogoText.js +10 -0
- package/lib/components/dynamic/MainPage.js +22 -0
- package/lib/components/help/Help.js +33 -0
- package/lib/components/index.js +6 -0
- package/lib/components/loginQrcode/Page.js +21 -0
- package/lib/components/version/Version.js +27 -0
- package/lib/index.js +29 -0
- package/lib/models/bilibili/bilibili.api.js +49 -0
- package/lib/models/bilibili/bilibili.get.web.data.js +80 -0
- package/lib/models/bilibili/bilibili.models.js +484 -0
- package/lib/models/bilibili/bilibili.query.js +393 -0
- package/lib/models/bilibili/bilibili.task.js +256 -0
- package/lib/models/bilibili/bilibili.wbi.js +49 -0
- package/lib/models/help/help.js +20 -0
- package/lib/models/version/version.js +62 -0
- package/lib/models/weibo/weibo.api.js +19 -0
- package/lib/models/weibo/weibo.get.web.data.js +55 -0
- package/lib/models/weibo/weibo.query.js +323 -0
- package/lib/models/weibo/weibo.task.js +215 -0
- package/lib/types/apps/bilibili.d.ts +6 -0
- package/lib/types/apps/help.d.ts +6 -0
- package/lib/types/apps/index.d.ts +4 -0
- package/lib/types/apps/version.d.ts +6 -0
- package/lib/types/apps/weibo.d.ts +6 -0
- package/lib/types/components/dynamic/Account.d.ts +13 -0
- package/lib/types/components/dynamic/Content.d.ts +12 -0
- package/lib/types/components/dynamic/Footer.d.ts +11 -0
- package/lib/types/components/dynamic/ForwardContent.d.ts +6 -0
- package/lib/types/components/dynamic/LogoText.d.ts +9 -0
- package/lib/types/components/dynamic/MainPage.d.ts +34 -0
- package/lib/types/components/help/Help.d.ts +12 -0
- package/lib/types/components/index.d.ts +5 -0
- package/lib/types/components/loginQrcode/Page.d.ts +7 -0
- package/lib/types/components/version/Version.d.ts +8 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/models/bilibili/bilibili.api.d.ts +47 -0
- package/lib/types/models/bilibili/bilibili.buid.fp.d.ts +2 -0
- package/lib/types/models/bilibili/bilibili.get.web.data.d.ts +6 -0
- package/lib/types/models/bilibili/bilibili.models.d.ts +20 -0
- package/lib/types/models/bilibili/bilibili.query.d.ts +13 -0
- package/lib/types/models/bilibili/bilibili.task.d.ts +18 -0
- package/lib/types/models/bilibili/bilibili.wbi.d.ts +5 -0
- package/lib/types/models/help/help.d.ts +8 -0
- package/lib/types/models/version/version.d.ts +7 -0
- package/lib/types/models/weibo/weibo.api.d.ts +17 -0
- package/lib/types/models/weibo/weibo.get.web.data.d.ts +8 -0
- package/lib/types/models/weibo/weibo.query.d.ts +18 -0
- package/lib/types/models/weibo/weibo.task.d.ts +17 -0
- package/lib/types/utils/config.d.ts +21 -0
- package/lib/types/utils/image.d.ts +10 -0
- package/lib/types/utils/paths.d.ts +10 -0
- package/lib/types/utils/puppeteer.render.d.ts +23 -0
- package/lib/utils/config.js +108 -0
- package/lib/utils/image.js +26 -0
- package/lib/utils/paths.js +18 -0
- package/lib/utils/puppeteer.render.js +102 -0
- package/package.json +106 -0
- package/public/output.css +1 -0
- package/resources/css/dynamic/Account.css +68 -0
- package/resources/css/dynamic/Content.box.grid.4.css +4 -0
- package/resources/css/dynamic/Content.box.grid.9.css +4 -0
- package/resources/css/dynamic/Content.css +87 -0
- package/resources/css/dynamic/Footer.css +44 -0
- package/resources/css/dynamic/ForwardContent.css +11 -0
- package/resources/css/dynamic/LogoText.css +15 -0
- package/resources/css/dynamic/MainPage.css +93 -0
- package/resources/css/help/help.css +182 -0
- package/resources/css/loginQrcode/Page.css +55 -0
- package/resources/css/version/version.css +116 -0
- package/resources/fonts/iconfont.16acc2.ttf +0 -0
- package/resources/img/background/Girl.png +0 -0
- package/resources/img/icon/dynamic/bili-rich-text-module-goods-taobao.svg +1 -0
- package/resources/img/icon/dynamic/bili-rich-text-module-lottery.svg +1 -0
- package/resources/img/icon/dynamic/bilibili.svg +6 -0
- package/resources/img/icon/dynamic/weibo.svg +43 -0
- package/resources/img/icon/puplic/archaic_stone.png +0 -0
- package/resources/img/icon/puplic/condessence_crystal.png +0 -0
- package/resources/img/icon/puplic/delightful_encounter.png +0 -0
- package/resources/img/icon/puplic/diagram.png +0 -0
- package/resources/img/icon/puplic/essence_of_pure_sacred_dewdrop.png +0 -0
- package/resources/img/icon/puplic/everamber.png +0 -0
- package/resources/img/icon/puplic/flower_1.png +0 -0
- package/resources/img/icon/puplic/flower_2.png +0 -0
- package/resources/img/icon/puplic/kamera.png +0 -0
- package/resources/img/icon/puplic/lumidouce_bell.png +0 -0
- package/resources/img/icon/puplic/mora.png +0 -0
- package/resources/img/icon/puplic/pluie_lotus.png +0 -0
- package/resources/img/icon/puplic/restaurant_smoothie.png +0 -0
- package/resources/img/icon/puplic/romaritime_flower.png +0 -0
- package/resources/img/icon/puplic/shell.png +0 -0
- package/resources/img/icon/puplic/spring_of_pure_sacred_dewdrop.png +0 -0
- package/resources/img/icon/puplic/surging_sacred_chalice.png +0 -0
- package/resources/img/icon/puplic/tourbillon_device.png +0 -0
- package/resources/img/icon/puplic/unfading_silky_grace.png +0 -0
- package/resources/img/icon/puplic/wisdom.png +0 -0
- package/resources/img/icon/puplic/wondrous_lovely_flower.png +0 -0
- package/resources/img/icon/puplic//345/262/251/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
- package/resources/img/icon/puplic//346/260/264/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
- package/resources/img/icon/puplic//350/215/211/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
- package/resources/img/icon/puplic//351/222/223/351/261/274.png +0 -0
- package/resources/img/icon/puplic//351/233/267/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
- package/resources/img/icon/puplic//351/243/216/347/245/236/347/236/263/345/205/261/351/270/243/347/237/263.png +0 -0
- package/resources/img/icon/puplic//351/243/216/350/275/246.png +0 -0
- package/resources/img/readme/girl.png +0 -0
- package/resources/img/readme/min-Girl.png +0 -0
- package/resources/img/readme/mini-help.jpg +0 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
import { Bot, Segment } from 'yunzai';
|
|
3
|
+
|
|
4
|
+
class BiliQuery {
|
|
5
|
+
static formatDynamicData(data) {
|
|
6
|
+
const BiliDrawDynamicLinkUrl = "https://m.bilibili.com/dynamic/";
|
|
7
|
+
let desc, pics = [], majorType;
|
|
8
|
+
let formatData = { data: {} };
|
|
9
|
+
const author = data?.modules?.module_author || {};
|
|
10
|
+
formatData.data.face = author.face;
|
|
11
|
+
formatData.data.name = author.name;
|
|
12
|
+
formatData.data.pendant = author?.pendant?.image || data?.pendant?.image;
|
|
13
|
+
formatData.data.created = moment().format("YYYY年MM月DD日 HH:mm:ss");
|
|
14
|
+
formatData.data.type = data.type;
|
|
15
|
+
switch (data.type) {
|
|
16
|
+
case "DYNAMIC_TYPE_AV":
|
|
17
|
+
desc = data?.modules?.module_dynamic?.major?.archive || {};
|
|
18
|
+
formatData.data.title = desc?.title;
|
|
19
|
+
formatData.data.content = this.parseRichTextNodes(desc?.desc);
|
|
20
|
+
formatData.data.url = this.formatUrl(desc?.jump_url);
|
|
21
|
+
formatData.data.pubTime = author.pub_time;
|
|
22
|
+
formatData.data.pubTs = moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss");
|
|
23
|
+
formatData.data.category = "视频动态";
|
|
24
|
+
formatData.data.pics = [{ url: desc?.cover }];
|
|
25
|
+
break;
|
|
26
|
+
case "DYNAMIC_TYPE_WORD":
|
|
27
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
28
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
29
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
30
|
+
pics = desc?.pics;
|
|
31
|
+
pics = pics.map((item) => { return { url: item?.url, width: item?.width, height: item?.height }; }) || [];
|
|
32
|
+
formatData.data.content = this.parseRichTextNodes(desc?.summary?.rich_text_nodes || desc?.summary?.text) || "";
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
desc = data?.modules?.module_dynamic?.desc || {};
|
|
36
|
+
pics = data?.modules?.module_dynamic?.major?.draw?.items;
|
|
37
|
+
pics = [];
|
|
38
|
+
formatData.data.content = this.parseRichTextNodes(desc?.text);
|
|
39
|
+
}
|
|
40
|
+
formatData.data.title = "";
|
|
41
|
+
formatData.data.url = `${BiliDrawDynamicLinkUrl}${data.id_str}`;
|
|
42
|
+
formatData.data.pubTime = author.pub_time;
|
|
43
|
+
formatData.data.pubTs = moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss");
|
|
44
|
+
formatData.data.category = "图文动态";
|
|
45
|
+
break;
|
|
46
|
+
case "DYNAMIC_TYPE_DRAW":
|
|
47
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
48
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
49
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
50
|
+
pics = desc?.pics;
|
|
51
|
+
pics = pics.map((item) => { return { url: item?.url, width: item?.width, height: item?.height }; });
|
|
52
|
+
formatData.data.content = this.parseRichTextNodes(desc?.summary?.rich_text_nodes || desc?.summary?.text) || "";
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
desc = data?.modules?.module_dynamic?.desc;
|
|
56
|
+
pics = data?.modules?.module_dynamic?.major?.draw?.items;
|
|
57
|
+
pics = pics.map((item) => { return { url: item?.src }; });
|
|
58
|
+
formatData.data.content = this.parseRichTextNodes(desc?.text);
|
|
59
|
+
}
|
|
60
|
+
formatData.data.title = "";
|
|
61
|
+
formatData.data.url = `${BiliDrawDynamicLinkUrl}${data.id_str}`;
|
|
62
|
+
formatData.data.pubTime = author.pub_time;
|
|
63
|
+
formatData.data.pubTs = moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss");
|
|
64
|
+
formatData.data.pics = pics;
|
|
65
|
+
formatData.data.category = "图文动态";
|
|
66
|
+
break;
|
|
67
|
+
case "DYNAMIC_TYPE_ARTICLE":
|
|
68
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
69
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
70
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
71
|
+
pics = desc?.pics;
|
|
72
|
+
pics = pics.map((item) => { return { url: item?.url, width: item?.width, height: item?.height }; }) || [];
|
|
73
|
+
formatData.data.title = desc?.title;
|
|
74
|
+
formatData.data.pics = pics;
|
|
75
|
+
formatData.data.content = this.parseRichTextNodes(desc?.summary?.rich_text_nodes || desc?.summary?.text) || "";
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
desc = data?.modules?.module_dynamic?.major?.article || {};
|
|
79
|
+
if (desc.covers && desc.covers.length) {
|
|
80
|
+
pics = [{ url: desc?.covers }];
|
|
81
|
+
}
|
|
82
|
+
formatData.data.title = desc?.title;
|
|
83
|
+
formatData.data.pics = pics;
|
|
84
|
+
formatData.data.content = "";
|
|
85
|
+
}
|
|
86
|
+
formatData.data.url = this.formatUrl(desc?.jump_url);
|
|
87
|
+
formatData.data.pubTime = author.pub_time;
|
|
88
|
+
formatData.data.pubTs = moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss");
|
|
89
|
+
formatData.data.category = "文章动态";
|
|
90
|
+
break;
|
|
91
|
+
case "DYNAMIC_TYPE_FORWARD":
|
|
92
|
+
desc = data?.modules?.module_dynamic?.desc || {};
|
|
93
|
+
formatData.data.title = "";
|
|
94
|
+
formatData.data.content = this.parseRichTextNodes(desc?.rich_text_nodes) || this.parseRichTextNodes(desc?.text);
|
|
95
|
+
formatData.data.pubTime = author.pub_time;
|
|
96
|
+
formatData.data.pubTs = moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss");
|
|
97
|
+
formatData.data.url = `${BiliDrawDynamicLinkUrl}${data.id_str}`;
|
|
98
|
+
formatData.data.pics = [data?.cover];
|
|
99
|
+
formatData.data.orig = this.formatDynamicData(data.orig);
|
|
100
|
+
formatData.data.category = "转发动态";
|
|
101
|
+
break;
|
|
102
|
+
case "DYNAMIC_TYPE_LIVE_RCMD":
|
|
103
|
+
desc = data?.modules?.module_dynamic?.major?.live_rcmd?.content;
|
|
104
|
+
if (!desc)
|
|
105
|
+
break;
|
|
106
|
+
desc = JSON.parse(desc);
|
|
107
|
+
desc = desc?.live_play_info;
|
|
108
|
+
if (!desc)
|
|
109
|
+
break;
|
|
110
|
+
formatData.data.title = desc?.title;
|
|
111
|
+
formatData.data.content = "";
|
|
112
|
+
formatData.data.pubTime = "";
|
|
113
|
+
formatData.data.pubTs = "";
|
|
114
|
+
formatData.data.url = `https:${desc.link}`;
|
|
115
|
+
formatData.data.pics = [{ url: desc?.cover }];
|
|
116
|
+
formatData.data.category = "直播动态";
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
...formatData,
|
|
121
|
+
uid: data?.id_str,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
;
|
|
125
|
+
static parseRichTextNodes = (nodes) => {
|
|
126
|
+
if (typeof nodes === 'string') {
|
|
127
|
+
return nodes.replace(/\n/g, '<br>');
|
|
128
|
+
}
|
|
129
|
+
else if (Array.isArray(nodes)) {
|
|
130
|
+
return nodes.map((node) => {
|
|
131
|
+
switch (node.type) {
|
|
132
|
+
case 'RICH_TEXT_NODE_TYPE_TOPIC':
|
|
133
|
+
let jumpUrl = node?.jump_url;
|
|
134
|
+
if (jumpUrl && !jumpUrl.startsWith('http://') && !jumpUrl.startsWith('https://')) {
|
|
135
|
+
jumpUrl = `https://${jumpUrl}`;
|
|
136
|
+
}
|
|
137
|
+
return `<span class="bili-rich-text-module topic" href="${jumpUrl}">${node?.text}</span>`;
|
|
138
|
+
case 'RICH_TEXT_NODE_TYPE_TEXT':
|
|
139
|
+
return node.text.replace(/\n/g, '<br>');
|
|
140
|
+
case 'RICH_TEXT_NODE_TYPE_AT':
|
|
141
|
+
return `<span data-module="desc" data-type="at" data-oid="${node?.rid}" class="bili-rich-text-module at">${node?.text}</span>`;
|
|
142
|
+
case 'RICH_TEXT_NODE_TYPE_LOTTERY':
|
|
143
|
+
return `<span data-module="desc" data-type="lottery" data-oid="${node?.rid}" class="bili-rich-text-module lottery">${node?.text}</span>`;
|
|
144
|
+
case 'RICH_TEXT_NODE_TYPE_WEB':
|
|
145
|
+
return node.text;
|
|
146
|
+
case 'RICH_TEXT_NODE_TYPE_EMOJI':
|
|
147
|
+
const emoji = node.emoji;
|
|
148
|
+
return `<img src="${emoji?.icon_url}" alt="${emoji?.text}" title="${emoji?.text}" style="vertical-align: middle; width: ${emoji?.size}em; height: ${emoji?.size}em;">`;
|
|
149
|
+
case 'RICH_TEXT_NODE_TYPE_GOODS':
|
|
150
|
+
const goods_url = node?.jump_url;
|
|
151
|
+
return `<span data-module="desc" data-type="goods" data-url="${goods_url}" data-oid="${node?.rid}" class="bili-rich-text-module goods ${node?.icon_name}">​${node?.text}</span>`;
|
|
152
|
+
default:
|
|
153
|
+
return node;
|
|
154
|
+
}
|
|
155
|
+
}).join('');
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return nodes;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
static formatUrl(url) {
|
|
162
|
+
return 0 == url.indexOf('//') ? `https:${url}` : url;
|
|
163
|
+
}
|
|
164
|
+
static async formatTextDynamicData(upName, data, isForward, setData) {
|
|
165
|
+
const BiliDrawDynamicLinkUrl = "https://m.bilibili.com/dynamic/";
|
|
166
|
+
let desc, msg, pics, author, majorType, content, dynamicTitle;
|
|
167
|
+
let title = `B站【${upName}】动态推送:\n`;
|
|
168
|
+
switch (data.type) {
|
|
169
|
+
case "DYNAMIC_TYPE_AV":
|
|
170
|
+
desc = data?.modules?.module_dynamic?.major?.archive;
|
|
171
|
+
author = data?.modules?.module_author;
|
|
172
|
+
if (!desc && !author)
|
|
173
|
+
return;
|
|
174
|
+
title = `B站【${upName}】视频动态推送:\n`;
|
|
175
|
+
msg = [
|
|
176
|
+
title,
|
|
177
|
+
`-----------------------------\n`,
|
|
178
|
+
`标题:${desc.title}\n`,
|
|
179
|
+
`${desc.desc}\n`,
|
|
180
|
+
`链接:${this.formatUrl(desc.jump_url)}\n`,
|
|
181
|
+
`时间:${author ? moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss") : ""}\n`,
|
|
182
|
+
Segment.image(desc?.cover),
|
|
183
|
+
];
|
|
184
|
+
return msg;
|
|
185
|
+
case "DYNAMIC_TYPE_WORD":
|
|
186
|
+
author = data?.modules?.module_author;
|
|
187
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
188
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
189
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
190
|
+
pics = desc?.pics;
|
|
191
|
+
pics = pics.map((item) => { return item?.url; }) || [];
|
|
192
|
+
content = this.parseRichTextNodes(desc?.summary?.text) || "";
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
desc = data?.modules?.module_dynamic?.desc || {};
|
|
196
|
+
pics = data?.modules?.module_dynamic?.major?.draw?.items;
|
|
197
|
+
pics = [];
|
|
198
|
+
content = this.parseRichTextNodes(desc?.text);
|
|
199
|
+
}
|
|
200
|
+
if (!desc && !author)
|
|
201
|
+
return;
|
|
202
|
+
title = `B站【${upName}】动态推送:\n`;
|
|
203
|
+
msg = [
|
|
204
|
+
title,
|
|
205
|
+
`-----------------------------\n`,
|
|
206
|
+
`内容:${this.dynamicContentLimit(content, setData)}\n`,
|
|
207
|
+
`链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
|
|
208
|
+
`时间:${author ? moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss") : ""}`,
|
|
209
|
+
];
|
|
210
|
+
return msg;
|
|
211
|
+
case "DYNAMIC_TYPE_DRAW":
|
|
212
|
+
author = data?.modules?.module_author;
|
|
213
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
214
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
215
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
216
|
+
pics = desc?.pics;
|
|
217
|
+
pics = pics.map((item) => {
|
|
218
|
+
return item.url;
|
|
219
|
+
});
|
|
220
|
+
content = this.parseRichTextNodes(desc?.summary?.text) || "";
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
desc = data?.modules?.module_dynamic?.desc;
|
|
224
|
+
pics = data?.modules?.module_dynamic?.major?.draw?.items;
|
|
225
|
+
pics = pics.map((item) => { return item?.src; });
|
|
226
|
+
content = this.parseRichTextNodes(desc?.text);
|
|
227
|
+
}
|
|
228
|
+
if (!desc && !pics && !author)
|
|
229
|
+
return;
|
|
230
|
+
const dynamicPicCountLimit = setData.pushPicCountLimit || 3;
|
|
231
|
+
if (pics.length > dynamicPicCountLimit) {
|
|
232
|
+
pics.length = dynamicPicCountLimit;
|
|
233
|
+
}
|
|
234
|
+
pics = pics.map((item) => {
|
|
235
|
+
return Segment.image(item);
|
|
236
|
+
});
|
|
237
|
+
title = `B站【${upName}】图文动态推送:\n`;
|
|
238
|
+
msg = [
|
|
239
|
+
title,
|
|
240
|
+
`-----------------------------\n`,
|
|
241
|
+
`${this.dynamicContentLimit(content, setData)}\n`,
|
|
242
|
+
`链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
|
|
243
|
+
`时间:${author ? moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss") : ""}\n`,
|
|
244
|
+
...pics,
|
|
245
|
+
];
|
|
246
|
+
return msg;
|
|
247
|
+
case "DYNAMIC_TYPE_ARTICLE":
|
|
248
|
+
author = data?.modules?.module_author;
|
|
249
|
+
majorType = data?.modules?.module_dynamic?.major?.type;
|
|
250
|
+
if (majorType === "MAJOR_TYPE_OPUS") {
|
|
251
|
+
desc = data?.modules?.module_dynamic?.major?.opus || {};
|
|
252
|
+
pics = desc?.pics;
|
|
253
|
+
pics = pics.map((item) => { return item.url; }) || [];
|
|
254
|
+
dynamicTitle = desc?.title;
|
|
255
|
+
content = this.parseRichTextNodes(desc?.summary?.rich_text_nodes || desc?.summary?.text) || "";
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
desc = data?.modules?.module_dynamic?.major?.article || {};
|
|
259
|
+
if (desc.covers && desc.covers.length) {
|
|
260
|
+
pics = [desc?.covers];
|
|
261
|
+
}
|
|
262
|
+
dynamicTitle = desc?.title;
|
|
263
|
+
pics = pics;
|
|
264
|
+
content = "";
|
|
265
|
+
}
|
|
266
|
+
if (!desc && !author)
|
|
267
|
+
return;
|
|
268
|
+
pics = pics.map((item) => {
|
|
269
|
+
return Segment.image(item);
|
|
270
|
+
});
|
|
271
|
+
title = `B站【${upName}】文章动态推送:\n`;
|
|
272
|
+
msg = [
|
|
273
|
+
title,
|
|
274
|
+
`-----------------------------\n`,
|
|
275
|
+
`标题:${dynamicTitle}\n`,
|
|
276
|
+
`链接:${this.formatUrl(desc.jump_url)}\n`,
|
|
277
|
+
`时间:${author ? moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss") : ""}\n`,
|
|
278
|
+
...pics,
|
|
279
|
+
];
|
|
280
|
+
return msg;
|
|
281
|
+
case "DYNAMIC_TYPE_FORWARD":
|
|
282
|
+
author = data?.modules?.module_author;
|
|
283
|
+
desc = data?.modules?.module_dynamic?.desc || {};
|
|
284
|
+
content = this.parseRichTextNodes(desc?.text);
|
|
285
|
+
if (!desc && !author)
|
|
286
|
+
return;
|
|
287
|
+
if (!data.orig)
|
|
288
|
+
return;
|
|
289
|
+
isForward = true;
|
|
290
|
+
let orig = await this.formatTextDynamicData(upName, data.orig, isForward, setData);
|
|
291
|
+
if (orig && orig.length) {
|
|
292
|
+
orig = orig.slice(2);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
title = `B站【${upName}】转发动态推送:\n`;
|
|
298
|
+
msg = [
|
|
299
|
+
title,
|
|
300
|
+
`-----------------------------\n`,
|
|
301
|
+
`${this.dynamicContentLimit(content, setData)}\n`,
|
|
302
|
+
`链接:${BiliDrawDynamicLinkUrl}${data.id_str}\n`,
|
|
303
|
+
`时间:${author ? moment(author.pub_ts * 1000).format("YYYY年MM月DD日 HH:mm:ss") : ""}\n`,
|
|
304
|
+
"\n---以下为转发内容---\n",
|
|
305
|
+
...orig,
|
|
306
|
+
];
|
|
307
|
+
return msg;
|
|
308
|
+
case "DYNAMIC_TYPE_LIVE_RCMD":
|
|
309
|
+
desc = data?.modules?.module_dynamic?.major?.live_rcmd?.content;
|
|
310
|
+
if (!desc)
|
|
311
|
+
return;
|
|
312
|
+
desc = JSON.parse(desc);
|
|
313
|
+
desc = desc?.live_play_info;
|
|
314
|
+
if (!desc)
|
|
315
|
+
return;
|
|
316
|
+
title = `B站【${upName}】直播动态推送:\n`;
|
|
317
|
+
msg = [
|
|
318
|
+
title,
|
|
319
|
+
`-----------------------------\n`,
|
|
320
|
+
`标题:${desc.title}\n`,
|
|
321
|
+
`链接:https:${desc.link}\n`,
|
|
322
|
+
Segment.image(desc.cover),
|
|
323
|
+
];
|
|
324
|
+
return msg;
|
|
325
|
+
default:
|
|
326
|
+
(Bot.logger ?? logger)?.mark(`未处理的B站推送【${upName}】:${data.type}`);
|
|
327
|
+
return "continue";
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
static dynamicContentLimit(content, setData) {
|
|
331
|
+
const lines = content.split("\n");
|
|
332
|
+
const lengthLimit = setData.pushContentLenLimit || 100;
|
|
333
|
+
const lineLimit = setData.pushContentLineLimit || 5;
|
|
334
|
+
if (lines.length > lineLimit) {
|
|
335
|
+
lines.length = lineLimit;
|
|
336
|
+
}
|
|
337
|
+
let totalLength = 0;
|
|
338
|
+
for (let i = 0; i < lines.length; i++) {
|
|
339
|
+
const remainingLength = lengthLimit - totalLength;
|
|
340
|
+
if (totalLength >= lengthLimit) {
|
|
341
|
+
lines.splice(i--, 1);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (lines[i].length > remainingLength) {
|
|
345
|
+
lines[i] = lines[i].slice(0, remainingLength) + "...";
|
|
346
|
+
totalLength = lengthLimit;
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
totalLength += lines[i].length;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return lines.join("\n");
|
|
353
|
+
}
|
|
354
|
+
static typeHandle(up, msg, type) {
|
|
355
|
+
const typeMap = {
|
|
356
|
+
"直播": "DYNAMIC_TYPE_LIVE_RCMD",
|
|
357
|
+
"转发": "DYNAMIC_TYPE_FORWARD",
|
|
358
|
+
"文章": "DYNAMIC_TYPE_ARTICLE",
|
|
359
|
+
"图文": ["DYNAMIC_TYPE_DRAW", "DYNAMIC_TYPE_WORD"],
|
|
360
|
+
"视频": "DYNAMIC_TYPE_AV"
|
|
361
|
+
};
|
|
362
|
+
let newType = new Set(up.type || []);
|
|
363
|
+
const handleType = (action) => {
|
|
364
|
+
let isHandled = false;
|
|
365
|
+
for (const [key, value] of Object.entries(typeMap)) {
|
|
366
|
+
if (msg.indexOf(key) !== -1) {
|
|
367
|
+
if (Array.isArray(value)) {
|
|
368
|
+
value.forEach(v => action === "add" ? newType.add(v) : newType.delete(v));
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
action === "add" ? newType.add(value) : newType.delete(value);
|
|
372
|
+
}
|
|
373
|
+
isHandled = true;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return isHandled;
|
|
377
|
+
};
|
|
378
|
+
if (type === "add") {
|
|
379
|
+
handleType("add");
|
|
380
|
+
}
|
|
381
|
+
else if (type === "del") {
|
|
382
|
+
if (!newType.size) {
|
|
383
|
+
newType = new Set(Object.values(typeMap).flat());
|
|
384
|
+
}
|
|
385
|
+
if (!handleType("delete")) {
|
|
386
|
+
newType.clear();
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return Array.from(newType);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export { BiliQuery };
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import QRCode from 'qrcode';
|
|
2
|
+
import { Redis, Bot, Segment } from 'yunzai';
|
|
3
|
+
import Config from '../../utils/config.js';
|
|
4
|
+
import Image 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';
|
|
8
|
+
|
|
9
|
+
class BiliTask {
|
|
10
|
+
taskName;
|
|
11
|
+
key;
|
|
12
|
+
e;
|
|
13
|
+
constructor(e) {
|
|
14
|
+
this.taskName = "biliTask";
|
|
15
|
+
this.key = "Yz:yuki:bili:upPush:";
|
|
16
|
+
}
|
|
17
|
+
async hendleEventDynamicData(uid, count = 0) {
|
|
18
|
+
const resp = await new BiliGetWebData().getBiliDynamicListDataByUid(uid);
|
|
19
|
+
const resjson = await resp.data;
|
|
20
|
+
let { cookie } = await readSyncCookie();
|
|
21
|
+
if (resjson.code === 0) {
|
|
22
|
+
return resjson;
|
|
23
|
+
}
|
|
24
|
+
else if (resjson.code === -352) {
|
|
25
|
+
await postGateway(cookie);
|
|
26
|
+
if (count < 3) {
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (10500 - 2000 + 1) + 2000)));
|
|
28
|
+
await this.hendleEventDynamicData(uid, count + 1);
|
|
29
|
+
logger.error(`获取 ${uid} 动态,Gateway count:${String(count)}`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
count = 0;
|
|
33
|
+
return resjson;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (resjson.code !== 0) {
|
|
37
|
+
return resjson;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async runTask() {
|
|
41
|
+
let biliConfigData = await Config.getUserConfig("bilibili", "config");
|
|
42
|
+
let biliPushData = await Config.getUserConfig("bilibili", "push");
|
|
43
|
+
let interval = biliConfigData.interval || 7200;
|
|
44
|
+
let lastLiveStatus = JSON.parse(await Redis.get("yuki:bililive:lastlivestatus")) || {};
|
|
45
|
+
const uidMap = new Map();
|
|
46
|
+
const dynamicList = {};
|
|
47
|
+
await this.processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus);
|
|
48
|
+
let now = Date.now() / 1000;
|
|
49
|
+
await this.pushDynamicMessages(uidMap, dynamicList, now, interval, biliConfigData);
|
|
50
|
+
}
|
|
51
|
+
async processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus) {
|
|
52
|
+
for (let chatType in biliPushData) {
|
|
53
|
+
for (let chatId in biliPushData[chatType]) {
|
|
54
|
+
const subUpsOfChat = biliPushData[chatType][chatId] || [];
|
|
55
|
+
for (let subInfoOfup of subUpsOfChat) {
|
|
56
|
+
if (!lastLiveStatus[subInfoOfup.uid]) {
|
|
57
|
+
lastLiveStatus[subInfoOfup.uid] = 0;
|
|
58
|
+
}
|
|
59
|
+
const resp = await this.hendleEventDynamicData(subInfoOfup.uid);
|
|
60
|
+
if (resp) {
|
|
61
|
+
if (resp.code === 0) {
|
|
62
|
+
const dynamicData = resp.data?.items || [];
|
|
63
|
+
dynamicList[subInfoOfup.uid] = dynamicData;
|
|
64
|
+
}
|
|
65
|
+
else if (resp.code === -352) {
|
|
66
|
+
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:-352`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
else if (resp.code !== 0) {
|
|
70
|
+
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resCode:${resp.code}`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
logger.error(`获取 ${subInfoOfup.uid} 动态失败,resp 为空`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const chatIds = Array.from(new Set([...Object((uidMap.get(subInfoOfup.uid) && uidMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
|
|
79
|
+
const bot_id = subInfoOfup.bot_id || [];
|
|
80
|
+
const { name, type } = subInfoOfup;
|
|
81
|
+
uidMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type, chatType });
|
|
82
|
+
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (4000 - 1000 + 1) + 1000)));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async pushDynamicMessages(uidMap, dynamicList, now, interval, biliConfigData) {
|
|
88
|
+
for (let [key, value] of uidMap) {
|
|
89
|
+
const tempDynamicList = dynamicList[key] || [];
|
|
90
|
+
const willPushDynamicList = [];
|
|
91
|
+
for (let dynamicItem of tempDynamicList) {
|
|
92
|
+
let author = dynamicItem?.modules?.module_author || {};
|
|
93
|
+
logger.info(`正在检测B站动态 [ ${author?.name} : ${author?.mid} ]`);
|
|
94
|
+
if (!author?.pub_ts)
|
|
95
|
+
continue;
|
|
96
|
+
if (Number(now - author.pub_ts) > interval) {
|
|
97
|
+
logger.info(`超过间隔时间,跳过该up [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit)
|
|
101
|
+
continue;
|
|
102
|
+
willPushDynamicList.push(dynamicItem);
|
|
103
|
+
}
|
|
104
|
+
const pushMapInfo = value || {};
|
|
105
|
+
const { chatIds, bot_id, upName, type, chatType } = pushMapInfo;
|
|
106
|
+
for (let pushDynamicData of willPushDynamicList) {
|
|
107
|
+
if (chatIds && chatIds.length) {
|
|
108
|
+
for (let chatId of chatIds) {
|
|
109
|
+
if (type && type.length && !type.includes(pushDynamicData.type))
|
|
110
|
+
continue;
|
|
111
|
+
await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType);
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000)));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType) {
|
|
119
|
+
const id_str = pushDynamicData.id_str;
|
|
120
|
+
let sended = await Redis.get(`${this.key}${chatId}:${id_str}`);
|
|
121
|
+
if (sended)
|
|
122
|
+
return;
|
|
123
|
+
if (!!biliConfigData.pushMsgMode) {
|
|
124
|
+
const { data, uid } = await BiliQuery.formatDynamicData(pushDynamicData);
|
|
125
|
+
const extentData = { ...data };
|
|
126
|
+
const eval2 = eval;
|
|
127
|
+
let banWords = eval2(`/${biliConfigData.banWords.join("|")}/g`);
|
|
128
|
+
if (new RegExp(banWords).test(`${extentData?.title}${extentData?.content}`)) {
|
|
129
|
+
return "return";
|
|
130
|
+
}
|
|
131
|
+
let boxGrid = !!biliConfigData.boxGrid === false ? false : true;
|
|
132
|
+
let isSplit = !!biliConfigData.isSplit === false ? false : true;
|
|
133
|
+
let style = isSplit ? '' : '.unfold { height: 7500px; }';
|
|
134
|
+
const urlQrcodeData = await QRCode.toDataURL(extentData?.url);
|
|
135
|
+
let renderData = this.buildRenderData(extentData, urlQrcodeData, boxGrid);
|
|
136
|
+
const ScreenshotOptionsData = {
|
|
137
|
+
addStyle: style,
|
|
138
|
+
header: { 'Referer': 'https://space.bilibili.com/' },
|
|
139
|
+
isSplit: isSplit,
|
|
140
|
+
modelName: 'bilibili',
|
|
141
|
+
SOptions: {
|
|
142
|
+
type: 'jpeg',
|
|
143
|
+
quality: 98,
|
|
144
|
+
},
|
|
145
|
+
saveHtmlfile: false,
|
|
146
|
+
};
|
|
147
|
+
let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
|
|
148
|
+
if (!imgs)
|
|
149
|
+
return;
|
|
150
|
+
Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
|
|
151
|
+
(logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");
|
|
152
|
+
for (let i = 0; i < imgs.length; i++) {
|
|
153
|
+
const image = imgs[i];
|
|
154
|
+
await this.sendMessage(chatId, bot_id, chatType, Segment.image(image));
|
|
155
|
+
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000)));
|
|
156
|
+
}
|
|
157
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData);
|
|
161
|
+
Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
|
|
162
|
+
if (dynamicMsg == "continue") {
|
|
163
|
+
return "return";
|
|
164
|
+
}
|
|
165
|
+
if (biliConfigData.banWords.length > 0) {
|
|
166
|
+
const banWords = new RegExp(biliConfigData.banWords.join("|"), "g");
|
|
167
|
+
if (banWords.test(dynamicMsg.join(""))) {
|
|
168
|
+
return "return";
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
await this.sendMessage(chatId, bot_id, chatType, dynamicMsg);
|
|
172
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
buildRenderData(extentData, urlQrcodeData, boxGrid) {
|
|
176
|
+
if (extentData.orig && (extentData.orig).length !== 0) {
|
|
177
|
+
return {
|
|
178
|
+
data: {
|
|
179
|
+
appName: "bilibili",
|
|
180
|
+
boxGrid: boxGrid,
|
|
181
|
+
type: extentData?.type,
|
|
182
|
+
face: extentData?.face,
|
|
183
|
+
pendant: extentData?.pendant,
|
|
184
|
+
name: extentData?.name,
|
|
185
|
+
pubTs: extentData?.pubTs,
|
|
186
|
+
title: extentData?.title,
|
|
187
|
+
content: extentData?.content,
|
|
188
|
+
urlImgData: urlQrcodeData,
|
|
189
|
+
created: extentData?.created,
|
|
190
|
+
pics: extentData?.pics,
|
|
191
|
+
category: extentData?.category,
|
|
192
|
+
orig: {
|
|
193
|
+
data: {
|
|
194
|
+
type: extentData?.orig?.data?.type,
|
|
195
|
+
face: extentData?.orig?.data?.face,
|
|
196
|
+
pendant: extentData?.orig?.data?.pendant,
|
|
197
|
+
name: extentData?.orig?.data?.name,
|
|
198
|
+
pubTs: extentData?.orig?.data?.pubTs,
|
|
199
|
+
title: extentData?.orig?.data?.title,
|
|
200
|
+
content: extentData?.orig?.data?.content,
|
|
201
|
+
pics: extentData?.orig?.data?.pics,
|
|
202
|
+
category: extentData?.orig?.data?.category,
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
return {
|
|
210
|
+
data: {
|
|
211
|
+
appName: "bilibili",
|
|
212
|
+
boxGrid: boxGrid,
|
|
213
|
+
type: extentData?.type,
|
|
214
|
+
face: extentData?.face,
|
|
215
|
+
pendant: extentData?.pendant,
|
|
216
|
+
name: extentData?.name,
|
|
217
|
+
pubTs: extentData?.pubTs,
|
|
218
|
+
title: extentData?.title,
|
|
219
|
+
content: extentData?.content,
|
|
220
|
+
urlImgData: urlQrcodeData,
|
|
221
|
+
created: extentData?.created,
|
|
222
|
+
pics: extentData?.pics,
|
|
223
|
+
category: extentData?.category,
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async renderDynamicCard(uid, renderData, ScreenshotOptionsData) {
|
|
229
|
+
const dynamicMsg = await Image.renderPage(uid, "MainPage", renderData, ScreenshotOptionsData);
|
|
230
|
+
if (dynamicMsg !== false) {
|
|
231
|
+
return dynamicMsg.img;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async sendMessage(chatId, bot_id, chatType, message) {
|
|
238
|
+
if (chatType === "group") {
|
|
239
|
+
await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(message)
|
|
240
|
+
.catch((error) => {
|
|
241
|
+
(logger ?? Bot.logger)?.error(`群组[${chatId}]推送失败:${JSON.stringify(error)}`);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
else if (chatType === "private") {
|
|
245
|
+
await (Bot[bot_id] ?? Bot)?.pickUser(String(chatId)).sendMsg(message)
|
|
246
|
+
.catch((error) => {
|
|
247
|
+
(logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
async randomDelay(min, max) {
|
|
252
|
+
await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (max - min + 1) + min)));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export { BiliTask };
|