koishi-plugin-bilibili-notify 3.0.0-alpha.7 → 3.0.0-alpha.9

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.js CHANGED
@@ -551,67 +551,172 @@ class BiliAPI extends koishi_1.Service {
551
551
  }
552
552
  }
553
553
  __decorate([
554
- (0, retry_1.default)()
554
+ (0, retry_1.default)({
555
+ attempts: 3,
556
+ onFailure(error, attempts) {
557
+ this.logger.error(`getTheUserWhoIsLiveStreaming() 第${attempts}次失败: ${error.message}`);
558
+ },
559
+ })
555
560
  ], BiliAPI.prototype, "getTheUserWhoIsLiveStreaming", null);
556
561
  __decorate([
557
- (0, retry_1.default)()
562
+ (0, retry_1.default)({
563
+ attempts: 3,
564
+ onFailure(error, attempts) {
565
+ this.logger.error(`getLiveRoomInfoStreamKey() 第${attempts}次失败: ${error.message}`);
566
+ },
567
+ })
558
568
  ], BiliAPI.prototype, "getLiveRoomInfoStreamKey", null);
559
569
  __decorate([
560
- (0, retry_1.default)()
570
+ (0, retry_1.default)({
571
+ attempts: 3,
572
+ onFailure(error, attempts) {
573
+ this.logger.error(`getServerUTCTime() 第${attempts}次失败: ${error.message}`);
574
+ },
575
+ })
561
576
  ], BiliAPI.prototype, "getServerUTCTime", null);
562
577
  __decorate([
563
- (0, retry_1.default)()
578
+ (0, retry_1.default)({
579
+ attempts: 3,
580
+ onFailure(error, attempts) {
581
+ this.logger.error(`getTimeNow() 第${attempts}次失败: ${error.message}`);
582
+ },
583
+ })
564
584
  ], BiliAPI.prototype, "getTimeNow", null);
565
585
  __decorate([
566
- (0, retry_1.default)()
586
+ (0, retry_1.default)({
587
+ attempts: 3,
588
+ onFailure(error, attempts) {
589
+ this.logger.error(`getAllGroup() 第${attempts}次失败: ${error.message}`);
590
+ },
591
+ })
567
592
  ], BiliAPI.prototype, "getAllGroup", null);
568
593
  __decorate([
569
- (0, retry_1.default)()
594
+ (0, retry_1.default)({
595
+ attempts: 3,
596
+ onFailure(error, attempts) {
597
+ this.logger.error(`removeUserFromGroup() 第${attempts}次失败: ${error.message}`);
598
+ },
599
+ })
570
600
  ], BiliAPI.prototype, "removeUserFromGroup", null);
571
601
  __decorate([
572
- (0, retry_1.default)()
602
+ (0, retry_1.default)({
603
+ attempts: 3,
604
+ onFailure(error, attempts) {
605
+ this.logger.error(`copyUserToGroup() 第${attempts}次失败: ${error.message}`);
606
+ },
607
+ })
573
608
  ], BiliAPI.prototype, "copyUserToGroup", null);
574
609
  __decorate([
575
- (0, retry_1.default)()
610
+ (0, retry_1.default)({
611
+ attempts: 3,
612
+ onFailure(error, attempts) {
613
+ this.logger.error(`getUserSpaceDynamic() 第${attempts}次失败: ${error.message}`);
614
+ },
615
+ })
576
616
  ], BiliAPI.prototype, "getUserSpaceDynamic", null);
577
617
  __decorate([
578
- (0, retry_1.default)()
618
+ (0, retry_1.default)({
619
+ attempts: 3,
620
+ onFailure(error, attempts) {
621
+ this.logger.error(`createGroup() 第${attempts}次失败: ${error.message}`);
622
+ },
623
+ })
579
624
  ], BiliAPI.prototype, "createGroup", null);
580
625
  __decorate([
581
- (0, retry_1.default)()
626
+ (0, retry_1.default)({
627
+ attempts: 3,
628
+ onFailure(error, attempts) {
629
+ this.logger.error(`getAllDynamic() 第${attempts}次失败: ${error.message}`);
630
+ },
631
+ })
582
632
  ], BiliAPI.prototype, "getAllDynamic", null);
583
633
  __decorate([
584
- (0, retry_1.default)()
634
+ (0, retry_1.default)({
635
+ attempts: 3,
636
+ onFailure(error, attempts) {
637
+ this.logger.error(`hasNewDynamic() 第${attempts}次失败: ${error.message}`);
638
+ },
639
+ })
585
640
  ], BiliAPI.prototype, "hasNewDynamic", null);
586
641
  __decorate([
587
- (0, retry_1.default)()
642
+ (0, retry_1.default)({
643
+ attempts: 3,
644
+ onFailure(error, attempts) {
645
+ this.logger.error(`follow() 第${attempts}次失败: ${error.message}`);
646
+ },
647
+ })
588
648
  ], BiliAPI.prototype, "follow", null);
589
649
  __decorate([
590
- (0, retry_1.default)()
650
+ (0, retry_1.default)({
651
+ attempts: 3,
652
+ onFailure(error, attempts) {
653
+ this.logger.error(`getRelationGroupDetail() 第${attempts}次失败: ${error.message}`);
654
+ },
655
+ })
591
656
  ], BiliAPI.prototype, "getRelationGroupDetail", null);
592
657
  __decorate([
593
- (0, retry_1.default)()
658
+ (0, retry_1.default)({
659
+ attempts: 3,
660
+ onFailure(error, attempts) {
661
+ this.logger.error(`getCookieInfo() 第${attempts}次失败: ${error.message}`);
662
+ },
663
+ })
594
664
  ], BiliAPI.prototype, "getCookieInfo", null);
595
665
  __decorate([
596
- (0, retry_1.default)()
666
+ (0, retry_1.default)({
667
+ attempts: 3,
668
+ onFailure(error, attempts) {
669
+ this.logger.error(`getUserInfo() 第${attempts}次失败: ${error.message}`);
670
+ },
671
+ })
597
672
  ], BiliAPI.prototype, "getUserInfo", null);
598
673
  __decorate([
599
- (0, retry_1.default)()
674
+ (0, retry_1.default)({
675
+ attempts: 3,
676
+ onFailure(error, attempts) {
677
+ this.logger.error(`getWbiKeys() 第${attempts}次失败: ${error.message}`);
678
+ },
679
+ })
600
680
  ], BiliAPI.prototype, "getWbiKeys", null);
601
681
  __decorate([
602
- (0, retry_1.default)()
682
+ (0, retry_1.default)({
683
+ attempts: 3,
684
+ onFailure(error, attempts) {
685
+ this.logger.error(`getMyselfInfo() 第${attempts}次失败: ${error.message}`);
686
+ },
687
+ })
603
688
  ], BiliAPI.prototype, "getMyselfInfo", null);
604
689
  __decorate([
605
- (0, retry_1.default)()
690
+ (0, retry_1.default)({
691
+ attempts: 3,
692
+ onFailure(error, attempts) {
693
+ this.logger.error(`getLoginQRCode() 第${attempts}次失败: ${error.message}`);
694
+ },
695
+ })
606
696
  ], BiliAPI.prototype, "getLoginQRCode", null);
607
697
  __decorate([
608
- (0, retry_1.default)()
698
+ (0, retry_1.default)({
699
+ attempts: 3,
700
+ onFailure(error, attempts) {
701
+ this.logger.error(`getLoginStatus() 第${attempts}次失败: ${error.message}`);
702
+ },
703
+ })
609
704
  ], BiliAPI.prototype, "getLoginStatus", null);
610
705
  __decorate([
611
- (0, retry_1.default)()
706
+ (0, retry_1.default)({
707
+ attempts: 3,
708
+ onFailure(error, attempts) {
709
+ this.logger.error(`getLiveRoomInfo() 第${attempts}次失败: ${error.message}`);
710
+ },
711
+ })
612
712
  ], BiliAPI.prototype, "getLiveRoomInfo", null);
613
713
  __decorate([
614
- (0, retry_1.default)()
714
+ (0, retry_1.default)({
715
+ attempts: 3,
716
+ onFailure(error, attempts) {
717
+ this.logger.error(`getMasterInfo() 第${attempts}次失败: ${error.message}`);
718
+ },
719
+ })
615
720
  ], BiliAPI.prototype, "getMasterInfo", null);
616
721
  (function (BiliAPI) {
617
722
  BiliAPI.Config = koishi_1.Schema.object({
@@ -165,6 +165,8 @@ class ComRegister {
165
165
  }]);
166
166
  // 销毁定时器
167
167
  this.loginTimer();
168
+ // 订阅手动订阅中的订阅
169
+ await this.loadSubFromConfig(config.sub);
168
170
  // 订阅之前的订阅
169
171
  await this.loadSubFromDatabase();
170
172
  // 清除控制台通知
@@ -175,7 +177,6 @@ class ComRegister {
175
177
  await session.execute('bili show');
176
178
  // 开启cookies刷新检测
177
179
  ctx.ba.enableRefreshCookiesDetect();
178
- return;
179
180
  }
180
181
  }
181
182
  finally {
@@ -1392,9 +1393,14 @@ class ComRegister {
1392
1393
  // 定义弹幕存放数组
1393
1394
  const currentLiveDanmakuArr = [];
1394
1395
  const temporaryLiveDanmakuArr = [];
1396
+ // 定义开播状态
1397
+ let liveStatus = false;
1395
1398
  // 处理target
1396
1399
  // 定义channelIdArr总长度
1397
1400
  let channelIdArrLen = 0;
1401
+ // 定义数据
1402
+ let liveRoomInfo;
1403
+ let masterInfo;
1398
1404
  // 找到频道/群组对应的
1399
1405
  const danmakuPushTargetArr = target.map(channel => {
1400
1406
  // 获取符合条件的target
@@ -1409,10 +1415,13 @@ class ComRegister {
1409
1415
  });
1410
1416
  // 定义定时推送函数
1411
1417
  const pushAtTimeFunc = async () => {
1412
- // 获取直播间信息
1413
- const liveRoomInfo = await this.useLiveRoomInfo(roomId);
1414
- // 获取主播信息
1415
- const masterInfo = await this.useMasterInfo(liveRoomInfo.uid);
1418
+ // 判断是否信息是否获取成功
1419
+ if (!(await useMasterAndLiveRoomInfo())) {
1420
+ // 未获取成功,直接返回
1421
+ return this.sendPrivateMsg('获取直播间信息失败,推送直播卡片失败!');
1422
+ }
1423
+ // 设置开播时间
1424
+ liveTime = liveRoomInfo.live_time;
1416
1425
  // 设置直播中消息
1417
1426
  const liveMsg = this.config.customLive ? this.config.customLive
1418
1427
  .replace('-name', masterInfo.username)
@@ -1436,10 +1445,44 @@ class ComRegister {
1436
1445
  temporaryLiveDanmakuArr.length = 0;
1437
1446
  }
1438
1447
  };
1439
- // 获取直播间信息
1440
- const liveRoomInfo = await this.useLiveRoomInfo(roomId);
1441
- // 获取主播信息
1442
- const masterInfo = await this.useMasterInfo(liveRoomInfo.uid);
1448
+ // 定义直播间信息获取函数
1449
+ const useMasterAndLiveRoomInfo = async () => {
1450
+ // 定义flag
1451
+ let flag = true;
1452
+ // 判断是否已存在值
1453
+ if (liveRoomInfo && masterInfo && liveTime) {
1454
+ // 所有值均已存在,不需要再获取信息
1455
+ return flag;
1456
+ }
1457
+ // 获取直播间信息
1458
+ liveRoomInfo = await this.useLiveRoomInfo(roomId).catch(() => {
1459
+ // 设置flag为false
1460
+ flag = false;
1461
+ // 返回空
1462
+ return null;
1463
+ });
1464
+ // 判断是否成功获取信息
1465
+ if (!flag || !liveRoomInfo || !liveRoomInfo.uid) {
1466
+ // 上一步未成功
1467
+ flag = false;
1468
+ // 返回flag
1469
+ return flag;
1470
+ }
1471
+ // 获取主播信息(需要满足flag为true,liveRoomInfo.uid有值)
1472
+ masterInfo = await this.useMasterInfo(liveRoomInfo.uid).catch(() => {
1473
+ // 设置flag为false
1474
+ flag = false;
1475
+ // 返回空
1476
+ return null;
1477
+ });
1478
+ // 返回信息
1479
+ return flag;
1480
+ };
1481
+ // 判断是否信息是否获取成功
1482
+ if (!(await useMasterAndLiveRoomInfo())) {
1483
+ // 未获取成功,直接返回
1484
+ return this.sendPrivateMsg('获取直播间信息失败,启动直播间弹幕检测失败!');
1485
+ }
1443
1486
  // 构建消息处理函数
1444
1487
  const handler = {
1445
1488
  onOpen: () => {
@@ -1469,10 +1512,14 @@ class ComRegister {
1469
1512
  temporaryLiveDanmakuArr.push(content);
1470
1513
  },
1471
1514
  onLiveStart: async () => {
1472
- // 获取直播间信息
1473
- const liveRoomInfo = await this.useLiveRoomInfo(roomId);
1474
- // 获取主播信息
1475
- const masterInfo = await this.useMasterInfo(liveRoomInfo.uid);
1515
+ // 判断是否已经开播
1516
+ if (liveStatus)
1517
+ return;
1518
+ // 判断是否信息是否获取成功
1519
+ if (!(await useMasterAndLiveRoomInfo())) {
1520
+ // 未获取成功,直接返回
1521
+ return this.sendPrivateMsg('获取直播间信息失败,推送直播开播卡片失败!');
1522
+ }
1476
1523
  // 设置开播时间
1477
1524
  liveTime = liveRoomInfo.live_time;
1478
1525
  // 定义开播通知语
@@ -1480,7 +1527,7 @@ class ComRegister {
1480
1527
  .replace('-name', masterInfo.username)
1481
1528
  .replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
1482
1529
  .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1483
- // 推送下播通知
1530
+ // 推送开播通知
1484
1531
  await this.sendLiveNotifyCard({
1485
1532
  username: masterInfo.username,
1486
1533
  userface: masterInfo.userface,
@@ -1492,12 +1539,15 @@ class ComRegister {
1492
1539
  // 开始直播,开启定时器
1493
1540
  pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
1494
1541
  }
1542
+ // 设置开播状态为true
1543
+ liveStatus = true;
1495
1544
  },
1496
1545
  onLiveEnd: async () => {
1497
- // 获取直播间消息
1498
- const liveRoomInfo = await this.useLiveRoomInfo(roomId);
1499
- // 获取主播信息
1500
- const masterInfo = await this.useMasterInfo(liveRoomInfo.uid);
1546
+ // 判断是否信息是否获取成功
1547
+ if (!(await useMasterAndLiveRoomInfo())) {
1548
+ // 未获取成功,直接返回
1549
+ return this.sendPrivateMsg('获取直播间信息失败,推送直播下播卡片失败!');
1550
+ }
1501
1551
  // 更改直播时长
1502
1552
  liveRoomInfo.live_time = liveTime;
1503
1553
  // 定义下播播通知语
@@ -1515,6 +1565,8 @@ class ComRegister {
1515
1565
  pushAtTimeTimer();
1516
1566
  // 将推送定时器变量置空
1517
1567
  pushAtTimeTimer = null;
1568
+ // 将直播状态设置为false
1569
+ liveStatus = false;
1518
1570
  }
1519
1571
  };
1520
1572
  // 启动直播间弹幕监测
@@ -1543,6 +1595,8 @@ class ComRegister {
1543
1595
  // 开始直播,开启定时器
1544
1596
  pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
1545
1597
  }
1598
+ // 设置直播状态为true
1599
+ liveStatus = true;
1546
1600
  }
1547
1601
  }
1548
1602
  subShow() {
@@ -1,2 +1,6 @@
1
- declare function Retry(attempts?: number, onFailure?: (error: Error, attempts: number) => Promise<void> | void): MethodDecorator;
1
+ interface RetryOptions {
2
+ attempts: number;
3
+ onFailure?: (error: Error, attempts: number) => Promise<void> | void;
4
+ }
5
+ declare function Retry(options?: RetryOptions): MethodDecorator;
2
6
  export default Retry;
@@ -1,20 +1,18 @@
1
1
  "use strict";
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- /* eslint-disable @typescript-eslint/ban-types */
4
2
  Object.defineProperty(exports, "__esModule", { value: true });
5
- function Retry(attempts = 3, onFailure) {
3
+ function Retry(options = { attempts: 3 }) {
6
4
  return function (target, propertyKey, descriptor) {
7
5
  const originalMethod = descriptor.value;
8
6
  descriptor.value = async function (...args) {
9
7
  let lastError;
10
- for (let i = 0; i < attempts; i++) {
8
+ for (let i = 0; i < options.attempts; i++) {
11
9
  try {
12
10
  return await originalMethod.apply(this, args);
13
11
  }
14
12
  catch (error) {
15
13
  lastError = error;
16
- if (onFailure) {
17
- await onFailure.call(this, lastError, i + 1);
14
+ if (options.onFailure) {
15
+ await options.onFailure.call(this, lastError, i + 1);
18
16
  }
19
17
  }
20
18
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 高阶函数:为函数添加锁机制
3
+ * @param {Function} fn - 需要包装的原始函数
4
+ * @returns {Function} 带锁功能的函数
5
+ */
6
+ declare function withLock(fn: any): (...args: any[]) => void;
7
+ export default withLock;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * 高阶函数:为函数添加锁机制
5
+ * @param {Function} fn - 需要包装的原始函数
6
+ * @returns {Function} 带锁功能的函数
7
+ */
8
+ function withLock(fn) {
9
+ // 判断是否是异步函数
10
+ const isAsync = fn.constructor.name === 'AsyncFunction';
11
+ // 定义锁标志
12
+ let locked = false;
13
+ // 判断是否为异步函数
14
+ if (isAsync) {
15
+ // 变为Promise
16
+ return function (...args) {
17
+ // 已加锁则跳过执行
18
+ if (locked)
19
+ return;
20
+ // 获取锁
21
+ locked = true;
22
+ // 将异步函数转为Promise链
23
+ Promise.resolve(fn(...args))
24
+ .catch(err => {
25
+ // 打印错误
26
+ console.error("Execution error:", err);
27
+ // 重新抛出错误
28
+ throw err;
29
+ })
30
+ .finally(() => {
31
+ // 确保释放锁
32
+ locked = false;
33
+ });
34
+ };
35
+ }
36
+ // 不是异步函数
37
+ return function (...args) {
38
+ // 已加锁则跳过执行
39
+ if (locked)
40
+ return;
41
+ // 获取锁
42
+ locked = true;
43
+ try {
44
+ // 执行函数
45
+ fn(...args);
46
+ }
47
+ catch (err) {
48
+ // 打印错误
49
+ console.error("Execution error:", err);
50
+ // 重新抛出错误
51
+ throw err;
52
+ }
53
+ finally {
54
+ // 无论成功失败都释放锁
55
+ locked = false;
56
+ }
57
+ };
58
+ }
59
+ exports.default = withLock;
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.7",
4
+ "version": "3.0.0-alpha.9",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
package/readme.md CHANGED
@@ -219,6 +219,8 @@
219
219
  - ver 3.0.0-alpha.5 修复:订阅的直播开播后,未开启弹幕推送会一直报错、主播开播推送下播卡片,直播时长显示NaN; 新增:直播检测模式选项; 优化:下播卡片内容
220
220
  - ver 3.0.0-alpha.6 修复:连续发送两次直播中通知卡片; 优化:下播通知卡片
221
221
  - ver 3.0.0-alpha.7 修复:`ver 3.0.0-alpha.5` 未能解决的bug; 优化:ba代码结构
222
+ - ver 3.0.0-alpha.8 修复:开播通知连续发送两次,登录后不会加载手动订阅中的订阅; 优化:网络请求报错
223
+ - ver 3.0.0-alpha.9 优化:加强直播推送对获取直播信息的错误处理
222
224
 
223
225
  ## 交流群
224
226