koishi-plugin-bilibili-notify 3.0.0-alpha.22 → 3.0.0-alpha.24

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/lib/biliAPI.d.ts CHANGED
@@ -26,21 +26,7 @@ declare class BiliAPI extends Service {
26
26
  }): Promise<string>;
27
27
  encrypt(text: string): string;
28
28
  decrypt(text: string): string;
29
- getTheUserWhoIsLiveStreaming(): Promise<{
30
- count: number;
31
- group: string;
32
- items: [
33
- {
34
- face: string;
35
- is_reserve_recall: boolean;
36
- jump_url: string;
37
- mid: number;
38
- room_id: number;
39
- title: string;
40
- uname: string;
41
- }
42
- ];
43
- }>;
29
+ getTheUserWhoIsLiveStreaming(): Promise<any>;
44
30
  getLiveRoomInfoStreamKey(roomId: string): Promise<any>;
45
31
  getServerUTCTime(): Promise<number>;
46
32
  getTimeNow(): Promise<any>;
package/lib/biliAPI.js CHANGED
@@ -120,9 +120,9 @@ class BiliAPI extends koishi_1.Service {
120
120
  // BA API
121
121
  async getTheUserWhoIsLiveStreaming() {
122
122
  // 获取直播间信息流密钥
123
- const { data: { live_users }, } = await this.client.get(GET_LATEST_UPDATED_UPS);
123
+ const { data } = await this.client.get(GET_LATEST_UPDATED_UPS);
124
124
  // 返回data
125
- return live_users;
125
+ return data;
126
126
  }
127
127
  async getLiveRoomInfoStreamKey(roomId) {
128
128
  // 获取直播间信息流密钥
package/lib/blive.js CHANGED
@@ -33,7 +33,7 @@ class BLive extends koishi_1.Service {
33
33
  },
34
34
  });
35
35
  // logger
36
- this.logger.info(`${roomId}直播间弹幕监听已开启`);
36
+ this.logger.info(`${roomId}直播间监听已开启`);
37
37
  }
38
38
  closeListener(roomId) {
39
39
  // 判断直播间监听器是否关闭
@@ -26,8 +26,8 @@ declare class ComRegister {
26
26
  sendPrivateMsgAndRebootService(): Promise<void>;
27
27
  sendPrivateMsgAndStopService(): Promise<void>;
28
28
  sendMsg(targets: Target, content: any, live?: boolean): Promise<void>;
29
- dynamicDetect(): () => Promise<void>;
30
- debug_dynamicDetect(): () => Promise<void>;
29
+ dynamicDetect(): (...args: any[]) => void;
30
+ debug_dynamicDetect(): (...args: any[]) => void;
31
31
  sendLiveNotifyCard(info: {
32
32
  username: string;
33
33
  userface: string;
@@ -213,6 +213,44 @@ class ComRegister {
213
213
  // 发送提示
214
214
  await session.send("已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误");
215
215
  });
216
+ biliCom
217
+ .subcommand(".ll")
218
+ .usage("展示当前正在直播的订阅对象")
219
+ .example("bili ll")
220
+ .action(async () => {
221
+ // 获取liveUsers
222
+ const { data: { live_users }, } = (await ctx.ba.getTheUserWhoIsLiveStreaming());
223
+ // 定义当前正在直播且订阅的UP主列表
224
+ const subLiveUsers = [];
225
+ // 获取当前订阅的UP主
226
+ for (const sub of this.subManager) {
227
+ // 定义开播标志位
228
+ let onLive = false;
229
+ // 遍历liveUsers
230
+ for (const user of live_users.items) {
231
+ // 判断是否是订阅直播的UP
232
+ if (user.mid.toString() === sub.uid && sub.live) {
233
+ // 设置标志位为true
234
+ onLive = true;
235
+ // break
236
+ break;
237
+ }
238
+ }
239
+ // 判断是否未开播
240
+ subLiveUsers.push({
241
+ uid: Number.parseInt(sub.uid),
242
+ uname: sub.uname,
243
+ onLive,
244
+ });
245
+ }
246
+ // 定义table字符串
247
+ let table = "";
248
+ // 遍历liveUsers
249
+ for (const user of subLiveUsers) {
250
+ table += `[UID:${user.uid}] 「${user.uname}」 ${user.onLive ? "正在直播" : "未开播"}\n`;
251
+ }
252
+ return table;
253
+ });
216
254
  }
217
255
  async init(config) {
218
256
  // 设置logger
@@ -256,11 +294,7 @@ class ComRegister {
256
294
  bot, channelId,
257
295
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
258
296
  content) => {
259
- try {
260
- // 发送消息
261
- await bot.sendMessage(channelId, content);
262
- }
263
- catch (e) {
297
+ (0, utils_1.withRetry)(async () => await bot.sendMessage(channelId, content), 0).catch(async (e) => {
264
298
  if (e.message === "this._request is not a function") {
265
299
  // 2S之后重新发送消息
266
300
  this.ctx.setTimeout(async () => {
@@ -272,7 +306,7 @@ class ComRegister {
272
306
  // 打印错误信息
273
307
  this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
274
308
  await this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
275
- }
309
+ });
276
310
  };
277
311
  }
278
312
  // 检查登录数据库是否有数据
@@ -441,190 +475,180 @@ class ComRegister {
441
475
  let updateBaseline;
442
476
  // 第一条动态的动态ID
443
477
  let dynamicIdStr;
444
- // 相当于锁的作用,防止上一个循环没处理完
445
- let flag = true;
446
- // 返回一个闭包函数
447
- return async () => {
448
- // 判断上一个循环是否完成
449
- if (!flag)
478
+ // 定义handler
479
+ const handler = async () => {
480
+ // 检测启动初始化
481
+ if (detectSetup) {
482
+ // 获取动态信息
483
+ const data = (await this.ctx.ba.getAllDynamic());
484
+ // 判断获取动态信息是否成功
485
+ if (data.code !== 0)
486
+ return;
487
+ // 设置更新基线
488
+ updateBaseline = data.data.update_baseline;
489
+ // 设置初始化为false
490
+ detectSetup = false;
491
+ // 初始化完成
450
492
  return;
451
- flag = false;
452
- // 无论是否执行成功都要释放锁
493
+ }
494
+ // 获取用户所有动态数据
495
+ let updateNum;
496
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
497
+ let content;
453
498
  try {
454
- // 检测启动初始化
455
- if (detectSetup) {
456
- // 获取动态信息
457
- const data = (await this.ctx.ba.getAllDynamic());
458
- // 判断获取动态信息是否成功
459
- if (data.code !== 0)
460
- return;
461
- // 设置更新基线
462
- updateBaseline = data.data.update_baseline;
463
- // 设置初始化为false
464
- detectSetup = false;
465
- // 初始化完成
499
+ // 查询是否有新动态
500
+ const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
501
+ updateNum = data.data.update_num;
502
+ // 没有新动态或获取动态信息失败直接返回
503
+ if (updateNum <= 0 || data.code !== 0)
466
504
  return;
467
- }
468
- // 获取用户所有动态数据
469
- let updateNum;
470
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
471
- let content;
472
- try {
473
- // 查询是否有新动态
474
- const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
475
- updateNum = data.data.update_num;
476
- // 没有新动态或获取动态信息失败直接返回
477
- if (updateNum <= 0 || data.code !== 0)
478
- return;
479
- // 获取动态内容
480
- content = (await this.ctx.ba.getAllDynamic(updateBaseline));
481
- }
482
- catch (e) {
483
- return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
484
- }
485
- // 判断获取动态内容是否成功
486
- if (content.code !== 0) {
487
- switch (content.code) {
488
- case -101: {
489
- // 账号未登录
490
- // 输出日志
491
- this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
492
- // 发送私聊消息
493
- await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
494
- // 停止服务
495
- await this.ctx.sm.disposePlugin();
496
- // 结束循环
497
- break;
498
- }
499
- case -352: {
500
- // 风控
501
- // 输出日志
502
- this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
503
- // 发送私聊消息
504
- await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
505
- // 停止服务
506
- await this.ctx.sm.disposePlugin();
507
- // 结束循环
508
- break;
509
- }
510
- case 4101128:
511
- case 4101129: {
512
- // 获取动态信息错误
513
- // 输出日志
514
- this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
515
- // 发送私聊消息
516
- await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
517
- // 结束循环
518
- break;
519
- }
520
- default: {
521
- // 未知错误
522
- // 发送私聊消息
523
- await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
524
- // 结束循环
525
- break;
526
- }
505
+ // 获取动态内容
506
+ content = (await this.ctx.ba.getAllDynamic(updateBaseline));
507
+ }
508
+ catch (e) {
509
+ return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
510
+ }
511
+ // 判断获取动态内容是否成功
512
+ if (content.code !== 0) {
513
+ switch (content.code) {
514
+ case -101: {
515
+ // 账号未登录
516
+ // 输出日志
517
+ this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
518
+ // 发送私聊消息
519
+ await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
520
+ // 停止服务
521
+ await this.ctx.sm.disposePlugin();
522
+ // 结束循环
523
+ break;
524
+ }
525
+ case -352: {
526
+ // 风控
527
+ // 输出日志
528
+ this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
529
+ // 发送私聊消息
530
+ await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
531
+ // 停止服务
532
+ await this.ctx.sm.disposePlugin();
533
+ // 结束循环
534
+ break;
535
+ }
536
+ case 4101128:
537
+ case 4101129: {
538
+ // 获取动态信息错误
539
+ // 输出日志
540
+ this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
541
+ // 发送私聊消息
542
+ await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
543
+ // 结束循环
544
+ break;
545
+ }
546
+ default: {
547
+ // 未知错误
548
+ // 发送私聊消息
549
+ await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
550
+ // 结束循环
551
+ break;
527
552
  }
528
553
  }
529
- // 获取数据内容
530
- const data = content.data;
531
- // 更新基线
532
- updateBaseline = data.update_baseline;
533
- // 有新动态内容
534
- const items = data.items;
535
- // 检查更新的动态
536
- for (let num = updateNum - 1; num >= 0; num--) {
537
- // 没有动态内容则直接跳过
538
- if (!items[num])
539
- continue;
540
- // 从动态数据中取出UP主名称、UID和动态ID
541
- const upUID = items[num].modules.module_author.mid;
542
- // 寻找关注的UP主的动态
543
- for (const sub of this.subManager) {
544
- // 判断是否是订阅的UP主
545
- // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
546
- if (sub.dynamic && sub.uid == upUID) {
547
- // 订阅该UP主,推送该动态
548
- // 判断更新动态是否为1条
549
- if (updateNum === 1) {
550
- // 判断dynamicIdStr是否有值,是否与当前动态ID一致
551
- if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
552
- // 重复动态,不再推送,直接返回
553
- return;
554
- }
555
- // 存储该动态ID
556
- dynamicIdStr = items[num].id_str;
554
+ }
555
+ // 获取数据内容
556
+ const data = content.data;
557
+ // 更新基线
558
+ updateBaseline = data.update_baseline;
559
+ // 有新动态内容
560
+ const items = data.items;
561
+ // 检查更新的动态
562
+ for (let num = updateNum - 1; num >= 0; num--) {
563
+ // 没有动态内容则直接跳过
564
+ if (!items[num])
565
+ continue;
566
+ // 从动态数据中取出UP主名称、UID和动态ID
567
+ const upUID = items[num].modules.module_author.mid;
568
+ // 寻找关注的UP主的动态
569
+ for (const sub of this.subManager) {
570
+ // 判断是否是订阅的UP主
571
+ // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
572
+ if (sub.dynamic && sub.uid == upUID) {
573
+ // 订阅该UP主,推送该动态
574
+ // 判断更新动态是否为1
575
+ if (updateNum === 1) {
576
+ // 判断dynamicIdStr是否有值,是否与当前动态ID一致
577
+ if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
578
+ // 重复动态,不再推送,直接返回
579
+ return;
557
580
  }
558
- // 定义变量
559
- let pic;
560
- let buffer;
561
- // 从动态数据中取出UP主名称和动态ID
562
- const upName = items[num].modules.module_author.name;
563
- const dynamicId = items[num].id_str;
564
- // 推送该条动态
565
- const attempts = 3;
566
- for (let i = 0; i < attempts; i++) {
567
- // 获取动态推送图片
568
- try {
569
- // 渲染图片
570
- const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
571
- // 赋值
572
- pic = gimgPic;
573
- buffer = gimgBuffer;
574
- // 成功则跳出循环
575
- break;
576
- }
577
- catch (e) {
578
- // 直播开播动态,不做处理
579
- if (e.message === "直播开播动态,不做处理")
580
- return;
581
- if (e.message === "出现关键词,屏蔽该动态") {
582
- // 如果需要发送才发送
583
- if (this.config.filter.notify) {
584
- await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
585
- }
586
- return;
587
- }
588
- if (e.message === "已屏蔽转发动态") {
589
- if (this.config.filter.notify) {
590
- await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
591
- }
592
- return;
581
+ // 存储该动态ID
582
+ dynamicIdStr = items[num].id_str;
583
+ }
584
+ // 定义变量
585
+ let pic;
586
+ let buffer;
587
+ // 从动态数据中取出UP主名称和动态ID
588
+ const upName = items[num].modules.module_author.name;
589
+ const dynamicId = items[num].id_str;
590
+ // 推送该条动态
591
+ const attempts = 3;
592
+ for (let i = 0; i < attempts; i++) {
593
+ // 获取动态推送图片
594
+ try {
595
+ // 渲染图片
596
+ const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
597
+ // 赋值
598
+ pic = gimgPic;
599
+ buffer = gimgBuffer;
600
+ // 成功则跳出循环
601
+ break;
602
+ }
603
+ catch (e) {
604
+ // 直播开播动态,不做处理
605
+ if (e.message === "直播开播动态,不做处理")
606
+ return;
607
+ if (e.message === "出现关键词,屏蔽该动态") {
608
+ // 如果需要发送才发送
609
+ if (this.config.filter.notify) {
610
+ await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
593
611
  }
594
- // 未知错误
595
- if (i === attempts - 1) {
596
- this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
597
- // 发送私聊消息并重启服务
598
- return await this.sendPrivateMsgAndStopService();
612
+ return;
613
+ }
614
+ if (e.message === "已屏蔽转发动态") {
615
+ if (this.config.filter.notify) {
616
+ await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
599
617
  }
618
+ return;
619
+ }
620
+ // 未知错误
621
+ if (i === attempts - 1) {
622
+ this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
623
+ // 发送私聊消息并重启服务
624
+ return await this.sendPrivateMsgAndStopService();
600
625
  }
601
626
  }
602
- // 判断是否需要发送URL
603
- const dUrl = this.config.dynamicUrl
604
- ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
605
- : "";
606
- // 如果pic存在,则直接返回pic
607
- if (pic) {
608
- this.logger.info("推送动态中,使用render模式");
609
- // pic存在,使用的是render模式
610
- await this.sendMsg(sub.target, pic + dUrl);
611
- }
612
- else if (buffer) {
613
- this.logger.info("推送动态中,使用page模式");
614
- // pic不存在,说明使用的是page模式
615
- await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
616
- }
617
- else {
618
- this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
619
- }
627
+ }
628
+ // 判断是否需要发送URL
629
+ const dUrl = this.config.dynamicUrl
630
+ ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
631
+ : "";
632
+ // 如果pic存在,则直接返回pic
633
+ if (pic) {
634
+ this.logger.info("推送动态中,使用render模式");
635
+ // pic存在,使用的是render模式
636
+ await this.sendMsg(sub.target, pic + dUrl);
637
+ }
638
+ else if (buffer) {
639
+ this.logger.info("推送动态中,使用page模式");
640
+ // pic不存在,说明使用的是page模式
641
+ await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
642
+ }
643
+ else {
644
+ this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
620
645
  }
621
646
  }
622
647
  }
623
648
  }
624
- finally {
625
- flag = true;
626
- }
627
649
  };
650
+ // 返回一个闭包函数
651
+ return (0, utils_1.withLock)(handler);
628
652
  }
629
653
  debug_dynamicDetect() {
630
654
  // 检测初始化变量
@@ -633,205 +657,195 @@ class ComRegister {
633
657
  let updateBaseline;
634
658
  // 第一条动态的动态ID
635
659
  let dynamicIdStr;
636
- // 相当于锁的作用,防止上一个循环没处理完
637
- let flag = true;
638
- // 返回一个闭包函数
639
- return async () => {
640
- // 判断上一个循环是否完成
641
- if (!flag)
660
+ // 定义处理逻辑
661
+ const handler = async () => {
662
+ console.log(`初始化状态:${detectSetup}`);
663
+ // 检测启动初始化
664
+ if (detectSetup) {
665
+ // 获取动态信息
666
+ const data = (await this.ctx.ba.getAllDynamic());
667
+ // 判断获取动态信息是否成功
668
+ if (data.code !== 0)
669
+ return;
670
+ console.log(`更新基线:${data.data.update_baseline}`);
671
+ // 设置更新基线
672
+ updateBaseline = data.data.update_baseline;
673
+ // 设置初始化为false
674
+ detectSetup = false;
675
+ // 初始化完成
642
676
  return;
643
- flag = false;
644
- // 无论是否执行成功都要释放锁
677
+ }
678
+ // 获取用户所有动态数据
679
+ let updateNum;
680
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
681
+ let content;
645
682
  try {
646
- console.log(`初始化状态:${detectSetup}`);
647
- // 检测启动初始化
648
- if (detectSetup) {
649
- // 获取动态信息
650
- const data = (await this.ctx.ba.getAllDynamic());
651
- // 判断获取动态信息是否成功
652
- if (data.code !== 0)
653
- return;
654
- console.log(`更新基线:${data.data.update_baseline}`);
655
- // 设置更新基线
656
- updateBaseline = data.data.update_baseline;
657
- // 设置初始化为false
658
- detectSetup = false;
659
- // 初始化完成
683
+ // 查询是否有新动态
684
+ const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
685
+ updateNum = data.data.update_num;
686
+ // biome-ignore lint/style/noUnusedTemplateLiteral: <explanation>
687
+ console.log(`获取是否有新动态:`);
688
+ console.log(data);
689
+ // 没有新动态或获取动态信息失败直接返回
690
+ if (updateNum <= 0 || data.code !== 0)
660
691
  return;
661
- }
662
- // 获取用户所有动态数据
663
- let updateNum;
664
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
665
- let content;
666
- try {
667
- // 查询是否有新动态
668
- const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
669
- updateNum = data.data.update_num;
670
- // biome-ignore lint/style/noUnusedTemplateLiteral: <explanation>
671
- console.log(`获取是否有新动态:`);
672
- console.log(data);
673
- // 没有新动态或获取动态信息失败直接返回
674
- if (updateNum <= 0 || data.code !== 0)
675
- return;
676
- // 获取动态内容
677
- content = (await this.ctx.ba.getAllDynamic(updateBaseline));
678
- console.log("获取动态内容:");
679
- console.log(content.data.items[0]);
680
- }
681
- catch (e) {
682
- return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
683
- }
684
- // 判断获取动态内容是否成功
685
- if (content.code !== 0) {
686
- switch (content.code) {
687
- case -101: {
688
- // 账号未登录
689
- // 输出日志
690
- this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
691
- // 发送私聊消息
692
- await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
693
- // 停止服务
694
- await this.ctx.sm.disposePlugin();
695
- // 结束循环
696
- break;
697
- }
698
- case -352: {
699
- // 风控
700
- // 输出日志
701
- this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
702
- // 发送私聊消息
703
- await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
704
- // 停止服务
705
- await this.ctx.sm.disposePlugin();
706
- // 结束循环
707
- break;
708
- }
709
- case 4101128:
710
- case 4101129: {
711
- // 获取动态信息错误
712
- // 输出日志
713
- this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
714
- // 发送私聊消息
715
- await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
716
- // 结束循环
717
- break;
718
- }
719
- default: {
720
- // 未知错误
721
- // 发送私聊消息
722
- await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
723
- // 结束循环
724
- break;
725
- }
692
+ // 获取动态内容
693
+ content = (await this.ctx.ba.getAllDynamic(updateBaseline));
694
+ console.log("获取动态内容:");
695
+ console.log(content.data.items[0]);
696
+ }
697
+ catch (e) {
698
+ return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
699
+ }
700
+ // 判断获取动态内容是否成功
701
+ if (content.code !== 0) {
702
+ switch (content.code) {
703
+ case -101: {
704
+ // 账号未登录
705
+ // 输出日志
706
+ this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
707
+ // 发送私聊消息
708
+ await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
709
+ // 停止服务
710
+ await this.ctx.sm.disposePlugin();
711
+ // 结束循环
712
+ break;
713
+ }
714
+ case -352: {
715
+ // 风控
716
+ // 输出日志
717
+ this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
718
+ // 发送私聊消息
719
+ await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
720
+ // 停止服务
721
+ await this.ctx.sm.disposePlugin();
722
+ // 结束循环
723
+ break;
724
+ }
725
+ case 4101128:
726
+ case 4101129: {
727
+ // 获取动态信息错误
728
+ // 输出日志
729
+ this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
730
+ // 发送私聊消息
731
+ await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
732
+ // 结束循环
733
+ break;
734
+ }
735
+ default: {
736
+ // 未知错误
737
+ // 发送私聊消息
738
+ await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
739
+ // 结束循环
740
+ break;
726
741
  }
727
742
  }
728
- // 获取数据内容
729
- const data = content.data;
730
- // 更新基线
731
- updateBaseline = data.update_baseline;
732
- console.log(`更新基线:${updateBaseline}`);
733
- // 有新动态内容
734
- const items = data.items;
735
- // 检查更新的动态
736
- for (let num = updateNum - 1; num >= 0; num--) {
737
- // 有更新动态
738
- console.log("有更新动态");
739
- // 没有动态内容则直接跳过
740
- if (!items[num])
741
- continue;
742
- // 从动态数据中取出UP主名称、UID和动态ID
743
- const upName = content.data.items[num].modules.module_author.name;
744
- const upUID = items[num].modules.module_author.mid;
745
- const dynamicId = content.data.items[num].id_str;
746
- console.log(`寻找关注的UP主,当前动态UP主:${upName},UID:${upUID},动态ID:${dynamicId}`);
747
- // 寻找关注的UP主的动态
748
- for (const sub of this.subManager) {
749
- console.log(`当前订阅UP主:${sub.uid}`);
750
- // 判断是否是订阅的UP
751
- // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
752
- if (sub.dynamic && sub.uid == upUID) {
753
- // 订阅该UP主,推送该动态
754
- // 判断更新动态是否为1条
755
- if (updateNum === 1) {
756
- // 判断dynamicIdStr是否有值,是否与当前动态ID一致
757
- if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
758
- // 重复动态,不再推送,直接返回
759
- return;
760
- }
761
- // 存储该动态ID
762
- dynamicIdStr = items[num].id_str;
743
+ }
744
+ // 获取数据内容
745
+ const data = content.data;
746
+ // 更新基线
747
+ updateBaseline = data.update_baseline;
748
+ console.log(`更新基线:${updateBaseline}`);
749
+ // 有新动态内容
750
+ const items = data.items;
751
+ // 检查更新的动态
752
+ for (let num = updateNum - 1; num >= 0; num--) {
753
+ // 有更新动态
754
+ console.log("有更新动态");
755
+ // 没有动态内容则直接跳过
756
+ if (!items[num])
757
+ continue;
758
+ // 从动态数据中取出UP主名称、UID和动态ID
759
+ const upName = content.data.items[num].modules.module_author.name;
760
+ const upUID = items[num].modules.module_author.mid;
761
+ const dynamicId = content.data.items[num].id_str;
762
+ console.log(`寻找关注的UP主,当前动态UP主:${upName},UID:${upUID},动态ID:${dynamicId}`);
763
+ // 寻找关注的UP主的动态
764
+ for (const sub of this.subManager) {
765
+ console.log(`当前订阅UP主:${sub.uid}`);
766
+ // 判断是否是订阅的UP主
767
+ // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
768
+ if (sub.dynamic && sub.uid == upUID) {
769
+ // 订阅该UP主,推送该动态
770
+ // 判断更新动态是否为1
771
+ if (updateNum === 1) {
772
+ // 判断dynamicIdStr是否有值,是否与当前动态ID一致
773
+ if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
774
+ // 重复动态,不再推送,直接返回
775
+ return;
763
776
  }
764
- // 定义变量
765
- let pic;
766
- let buffer;
767
- // 从动态数据中取出UP主名称和动态ID
768
- const upName = items[num].modules.module_author.name;
769
- const dynamicId = items[num].id_str;
770
- console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
771
- // 推送该条动态
772
- const attempts = 3;
773
- for (let i = 0; i < attempts; i++) {
774
- // 获取动态推送图片
775
- try {
776
- // 渲染图片
777
- const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
778
- // 赋值
779
- pic = gimgPic;
780
- buffer = gimgBuffer;
781
- // 成功则跳出循环
782
- break;
783
- }
784
- catch (e) {
785
- // 直播开播动态,不做处理
786
- if (e.message === "直播开播动态,不做处理")
787
- return;
788
- if (e.message === "出现关键词,屏蔽该动态") {
789
- // 如果需要发送才发送
790
- if (this.config.filter.notify) {
791
- await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
792
- }
793
- return;
794
- }
795
- if (e.message === "已屏蔽转发动态") {
796
- if (this.config.filter.notify) {
797
- await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
798
- }
799
- return;
777
+ // 存储该动态ID
778
+ dynamicIdStr = items[num].id_str;
779
+ }
780
+ // 定义变量
781
+ let pic;
782
+ let buffer;
783
+ // 从动态数据中取出UP主名称和动态ID
784
+ const upName = items[num].modules.module_author.name;
785
+ const dynamicId = items[num].id_str;
786
+ console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
787
+ // 推送该条动态
788
+ const attempts = 3;
789
+ for (let i = 0; i < attempts; i++) {
790
+ // 获取动态推送图片
791
+ try {
792
+ // 渲染图片
793
+ const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
794
+ // 赋值
795
+ pic = gimgPic;
796
+ buffer = gimgBuffer;
797
+ // 成功则跳出循环
798
+ break;
799
+ }
800
+ catch (e) {
801
+ // 直播开播动态,不做处理
802
+ if (e.message === "直播开播动态,不做处理")
803
+ return;
804
+ if (e.message === "出现关键词,屏蔽该动态") {
805
+ // 如果需要发送才发送
806
+ if (this.config.filter.notify) {
807
+ await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
800
808
  }
801
- // 未知错误
802
- if (i === attempts - 1) {
803
- this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
804
- // 发送私聊消息并重启服务
805
- return await this.sendPrivateMsgAndStopService();
809
+ return;
810
+ }
811
+ if (e.message === "已屏蔽转发动态") {
812
+ if (this.config.filter.notify) {
813
+ await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
806
814
  }
815
+ return;
816
+ }
817
+ // 未知错误
818
+ if (i === attempts - 1) {
819
+ this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
820
+ // 发送私聊消息并重启服务
821
+ return await this.sendPrivateMsgAndStopService();
807
822
  }
808
823
  }
809
- // 判断是否需要发送URL
810
- const dUrl = this.config.dynamicUrl
811
- ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
812
- : "";
813
- // 如果pic存在,则直接返回pic
814
- if (pic) {
815
- this.logger.info("推送动态中,使用render模式");
816
- // pic存在,使用的是render模式
817
- await this.sendMsg(sub.target, pic + dUrl);
818
- }
819
- else if (buffer) {
820
- this.logger.info("推送动态中,使用page模式");
821
- // pic不存在,说明使用的是page模式
822
- await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
823
- }
824
- else {
825
- this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
826
- }
824
+ }
825
+ // 判断是否需要发送URL
826
+ const dUrl = this.config.dynamicUrl
827
+ ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
828
+ : "";
829
+ // 如果pic存在,则直接返回pic
830
+ if (pic) {
831
+ this.logger.info("推送动态中,使用render模式");
832
+ // pic存在,使用的是render模式
833
+ await this.sendMsg(sub.target, pic + dUrl);
834
+ }
835
+ else if (buffer) {
836
+ this.logger.info("推送动态中,使用page模式");
837
+ // pic不存在,说明使用的是page模式
838
+ await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
839
+ }
840
+ else {
841
+ this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
827
842
  }
828
843
  }
829
844
  }
830
845
  }
831
- finally {
832
- flag = true;
833
- }
834
846
  };
847
+ // 加工handler并返回
848
+ return (0, utils_1.withLock)(handler);
835
849
  }
836
850
  // 定义发送直播通知卡片方法
837
851
  async sendLiveNotifyCard(info, liveType, followerDisplay, liveNotifyMsg) {
@@ -1372,6 +1386,7 @@ class ComRegister {
1372
1386
  this.subManager.push({
1373
1387
  id: +sub.uid,
1374
1388
  uid: sub.uid,
1389
+ uname: data.name,
1375
1390
  roomId: sub.live ? data.live_room.roomid : "",
1376
1391
  target: sub.target,
1377
1392
  platform: "",
@@ -41,6 +41,8 @@ declare namespace GenerateImg {
41
41
  removeBorder: boolean;
42
42
  cardColorStart: string;
43
43
  cardColorEnd: string;
44
+ cardBasePlateColor: string;
45
+ cardBasePlateBorder: string;
44
46
  enableLargeFont: boolean;
45
47
  font: string;
46
48
  hideDesc: boolean;
@@ -70,9 +70,9 @@ class GenerateImg extends koishi_1.Service {
70
70
  width: 100%;
71
71
  height: auto;
72
72
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
73
- padding: 15px;
73
+ padding: ${this.giConfig.cardBasePlateBorder};
74
74
  border-radius: 10px;
75
- background-color: #FFF5EE;
75
+ background-color: ${this.giConfig.cardBasePlateColor};
76
76
  }
77
77
 
78
78
  .card {
@@ -575,7 +575,7 @@ class GenerateImg extends koishi_1.Service {
575
575
  // 判断是否开启大字体模式
576
576
  let style;
577
577
  if (this.giConfig.enableLargeFont) {
578
- style = `
578
+ style = /* css */ `
579
579
  @font-face {
580
580
  font-family: "Custom Font";
581
581
  src: url(${fontURL});
@@ -605,9 +605,9 @@ class GenerateImg extends koishi_1.Service {
605
605
  width: 100%;
606
606
  height: auto;
607
607
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
608
- padding: 15px;
608
+ padding: ${this.giConfig.cardBasePlateBorder};
609
609
  border-radius: 10px;
610
- background-color: #FFF5EE;
610
+ background-color: ${this.giConfig.cardBasePlateColor};
611
611
  }
612
612
 
613
613
  .card {
@@ -940,7 +940,7 @@ class GenerateImg extends koishi_1.Service {
940
940
  `;
941
941
  }
942
942
  else {
943
- style = `
943
+ style = /* css */ `
944
944
  @font-face {
945
945
  font-family: "Custom Font";
946
946
  src: url(${fontURL});
@@ -970,9 +970,9 @@ class GenerateImg extends koishi_1.Service {
970
970
  width: 100%;
971
971
  height: auto;
972
972
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
973
- padding: 15px;
973
+ padding: ${this.giConfig.cardBasePlateBorder};
974
974
  border-radius: 10px;
975
- background-color: #FFF5EE;
975
+ background-color: ${this.giConfig.cardBasePlateColor};
976
976
  }
977
977
 
978
978
  .card {
@@ -1521,6 +1521,8 @@ class GenerateImg extends koishi_1.Service {
1521
1521
  removeBorder: koishi_1.Schema.boolean(),
1522
1522
  cardColorStart: koishi_1.Schema.string(),
1523
1523
  cardColorEnd: koishi_1.Schema.string(),
1524
+ cardBasePlateColor: koishi_1.Schema.string(),
1525
+ cardBasePlateBorder: koishi_1.Schema.string(),
1524
1526
  enableLargeFont: koishi_1.Schema.boolean(),
1525
1527
  font: koishi_1.Schema.string(),
1526
1528
  hideDesc: koishi_1.Schema.boolean(),
package/lib/index.d.ts CHANGED
@@ -10,6 +10,18 @@ declare class ServerManager extends Service {
10
10
  servers: ForkScope[];
11
11
  renderType: number;
12
12
  dynamicLoopTime: number;
13
+ renderTypePatternMatching: {
14
+ render: number;
15
+ page: number;
16
+ };
17
+ dynamicLoopTimePatternMatching: {
18
+ "1\u5206\u949F": number;
19
+ "2\u5206\u949F": number;
20
+ "3\u5206\u949F": number;
21
+ "5\u5206\u949F": number;
22
+ "10\u5206\u949F": number;
23
+ "20\u5206\u949F": number;
24
+ };
13
25
  constructor(ctx: Context);
14
26
  protected start(): void | Promise<void>;
15
27
  registerPlugin: () => boolean;
@@ -57,6 +69,8 @@ export interface Config {
57
69
  removeBorder: boolean;
58
70
  cardColorStart: string;
59
71
  cardColorEnd: string;
72
+ cardBasePlateColor: string;
73
+ cardBasePlateBorder: string;
60
74
  enableLargeFont: boolean;
61
75
  font: string;
62
76
  filter: {};
package/lib/index.js CHANGED
@@ -56,6 +56,20 @@ class ServerManager extends koishi_1.Service {
56
56
  renderType;
57
57
  // 动态循环时间
58
58
  dynamicLoopTime;
59
+ // 定义渲染类型模式匹配
60
+ renderTypePatternMatching = {
61
+ render: 0,
62
+ page: 1,
63
+ };
64
+ // 定义具体时间模式匹配
65
+ dynamicLoopTimePatternMatching = {
66
+ "1分钟": 60,
67
+ "2分钟": 120,
68
+ "3分钟": 180,
69
+ "5分钟": 300,
70
+ "10分钟": 600,
71
+ "20分钟": 1200,
72
+ };
59
73
  constructor(ctx) {
60
74
  super(ctx, "sm");
61
75
  // 插件运行相关指令
@@ -99,35 +113,10 @@ class ServerManager extends koishi_1.Service {
99
113
  start() {
100
114
  // 加载配置
101
115
  // 根据用户设置的渲染模式设置
102
- switch (globalConfig.renderType) {
103
- case "render":
104
- this.renderType = 0;
105
- break;
106
- case "page":
107
- this.renderType = 1;
108
- break;
109
- }
116
+ this.renderType = this.renderTypePatternMatching[globalConfig.renderType];
110
117
  // 转换为具体时间
111
- switch (globalConfig.dynamicLoopTime) {
112
- case "1分钟":
113
- this.dynamicLoopTime = 60;
114
- break;
115
- case "2分钟":
116
- this.dynamicLoopTime = 120;
117
- break;
118
- case "3分钟":
119
- this.dynamicLoopTime = 180;
120
- break;
121
- case "5分钟":
122
- this.dynamicLoopTime = 300;
123
- break;
124
- case "10分钟":
125
- this.dynamicLoopTime = 600;
126
- break;
127
- case "20分钟":
128
- this.dynamicLoopTime = 1200;
129
- break;
130
- }
118
+ this.dynamicLoopTime =
119
+ this.dynamicLoopTimePatternMatching[globalConfig.dynamicLoopTime];
131
120
  // 注册插件
132
121
  if (!this.registerPlugin()) {
133
122
  this.logger.error("插件启动失败");
@@ -151,6 +140,8 @@ class ServerManager extends koishi_1.Service {
151
140
  removeBorder: globalConfig.removeBorder,
152
141
  cardColorStart: globalConfig.cardColorStart,
153
142
  cardColorEnd: globalConfig.cardColorEnd,
143
+ cardBasePlateColor: globalConfig.cardBasePlateColor,
144
+ cardBasePlateBorder: globalConfig.cardBasePlateBorder,
154
145
  hideDesc: globalConfig.hideDesc,
155
146
  enableLargeFont: globalConfig.enableLargeFont,
156
147
  font: globalConfig.font,
@@ -387,6 +378,14 @@ exports.Config = koishi_1.Schema.object({
387
378
  .pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
388
379
  .default("#F9CCDF")
389
380
  .description("推送卡片的结束渐变背景色,请填入16进制颜色代码,参考网站:https://colorate.azurewebsites.net/"),
381
+ cardBasePlateColor: koishi_1.Schema.string()
382
+ .pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
383
+ .default("#FFF5EE")
384
+ .description("推送卡片底板颜色,请填入16进制颜色代码"),
385
+ cardBasePlateBorder: koishi_1.Schema.string()
386
+ .pattern(/\d*\.?\d+(?:px|em|rem|%|vh|vw|vmin|vmax)/)
387
+ .default("15px")
388
+ .description("推送卡片底板边框宽度,请填入css单位,例如1px,12.5rem,100%"),
390
389
  enableLargeFont: koishi_1.Schema.boolean()
391
390
  .default(false)
392
391
  .description("是否开启动态推送卡片大字体模式,默认为小字体。小字体更漂亮,但阅读比较吃力,大字体更易阅读,但相对没这么好看"),
@@ -20,6 +20,7 @@ export type Target = Array<TargetItem>;
20
20
  export type SubItem = {
21
21
  id: number;
22
22
  uid: string;
23
+ uname: string;
23
24
  roomId: string;
24
25
  target: Target;
25
26
  platform: string;
@@ -35,3 +36,17 @@ export type MasterInfo = {
35
36
  liveEndFollowerNum: number;
36
37
  liveFollowerChange: number;
37
38
  };
39
+ export type LiveUsersItem = {
40
+ face: string;
41
+ is_reserve_recall: boolean;
42
+ jump_url: string;
43
+ mid: number;
44
+ room_id: number;
45
+ title: string;
46
+ uname: string;
47
+ };
48
+ export type LiveUsers = {
49
+ count: number;
50
+ group: string;
51
+ items: Array<LiveUsersItem>;
52
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-bilibili-notify",
3
3
  "description": "Koishi bilibili notify plugin",
4
- "version": "3.0.0-alpha.22",
4
+ "version": "3.0.0-alpha.24",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
package/readme.md CHANGED
@@ -59,6 +59,10 @@
59
59
 
60
60
  - 使用指令 `bili list`
61
61
 
62
+ 查看目前订阅直播的UP主们的直播情况:
63
+
64
+ - 使用指令 `bili ll`
65
+
62
66
  插件的启动、停止和重启
63
67
 
64
68
  - 使用指令 `sys`
@@ -202,6 +206,8 @@
202
206
  - ver 3.0.0-alpha.20 优化:订阅配置中开关选项默认为关闭
203
207
  - ver 3.0.0-alpha.21 优化:部分代码; 新增:更新插件后,由于机器人还未启动,已开始发送消息报错 `this._request is not a function` ,新增报错后自动重新发送消息的功能
204
208
  - ver 3.0.0-alpha.22 优化:订阅配置展示优化
209
+ - ver 3.0.0-alpha.23 新增:指令 `bili ll` 可以查看当前订阅直播的UP主们的开播情况
210
+ - ver 3.0.0-alpha.24 新增:配置项,`cardBasePlateColor` 和 `cardBasePlateBorder`,分别设置卡片底板颜色和底板边框宽度; 优化:部分代码结构
205
211
 
206
212
  ## 交流群
207
213