koishi-plugin-bilibili-notify 3.0.0-alpha.20 → 3.0.0-alpha.21
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 +22 -22
- package/lib/blive.d.ts +3 -3
- package/lib/blive.js +10 -8
- package/lib/comRegister.js +34 -24
- package/lib/index.js +3 -6
- package/lib/utils/index.d.ts +13 -0
- package/lib/utils/index.js +102 -0
- package/package.json +1 -1
- package/readme.md +1 -0
package/lib/biliAPI.js
CHANGED
|
@@ -16,7 +16,7 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
16
16
|
const tough_cookie_1 = require("tough-cookie");
|
|
17
17
|
const axios_cookiejar_support_1 = require("axios-cookiejar-support");
|
|
18
18
|
const jsdom_1 = require("jsdom");
|
|
19
|
-
const
|
|
19
|
+
const utils_1 = require("./utils");
|
|
20
20
|
const mixinKeyEncTab = [
|
|
21
21
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
|
|
22
22
|
33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61,
|
|
@@ -570,7 +570,7 @@ class BiliAPI extends koishi_1.Service {
|
|
|
570
570
|
}
|
|
571
571
|
}
|
|
572
572
|
__decorate([
|
|
573
|
-
(0,
|
|
573
|
+
(0, utils_1.Retry)({
|
|
574
574
|
attempts: 3,
|
|
575
575
|
onFailure(error, attempts) {
|
|
576
576
|
this.logger.error(`getTheUserWhoIsLiveStreaming() 第${attempts}次失败: ${error.message}`);
|
|
@@ -578,7 +578,7 @@ __decorate([
|
|
|
578
578
|
})
|
|
579
579
|
], BiliAPI.prototype, "getTheUserWhoIsLiveStreaming", null);
|
|
580
580
|
__decorate([
|
|
581
|
-
(0,
|
|
581
|
+
(0, utils_1.Retry)({
|
|
582
582
|
attempts: 3,
|
|
583
583
|
onFailure(error, attempts) {
|
|
584
584
|
this.logger.error(`getLiveRoomInfoStreamKey() 第${attempts}次失败: ${error.message}`);
|
|
@@ -586,7 +586,7 @@ __decorate([
|
|
|
586
586
|
})
|
|
587
587
|
], BiliAPI.prototype, "getLiveRoomInfoStreamKey", null);
|
|
588
588
|
__decorate([
|
|
589
|
-
(0,
|
|
589
|
+
(0, utils_1.Retry)({
|
|
590
590
|
attempts: 3,
|
|
591
591
|
onFailure(error, attempts) {
|
|
592
592
|
this.logger.error(`getServerUTCTime() 第${attempts}次失败: ${error.message}`);
|
|
@@ -594,7 +594,7 @@ __decorate([
|
|
|
594
594
|
})
|
|
595
595
|
], BiliAPI.prototype, "getServerUTCTime", null);
|
|
596
596
|
__decorate([
|
|
597
|
-
(0,
|
|
597
|
+
(0, utils_1.Retry)({
|
|
598
598
|
attempts: 3,
|
|
599
599
|
onFailure(error, attempts) {
|
|
600
600
|
this.logger.error(`getTimeNow() 第${attempts}次失败: ${error.message}`);
|
|
@@ -602,7 +602,7 @@ __decorate([
|
|
|
602
602
|
})
|
|
603
603
|
], BiliAPI.prototype, "getTimeNow", null);
|
|
604
604
|
__decorate([
|
|
605
|
-
(0,
|
|
605
|
+
(0, utils_1.Retry)({
|
|
606
606
|
attempts: 3,
|
|
607
607
|
onFailure(error, attempts) {
|
|
608
608
|
this.logger.error(`getAllGroup() 第${attempts}次失败: ${error.message}`);
|
|
@@ -610,7 +610,7 @@ __decorate([
|
|
|
610
610
|
})
|
|
611
611
|
], BiliAPI.prototype, "getAllGroup", null);
|
|
612
612
|
__decorate([
|
|
613
|
-
(0,
|
|
613
|
+
(0, utils_1.Retry)({
|
|
614
614
|
attempts: 3,
|
|
615
615
|
onFailure(error, attempts) {
|
|
616
616
|
this.logger.error(`removeUserFromGroup() 第${attempts}次失败: ${error.message}`);
|
|
@@ -618,7 +618,7 @@ __decorate([
|
|
|
618
618
|
})
|
|
619
619
|
], BiliAPI.prototype, "removeUserFromGroup", null);
|
|
620
620
|
__decorate([
|
|
621
|
-
(0,
|
|
621
|
+
(0, utils_1.Retry)({
|
|
622
622
|
attempts: 3,
|
|
623
623
|
onFailure(error, attempts) {
|
|
624
624
|
this.logger.error(`copyUserToGroup() 第${attempts}次失败: ${error.message}`);
|
|
@@ -626,7 +626,7 @@ __decorate([
|
|
|
626
626
|
})
|
|
627
627
|
], BiliAPI.prototype, "copyUserToGroup", null);
|
|
628
628
|
__decorate([
|
|
629
|
-
(0,
|
|
629
|
+
(0, utils_1.Retry)({
|
|
630
630
|
attempts: 3,
|
|
631
631
|
onFailure(error, attempts) {
|
|
632
632
|
this.logger.error(`getUserSpaceDynamic() 第${attempts}次失败: ${error.message}`);
|
|
@@ -634,7 +634,7 @@ __decorate([
|
|
|
634
634
|
})
|
|
635
635
|
], BiliAPI.prototype, "getUserSpaceDynamic", null);
|
|
636
636
|
__decorate([
|
|
637
|
-
(0,
|
|
637
|
+
(0, utils_1.Retry)({
|
|
638
638
|
attempts: 3,
|
|
639
639
|
onFailure(error, attempts) {
|
|
640
640
|
this.logger.error(`createGroup() 第${attempts}次失败: ${error.message}`);
|
|
@@ -642,7 +642,7 @@ __decorate([
|
|
|
642
642
|
})
|
|
643
643
|
], BiliAPI.prototype, "createGroup", null);
|
|
644
644
|
__decorate([
|
|
645
|
-
(0,
|
|
645
|
+
(0, utils_1.Retry)({
|
|
646
646
|
attempts: 3,
|
|
647
647
|
onFailure(error, attempts) {
|
|
648
648
|
this.logger.error(`getAllDynamic() 第${attempts}次失败: ${error.message}`);
|
|
@@ -650,7 +650,7 @@ __decorate([
|
|
|
650
650
|
})
|
|
651
651
|
], BiliAPI.prototype, "getAllDynamic", null);
|
|
652
652
|
__decorate([
|
|
653
|
-
(0,
|
|
653
|
+
(0, utils_1.Retry)({
|
|
654
654
|
attempts: 3,
|
|
655
655
|
onFailure(error, attempts) {
|
|
656
656
|
this.logger.error(`hasNewDynamic() 第${attempts}次失败: ${error.message}`);
|
|
@@ -658,7 +658,7 @@ __decorate([
|
|
|
658
658
|
})
|
|
659
659
|
], BiliAPI.prototype, "hasNewDynamic", null);
|
|
660
660
|
__decorate([
|
|
661
|
-
(0,
|
|
661
|
+
(0, utils_1.Retry)({
|
|
662
662
|
attempts: 3,
|
|
663
663
|
onFailure(error, attempts) {
|
|
664
664
|
this.logger.error(`follow() 第${attempts}次失败: ${error.message}`);
|
|
@@ -666,7 +666,7 @@ __decorate([
|
|
|
666
666
|
})
|
|
667
667
|
], BiliAPI.prototype, "follow", null);
|
|
668
668
|
__decorate([
|
|
669
|
-
(0,
|
|
669
|
+
(0, utils_1.Retry)({
|
|
670
670
|
attempts: 3,
|
|
671
671
|
onFailure(error, attempts) {
|
|
672
672
|
this.logger.error(`getRelationGroupDetail() 第${attempts}次失败: ${error.message}`);
|
|
@@ -674,7 +674,7 @@ __decorate([
|
|
|
674
674
|
})
|
|
675
675
|
], BiliAPI.prototype, "getRelationGroupDetail", null);
|
|
676
676
|
__decorate([
|
|
677
|
-
(0,
|
|
677
|
+
(0, utils_1.Retry)({
|
|
678
678
|
attempts: 3,
|
|
679
679
|
onFailure(error, attempts) {
|
|
680
680
|
this.logger.error(`getCookieInfo() 第${attempts}次失败: ${error.message}`);
|
|
@@ -682,7 +682,7 @@ __decorate([
|
|
|
682
682
|
})
|
|
683
683
|
], BiliAPI.prototype, "getCookieInfo", null);
|
|
684
684
|
__decorate([
|
|
685
|
-
(0,
|
|
685
|
+
(0, utils_1.Retry)({
|
|
686
686
|
attempts: 3,
|
|
687
687
|
onFailure(error, attempts) {
|
|
688
688
|
this.logger.error(`getUserInfo() 第${attempts}次失败: ${error.message}`);
|
|
@@ -690,7 +690,7 @@ __decorate([
|
|
|
690
690
|
})
|
|
691
691
|
], BiliAPI.prototype, "getUserInfo", null);
|
|
692
692
|
__decorate([
|
|
693
|
-
(0,
|
|
693
|
+
(0, utils_1.Retry)({
|
|
694
694
|
attempts: 3,
|
|
695
695
|
onFailure(error, attempts) {
|
|
696
696
|
this.logger.error(`getWbiKeys() 第${attempts}次失败: ${error.message}`);
|
|
@@ -698,7 +698,7 @@ __decorate([
|
|
|
698
698
|
})
|
|
699
699
|
], BiliAPI.prototype, "getWbiKeys", null);
|
|
700
700
|
__decorate([
|
|
701
|
-
(0,
|
|
701
|
+
(0, utils_1.Retry)({
|
|
702
702
|
attempts: 3,
|
|
703
703
|
onFailure(error, attempts) {
|
|
704
704
|
this.logger.error(`getMyselfInfo() 第${attempts}次失败: ${error.message}`);
|
|
@@ -706,7 +706,7 @@ __decorate([
|
|
|
706
706
|
})
|
|
707
707
|
], BiliAPI.prototype, "getMyselfInfo", null);
|
|
708
708
|
__decorate([
|
|
709
|
-
(0,
|
|
709
|
+
(0, utils_1.Retry)({
|
|
710
710
|
attempts: 3,
|
|
711
711
|
onFailure(error, attempts) {
|
|
712
712
|
this.logger.error(`getLoginQRCode() 第${attempts}次失败: ${error.message}`);
|
|
@@ -714,7 +714,7 @@ __decorate([
|
|
|
714
714
|
})
|
|
715
715
|
], BiliAPI.prototype, "getLoginQRCode", null);
|
|
716
716
|
__decorate([
|
|
717
|
-
(0,
|
|
717
|
+
(0, utils_1.Retry)({
|
|
718
718
|
attempts: 3,
|
|
719
719
|
onFailure(error, attempts) {
|
|
720
720
|
this.logger.error(`getLoginStatus() 第${attempts}次失败: ${error.message}`);
|
|
@@ -722,7 +722,7 @@ __decorate([
|
|
|
722
722
|
})
|
|
723
723
|
], BiliAPI.prototype, "getLoginStatus", null);
|
|
724
724
|
__decorate([
|
|
725
|
-
(0,
|
|
725
|
+
(0, utils_1.Retry)({
|
|
726
726
|
attempts: 3,
|
|
727
727
|
onFailure(error, attempts) {
|
|
728
728
|
this.logger.error(`getLiveRoomInfo() 第${attempts}次失败: ${error.message}`);
|
|
@@ -730,7 +730,7 @@ __decorate([
|
|
|
730
730
|
})
|
|
731
731
|
], BiliAPI.prototype, "getLiveRoomInfo", null);
|
|
732
732
|
__decorate([
|
|
733
|
-
(0,
|
|
733
|
+
(0, utils_1.Retry)({
|
|
734
734
|
attempts: 3,
|
|
735
735
|
onFailure(error, attempts) {
|
|
736
736
|
this.logger.error(`getMasterInfo() 第${attempts}次失败: ${error.message}`);
|
package/lib/blive.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Awaitable, Context, Service } from "koishi";
|
|
2
|
-
import { type MsgHandler } from
|
|
3
|
-
declare module
|
|
1
|
+
import { type Awaitable, type Context, Service } from "koishi";
|
|
2
|
+
import { type MsgHandler } from "blive-message-listener";
|
|
3
|
+
declare module "koishi" {
|
|
4
4
|
interface Context {
|
|
5
5
|
bl: BLive;
|
|
6
6
|
}
|
package/lib/blive.js
CHANGED
|
@@ -4,12 +4,12 @@ const koishi_1 = require("koishi");
|
|
|
4
4
|
const blive_message_listener_1 = require("blive-message-listener");
|
|
5
5
|
class BLive extends koishi_1.Service {
|
|
6
6
|
// 必要服务
|
|
7
|
-
static inject = [
|
|
7
|
+
static inject = ["ba"];
|
|
8
8
|
// 定义类属性
|
|
9
9
|
listenerRecord = {};
|
|
10
10
|
constructor(ctx) {
|
|
11
11
|
// Extends super
|
|
12
|
-
super(ctx,
|
|
12
|
+
super(ctx, "bl");
|
|
13
13
|
}
|
|
14
14
|
// 注册插件dispose逻辑
|
|
15
15
|
stop() {
|
|
@@ -24,20 +24,22 @@ class BLive extends koishi_1.Service {
|
|
|
24
24
|
// 获取自身信息
|
|
25
25
|
const mySelfInfo = await this.ctx.ba.getMyselfInfo();
|
|
26
26
|
// 创建实例并保存到Record中
|
|
27
|
-
this.listenerRecord[roomId] = (0, blive_message_listener_1.startListen)(parseInt(roomId), handler, {
|
|
27
|
+
this.listenerRecord[roomId] = (0, blive_message_listener_1.startListen)(Number.parseInt(roomId), handler, {
|
|
28
28
|
ws: {
|
|
29
29
|
headers: {
|
|
30
|
-
Cookie: cookiesStr
|
|
30
|
+
Cookie: cookiesStr,
|
|
31
31
|
},
|
|
32
|
-
uid: mySelfInfo.data.mid
|
|
33
|
-
}
|
|
32
|
+
uid: mySelfInfo.data.mid,
|
|
33
|
+
},
|
|
34
34
|
});
|
|
35
35
|
// logger
|
|
36
36
|
this.logger.info(`${roomId}直播间弹幕监听已开启`);
|
|
37
37
|
}
|
|
38
38
|
closeListener(roomId) {
|
|
39
39
|
// 判断直播间监听器是否关闭
|
|
40
|
-
if (!this.listenerRecord ||
|
|
40
|
+
if (!this.listenerRecord ||
|
|
41
|
+
!this.listenerRecord[roomId] ||
|
|
42
|
+
!this.listenerRecord[roomId].closed) {
|
|
41
43
|
// 输出logger
|
|
42
44
|
this.logger.info(`${roomId}直播间弹幕监听器无需关闭`);
|
|
43
45
|
}
|
|
@@ -49,7 +51,7 @@ class BLive extends koishi_1.Service {
|
|
|
49
51
|
delete this.listenerRecord[roomId];
|
|
50
52
|
// 输出logger
|
|
51
53
|
this.logger.info(`${roomId}直播间弹幕监听已关闭`);
|
|
52
|
-
// 直接返回
|
|
54
|
+
// 直接返回
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
// 未关闭成功
|
package/lib/comRegister.js
CHANGED
|
@@ -8,8 +8,12 @@ const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
|
|
|
8
8
|
const koishi_1 = require("koishi");
|
|
9
9
|
// 外部依赖:qrcode
|
|
10
10
|
const qrcode_1 = __importDefault(require("qrcode"));
|
|
11
|
+
// Utils
|
|
12
|
+
const utils_1 = require("./utils");
|
|
11
13
|
// Types
|
|
12
14
|
const type_1 = require("./type");
|
|
15
|
+
// TODO:WorlCloud
|
|
16
|
+
// import { Segment, useDefault } from "segmentit";
|
|
13
17
|
class ComRegister {
|
|
14
18
|
// 必须服务
|
|
15
19
|
static inject = ["ba", "gi", "database", "bl", "sm"];
|
|
@@ -213,6 +217,8 @@ class ComRegister {
|
|
|
213
217
|
async init(config) {
|
|
214
218
|
// 设置logger
|
|
215
219
|
this.logger = this.ctx.logger("cr");
|
|
220
|
+
// logger
|
|
221
|
+
this.logger.info("加载订阅中...");
|
|
216
222
|
// 将config设置给类属性
|
|
217
223
|
this.config = config;
|
|
218
224
|
// 拿到私人机器人实例
|
|
@@ -229,41 +235,43 @@ class ComRegister {
|
|
|
229
235
|
bot, channelId,
|
|
230
236
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
231
237
|
content) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
// 成功发送消息,跳出循环
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
catch (e) {
|
|
244
|
-
if (i === attempts - 1) {
|
|
245
|
-
// 已尝试三次
|
|
246
|
-
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
|
|
247
|
-
console.log(e);
|
|
248
|
-
this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
249
|
-
}
|
|
238
|
+
(0, utils_1.withRetry)(async () => await bot.sendMessage(channelId, content)).catch(async (e) => {
|
|
239
|
+
if (e.message === "this._request is not a function") {
|
|
240
|
+
// 2S之后重新发送消息
|
|
241
|
+
this.ctx.setTimeout(async () => {
|
|
242
|
+
await this.sendMsgFunc(bot, channelId, content);
|
|
243
|
+
}, 2000);
|
|
244
|
+
// 返回
|
|
245
|
+
return;
|
|
250
246
|
}
|
|
251
|
-
|
|
247
|
+
// 打印错误信息
|
|
248
|
+
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
|
|
249
|
+
await this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
250
|
+
});
|
|
252
251
|
};
|
|
253
252
|
}
|
|
254
253
|
else {
|
|
255
254
|
this.sendMsgFunc = async (
|
|
256
255
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
257
|
-
bot,
|
|
256
|
+
bot, channelId,
|
|
258
257
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
259
258
|
content) => {
|
|
260
259
|
try {
|
|
261
260
|
// 发送消息
|
|
262
|
-
await bot.sendMessage(
|
|
261
|
+
await bot.sendMessage(channelId, content);
|
|
263
262
|
}
|
|
264
263
|
catch (e) {
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
if (e.message === "this._request is not a function") {
|
|
265
|
+
// 2S之后重新发送消息
|
|
266
|
+
this.ctx.setTimeout(async () => {
|
|
267
|
+
await this.sendMsgFunc(bot, channelId, content);
|
|
268
|
+
}, 2000);
|
|
269
|
+
// 返回
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// 打印错误信息
|
|
273
|
+
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
|
|
274
|
+
await this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
}
|
|
@@ -283,6 +291,8 @@ class ComRegister {
|
|
|
283
291
|
this.checkIfDynamicDetectIsNeeded();
|
|
284
292
|
// 在控制台中显示订阅对象
|
|
285
293
|
this.updateSubNotifier();
|
|
294
|
+
// logger
|
|
295
|
+
this.logger.info("订阅加载完毕!");
|
|
286
296
|
}
|
|
287
297
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
288
298
|
getBot(pf) {
|
|
@@ -416,7 +426,7 @@ class ComRegister {
|
|
|
416
426
|
}
|
|
417
427
|
else {
|
|
418
428
|
for (const channel of sendArr) {
|
|
419
|
-
//
|
|
429
|
+
// 判断是否需要推送动态消息
|
|
420
430
|
if (channel.dynamic || channel.live) {
|
|
421
431
|
await this.sendMsgFunc(bot, channel.channelId, content);
|
|
422
432
|
}
|
package/lib/index.js
CHANGED
|
@@ -129,10 +129,7 @@ class ServerManager extends koishi_1.Service {
|
|
|
129
129
|
break;
|
|
130
130
|
}
|
|
131
131
|
// 注册插件
|
|
132
|
-
if (this.registerPlugin()) {
|
|
133
|
-
this.logger.info("插件启动成功");
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
132
|
+
if (!this.registerPlugin()) {
|
|
136
133
|
this.logger.error("插件启动失败");
|
|
137
134
|
}
|
|
138
135
|
}
|
|
@@ -312,8 +309,8 @@ exports.Config = koishi_1.Schema.object({
|
|
|
312
309
|
live: koishi_1.Schema.boolean().default(false).description("该频道/群组是否推送直播通知"),
|
|
313
310
|
liveGuardBuy: koishi_1.Schema.boolean().default(false).description("该频道/群组是否推送上舰消息"),
|
|
314
311
|
atAll: koishi_1.Schema.boolean().default(false).description("推送开播通知时是否艾特全体成员"),
|
|
315
|
-
})).
|
|
316
|
-
platform: koishi_1.Schema.string().required().description("
|
|
312
|
+
})).description("需推送的频道/群组详细设置"),
|
|
313
|
+
platform: koishi_1.Schema.string().required().description("推送平台,例如onebot、qq、discord"),
|
|
317
314
|
})).description("订阅用户需要发送的平台和频道/群组信息(一个平台下可以推送多个频道/群组)"),
|
|
318
315
|
}))
|
|
319
316
|
.role("table")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface RetryOptions {
|
|
2
|
+
attempts: number;
|
|
3
|
+
onFailure?: (error: Error, attempts: number) => Promise<void> | void;
|
|
4
|
+
}
|
|
5
|
+
export declare function Retry(options?: RetryOptions): MethodDecorator;
|
|
6
|
+
/**
|
|
7
|
+
* 高阶函数:为函数添加锁机制
|
|
8
|
+
* @param {Function} fn - 需要包装的原始函数
|
|
9
|
+
* @returns {Function} 带锁功能的函数
|
|
10
|
+
*/
|
|
11
|
+
export declare function withLock(fn: any): (...args: any[]) => void;
|
|
12
|
+
export declare function withRetry(fn: any, maxAttempts?: number, delayMs?: number): Promise<any>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Retry = Retry;
|
|
4
|
+
exports.withLock = withLock;
|
|
5
|
+
exports.withRetry = withRetry;
|
|
6
|
+
function Retry(options = { attempts: 3 }) {
|
|
7
|
+
return (
|
|
8
|
+
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
|
9
|
+
target, propertyKey,
|
|
10
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
11
|
+
descriptor) => {
|
|
12
|
+
const originalMethod = descriptor.value;
|
|
13
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
14
|
+
descriptor.value = async function (...args) {
|
|
15
|
+
let lastError;
|
|
16
|
+
for (let i = 0; i < options.attempts; i++) {
|
|
17
|
+
try {
|
|
18
|
+
return await originalMethod.apply(this, args);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
lastError = error;
|
|
22
|
+
if (options.onFailure) {
|
|
23
|
+
await options.onFailure.call(this, lastError, i + 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
|
28
|
+
throw lastError;
|
|
29
|
+
};
|
|
30
|
+
return descriptor;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 高阶函数:为函数添加锁机制
|
|
35
|
+
* @param {Function} fn - 需要包装的原始函数
|
|
36
|
+
* @returns {Function} 带锁功能的函数
|
|
37
|
+
*/
|
|
38
|
+
function withLock(fn) {
|
|
39
|
+
// 判断是否是异步函数
|
|
40
|
+
const isAsync = fn.constructor.name === "AsyncFunction";
|
|
41
|
+
// 定义锁标志
|
|
42
|
+
let locked = false;
|
|
43
|
+
// 判断是否为异步函数
|
|
44
|
+
if (isAsync) {
|
|
45
|
+
// 变为Promise
|
|
46
|
+
return (...args) => {
|
|
47
|
+
// 已加锁则跳过执行
|
|
48
|
+
if (locked)
|
|
49
|
+
return;
|
|
50
|
+
// 获取锁
|
|
51
|
+
locked = true;
|
|
52
|
+
// 将异步函数转为Promise链
|
|
53
|
+
Promise.resolve(fn(...args))
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
// 打印错误
|
|
56
|
+
console.error("Execution error:", err);
|
|
57
|
+
// 重新抛出错误
|
|
58
|
+
throw err;
|
|
59
|
+
})
|
|
60
|
+
.finally(() => {
|
|
61
|
+
// 确保释放锁
|
|
62
|
+
locked = false;
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// 不是异步函数
|
|
67
|
+
return (...args) => {
|
|
68
|
+
// 已加锁则跳过执行
|
|
69
|
+
if (locked)
|
|
70
|
+
return;
|
|
71
|
+
// 获取锁
|
|
72
|
+
locked = true;
|
|
73
|
+
try {
|
|
74
|
+
// 执行函数
|
|
75
|
+
fn(...args);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
// 打印错误
|
|
79
|
+
console.error("Execution error:", err);
|
|
80
|
+
// 重新抛出错误
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
// 无论成功失败都释放锁
|
|
85
|
+
locked = false;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async function withRetry(fn, maxAttempts = 3, delayMs = 1000) {
|
|
90
|
+
let attempt = 0;
|
|
91
|
+
while (attempt < maxAttempts) {
|
|
92
|
+
try {
|
|
93
|
+
return await fn();
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
attempt++;
|
|
97
|
+
if (attempt >= maxAttempts)
|
|
98
|
+
throw error;
|
|
99
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs * attempt)); // 指数退避
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -200,6 +200,7 @@
|
|
|
200
200
|
- ver 3.0.0-alpha.18 移除:直播检测API模式已被废弃; 优化:更多提示语数据显示优化
|
|
201
201
|
- ver 3.0.0-alpha.19 修复:开播提示语粉丝数单位错误; 优化:订阅配置中所有配置项改为必填项
|
|
202
202
|
- ver 3.0.0-alpha.20 优化:订阅配置中开关选项默认为关闭
|
|
203
|
+
- ver 3.0.0-alpha.21 优化:部分代码; 新增:更新插件后,由于机器人还未启动,已开始发送消息报错 `this._request is not a function` ,新增报错后自动重新发送消息的功能
|
|
203
204
|
|
|
204
205
|
## 交流群
|
|
205
206
|
|