koishi-plugin-bilibili-notify 3.0.0 → 3.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -482,35 +482,40 @@ class ComRegister {
482
482
  const handler = async () => {
483
483
  // 检测启动初始化
484
484
  if (detectSetup) {
485
- // 获取动态信息
486
- const data = (await this.ctx.ba.getAllDynamic());
485
+ // 使用withRetry函数进行重试
486
+ const content = await (0, utils_1.withRetry)(async () => {
487
+ // 获取动态内容
488
+ return (await this.ctx.ba.getAllDynamic());
489
+ }, 1).catch((e) => {
490
+ // logger
491
+ this.logger.error(`dynamicDetect getAllDynamic() 发生了错误,错误为:${e.message}`);
492
+ });
493
+ // content不存在则直接返回
494
+ if (!content)
495
+ return;
487
496
  // 判断获取动态信息是否成功
488
- if (data.code !== 0)
497
+ if (content.code !== 0)
489
498
  return;
490
499
  // 设置更新基线
491
- updateBaseline = data.data.update_baseline;
500
+ updateBaseline = content.data.update_baseline;
501
+ // 设置第一条动态的动态ID
502
+ dynamicIdStr = content.data.items[0].id_str;
492
503
  // 设置初始化为false
493
504
  detectSetup = false;
494
505
  // 初始化完成
495
506
  return;
496
507
  }
497
- // 获取用户所有动态数据
498
- let updateNum;
499
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
500
- let content;
501
- try {
502
- // 查询是否有新动态
503
- const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
504
- updateNum = data.data.update_num;
505
- // 没有新动态或获取动态信息失败直接返回
506
- if (updateNum <= 0 || data.code !== 0)
507
- return;
508
+ // 使用withRetry函数进行重试
509
+ const content = await (0, utils_1.withRetry)(async () => {
508
510
  // 获取动态内容
509
- content = (await this.ctx.ba.getAllDynamic(updateBaseline));
510
- }
511
- catch (e) {
512
- return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
513
- }
511
+ return (await this.ctx.ba.getAllDynamic(updateBaseline));
512
+ }, 1).catch((e) => {
513
+ // logger
514
+ this.logger.error(`dynamicDetect getAllDynamic() 发生了错误,错误为:${e.message}`);
515
+ });
516
+ // content不存在则直接返回
517
+ if (!content)
518
+ return;
514
519
  // 判断获取动态内容是否成功
515
520
  if (content.code !== 0) {
516
521
  switch (content.code) {
@@ -562,35 +567,26 @@ class ComRegister {
562
567
  // 有新动态内容
563
568
  const items = data.items;
564
569
  // 检查更新的动态
565
- for (let num = updateNum - 1; num >= 0; num--) {
570
+ for (const item of items) {
571
+ // 动态ID如果一致则结束循环
572
+ if (item.id_str === dynamicIdStr)
573
+ break;
566
574
  // 没有动态内容则直接跳过
567
- if (!items[num])
575
+ if (!item)
568
576
  continue;
569
577
  // 从动态数据中取出UP主名称、UID和动态ID
570
- const upUID = items[num].modules.module_author.mid;
578
+ const upUID = item.modules.module_author.mid.toString();
579
+ const upName = item.modules.module_author.name;
580
+ const dynamicId = item.id_str;
571
581
  // 寻找关注的UP主的动态
572
582
  for (const sub of this.subManager) {
573
583
  // 判断是否是订阅的UP主
574
- // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
575
- if (sub.dynamic && sub.uid == upUID) {
584
+ if (sub.dynamic && sub.uid === upUID) {
576
585
  // 订阅该UP主,推送该动态
577
- // 判断更新动态是否为1条
578
- if (updateNum === 1) {
579
- // 判断dynamicIdStr是否有值,是否与当前动态ID一致
580
- if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
581
- // 重复动态,不再推送,直接返回
582
- return;
583
- }
584
- // 存储该动态ID
585
- dynamicIdStr = items[num].id_str;
586
- }
587
- // 从动态数据中取出UP主名称和动态ID
588
- const upName = items[num].modules.module_author.name;
589
- const dynamicId = items[num].id_str;
590
586
  // 推送该条动态
591
587
  const buffer = await (0, utils_1.withRetry)(async () => {
592
588
  // 渲染图片
593
- return await this.ctx.gi.generateDynamicImg(items[num], sub.card);
589
+ return await this.ctx.gi.generateDynamicImg(item, sub.card);
594
590
  }, 1).catch(async (e) => {
595
591
  // 直播开播动态,不做处理
596
592
  if (e.message === "直播开播动态,不做处理")
@@ -615,7 +611,7 @@ class ComRegister {
615
611
  });
616
612
  // 判断是否执行成功,未执行成功直接返回
617
613
  if (!buffer)
618
- return;
614
+ continue;
619
615
  // 判断是否需要发送URL
620
616
  const dUrl = this.config.dynamicUrl
621
617
  ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
@@ -627,9 +623,9 @@ class ComRegister {
627
623
  // 判断是否需要发送动态中的图片
628
624
  if (this.config.pushImgsInDynamic) {
629
625
  // 判断是否为图文动态,且存在draw
630
- if (items[num].type === "DYNAMIC_TYPE_DRAW" &&
631
- items[num].modules.module_dynamic.major?.draw) {
632
- for (const img of items[num].modules.module_dynamic.major.draw
626
+ if (item.type === "DYNAMIC_TYPE_DRAW" &&
627
+ item.modules.module_dynamic.major?.draw) {
628
+ for (const img of item.modules.module_dynamic.major.draw
633
629
  .items) {
634
630
  await this.sendMsg(sub.target, (0, jsx_runtime_1.jsx)("img", { src: img.src, alt: "\u52A8\u6001\u56FE\u7247" }));
635
631
  }
@@ -640,6 +636,8 @@ class ComRegister {
640
636
  }
641
637
  }
642
638
  }
639
+ // 更新本次请求第一条动态的动态ID
640
+ dynamicIdStr = items[0].id_str;
643
641
  };
644
642
  // 返回一个闭包函数
645
643
  return (0, utils_1.withLock)(handler);
@@ -651,45 +649,52 @@ class ComRegister {
651
649
  let updateBaseline;
652
650
  // 第一条动态的动态ID
653
651
  let dynamicIdStr;
654
- // 定义处理逻辑
652
+ // 定义handler
655
653
  const handler = async () => {
656
- console.log(`初始化状态:${detectSetup}`);
654
+ this.logger.info(`初始化状态:${detectSetup}`);
657
655
  // 检测启动初始化
658
656
  if (detectSetup) {
659
- // 获取动态信息
660
- const data = (await this.ctx.ba.getAllDynamic());
657
+ // 使用withRetry函数进行重试
658
+ const content = await (0, utils_1.withRetry)(async () => {
659
+ // 获取动态内容
660
+ return (await this.ctx.ba.getAllDynamic());
661
+ }, 1).catch((e) => {
662
+ // logger
663
+ this.logger.error(`dynamicDetect getAllDynamic() 发生了错误,错误为:${e.message}`);
664
+ });
665
+ // content不存在则直接返回
666
+ if (!content)
667
+ return;
661
668
  // 判断获取动态信息是否成功
662
- if (data.code !== 0)
669
+ if (content.code !== 0)
663
670
  return;
664
- console.log(`更新基线:${data.data.update_baseline}`);
665
671
  // 设置更新基线
666
- updateBaseline = data.data.update_baseline;
672
+ updateBaseline = content.data.update_baseline;
673
+ this.logger.info(`更新基线:${updateBaseline}`);
674
+ // 设置第一条动态的动态ID
675
+ dynamicIdStr = content.data.items[0].id_str;
676
+ this.logger.info(`第一条动态ID:${dynamicIdStr}`);
667
677
  // 设置初始化为false
668
678
  detectSetup = false;
669
679
  // 初始化完成
680
+ this.logger.info("动态检测初始化完成");
670
681
  return;
671
682
  }
672
- // 获取用户所有动态数据
673
- let updateNum;
674
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
675
- let content;
676
- try {
677
- // 查询是否有新动态
678
- const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
679
- updateNum = data.data.update_num;
680
- // biome-ignore lint/style/noUnusedTemplateLiteral: <explanation>
681
- console.log(`获取是否有新动态:`);
682
- console.log(data);
683
- // 没有新动态或获取动态信息失败直接返回
684
- if (updateNum <= 0 || data.code !== 0)
685
- return;
683
+ this.logger.info(`更新基线:${updateBaseline}`);
684
+ this.logger.info(`第一条动态ID:${dynamicIdStr}`);
685
+ this.logger.info("获取动态内容中...");
686
+ // 使用withRetry函数进行重试
687
+ const content = await (0, utils_1.withRetry)(async () => {
686
688
  // 获取动态内容
687
- content = (await this.ctx.ba.getAllDynamic(updateBaseline));
688
- console.log("获取动态内容:");
689
- console.log(content.data.items[0]);
690
- }
691
- catch (e) {
692
- return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
689
+ return (await this.ctx.ba.getAllDynamic(updateBaseline));
690
+ }, 1).catch((e) => {
691
+ // logger
692
+ this.logger.error(`dynamicDetect getAllDynamic() 发生了错误,错误为:${e.message}`);
693
+ });
694
+ // content不存在则直接返回
695
+ if (!content) {
696
+ this.logger.error("获取动态内容失败");
697
+ return;
693
698
  }
694
699
  // 判断获取动态内容是否成功
695
700
  if (content.code !== 0) {
@@ -735,50 +740,41 @@ class ComRegister {
735
740
  }
736
741
  }
737
742
  }
743
+ this.logger.error("获取动态内容成功,开始检测动态");
738
744
  // 获取数据内容
739
745
  const data = content.data;
740
746
  // 更新基线
741
747
  updateBaseline = data.update_baseline;
742
- console.log(`更新基线:${updateBaseline}`);
748
+ this.logger.info(`更新基线:${updateBaseline}`);
743
749
  // 有新动态内容
744
750
  const items = data.items;
745
751
  // 检查更新的动态
746
- for (let num = updateNum - 1; num >= 0; num--) {
747
- // 有更新动态
748
- console.log("有更新动态");
752
+ for (const item of items) {
753
+ // 动态ID如果一致则结束循环
754
+ if (item.id_str === dynamicIdStr) {
755
+ this.logger.info("动态ID与上次检测第一条一致,结束循环");
756
+ // 结束循环
757
+ this.logger.info("动态检测结束");
758
+ break;
759
+ }
749
760
  // 没有动态内容则直接跳过
750
- if (!items[num])
761
+ if (!item)
751
762
  continue;
752
763
  // 从动态数据中取出UP主名称、UID和动态ID
753
- const upName = content.data.items[num].modules.module_author.name;
754
- const upUID = items[num].modules.module_author.mid;
755
- const dynamicId = content.data.items[num].id_str;
756
- console.log(`寻找关注的UP主,当前动态UP主:${upName},UID:${upUID},动态ID:${dynamicId}`);
764
+ const upUID = item.modules.module_author.mid.toString();
765
+ const upName = item.modules.module_author.name;
766
+ const dynamicId = item.id_str;
757
767
  // 寻找关注的UP主的动态
758
768
  for (const sub of this.subManager) {
759
- console.log(`当前订阅UP主:${sub.uid}`);
760
769
  // 判断是否是订阅的UP主
761
- // biome-ignore lint/suspicious/noDoubleEquals: <explanation>
762
- if (sub.dynamic && sub.uid == upUID) {
770
+ if (sub.dynamic && sub.uid === upUID) {
763
771
  // 订阅该UP主,推送该动态
764
- // 判断更新动态是否为1条
765
- if (updateNum === 1) {
766
- // 判断dynamicIdStr是否有值,是否与当前动态ID一致
767
- if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
768
- // 重复动态,不再推送,直接返回
769
- return;
770
- }
771
- // 存储该动态ID
772
- dynamicIdStr = items[num].id_str;
773
- }
774
- // 从动态数据中取出UP主名称和动态ID
775
- const upName = items[num].modules.module_author.name;
776
- const dynamicId = items[num].id_str;
777
- console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
772
+ this.logger.info(`寻找到需要推送的动态,订阅的UP主:${upName}(${upUID}),动态ID:${dynamicId}`);
773
+ this.logger.info("渲染推送卡片中...");
778
774
  // 推送该条动态
779
775
  const buffer = await (0, utils_1.withRetry)(async () => {
780
776
  // 渲染图片
781
- return await this.ctx.gi.generateDynamicImg(items[num], sub.card);
777
+ return await this.ctx.gi.generateDynamicImg(item, sub.card);
782
778
  }, 1).catch(async (e) => {
783
779
  // 直播开播动态,不做处理
784
780
  if (e.message === "直播开播动态,不做处理")
@@ -792,7 +788,7 @@ class ComRegister {
792
788
  }
793
789
  if (e.message === "已屏蔽转发动态") {
794
790
  if (this.config.filter.notify) {
795
- await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
791
+ await this.sendMsg(sub.target, `${upName}转发了一条动态,已屏蔽`);
796
792
  }
797
793
  return;
798
794
  }
@@ -801,31 +797,31 @@ class ComRegister {
801
797
  // 发送私聊消息并重启服务
802
798
  await this.sendPrivateMsgAndStopService();
803
799
  });
804
- // 屏蔽动态直接返回
805
- if (!buffer)
806
- return;
800
+ // 判断是否执行成功,未执行成功直接返回
801
+ if (!buffer) {
802
+ this.logger.error("渲染推送卡片失败");
803
+ // 下一条
804
+ continue;
805
+ }
807
806
  // 判断是否需要发送URL
808
807
  const dUrl = this.config.dynamicUrl
809
808
  ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
810
809
  : "";
811
810
  // logger
812
811
  this.logger.info("推送动态中...");
813
- // 推送动态卡片
812
+ // 发送推送卡片
814
813
  await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
815
814
  // 判断是否需要发送动态中的图片
816
815
  if (this.config.pushImgsInDynamic) {
817
816
  // 判断是否为图文动态,且存在draw
818
- if (items[num].type === "DYNAMIC_TYPE_DRAW" &&
819
- items[num].modules.module_dynamic.major?.draw) {
820
- // logger
817
+ if (item.type === "DYNAMIC_TYPE_DRAW" &&
818
+ item.modules.module_dynamic.major?.draw) {
821
819
  this.logger.info("推送动态图片中...");
822
- // 循环遍历图片
823
- for (const img of items[num].modules.module_dynamic.major.draw
820
+ for (const img of item.modules.module_dynamic.major.draw
824
821
  .items) {
825
822
  await this.sendMsg(sub.target, (0, jsx_runtime_1.jsx)("img", { src: img.src, alt: "\u52A8\u6001\u56FE\u7247" }));
826
823
  }
827
- // logger
828
- this.logger.info("推送动态图片完毕!");
824
+ this.logger.info("动态图片推送完毕!");
829
825
  }
830
826
  }
831
827
  // logger
@@ -833,8 +829,10 @@ class ComRegister {
833
829
  }
834
830
  }
835
831
  }
832
+ // 更新本次请求第一条动态的动态ID
833
+ dynamicIdStr = items[0].id_str;
836
834
  };
837
- // 加工handler并返回
835
+ // 返回一个闭包函数
838
836
  return (0, utils_1.withLock)(handler);
839
837
  }
840
838
  // 定义获取主播信息方法
@@ -952,6 +950,7 @@ class ComRegister {
952
950
  .replace("-name", masterInfo.username)
953
951
  .replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
954
952
  .replace("-watched", watched)
953
+ .replace("\\n", "\n")
955
954
  .replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
956
955
  : null;
957
956
  // 发送直播通知卡片
@@ -1030,6 +1029,7 @@ class ComRegister {
1030
1029
  .replace("-name", masterInfo.username)
1031
1030
  .replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
1032
1031
  .replace("-follower", follower)
1032
+ .replace("\\n", "\n")
1033
1033
  .replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
1034
1034
  : null;
1035
1035
  // 推送开播通知
@@ -1072,6 +1072,7 @@ class ComRegister {
1072
1072
  .replace("-name", masterInfo.username)
1073
1073
  .replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
1074
1074
  .replace("-follower_change", followerChange)
1075
+ .replace("\\n", "\n")
1075
1076
  : null;
1076
1077
  // 推送通知卡片
1077
1078
  await sendLiveNotifyCard(type_1.LiveType.StopBroadcast, followerChange, liveEndMsg);
@@ -1100,6 +1101,7 @@ class ComRegister {
1100
1101
  .replace("-name", masterInfo.username)
1101
1102
  .replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
1102
1103
  .replace("-watched", watched)
1104
+ .replace("\\n", "\n")
1103
1105
  .replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
1104
1106
  : null;
1105
1107
  // 发送直播通知卡片
@@ -1268,7 +1270,7 @@ class ComRegister {
1268
1270
  return { flag: true, msg: "用户订阅成功" };
1269
1271
  }
1270
1272
  async loadSubFromConfig(subs) {
1271
- for (const sub of subs) {
1273
+ await Promise.all(subs.map(async (sub) => {
1272
1274
  // logger
1273
1275
  this.logger.info(`加载订阅UID:${sub.uid}中...`);
1274
1276
  // 定义Data
@@ -1312,7 +1314,7 @@ class ComRegister {
1312
1314
  card: sub.card,
1313
1315
  });
1314
1316
  this.logger.info(`UID:${sub.uid}订阅加载完毕!`);
1315
- }
1317
+ }));
1316
1318
  }
1317
1319
  checkIfDynamicDetectIsNeeded() {
1318
1320
  // 检查是否有订阅对象需要动态监测
package/lib/index.d.ts CHANGED
@@ -33,6 +33,7 @@ export interface Config {
33
33
  userAgent: string;
34
34
  subTitle: {};
35
35
  sub: Array<{
36
+ name: string;
36
37
  uid: string;
37
38
  dynamic: boolean;
38
39
  live: boolean;
package/lib/index.js CHANGED
@@ -277,6 +277,7 @@ exports.Config = koishi_1.Schema.object({
277
277
  .description("设置请求头User-Agen,请求出现-352时可以尝试修改,UA获取方法可参考:https://blog.csdn.net/qq_44503987/article/details/104929111"),
278
278
  subTitle: koishi_1.Schema.object({}).description("订阅配置"),
279
279
  sub: koishi_1.Schema.array(koishi_1.Schema.object({
280
+ name: koishi_1.Schema.string().description("订阅用户昵称,只是给你自己看的(相当于备注),可填可不填"),
280
281
  uid: koishi_1.Schema.string().required().description("订阅用户UID"),
281
282
  dynamic: koishi_1.Schema.boolean().default(false).description("是否订阅用户动态"),
282
283
  live: koishi_1.Schema.boolean().default(false).description("是否订阅用户直播"),
@@ -370,14 +371,14 @@ exports.Config = koishi_1.Schema.object({
370
371
  .default(1)
371
372
  .description("设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时"),
372
373
  customLiveStart: koishi_1.Schema.string()
373
- .default("-name开播啦,当前粉丝数:-follower -link")
374
- .description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name开播啦,会发送为xxxUP开播啦"),
374
+ .default("-name开播啦,当前粉丝数:-follower\\n-link")
375
+ .description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name开播啦,会发送为xxxUP开播啦"),
375
376
  customLive: koishi_1.Schema.string()
376
- .default("-name正在直播,目前已播-time,累计看过人数:-watched -link")
377
- .description("自定义直播中提示语,-name代表UP昵称,-time代表开播时长,-watched代表累计看过人数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name正在直播,会发送为xxxUP正在直播xxx"),
377
+ .default("-name正在直播,目前已播-time,累计看过人数:-watched\\n-link")
378
+ .description("自定义直播中提示语,-name代表UP昵称,-time代表开播时长,-watched代表累计看过人数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name正在直播,会发送为xxxUP正在直播xxx"),
378
379
  customLiveEnd: koishi_1.Schema.string()
379
380
  .default("-name下播啦,本次直播了-time,粉丝数变化-follower_change")
380
- .description("自定义下播提示语,-name代表UP昵称,-follower_change代表本场直播粉丝数变,-time代表开播时长。例如-name下播啦,本次直播了-time,会发送为xxxUP下播啦,直播时长为xx小时xx分钟xx秒"),
381
+ .description("自定义下播提示语,-name代表UP昵称,-follower_change代表本场直播粉丝数变,-time代表开播时长,\\n为换行。例如-name下播啦,本次直播了-time,会发送为xxxUP下播啦,直播时长为xx小时xx分钟xx秒"),
381
382
  followerDisplay: koishi_1.Schema.boolean()
382
383
  .default(true)
383
384
  .description("粉丝数变化和看过本场直播的人数是否显示在推送卡片中"),
@@ -57,3 +57,36 @@ export type LiveUsers = {
57
57
  group: string;
58
58
  items: Array<LiveUsersItem>;
59
59
  };
60
+ export type AllDynamicInfo = {
61
+ code: number;
62
+ message: string;
63
+ data: {
64
+ has_more: boolean;
65
+ items: [
66
+ {
67
+ id_str: string;
68
+ type: string;
69
+ modules: {
70
+ module_author: {
71
+ mid: number;
72
+ name: string;
73
+ face: string;
74
+ };
75
+ module_dynamic: {
76
+ major: {
77
+ draw: {
78
+ items: Array<{
79
+ src: string;
80
+ alt: string;
81
+ }>;
82
+ };
83
+ };
84
+ };
85
+ };
86
+ }
87
+ ];
88
+ offset: string;
89
+ update_baseline: string;
90
+ update_num: number;
91
+ };
92
+ };
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",
4
+ "version": "3.0.1-alpha.1",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
package/readme.md CHANGED
@@ -213,6 +213,8 @@
213
213
  - ver 3.0.0-beta.1 修复:使用动态屏蔽时,同时开启动态debug模式,当检测到屏蔽动态时会直接报错关闭插件; 新增:配置项 `pushImgsInDynamic` 是否推送动态中的图片,默认不开启。开启后会单独推送动态中的图片,上舰信息直播间提示
214
214
  - ver 3.0.0-beta.2 新增:配置项 `sub.card`,能更改每个订阅的推送卡片样式,未更改的样式与全局样式保持一致
215
215
  - ver 3.0.0 优化:配置项 `sub.card` 添加实验性标识
216
+ - ver 3.0.1-alpha.0 优化:动态推送逻辑
217
+ - ver 3.0.1-alpha.1 新增:直播提示语换行符,配置项 `sub.name` 为可选项; 修复:debug模式下动态监测5S一次; 优化:加载订阅
216
218
 
217
219
  ## 交流群
218
220