yz-yuki-plugin 2.0.4-8 → 2.0.5-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 (51) hide show
  1. package/.puppeteerrc.cjs +1 -1
  2. package/CHANGELOG.md +3 -0
  3. package/README.md +19 -3
  4. package/defaultConfig/bilibili/config.yaml +2 -2
  5. package/defaultConfig/help/help.yaml +51 -51
  6. package/defaultConfig/weibo/config.yaml +2 -2
  7. package/lib/apps/bilibili.js +88 -84
  8. package/lib/apps/help.js +3 -3
  9. package/lib/apps/version.js +4 -4
  10. package/lib/apps/weibo.js +47 -47
  11. package/lib/components/dynamic/Account.js +3 -3
  12. package/lib/components/dynamic/Content.js +5 -5
  13. package/lib/components/dynamic/Footer.js +3 -3
  14. package/lib/components/dynamic/LogoText.js +2 -2
  15. package/lib/components/dynamic/MainPage.js +3 -3
  16. package/lib/components/loginQrcode/Page.js +1 -1
  17. package/lib/index.js +7 -9
  18. package/lib/models/bilibili/bilibili.api.d.ts +4 -4
  19. package/lib/models/bilibili/bilibili.api.js +13 -13
  20. package/lib/models/bilibili/bilibili.get.web.data.js +32 -18
  21. package/lib/models/bilibili/bilibili.models.d.ts +9 -9
  22. package/lib/models/bilibili/bilibili.models.js +248 -192
  23. package/lib/models/bilibili/bilibili.query.d.ts +5 -5
  24. package/lib/models/bilibili/bilibili.query.js +135 -114
  25. package/lib/models/bilibili/bilibili.task.d.ts +1 -1
  26. package/lib/models/bilibili/bilibili.task.js +41 -36
  27. package/lib/models/bilibili/bilibili.ticket.js +3 -3
  28. package/lib/models/bilibili/bilibili.wbi.js +10 -12
  29. package/lib/models/help/help.js +2 -2
  30. package/lib/models/weibo/weibo.api.js +2 -2
  31. package/lib/models/weibo/weibo.get.web.data.js +6 -7
  32. package/lib/models/weibo/weibo.query.d.ts +4 -4
  33. package/lib/models/weibo/weibo.query.js +66 -69
  34. package/lib/models/weibo/weibo.task.d.ts +1 -1
  35. package/lib/models/weibo/weibo.task.js +43 -38
  36. package/lib/utils/config.d.ts +2 -2
  37. package/lib/utils/config.js +8 -8
  38. package/lib/utils/paths.js +1 -1
  39. package/lib/utils/puppeteer.render.js +20 -22
  40. package/package.json +8 -4
  41. package/resources/css/dynamic/Account.css +1 -1
  42. package/resources/css/dynamic/Content.box.grid.4.css +2 -2
  43. package/resources/css/dynamic/Content.box.grid.9.css +2 -2
  44. package/resources/css/dynamic/Content.css +1 -1
  45. package/resources/css/dynamic/Footer.css +1 -1
  46. package/resources/css/dynamic/ForwardContent.css +1 -1
  47. package/resources/css/dynamic/LogoText.css +2 -2
  48. package/resources/css/dynamic/MainPage.css +4 -5
  49. package/resources/css/help/help.css +18 -11
  50. package/resources/css/loginQrcode/Page.css +7 -11
  51. package/resources/css/version/version.css +8 -6
@@ -12,9 +12,9 @@ class BiliTask {
12
12
  privateKey;
13
13
  e;
14
14
  constructor(e) {
15
- this.taskName = "biliTask";
16
- this.groupKey = "Yz:yuki:bili:upPush:group:";
17
- this.privateKey = "Yz:yuki:bili:upPush:private:";
15
+ this.taskName = 'biliTask';
16
+ this.groupKey = 'Yz:yuki:bili:upPush:group:';
17
+ this.privateKey = 'Yz:yuki:bili:upPush:private:';
18
18
  }
19
19
  async hendleEventDynamicData(uid, count = 0) {
20
20
  const resp = await new BiliGetWebData().getBiliDynamicListDataByUid(uid);
@@ -40,10 +40,10 @@ class BiliTask {
40
40
  }
41
41
  }
42
42
  async runTask() {
43
- let biliConfigData = await Config.getUserConfig("bilibili", "config");
44
- let biliPushData = await Config.getUserConfig("bilibili", "push");
43
+ let biliConfigData = await Config.getUserConfig('bilibili', 'config');
44
+ let biliPushData = await Config.getUserConfig('bilibili', 'push');
45
45
  let interval = biliConfigData.interval || 7200;
46
- let lastLiveStatus = JSON.parse(await Redis.get("yuki:bililive:lastlivestatus")) || {};
46
+ let lastLiveStatus = JSON.parse(await Redis.get('yuki:bililive:lastlivestatus')) || {};
47
47
  const uidMap = new Map(); // 存放group 和 private 对应所属 uid 与推送信息的映射
48
48
  const dynamicList = {}; // 存放获取的所有动态,键为 uid,值为动态数组
49
49
  await this.processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus);
@@ -59,7 +59,8 @@ class BiliTask {
59
59
  */
60
60
  async processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus) {
61
61
  const requestedDataOfUids = new Map(); // 存放已请求的 uid 映射
62
- for (let chatType in biliPushData) { // 遍历 group 和 private
62
+ for (let chatType in biliPushData) {
63
+ // 遍历 group 和 private
63
64
  if (!uidMap.has(chatType)) {
64
65
  uidMap.set(chatType, new Map());
65
66
  }
@@ -133,7 +134,7 @@ class BiliTask {
133
134
  logger.debug(`超过间隔,跳过 [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
134
135
  continue;
135
136
  } // 如果超过推送时间间隔,跳过当前循环
136
- if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit)
137
+ if (dynamicItem.type === 'DYNAMIC_TYPE_FORWARD' && !biliConfigData.pushTransmit)
137
138
  continue; // 如果关闭了转发动态的推送,跳过当前循环
138
139
  willPushDynamicList.push(dynamicItem);
139
140
  }
@@ -158,11 +159,11 @@ class BiliTask {
158
159
  async sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType) {
159
160
  const id_str = pushDynamicData.id_str;
160
161
  let sended, markKey;
161
- if (chatType === "group") {
162
+ if (chatType === 'group') {
162
163
  markKey = this.groupKey;
163
164
  sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
164
165
  }
165
- else if (chatType === "private") {
166
+ else if (chatType === 'private') {
166
167
  markKey = this.privateKey;
167
168
  sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
168
169
  }
@@ -172,9 +173,9 @@ class BiliTask {
172
173
  const { data, uid } = await BiliQuery.formatDynamicData(pushDynamicData); // 处理动态数据
173
174
  const extentData = { ...data };
174
175
  const eval2 = eval;
175
- let banWords = eval2(`/${biliConfigData.banWords.join("|")}/g`); // 构建屏蔽关键字正则表达式
176
+ let banWords = eval2(`/${biliConfigData.banWords.join('|')}/g`); // 构建屏蔽关键字正则表达式
176
177
  if (new RegExp(banWords).test(`${extentData?.title}${extentData?.content}`)) {
177
- return "return"; // 如果动态包含屏蔽关键字,则直接返回
178
+ return 'return'; // 如果动态包含屏蔽关键字,则直接返回
178
179
  }
179
180
  let boxGrid = !!biliConfigData.boxGrid === false ? false : true; // 是否启用九宫格样式,默认为 true
180
181
  let isSplit = !!biliConfigData.isSplit === false ? false : true; // 是否启用分片截图,默认为 true
@@ -184,42 +185,42 @@ class BiliTask {
184
185
  let renderData = this.buildRenderData(extentData, urlQrcodeData, boxGrid);
185
186
  const ScreenshotOptionsData = {
186
187
  addStyle: style,
187
- header: { 'Referer': 'https://space.bilibili.com/' },
188
+ header: { Referer: 'https://space.bilibili.com/' },
188
189
  isSplit: isSplit,
189
190
  modelName: 'bilibili',
190
191
  SOptions: {
191
192
  type: 'webp',
192
- quality: 98,
193
+ quality: 98
193
194
  },
194
195
  saveHtmlfile: false,
195
- pageSplitHeight: splitHeight,
196
+ pageSplitHeight: splitHeight
196
197
  };
197
198
  let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
198
199
  if (!imgs)
199
200
  return;
200
- Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
201
- (logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");
201
+ Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 10 }); // 设置已发送标记
202
+ (logger ?? Bot.logger)?.mark('优纪插件:B站动态执行推送');
202
203
  for (let i = 0; i < imgs.length; i++) {
203
204
  const image = imgs[i];
204
205
  await this.sendMessage(chatId, bot_id, chatType, Segment.image(image));
205
206
  await this.randomDelay(1000, 2000); // 随机延时1-2秒
206
207
  }
207
- await new Promise((resolve) => setTimeout(resolve, 1000)); // 休眠1秒
208
+ await new Promise(resolve => setTimeout(resolve, 1000)); // 休眠1秒
208
209
  }
209
210
  else {
210
211
  const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData); // 构建图文动态消息
211
- Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 }); // 设置已发送标记
212
- if (dynamicMsg == "continue") {
213
- return "return"; // 如果动态消息构建失败,则直接返回
212
+ Redis.set(`${markKey}${chatId}:${id_str}`, '1', { EX: 3600 * 10 }); // 设置已发送标记
213
+ if (dynamicMsg == 'continue') {
214
+ return 'return'; // 如果动态消息构建失败,则直接返回
214
215
  }
215
216
  if (biliConfigData.banWords.length > 0) {
216
- const banWords = new RegExp(biliConfigData.banWords.join("|"), "g"); // 构建屏蔽关键字正则表达式
217
- if (banWords.test(dynamicMsg.join(""))) {
218
- return "return"; // 如果动态消息包含屏蔽关键字,则直接返回
217
+ const banWords = new RegExp(biliConfigData.banWords.join('|'), 'g'); // 构建屏蔽关键字正则表达式
218
+ if (banWords.test(dynamicMsg.join(''))) {
219
+ return 'return'; // 如果动态消息包含屏蔽关键字,则直接返回
219
220
  }
220
221
  }
221
222
  await this.sendMessage(chatId, bot_id, chatType, dynamicMsg);
222
- await new Promise((resolve) => setTimeout(resolve, 1000));
223
+ await new Promise(resolve => setTimeout(resolve, 1000));
223
224
  }
224
225
  }
225
226
  /**
@@ -230,10 +231,10 @@ class BiliTask {
230
231
  * @returns 渲染数据
231
232
  */
232
233
  buildRenderData(extentData, urlQrcodeData, boxGrid) {
233
- if (extentData.orig && (extentData.orig).length !== 0) {
234
+ if (extentData.orig && extentData.orig.length !== 0) {
234
235
  return {
235
236
  data: {
236
- appName: "bilibili",
237
+ appName: 'bilibili',
237
238
  boxGrid: boxGrid,
238
239
  type: extentData?.type,
239
240
  face: extentData?.face,
@@ -256,7 +257,7 @@ class BiliTask {
256
257
  title: extentData?.orig?.data?.title,
257
258
  content: extentData?.orig?.data?.content,
258
259
  pics: extentData?.orig?.data?.pics,
259
- category: extentData?.orig?.data?.category,
260
+ category: extentData?.orig?.data?.category
260
261
  }
261
262
  }
262
263
  }
@@ -265,7 +266,7 @@ class BiliTask {
265
266
  else {
266
267
  return {
267
268
  data: {
268
- appName: "bilibili",
269
+ appName: 'bilibili',
269
270
  boxGrid: boxGrid,
270
271
  type: extentData?.type,
271
272
  face: extentData?.face,
@@ -277,7 +278,7 @@ class BiliTask {
277
278
  urlImgData: urlQrcodeData,
278
279
  created: extentData?.created,
279
280
  pics: extentData?.pics,
280
- category: extentData?.category,
281
+ category: extentData?.category
281
282
  }
282
283
  };
283
284
  }
@@ -290,7 +291,7 @@ class BiliTask {
290
291
  * @returns 图片数据
291
292
  */
292
293
  async renderDynamicCard(uid, renderData, ScreenshotOptionsData) {
293
- const dynamicMsg = await renderPage(uid, "MainPage", renderData, ScreenshotOptionsData); // 渲染动态卡片
294
+ const dynamicMsg = await renderPage(uid, 'MainPage', renderData, ScreenshotOptionsData); // 渲染动态卡片
294
295
  if (dynamicMsg !== false) {
295
296
  return dynamicMsg.img; // 缓存图片数据
296
297
  }
@@ -306,14 +307,18 @@ class BiliTask {
306
307
  * @param message 消息内容
307
308
  */
308
309
  async sendMessage(chatId, bot_id, chatType, message) {
309
- if (chatType === "group") {
310
- await (Bot[bot_id] ?? Bot)?.pickGroup(String(chatId)).sendMsg(message) // 发送群聊
310
+ if (chatType === 'group') {
311
+ await (Bot[bot_id] ?? Bot)
312
+ ?.pickGroup(String(chatId))
313
+ .sendMsg(message) // 发送群聊
311
314
  .catch((error) => {
312
315
  (logger ?? Bot.logger)?.error(`群组[${chatId}]推送失败:${JSON.stringify(error)}`);
313
316
  });
314
317
  }
315
- else if (chatType === "private") {
316
- await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(message)
318
+ else if (chatType === 'private') {
319
+ await (Bot[bot_id] ?? Bot)
320
+ ?.pickFriend(String(chatId))
321
+ .sendMsg(message)
317
322
  .catch((error) => {
318
323
  (logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
319
324
  }); // 发送好友私聊
@@ -325,7 +330,7 @@ class BiliTask {
325
330
  * @param max 最大延时时间
326
331
  */
327
332
  async randomDelay(min, max) {
328
- await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (max - min + 1) + min)));
333
+ await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (max - min + 1) + min)));
329
334
  }
330
335
  }
331
336
 
@@ -22,10 +22,10 @@ async function getBiliTicket(csrf) {
22
22
  const hexSign = hmacSha256('XgwSnGZ1p', `ts${ts}`);
23
23
  const url = 'https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket';
24
24
  const params = new URLSearchParams({
25
- key_id: 'ec02',
26
- hexsign: hexSign,
25
+ 'key_id': 'ec02',
26
+ 'hexsign': hexSign,
27
27
  'context[ts]': String(ts),
28
- csrf: csrf ?? '' // 使用空字符串代替null
28
+ 'csrf': csrf ?? '' // 使用空字符串代替null
29
29
  });
30
30
  try {
31
31
  const response = await fetch(`${url}?${params}`, {
@@ -2,15 +2,13 @@ import md5 from 'md5';
2
2
  import fetch from 'node-fetch';
3
3
 
4
4
  const mixinKeyEncTab = [
5
- 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
6
- 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
7
- 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
8
- 36, 20, 34, 44, 52
5
+ 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26,
6
+ 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
9
7
  ];
10
8
  // 对 imgKey 和 subKey 进行字符顺序打乱编码
11
9
  const getMixinKey = (orig) => mixinKeyEncTab
12
- .map((n) => orig[n])
13
- .join("")
10
+ .map(n => orig[n])
11
+ .join('')
14
12
  .slice(0, 32);
15
13
  // 为请求参数进行 wbi 签名
16
14
  function encWbi(params, img_key, sub_key) {
@@ -19,12 +17,12 @@ function encWbi(params, img_key, sub_key) {
19
17
  // 按照 key 重排参数
20
18
  const query = Object.keys(params)
21
19
  .sort()
22
- .map((key) => {
20
+ .map(key => {
23
21
  // 过滤 value 中的 "!'()*" 字符
24
- const value = params[key].toString().replace(chr_filter, "");
22
+ const value = params[key].toString().replace(chr_filter, '');
25
23
  return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
26
24
  })
27
- .join("&");
25
+ .join('&');
28
26
  const wbi_sign = md5(query + mixin_key); // 计算 w_rid
29
27
  //return query + "&w_rid=" + wbi_sign;
30
28
  return {
@@ -38,12 +36,12 @@ async function getWbiKeys(headers, cookie) {
38
36
  const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
39
37
  headers: {
40
38
  // SESSDATA 字段
41
- Cookie: cookie,
39
+ 'Cookie': cookie,
42
40
  'User-Agent': headers['User-Agent'],
43
- Referer: 'https://www.bilibili.com/' //对于直接浏览器调用可能不适用
41
+ 'Referer': 'https://www.bilibili.com/' //对于直接浏览器调用可能不适用
44
42
  }
45
43
  });
46
- const { data: { wbi_img: { img_url, sub_url }, }, } = (await res.json());
44
+ const { data: { wbi_img: { img_url, sub_url } } } = (await res.json());
47
45
  return {
48
46
  img_key: img_url.slice(img_url.lastIndexOf('/') + 1, img_url.lastIndexOf('.')),
49
47
  sub_key: sub_url.slice(sub_url.lastIndexOf('/') + 1, sub_url.lastIndexOf('.'))
@@ -4,7 +4,7 @@ class Help {
4
4
  e;
5
5
  model;
6
6
  constructor(e) {
7
- this.model = "help";
7
+ this.model = 'help';
8
8
  this.e = e;
9
9
  }
10
10
  static async get(e) {
@@ -12,7 +12,7 @@ class Help {
12
12
  return await helpData.getData();
13
13
  }
14
14
  async getData() {
15
- let helpData = Config.getDefaultConfig("help", "help");
15
+ let helpData = Config.getDefaultConfig('help', 'help');
16
16
  return helpData;
17
17
  }
18
18
  }
@@ -2,7 +2,7 @@ class WeiboApi {
2
2
  static WEIBO_API = {
3
3
  weiboGetIndex: 'https://m.weibo.cn/api/container/getIndex',
4
4
  //通过关键词${upKeyword}搜索博主 parama = { q: 'Keyword'},
5
- weiboAjaxSearch: 'https://weibo.com/ajax/side/search',
5
+ weiboAjaxSearch: 'https://weibo.com/ajax/side/search'
6
6
  };
7
7
  /**统一设置header */
8
8
  static WEIBO_HEADERS = {
@@ -14,7 +14,7 @@ class WeiboApi {
14
14
  'Sec-fetch-mode': 'same-origin',
15
15
  'Sec-fetch-site': 'same-origin',
16
16
  'Upgrade-insecure-requests': '1',
17
- 'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0',
17
+ 'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
18
18
  };
19
19
  }
20
20
 
@@ -5,8 +5,7 @@ import { WeiboQuery } from './weibo.query.js';
5
5
 
6
6
  class WeiboGetWebData {
7
7
  e;
8
- constructor(e) {
9
- }
8
+ constructor(e) { }
10
9
  /**通过uid获取博主信息 */
11
10
  async getBloggerInfo(target) {
12
11
  const param = { containerid: '100505' + target };
@@ -14,7 +13,7 @@ class WeiboGetWebData {
14
13
  url.search = new URLSearchParams(param).toString();
15
14
  const resp = await axios.get(url.toString(), {
16
15
  timeout: 10000,
17
- headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://m.weibo.cn' },
16
+ headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://m.weibo.cn' }
18
17
  });
19
18
  return resp;
20
19
  }
@@ -22,12 +21,12 @@ class WeiboGetWebData {
22
21
  async searchBloggerInfo(keyword) {
23
22
  const url = WeiboApi.WEIBO_API.weiboAjaxSearch;
24
23
  const params = {
25
- q: keyword,
24
+ q: keyword
26
25
  };
27
26
  const resp = await axios.get(url, {
28
27
  params,
29
28
  timeout: 10000,
30
- headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://s.weibo.com' },
29
+ headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://s.weibo.com' }
31
30
  });
32
31
  return resp;
33
32
  }
@@ -36,11 +35,11 @@ class WeiboGetWebData {
36
35
  const params = { containerid: '107603' + target };
37
36
  const url = new URL(WeiboApi.WEIBO_API.weiboGetIndex);
38
37
  url.search = new URLSearchParams(params).toString();
39
- await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 1000 + 1) + 1000)));
38
+ await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (6500 - 1000 + 1) + 1000)));
40
39
  try {
41
40
  const response = await axios.get(url.toString(), {
42
41
  timeout: 15000,
43
- headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://m.weibo.cn' },
42
+ headers: { 'accept': '*/*', 'Content-Type': 'application/json', 'referer': 'https://m.weibo.cn' }
44
43
  });
45
44
  const { ok, data, msg } = response.data;
46
45
  if (!ok && msg !== '这里还没有内容') {
@@ -17,10 +17,10 @@ export declare class WeiboQuery {
17
17
  };
18
18
  }>;
19
19
  /**
20
- * 动态内容富文本节点解析
21
- * @param nodes - 动态内容富文本节点
22
- * @returns 解析后的动态内容富文本
23
- */
20
+ * 动态内容富文本节点解析
21
+ * @param nodes - 动态内容富文本节点
22
+ * @returns 解析后的动态内容富文本
23
+ */
24
24
  static parseRichTextNodes: (nodes: any[] | string | any) => any;
25
25
  /**
26
26
  * 生成动态消息文字内容