koishi-plugin-bilibili-notify 3.0.0-alpha.12 → 3.0.0-alpha.14

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.
@@ -1,53 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- /* eslint-disable @typescript-eslint/no-explicit-any */
4
3
  const koishi_1 = require("koishi");
5
- const path_1 = require("path");
6
- const url_1 = require("url");
4
+ const node_path_1 = require("node:path");
5
+ const node_url_1 = require("node:url");
7
6
  // 动态类型
8
- const DYNAMIC_TYPE_NONE = 'DYNAMIC_TYPE_NONE';
9
- const DYNAMIC_TYPE_FORWARD = 'DYNAMIC_TYPE_FORWARD';
10
- const DYNAMIC_TYPE_AV = 'DYNAMIC_TYPE_AV';
11
- const DYNAMIC_TYPE_PGC = 'DYNAMIC_TYPE_PGC';
12
- const DYNAMIC_TYPE_COURSES = 'DYNAMIC_TYPE_COURSES';
13
- const DYNAMIC_TYPE_WORD = 'DYNAMIC_TYPE_WORD';
14
- const DYNAMIC_TYPE_DRAW = 'DYNAMIC_TYPE_DRAW';
15
- const DYNAMIC_TYPE_ARTICLE = 'DYNAMIC_TYPE_ARTICLE';
16
- const DYNAMIC_TYPE_MUSIC = 'DYNAMIC_TYPE_MUSIC';
17
- const DYNAMIC_TYPE_COMMON_SQUARE = 'DYNAMIC_TYPE_COMMON_SQUARE';
18
- const DYNAMIC_TYPE_COMMON_VERTICAL = 'DYNAMIC_TYPE_COMMON_VERTICAL';
19
- const DYNAMIC_TYPE_LIVE = 'DYNAMIC_TYPE_LIVE';
20
- const DYNAMIC_TYPE_MEDIALIST = 'DYNAMIC_TYPE_MEDIALIST';
21
- const DYNAMIC_TYPE_COURSES_SEASON = 'DYNAMIC_TYPE_COURSES_SEASON';
22
- const DYNAMIC_TYPE_COURSES_BATCH = 'DYNAMIC_TYPE_COURSES_BATCH';
23
- const DYNAMIC_TYPE_AD = 'DYNAMIC_TYPE_AD';
24
- const DYNAMIC_TYPE_APPLET = 'DYNAMIC_TYPE_APPLET';
25
- const DYNAMIC_TYPE_SUBSCRIPTION = 'DYNAMIC_TYPE_SUBSCRIPTION';
26
- const DYNAMIC_TYPE_LIVE_RCMD = 'DYNAMIC_TYPE_LIVE_RCMD';
27
- const DYNAMIC_TYPE_BANNER = 'DYNAMIC_TYPE_BANNER';
28
- const DYNAMIC_TYPE_UGC_SEASON = 'DYNAMIC_TYPE_UGC_SEASON';
29
- const DYNAMIC_TYPE_SUBSCRIPTION_NEW = 'DYNAMIC_TYPE_SUBSCRIPTION_NEW';
7
+ const DYNAMIC_TYPE_NONE = "DYNAMIC_TYPE_NONE";
8
+ const DYNAMIC_TYPE_FORWARD = "DYNAMIC_TYPE_FORWARD";
9
+ const DYNAMIC_TYPE_AV = "DYNAMIC_TYPE_AV";
10
+ const DYNAMIC_TYPE_PGC = "DYNAMIC_TYPE_PGC";
11
+ const DYNAMIC_TYPE_COURSES = "DYNAMIC_TYPE_COURSES";
12
+ const DYNAMIC_TYPE_WORD = "DYNAMIC_TYPE_WORD";
13
+ const DYNAMIC_TYPE_DRAW = "DYNAMIC_TYPE_DRAW";
14
+ const DYNAMIC_TYPE_ARTICLE = "DYNAMIC_TYPE_ARTICLE";
15
+ const DYNAMIC_TYPE_MUSIC = "DYNAMIC_TYPE_MUSIC";
16
+ const DYNAMIC_TYPE_COMMON_SQUARE = "DYNAMIC_TYPE_COMMON_SQUARE";
17
+ const DYNAMIC_TYPE_COMMON_VERTICAL = "DYNAMIC_TYPE_COMMON_VERTICAL";
18
+ const DYNAMIC_TYPE_LIVE = "DYNAMIC_TYPE_LIVE";
19
+ const DYNAMIC_TYPE_MEDIALIST = "DYNAMIC_TYPE_MEDIALIST";
20
+ const DYNAMIC_TYPE_COURSES_SEASON = "DYNAMIC_TYPE_COURSES_SEASON";
21
+ const DYNAMIC_TYPE_COURSES_BATCH = "DYNAMIC_TYPE_COURSES_BATCH";
22
+ const DYNAMIC_TYPE_AD = "DYNAMIC_TYPE_AD";
23
+ const DYNAMIC_TYPE_APPLET = "DYNAMIC_TYPE_APPLET";
24
+ const DYNAMIC_TYPE_SUBSCRIPTION = "DYNAMIC_TYPE_SUBSCRIPTION";
25
+ const DYNAMIC_TYPE_LIVE_RCMD = "DYNAMIC_TYPE_LIVE_RCMD";
26
+ const DYNAMIC_TYPE_BANNER = "DYNAMIC_TYPE_BANNER";
27
+ const DYNAMIC_TYPE_UGC_SEASON = "DYNAMIC_TYPE_UGC_SEASON";
28
+ const DYNAMIC_TYPE_SUBSCRIPTION_NEW = "DYNAMIC_TYPE_SUBSCRIPTION_NEW";
30
29
  // 内容卡片类型
31
- /* const ADDITIONAL_TYPE_NONE = 'ADDITIONAL_TYPE_NONE'
32
- const ADDITIONAL_TYPE_PGC = 'ADDITIONAL_TYPE_PGC'
33
- const ADDITIONAL_TYPE_GOODS = 'ADDITIONAL_TYPE_GOODS'
34
- const ADDITIONAL_TYPE_VOTE = 'ADDITIONAL_TYPE_VOTE'
35
- const ADDITIONAL_TYPE_COMMON = 'ADDITIONAL_TYPE_COMMON'
36
- const ADDITIONAL_TYPE_MATCH = 'ADDITIONAL_TYPE_MATCH'
37
- const ADDITIONAL_TYPE_UP_RCMD = 'ADDITIONAL_TYPE_UP_RCMD'
38
- const ADDITIONAL_TYPE_UGC = 'ADDITIONAL_TYPE_UGC' */
39
- const ADDITIONAL_TYPE_RESERVE = 'ADDITIONAL_TYPE_RESERVE';
30
+ const ADDITIONAL_TYPE_RESERVE = "ADDITIONAL_TYPE_RESERVE";
40
31
  class GenerateImg extends koishi_1.Service {
41
- static inject = ['puppeteer', 'ba'];
32
+ static inject = ["puppeteer", "ba"];
42
33
  giConfig;
43
34
  constructor(ctx, config) {
44
- super(ctx, 'gi');
35
+ super(ctx, "gi");
45
36
  this.giConfig = config;
46
37
  }
47
- async generateLiveImg(data, username, userface, liveStatus /*0未开播 1刚开播 2已开播 3停止直播*/) {
38
+ async generateLiveImg(
39
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
40
+ data, username, userface, liveStatus /*0未开播 1刚开播 2已开播 3停止直播*/) {
48
41
  const [titleStatus, liveTime, cover] = await this.getLiveStatus(data.live_time, liveStatus);
49
42
  // 加载字体
50
- const fontURL = (0, url_1.pathToFileURL)((0, path_1.resolve)(__dirname, 'font/HYZhengYuan-75W.ttf'));
43
+ const fontURL = (0, node_url_1.pathToFileURL)((0, node_path_1.resolve)(__dirname, "font/HYZhengYuan-75W.ttf"));
51
44
  // 卡片内容
52
45
  const html = `
53
46
  <!DOCTYPE html>
@@ -160,7 +153,7 @@ class GenerateImg extends koishi_1.Service {
160
153
  </head>
161
154
  <body>
162
155
  <div class="background">
163
- <div ${this.giConfig.removeBorder ? '' : 'class="base-plate"'}>
156
+ <div ${this.giConfig.removeBorder ? "" : 'class="base-plate"'}>
164
157
  <div class="card">
165
158
  <img src="${cover ? data.user_cover : data.keyframe}"
166
159
  alt="封面">
@@ -174,7 +167,7 @@ class GenerateImg extends koishi_1.Service {
174
167
  <span class="broadcast-message">${username}${titleStatus}</span>
175
168
  </div>
176
169
  </div>
177
- ${this.giConfig.hideDesc ? '' : `<p class="card-text">${data.description ? data.description : '这个主播很懒,什么都简介都没写'}</p>`}
170
+ ${this.giConfig.hideDesc ? "" : `<p class="card-text">${data.description ? data.description : "这个主播很懒,什么都简介都没写"}</p>`}
178
171
  <p class="card-link">
179
172
  <span>人气:${data.online > 10000 ? `${(data.online / 10000).toFixed(1)}万` : data.online}</span>
180
173
  <span>分区名称:${data.area_name}</span>
@@ -194,21 +187,22 @@ class GenerateImg extends koishi_1.Service {
194
187
  for (let i = 0; i < attempts; i++) {
195
188
  try {
196
189
  // 判断渲染方式
197
- if (this.giConfig.renderType) { // 为1则为真,进入page模式
198
- const htmlPath = 'file://' + __dirname.replaceAll('\\', '/') + '/page/0.html';
190
+ if (this.giConfig.renderType) {
191
+ // 为1则为真,进入page模式
192
+ const htmlPath = `file://${__dirname.replaceAll("\\", "/")}/page/0.html`;
199
193
  const page = await this.ctx.puppeteer.page();
200
194
  await page.goto(htmlPath);
201
- await page.setContent(html, { waitUntil: 'networkidle0' });
202
- const elementHandle = await page.$('html');
195
+ await page.setContent(html, { waitUntil: "networkidle0" });
196
+ const elementHandle = await page.$("html");
203
197
  const boundingBox = await elementHandle.boundingBox();
204
198
  const buffer = await page.screenshot({
205
- type: 'png',
199
+ type: "png",
206
200
  clip: {
207
201
  x: boundingBox.x,
208
202
  y: boundingBox.y,
209
203
  width: boundingBox.width,
210
- height: boundingBox.height
211
- }
204
+ height: boundingBox.height,
205
+ },
212
206
  });
213
207
  await elementHandle.dispose();
214
208
  await page.close();
@@ -219,12 +213,14 @@ class GenerateImg extends koishi_1.Service {
219
213
  return { pic };
220
214
  }
221
215
  catch (e) {
222
- if (i === attempts - 1) { // 已尝试三次
223
- throw new Error('生成图片失败!错误: ' + e.toString());
216
+ if (i === attempts - 1) {
217
+ // 已尝试三次
218
+ throw new Error(`生成图片失败!错误: ${e.toString()}`);
224
219
  }
225
220
  }
226
221
  }
227
222
  }
223
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
228
224
  async generateDynamicImg(data) {
229
225
  // module_author
230
226
  const module_author = data.modules.module_author;
@@ -246,11 +242,15 @@ class GenerateImg extends koishi_1.Service {
246
242
  const forward = module_stat.forward.count;
247
243
  const like = module_stat.like.count;
248
244
  // TOPIC
249
- const topic = data.modules.module_dynamic.topic ? data.modules.module_dynamic.topic.name : '';
250
- const getDynamicMajor = async (dynamicMajorData, forward) => {
245
+ const topic = data.modules.module_dynamic.topic
246
+ ? data.modules.module_dynamic.topic.name
247
+ : "";
248
+ const getDynamicMajor = async (
249
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
250
+ dynamicMajorData, forward) => {
251
251
  // 定义返回值
252
- let main = '';
253
- let link = '';
252
+ let main = "";
253
+ let link = "";
254
254
  // 定义forward类型返回值
255
255
  let forwardInfo;
256
256
  // 最基本的图文处理
@@ -259,27 +259,26 @@ class GenerateImg extends koishi_1.Service {
259
259
  if (module_dynamic.desc) {
260
260
  const richText = module_dynamic.desc.rich_text_nodes.reduce((accumulator, currentValue) => {
261
261
  if (currentValue.emoji) {
262
- return accumulator + `<img style="width:28px; height:28px;" src="${currentValue.emoji.icon_url}"/>`;
263
- }
264
- else {
265
- return accumulator + currentValue.text;
262
+ return `${accumulator}<img style="width:28px; height:28px;" src="${currentValue.emoji.icon_url}"/>`;
266
263
  }
267
- }, '');
264
+ return accumulator + currentValue.text;
265
+ }, "");
268
266
  // 关键字和正则屏蔽
269
- if (this.giConfig.filter.enable) { // 开启动态屏蔽功能
270
- if (this.giConfig.filter.regex) { // 正则屏蔽
267
+ if (this.giConfig.filter.enable) {
268
+ // 开启动态屏蔽功能
269
+ if (this.giConfig.filter.regex) {
270
+ // 正则屏蔽
271
271
  const reg = new RegExp(this.giConfig.filter.regex);
272
272
  if (reg.test(richText))
273
- throw new Error('出现关键词,屏蔽该动态');
273
+ throw new Error("出现关键词,屏蔽该动态");
274
274
  }
275
275
  if (this.giConfig.filter.keywords.length !== 0 &&
276
- this.giConfig.filter.keywords
277
- .some(keyword => richText.includes(keyword))) {
278
- throw new Error('出现关键词,屏蔽该动态');
276
+ this.giConfig.filter.keywords.some((keyword) => richText.includes(keyword))) {
277
+ throw new Error("出现关键词,屏蔽该动态");
279
278
  }
280
279
  }
281
280
  // 查找\n
282
- const text = richText.replace(/\n/g, '<br>');
281
+ const text = richText.replace(/\n/g, "<br>");
283
282
  // 拼接字符串
284
283
  if (text) {
285
284
  main += `
@@ -290,9 +289,9 @@ class GenerateImg extends koishi_1.Service {
290
289
  }
291
290
  }
292
291
  // 图片
293
- let major = '';
294
- const arrowImg = (0, url_1.pathToFileURL)((0, path_1.resolve)(__dirname, 'img/arrow.png'));
295
- if (module_dynamic.major && module_dynamic.major.draw) {
292
+ let major = "";
293
+ const arrowImg = (0, node_url_1.pathToFileURL)((0, node_path_1.resolve)(__dirname, "img/arrow.png"));
294
+ if (module_dynamic.major?.draw) {
296
295
  if (module_dynamic.major.draw.items.length === 1) {
297
296
  const height = module_dynamic.major.draw.items[0].height;
298
297
  console.log(height);
@@ -317,13 +316,13 @@ class GenerateImg extends koishi_1.Service {
317
316
  }
318
317
  else if (module_dynamic.major.draw.items.length === 4) {
319
318
  major += module_dynamic.major.draw.items.reduce((acc, cV) => {
320
- return acc + `<img class="four-photo-item" src="${cV.src}"/>`;
321
- }, '');
319
+ return `${acc}<img class="four-photo-item" src="${cV.src}"/>`;
320
+ }, "");
322
321
  }
323
322
  else {
324
323
  major += module_dynamic.major.draw.items.reduce((acc, cV) => {
325
- return acc + `<img class="photo-item" src="${cV.src}"/>`;
326
- }, '');
324
+ return `${acc}<img class="photo-item" src="${cV.src}"/>`;
325
+ }, "");
327
326
  }
328
327
  main += `
329
328
  <div class="card-major">
@@ -343,7 +342,7 @@ class GenerateImg extends koishi_1.Service {
343
342
  if (dynamicMajorData.type === DYNAMIC_TYPE_FORWARD) {
344
343
  //转发动态屏蔽
345
344
  if (this.giConfig.filter.enable && this.giConfig.filter.forward) {
346
- throw new Error('已屏蔽转发动态');
345
+ throw new Error("已屏蔽转发动态");
347
346
  }
348
347
  // User info
349
348
  const forward_module_author = dynamicMajorData.orig.modules.module_author;
@@ -357,7 +356,7 @@ class GenerateImg extends koishi_1.Service {
357
356
  <div class="card-forward">
358
357
  <div class="forward-userinfo">
359
358
  <img class="forward-avatar" src="${forwardUserAvatarUrl}" alt="avatar">
360
- <span class="forward-username">${forwardUserName} ${forwardInfo ? forwardInfo : ''}</span>
359
+ <span class="forward-username">${forwardUserName} ${forwardInfo ? forwardInfo : ""}</span>
361
360
  </div>
362
361
  <div class="forward-main">
363
362
  ${forwardMain}
@@ -370,12 +369,13 @@ class GenerateImg extends koishi_1.Service {
370
369
  const additional = dynamicMajorData.modules.module_dynamic.additional;
371
370
  // 有附加信息,判断类型
372
371
  switch (additional.type) {
373
- case ADDITIONAL_TYPE_RESERVE: { // 预约信息
372
+ case ADDITIONAL_TYPE_RESERVE: {
373
+ // 预约信息
374
374
  const reserve = additional.reserve;
375
375
  // 定义按钮
376
376
  let button;
377
377
  // 判断按钮类型
378
- if (reserve.button.uncheck.text === '已结束') {
378
+ if (reserve.button.uncheck.text === "已结束") {
379
379
  button = `
380
380
  <button class="reserve-button-end">
381
381
  <span>${reserve.button.uncheck.text}</span>
@@ -413,8 +413,8 @@ class GenerateImg extends koishi_1.Service {
413
413
  <span class="reserve-time">${reserve.desc1.text}</span>
414
414
  <span class="reserve-num">${reserve.desc2.text}</span>
415
415
  </div>
416
- ${reserve.desc3 ?
417
- `<div class="reserve-prize">
416
+ ${reserve.desc3
417
+ ? `<div class="reserve-prize">
418
418
  <svg class="bili-dyn-card-reserve__lottery__icon"
419
419
  style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
420
420
  xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" width="16"
@@ -443,7 +443,8 @@ class GenerateImg extends koishi_1.Service {
443
443
  d="M4.359835 1.609835C4.21339 1.756285 4.21339 1.99372 4.359835 2.140165L8.0429 5.823225C8.140525 5.920875 8.140525 6.079125 8.0429 6.176775L4.359835 9.859825C4.21339 10.006275 4.21339 10.243725 4.359835 10.390175C4.506285 10.5366 4.743725 10.5366 4.89017 10.390175L8.573225 6.7071C8.96375 6.316575 8.96375 5.683425 8.573225 5.2929L4.89017 1.609835C4.743725 1.46339 4.506285 1.46339 4.359835 1.609835z"
444
444
  fill="currentColor"></path>
445
445
  </svg>
446
- </div>` : ''}
446
+ </div>`
447
+ : ""}
447
448
  </div>
448
449
  </div>
449
450
  <div class="reserve-button">
@@ -457,13 +458,14 @@ class GenerateImg extends koishi_1.Service {
457
458
  link += `请将$替换为. www$bilibili$com/opus/${dynamicMajorData.id_str}`;
458
459
  break;
459
460
  }
460
- case DYNAMIC_TYPE_AV: { // 投稿新视频
461
+ case DYNAMIC_TYPE_AV: {
462
+ // 投稿新视频
461
463
  // 处理文字
462
464
  basicDynamic();
463
465
  const archive = dynamicMajorData.modules.module_dynamic.major.archive;
464
- if (archive.badge.text === '投稿视频') {
466
+ if (archive.badge.text === "投稿视频") {
465
467
  if (forward) {
466
- forwardInfo = '投稿了视频';
468
+ forwardInfo = "投稿了视频";
467
469
  }
468
470
  else {
469
471
  pubTime = `${pubTime} · 投稿了视频`;
@@ -529,33 +531,42 @@ class GenerateImg extends koishi_1.Service {
529
531
  link = `请将$替换为. www$bilibili$com/video/${archive.bvid}`;
530
532
  break;
531
533
  }
532
- case DYNAMIC_TYPE_LIVE: return [`${upName}发起了直播预约,我暂时无法渲染,请自行查看`, link];
533
- case DYNAMIC_TYPE_MEDIALIST: return [`${upName}分享了收藏夹,我暂时无法渲染,请自行查看`, link];
534
- case DYNAMIC_TYPE_PGC: return [`${upName}发布了剧集(番剧、电影、纪录片),我暂时无法渲染,请自行查看`, link];
535
- case DYNAMIC_TYPE_ARTICLE: return [`${upName}投稿了新专栏,我暂时无法渲染,请自行查看`, link];
536
- case DYNAMIC_TYPE_MUSIC: return [`${upName}发行了新歌,我暂时无法渲染,请自行查看`, link];
537
- case DYNAMIC_TYPE_COMMON_SQUARE: return [`${upName}发布了装扮|剧集|点评|普通分享,我暂时无法渲染,请自行查看`, link];
538
- case DYNAMIC_TYPE_COURSES_SEASON: return [`${upName}发布了新课程,我暂时无法渲染,请自行查看`, link];
539
- case DYNAMIC_TYPE_UGC_SEASON: return [`${upName}更新了合集,我暂时无法渲染,请自行查看`, link];
540
- case DYNAMIC_TYPE_NONE: return [`${upName}发布了一条无效动态`, link];
534
+ case DYNAMIC_TYPE_LIVE:
535
+ return [`${upName}发起了直播预约,我暂时无法渲染,请自行查看`, link];
536
+ case DYNAMIC_TYPE_MEDIALIST:
537
+ return [`${upName}分享了收藏夹,我暂时无法渲染,请自行查看`, link];
538
+ case DYNAMIC_TYPE_PGC:
539
+ return [
540
+ `${upName}发布了剧集(番剧、电影、纪录片),我暂时无法渲染,请自行查看`,
541
+ link,
542
+ ];
543
+ case DYNAMIC_TYPE_ARTICLE:
544
+ return [`${upName}投稿了新专栏,我暂时无法渲染,请自行查看`, link];
545
+ case DYNAMIC_TYPE_MUSIC:
546
+ return [`${upName}发行了新歌,我暂时无法渲染,请自行查看`, link];
547
+ case DYNAMIC_TYPE_COMMON_SQUARE:
548
+ return [
549
+ `${upName}发布了装扮|剧集|点评|普通分享,我暂时无法渲染,请自行查看`,
550
+ link,
551
+ ];
552
+ case DYNAMIC_TYPE_COURSES_SEASON:
553
+ return [`${upName}发布了新课程,我暂时无法渲染,请自行查看`, link];
554
+ case DYNAMIC_TYPE_UGC_SEASON:
555
+ return [`${upName}更新了合集,我暂时无法渲染,请自行查看`, link];
556
+ case DYNAMIC_TYPE_NONE:
557
+ return [`${upName}发布了一条无效动态`, link];
541
558
  // 直播开播,不做处理
542
- case DYNAMIC_TYPE_LIVE_RCMD: throw new Error('直播开播动态,不做处理');
543
- case DYNAMIC_TYPE_SUBSCRIPTION_NEW:
544
- case DYNAMIC_TYPE_BANNER:
545
- case DYNAMIC_TYPE_SUBSCRIPTION:
546
- case DYNAMIC_TYPE_APPLET:
547
- case DYNAMIC_TYPE_AD:
548
- case DYNAMIC_TYPE_COURSES_BATCH:
549
- case DYNAMIC_TYPE_COURSES:
550
- case DYNAMIC_TYPE_COMMON_VERTICAL:
551
- default: return [`${upName}发布了一条我无法识别的动态,请自行查看`, ''];
559
+ case DYNAMIC_TYPE_LIVE_RCMD:
560
+ throw new Error("直播开播动态,不做处理");
561
+ default:
562
+ return [`${upName}发布了一条我无法识别的动态,请自行查看`, ""];
552
563
  }
553
564
  return [main, link, forwardInfo];
554
565
  };
555
566
  // 获取动态主要内容
556
567
  const [main, link] = await getDynamicMajor(data, false);
557
568
  // 加载字体
558
- const fontURL = (0, url_1.pathToFileURL)((0, path_1.resolve)(__dirname, 'font/HYZhengYuan-75W.ttf'));
569
+ const fontURL = (0, node_url_1.pathToFileURL)((0, node_path_1.resolve)(__dirname, "font/HYZhengYuan-75W.ttf"));
559
570
  // 判断是否开启大字体模式
560
571
  let style;
561
572
  if (this.giConfig.enableLargeFont) {
@@ -1301,7 +1312,7 @@ class GenerateImg extends koishi_1.Service {
1301
1312
  </head>
1302
1313
  <body>
1303
1314
  <div class="background">
1304
- <div ${this.giConfig.removeBorder ? '' : 'class="base-plate"'}>
1315
+ <div ${this.giConfig.removeBorder ? "" : 'class="base-plate"'}>
1305
1316
  <div class="card">
1306
1317
  <div class="card-body">
1307
1318
  <!-- 主播头像 -->
@@ -1311,24 +1322,28 @@ class GenerateImg extends koishi_1.Service {
1311
1322
  <div class="card-content">
1312
1323
  <div class="card-header">
1313
1324
  <div class="up-info">
1314
- <div class="up-name" style="${module_author.vip.type !== 0 ? 'color: #FB7299' : ''}">${upName}</div>
1325
+ <div class="up-name" style="${module_author.vip.type !== 0 ? "color: #FB7299" : ""}">${upName}</div>
1315
1326
  <div class="pub-time">${pubTime}</div>
1316
1327
  </div>
1317
- ${module_author.decorate ? `
1328
+ ${module_author.decorate
1329
+ ? `
1318
1330
  <div class="dress-up">
1319
1331
  <img src="${dynamicCardUrl}" />
1320
1332
  <span>${dynamicCardId}</span>
1321
1333
  </div>
1322
- ` : ''}
1334
+ `
1335
+ : ""}
1323
1336
  </div>
1324
1337
  <div class="card-topic">
1325
- ${topic ? `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"
1338
+ ${topic
1339
+ ? `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"
1326
1340
  class="bili-dyn-topic__icon">
1327
1341
  <path fill-rule="evenodd" clip-rule="evenodd"
1328
1342
  d="M11.4302 2.57458C11.4416 2.51023 11.4439 2.43974 11.4218 2.3528C11.3281 1.98196 10.9517 1.72037 10.5284 1.7527C10.432 1.76018 10.3599 1.78383 10.297 1.81376C10.2347 1.84398 10.1832 1.88155 10.1401 1.92465C10.1195 1.94485 10.1017 1.96692 10.0839 1.98897L10.0808 1.99289L10.0237 2.06277L9.91103 2.2033C9.76177 2.39141 9.61593 2.58191 9.47513 2.77556C9.33433 2.96936 9.19744 3.16585 9.06672 3.36638C9.00275 3.46491 8.93968 3.56401 8.87883 3.66461L8.56966 3.6613C8.00282 3.6574 7.43605 3.65952 6.86935 3.67034C6.80747 3.56778 6.74325 3.46677 6.67818 3.3664C6.54732 3.16585 6.41045 2.96934 6.26968 2.77568C6.12891 2.58186 5.98309 2.39134 5.83387 2.20322L5.72122 2.06268L5.66416 1.99279L5.6622 1.99036C5.64401 1.96783 5.62586 1.94535 5.60483 1.92454C5.56192 1.88144 5.51022 1.84388 5.44797 1.81364C5.38522 1.78386 5.31305 1.76006 5.21665 1.75273C4.80555 1.72085 4.4203 1.97094 4.32341 2.35273C4.30147 2.43968 4.30358 2.51018 4.31512 2.57453C4.32715 2.63859 4.34975 2.69546 4.38112 2.74649C4.39567 2.77075 4.41283 2.79315 4.42999 2.81557C4.43104 2.81694 4.43209 2.81831 4.43314 2.81968L4.48759 2.89122L4.59781 3.03355C4.74589 3.22242 4.89739 3.40905 5.05377 3.59254C5.09243 3.63788 5.13136 3.68306 5.17057 3.72785C4.99083 3.73681 4.81112 3.7467 4.63143 3.75756C4.41278 3.771 4.19397 3.78537 3.97547 3.80206L3.64757 3.82786L3.48362 3.84177L3.39157 3.85181C3.36984 3.8543 3.34834 3.8577 3.32679 3.86111C3.31761 3.86257 3.30843 3.86402 3.29921 3.86541C3.05406 3.90681 2.81526 3.98901 2.59645 4.10752C2.37765 4.22603 2.17867 4.38039 2.00992 4.56302C1.84117 4.74565 1.70247 4.95593 1.60144 5.18337C1.50025 5.4105 1.43687 5.65447 1.41362 5.90153C1.33103 6.77513 1.27663 7.6515 1.25742 8.5302C1.23758 9.40951 1.25835 10.2891 1.3098 11.1655C1.32266 11.3846 1.33738 11.6035 1.35396 11.8223L1.38046 12.1505L1.39472 12.3144L1.39658 12.335L1.39906 12.3583L1.40417 12.4048C1.40671 12.4305 1.41072 12.4558 1.41473 12.4811C1.41561 12.4866 1.41648 12.4922 1.41734 12.4977C1.45717 12.7449 1.53806 12.9859 1.65567 13.2074C1.77314 13.4289 1.92779 13.6304 2.11049 13.8022C2.29319 13.974 2.50441 14.1159 2.73329 14.2197C2.96201 14.3235 3.2084 14.3901 3.45836 14.4135C3.47066 14.415 3.48114 14.4159 3.49135 14.4167C3.49477 14.417 3.49817 14.4173 3.50159 14.4176L3.5425 14.4212L3.62448 14.4283L3.78843 14.4417L4.11633 14.4674C4.33514 14.4831 4.55379 14.4983 4.7726 14.5111C6.52291 14.6145 8.27492 14.6346 10.0263 14.5706C10.4642 14.5547 10.9019 14.5332 11.3396 14.5062C11.5584 14.4923 11.7772 14.4776 11.9959 14.4604L12.3239 14.434L12.4881 14.4196L12.5813 14.4093C12.6035 14.4065 12.6255 14.403 12.6474 14.3995C12.6565 14.3981 12.6655 14.3966 12.6746 14.3952C12.9226 14.3527 13.1635 14.2691 13.3844 14.1486C13.6052 14.0284 13.8059 13.8716 13.9759 13.6868C14.1463 13.5022 14.2861 13.2892 14.3874 13.0593C14.4381 12.9444 14.4793 12.8253 14.5108 12.7037C14.519 12.6734 14.5257 12.6428 14.5322 12.612L14.5421 12.566L14.55 12.5196C14.5556 12.4887 14.5607 12.4578 14.5641 12.4266C14.5681 12.3959 14.5723 12.363 14.5746 12.3373C14.6642 11.4637 14.7237 10.5864 14.7435 9.70617C14.764 8.825 14.7347 7.94337 14.6719 7.06715C14.6561 6.8479 14.6385 6.62896 14.6183 6.41033L14.5867 6.08246L14.5697 5.91853L14.5655 5.87758C14.5641 5.86445 14.5618 5.8473 14.5599 5.83231C14.5588 5.8242 14.5578 5.81609 14.5567 5.80797C14.5538 5.78514 14.5509 5.76229 14.5466 5.7396C14.5064 5.49301 14.4252 5.25275 14.3067 5.03242C14.1886 4.81208 14.0343 4.61153 13.8519 4.44095C13.6695 4.27038 13.4589 4.12993 13.2311 4.02733C13.0033 3.92458 12.7583 3.85907 12.5099 3.83636C12.4974 3.83492 12.4865 3.83394 12.4759 3.833C12.4729 3.83273 12.4698 3.83246 12.4668 3.83219L12.4258 3.82879L12.3438 3.82199L12.1798 3.80886L11.8516 3.78413C11.633 3.76915 11.4143 3.75478 11.1955 3.74288C10.993 3.73147 10.7904 3.72134 10.5878 3.71243L10.6914 3.59236C10.8479 3.40903 10.9992 3.22242 11.1473 3.03341L11.2576 2.89124L11.312 2.81971C11.3136 2.81773 11.3151 2.81575 11.3166 2.81377C11.3333 2.79197 11.3501 2.77013 11.3641 2.74653C11.3954 2.6955 11.418 2.63863 11.4302 2.57458ZM9.33039 5.49268C9.38381 5.16945 9.67705 4.95281 9.98536 5.00882L9.98871 5.00944C10.2991 5.06783 10.5063 5.37802 10.4524 5.70377L10.2398 6.99039L11.3846 6.9904C11.7245 6.9904 12 7.27925 12 7.63557C12 7.99188 11.7245 8.28073 11.3846 8.28073L10.0266 8.28059L9.7707 9.82911L11.0154 9.82913C11.3553 9.82913 11.6308 10.118 11.6308 10.4743C11.6308 10.8306 11.3553 11.1195 11.0154 11.1195L9.55737 11.1195L9.32807 12.5073C9.27465 12.8306 8.98141 13.0472 8.6731 12.9912L8.66975 12.9906C8.35937 12.9322 8.1522 12.622 8.20604 12.2962L8.40041 11.1195H6.89891L6.66961 12.5073C6.61619 12.8306 6.32295 13.0472 6.01464 12.9912L6.01129 12.9906C5.7009 12.9322 5.49374 12.622 5.54758 12.2962L5.74196 11.1195L4.61538 11.1195C4.27552 11.1195 4 10.8306 4 10.4743C4 10.118 4.27552 9.82913 4.61538 9.82913L5.95514 9.82911L6.21103 8.28059L4.98462 8.28073C4.64475 8.28073 4.36923 7.99188 4.36923 7.63557C4.36923 7.27925 4.64475 6.9904 4.98462 6.9904L6.42421 6.99039L6.67193 5.49268C6.72535 5.16945 7.01859 4.95281 7.3269 5.00882L7.33025 5.00944C7.64063 5.06783 7.8478 5.37802 7.79396 5.70377L7.58132 6.99039H9.08281L9.33039 5.49268ZM8.61374 9.82911L8.86963 8.28059H7.36813L7.11225 9.82911H8.61374Z"
1329
1343
  fill="currentColor"></path>
1330
1344
  </svg>
1331
- ${topic}` : ''}
1345
+ ${topic}`
1346
+ : ""}
1332
1347
  </div>
1333
1348
  ${main}
1334
1349
  <div class="card-stat">
@@ -1376,21 +1391,22 @@ class GenerateImg extends koishi_1.Service {
1376
1391
  for (let i = 0; i < attempts; i++) {
1377
1392
  try {
1378
1393
  // 判断渲染方式
1379
- if (this.giConfig.renderType) { // 为1则为真,进入page模式
1380
- const htmlPath = 'file://' + __dirname.replaceAll('\\', '/') + '/page/0.html';
1394
+ if (this.giConfig.renderType) {
1395
+ // 为1则为真,进入page模式
1396
+ const htmlPath = `file://${__dirname.replaceAll("\\", "/")}/page/0.html`;
1381
1397
  const page = await this.ctx.puppeteer.page();
1382
1398
  await page.goto(htmlPath);
1383
- await page.setContent(html, { waitUntil: 'networkidle0' });
1384
- const elementHandle = await page.$('html');
1399
+ await page.setContent(html, { waitUntil: "networkidle0" });
1400
+ const elementHandle = await page.$("html");
1385
1401
  const boundingBox = await elementHandle.boundingBox();
1386
1402
  const buffer = await page.screenshot({
1387
- type: 'png',
1403
+ type: "png",
1388
1404
  clip: {
1389
1405
  x: boundingBox.x,
1390
1406
  y: boundingBox.y,
1391
1407
  width: boundingBox.width,
1392
- height: boundingBox.height
1393
- }
1408
+ height: boundingBox.height,
1409
+ },
1394
1410
  });
1395
1411
  await elementHandle.dispose();
1396
1412
  await page.close();
@@ -1401,17 +1417,41 @@ class GenerateImg extends koishi_1.Service {
1401
1417
  return { pic, link };
1402
1418
  }
1403
1419
  catch (e) {
1404
- if (i === attempts - 1) { // 已尝试三次
1405
- throw new Error('生成图片失败!错误: ' + e.toString());
1420
+ if (i === attempts - 1) {
1421
+ // 已尝试三次
1422
+ throw new Error(`生成图片失败!错误: ${e.toString()}`);
1406
1423
  }
1407
1424
  }
1408
1425
  }
1409
1426
  }
1410
- async generateWordCloudImg(svgContent) {
1411
- // 渲染图片
1412
- const pic = await this.ctx.puppeteer.render(svgContent);
1413
- // 返回图片
1414
- return pic;
1427
+ async generateWordCloudImg() {
1428
+ const page = await this.ctx.puppeteer.page();
1429
+ // 创建HTML内容
1430
+ const htmlContent = `
1431
+ <!DOCTYPE html>
1432
+ <html>
1433
+ <head>
1434
+ <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
1435
+ </head>
1436
+ <body>
1437
+ <div id="chart" style="width:800px;height:600px;"></div>
1438
+ <script>
1439
+ const chart = echarts.init(document.getElementById('chart'));
1440
+ chart.setOption({
1441
+ title: { text: 'Node.js ECharts示例' },
1442
+ tooltip: {},
1443
+ xAxis: { data: ['A', 'B', 'C', 'D', 'E'] },
1444
+ yAxis: {},
1445
+ series: [{ name: '数据', type: 'bar', data: [5, 20, 36, 10, 15] }]
1446
+ });
1447
+ </script>
1448
+ </body>
1449
+ </html>
1450
+ `;
1451
+ // 加载HTML并截图
1452
+ await page.setContent(htmlContent);
1453
+ const buffer = await page.screenshot({ path: "output.png" });
1454
+ return buffer;
1415
1455
  }
1416
1456
  async getLiveStatus(time, liveStatus) {
1417
1457
  let titleStatus;
@@ -1419,25 +1459,25 @@ class GenerateImg extends koishi_1.Service {
1419
1459
  let cover;
1420
1460
  switch (liveStatus) {
1421
1461
  case 0: {
1422
- titleStatus = '未直播';
1423
- liveTime = '未开播';
1462
+ titleStatus = "未直播";
1463
+ liveTime = "未开播";
1424
1464
  cover = true;
1425
1465
  break;
1426
1466
  }
1427
1467
  case 1: {
1428
- titleStatus = '开播啦';
1468
+ titleStatus = "开播啦";
1429
1469
  liveTime = `开播时间:${time}`;
1430
1470
  cover = true;
1431
1471
  break;
1432
1472
  }
1433
1473
  case 2: {
1434
- titleStatus = '正在直播';
1474
+ titleStatus = "正在直播";
1435
1475
  liveTime = `直播时长:${await this.getTimeDifference(time)}`;
1436
1476
  cover = false;
1437
1477
  break;
1438
1478
  }
1439
1479
  case 3: {
1440
- titleStatus = '下播啦';
1480
+ titleStatus = "下播啦";
1441
1481
  liveTime = `开播时间:${time}`;
1442
1482
  cover = true;
1443
1483
  break;
@@ -1460,22 +1500,21 @@ class GenerateImg extends koishi_1.Service {
1460
1500
  const minutes = Math.floor((differenceInSeconds % (60 * 60)) / 60);
1461
1501
  const seconds = differenceInSeconds % 60;
1462
1502
  // 返回格式化的字符串
1463
- return days ?
1464
- `${days}天${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒` :
1465
- `${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒`;
1503
+ return days
1504
+ ? `${days}天${hours}小时${minutes.toString().padStart(2, "0")}分${seconds.toString().padStart(2, "0")}秒`
1505
+ : `${hours}小时${minutes.toString().padStart(2, "0")}分${seconds.toString().padStart(2, "0")}秒`;
1466
1506
  }
1467
1507
  unixTimestampToString(timestamp) {
1468
1508
  const date = new Date(timestamp * 1000);
1469
1509
  const year = date.getFullYear();
1470
- const month = ("0" + (date.getMonth() + 1)).slice(-2);
1471
- const day = ("0" + date.getDate()).slice(-2);
1472
- const hours = ("0" + (date.getHours())).slice(-2);
1473
- const minutes = ("0" + date.getMinutes()).slice(-2);
1474
- const seconds = ("0" + date.getSeconds()).slice(-2);
1510
+ const month = `0${date.getMonth() + 1}`.slice(-2);
1511
+ const day = `0${date.getDate()}`.slice(-2);
1512
+ const hours = `0${date.getHours()}`.slice(-2);
1513
+ const minutes = `0${date.getMinutes()}`.slice(-2);
1514
+ const seconds = `0${date.getSeconds()}`.slice(-2);
1475
1515
  return `${year}年${month}月${day}日 ${hours}:${minutes}:${seconds}`;
1476
1516
  }
1477
1517
  }
1478
- // eslint-disable-next-line @typescript-eslint/no-namespace
1479
1518
  (function (GenerateImg) {
1480
1519
  GenerateImg.Config = koishi_1.Schema.object({
1481
1520
  renderType: koishi_1.Schema.number(),
@@ -1484,14 +1523,14 @@ class GenerateImg extends koishi_1.Service {
1484
1523
  notify: koishi_1.Schema.boolean(),
1485
1524
  regex: koishi_1.Schema.string(),
1486
1525
  keywords: koishi_1.Schema.array(String),
1487
- forward: koishi_1.Schema.boolean()
1526
+ forward: koishi_1.Schema.boolean(),
1488
1527
  }),
1489
1528
  removeBorder: koishi_1.Schema.boolean(),
1490
1529
  cardColorStart: koishi_1.Schema.string(),
1491
1530
  cardColorEnd: koishi_1.Schema.string(),
1492
1531
  enableLargeFont: koishi_1.Schema.boolean(),
1493
1532
  font: koishi_1.Schema.string(),
1494
- hideDesc: koishi_1.Schema.boolean()
1533
+ hideDesc: koishi_1.Schema.boolean(),
1495
1534
  });
1496
1535
  })(GenerateImg || (GenerateImg = {}));
1497
1536
  exports.default = GenerateImg;
package/lib/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Context, ForkScope, Schema, Service } from 'koishi';
1
+ import { type Context, type ForkScope, Schema, Service } from "koishi";
2
2
  export declare const inject: string[];
3
3
  export declare const name = "bilibili-notify";
4
- declare module 'koishi' {
4
+ declare module "koishi" {
5
5
  interface Context {
6
6
  sm: ServerManager;
7
7
  }
@@ -24,7 +24,7 @@ export interface Config {
24
24
  basicSettings: {};
25
25
  unlockSubLimits: boolean;
26
26
  automaticResend: boolean;
27
- renderType: 'render' | 'page';
27
+ renderType: "render" | "page";
28
28
  userAgent: string;
29
29
  subTitle: {};
30
30
  sub: Array<{
@@ -44,9 +44,9 @@ export interface Config {
44
44
  }>;
45
45
  dynamic: {};
46
46
  dynamicUrl: boolean;
47
- dynamicLoopTime: '1分钟' | '2分钟' | '3分钟' | '5分钟' | '10分钟' | '20分钟';
47
+ dynamicLoopTime: "1分钟" | "2分钟" | "3分钟" | "5分钟" | "10分钟" | "20分钟";
48
48
  live: {};
49
- liveDetectMode: 'API' | 'WS';
49
+ liveDetectMode: "API" | "WS";
50
50
  restartPush: boolean;
51
51
  pushTime: number;
52
52
  customLiveStart: string;