yz-yuki-plugin 1.0.1-rc.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.
Files changed (124) hide show
  1. package/.puppeteerrc.cjs +4 -0
  2. package/CHANGELOG.md +7 -0
  3. package/LICENSE +21 -0
  4. package/README.md +195 -0
  5. package/defaultConfig/bilibili/config.yaml +41 -0
  6. package/defaultConfig/bilibili/push.yaml +0 -0
  7. package/defaultConfig/help/help.yaml +86 -0
  8. package/defaultConfig/weibo/config.yaml +41 -0
  9. package/defaultConfig/weibo/push.yaml +0 -0
  10. package/lib/apps/bilibili.js +402 -0
  11. package/lib/apps/help.js +37 -0
  12. package/lib/apps/index.js +4 -0
  13. package/lib/apps/version.js +34 -0
  14. package/lib/apps/weibo.js +252 -0
  15. package/lib/components/dynamic/Account.js +26 -0
  16. package/lib/components/dynamic/Content.js +118 -0
  17. package/lib/components/dynamic/Footer.js +36 -0
  18. package/lib/components/dynamic/ForwardContent.js +15 -0
  19. package/lib/components/dynamic/LogoText.js +10 -0
  20. package/lib/components/dynamic/MainPage.js +22 -0
  21. package/lib/components/help/Help.js +33 -0
  22. package/lib/components/index.js +6 -0
  23. package/lib/components/loginQrcode/Page.js +21 -0
  24. package/lib/components/version/Version.js +27 -0
  25. package/lib/index.js +29 -0
  26. package/lib/models/bilibili/bilibili.api.js +49 -0
  27. package/lib/models/bilibili/bilibili.get.web.data.js +80 -0
  28. package/lib/models/bilibili/bilibili.models.js +484 -0
  29. package/lib/models/bilibili/bilibili.query.js +393 -0
  30. package/lib/models/bilibili/bilibili.task.js +256 -0
  31. package/lib/models/bilibili/bilibili.wbi.js +49 -0
  32. package/lib/models/help/help.js +20 -0
  33. package/lib/models/version/version.js +62 -0
  34. package/lib/models/weibo/weibo.api.js +19 -0
  35. package/lib/models/weibo/weibo.get.web.data.js +55 -0
  36. package/lib/models/weibo/weibo.query.js +323 -0
  37. package/lib/models/weibo/weibo.task.js +215 -0
  38. package/lib/types/apps/bilibili.d.ts +6 -0
  39. package/lib/types/apps/help.d.ts +6 -0
  40. package/lib/types/apps/index.d.ts +4 -0
  41. package/lib/types/apps/version.d.ts +6 -0
  42. package/lib/types/apps/weibo.d.ts +6 -0
  43. package/lib/types/components/dynamic/Account.d.ts +13 -0
  44. package/lib/types/components/dynamic/Content.d.ts +12 -0
  45. package/lib/types/components/dynamic/Footer.d.ts +11 -0
  46. package/lib/types/components/dynamic/ForwardContent.d.ts +6 -0
  47. package/lib/types/components/dynamic/LogoText.d.ts +9 -0
  48. package/lib/types/components/dynamic/MainPage.d.ts +34 -0
  49. package/lib/types/components/help/Help.d.ts +12 -0
  50. package/lib/types/components/index.d.ts +5 -0
  51. package/lib/types/components/loginQrcode/Page.d.ts +7 -0
  52. package/lib/types/components/version/Version.d.ts +8 -0
  53. package/lib/types/index.d.ts +5 -0
  54. package/lib/types/models/bilibili/bilibili.api.d.ts +47 -0
  55. package/lib/types/models/bilibili/bilibili.buid.fp.d.ts +2 -0
  56. package/lib/types/models/bilibili/bilibili.get.web.data.d.ts +6 -0
  57. package/lib/types/models/bilibili/bilibili.models.d.ts +20 -0
  58. package/lib/types/models/bilibili/bilibili.query.d.ts +13 -0
  59. package/lib/types/models/bilibili/bilibili.task.d.ts +18 -0
  60. package/lib/types/models/bilibili/bilibili.wbi.d.ts +5 -0
  61. package/lib/types/models/help/help.d.ts +8 -0
  62. package/lib/types/models/version/version.d.ts +7 -0
  63. package/lib/types/models/weibo/weibo.api.d.ts +17 -0
  64. package/lib/types/models/weibo/weibo.get.web.data.d.ts +8 -0
  65. package/lib/types/models/weibo/weibo.query.d.ts +18 -0
  66. package/lib/types/models/weibo/weibo.task.d.ts +17 -0
  67. package/lib/types/utils/config.d.ts +21 -0
  68. package/lib/types/utils/image.d.ts +10 -0
  69. package/lib/types/utils/paths.d.ts +10 -0
  70. package/lib/types/utils/puppeteer.render.d.ts +23 -0
  71. package/lib/utils/config.js +108 -0
  72. package/lib/utils/image.js +26 -0
  73. package/lib/utils/paths.js +18 -0
  74. package/lib/utils/puppeteer.render.js +102 -0
  75. package/package.json +110 -0
  76. package/public/output.css +1 -0
  77. package/resources/css/dynamic/Account.css +68 -0
  78. package/resources/css/dynamic/Content.box.grid.4.css +4 -0
  79. package/resources/css/dynamic/Content.box.grid.9.css +4 -0
  80. package/resources/css/dynamic/Content.css +87 -0
  81. package/resources/css/dynamic/Footer.css +44 -0
  82. package/resources/css/dynamic/ForwardContent.css +11 -0
  83. package/resources/css/dynamic/LogoText.css +15 -0
  84. package/resources/css/dynamic/MainPage.css +93 -0
  85. package/resources/css/help/help.css +182 -0
  86. package/resources/css/loginQrcode/Page.css +55 -0
  87. package/resources/css/version/version.css +116 -0
  88. package/resources/fonts/iconfont.16acc2.ttf +0 -0
  89. package/resources/img/background/Girl.png +0 -0
  90. package/resources/img/icon/dynamic/bili-rich-text-module-goods-taobao.svg +1 -0
  91. package/resources/img/icon/dynamic/bili-rich-text-module-lottery.svg +1 -0
  92. package/resources/img/icon/dynamic/bilibili.svg +6 -0
  93. package/resources/img/icon/dynamic/weibo.svg +43 -0
  94. package/resources/img/icon/puplic/archaic_stone.png +0 -0
  95. package/resources/img/icon/puplic/condessence_crystal.png +0 -0
  96. package/resources/img/icon/puplic/delightful_encounter.png +0 -0
  97. package/resources/img/icon/puplic/diagram.png +0 -0
  98. package/resources/img/icon/puplic/essence_of_pure_sacred_dewdrop.png +0 -0
  99. package/resources/img/icon/puplic/everamber.png +0 -0
  100. package/resources/img/icon/puplic/flower_1.png +0 -0
  101. package/resources/img/icon/puplic/flower_2.png +0 -0
  102. package/resources/img/icon/puplic/kamera.png +0 -0
  103. package/resources/img/icon/puplic/lumidouce_bell.png +0 -0
  104. package/resources/img/icon/puplic/mora.png +0 -0
  105. package/resources/img/icon/puplic/pluie_lotus.png +0 -0
  106. package/resources/img/icon/puplic/restaurant_smoothie.png +0 -0
  107. package/resources/img/icon/puplic/romaritime_flower.png +0 -0
  108. package/resources/img/icon/puplic/shell.png +0 -0
  109. package/resources/img/icon/puplic/spring_of_pure_sacred_dewdrop.png +0 -0
  110. package/resources/img/icon/puplic/surging_sacred_chalice.png +0 -0
  111. package/resources/img/icon/puplic/tourbillon_device.png +0 -0
  112. package/resources/img/icon/puplic/unfading_silky_grace.png +0 -0
  113. package/resources/img/icon/puplic/wisdom.png +0 -0
  114. package/resources/img/icon/puplic/wondrous_lovely_flower.png +0 -0
  115. 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
  116. 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
  117. 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
  118. package/resources/img/icon/puplic//351/222/223/351/261/274.png +0 -0
  119. 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
  120. 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
  121. package/resources/img/icon/puplic//351/243/216/350/275/246.png +0 -0
  122. package/resources/img/readme/girl.png +0 -0
  123. package/resources/img/readme/min-Girl.png +0 -0
  124. 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}">&ZeroWidthSpace;${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 };