koishi-plugin-bilibili-notify 3.0.0-alpha.1 → 3.0.0-alpha.10
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 +260 -185
- package/lib/blive.d.ts +3 -2
- package/lib/blive.js +14 -7
- package/lib/comRegister.d.ts +28 -24
- package/lib/comRegister.js +443 -393
- package/lib/generateImg.js +4 -4
- package/lib/index.d.ts +13 -13
- package/lib/index.js +155 -154
- package/lib/utils/retry.d.ts +6 -0
- package/lib/utils/retry.js +24 -0
- package/lib/utils/withLock.d.ts +7 -0
- package/lib/utils/withLock.js +59 -0
- package/package.json +1 -1
- package/readme.md +10 -1
package/lib/generateImg.js
CHANGED
|
@@ -176,7 +176,7 @@ class GenerateImg extends koishi_1.Service {
|
|
|
176
176
|
</div>
|
|
177
177
|
${this.giConfig.hideDesc ? '' : `<p class="card-text">${data.description ? data.description : '这个主播很懒,什么都简介都没写'}</p>`}
|
|
178
178
|
<p class="card-link">
|
|
179
|
-
|
|
179
|
+
<span>人气:${data.online > 10000 ? `${(data.online / 10000).toFixed(1)}万` : data.online}</span>
|
|
180
180
|
<span>分区名称:${data.area_name}</span>
|
|
181
181
|
</p>
|
|
182
182
|
<p class="card-link">
|
|
@@ -1432,7 +1432,7 @@ class GenerateImg extends koishi_1.Service {
|
|
|
1432
1432
|
}
|
|
1433
1433
|
case 3: {
|
|
1434
1434
|
titleStatus = '下播啦';
|
|
1435
|
-
liveTime =
|
|
1435
|
+
liveTime = `开播时间:${time}`;
|
|
1436
1436
|
cover = true;
|
|
1437
1437
|
break;
|
|
1438
1438
|
}
|
|
@@ -1455,8 +1455,8 @@ class GenerateImg extends koishi_1.Service {
|
|
|
1455
1455
|
const seconds = differenceInSeconds % 60;
|
|
1456
1456
|
// 返回格式化的字符串
|
|
1457
1457
|
return days ?
|
|
1458
|
-
`${days}
|
|
1459
|
-
`${hours}小时${minutes.toString().padStart(2, '0')}
|
|
1458
|
+
`${days}天${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒` :
|
|
1459
|
+
`${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒`;
|
|
1460
1460
|
}
|
|
1461
1461
|
unixTimestampToString(timestamp) {
|
|
1462
1462
|
const date = new Date(timestamp * 1000);
|
package/lib/index.d.ts
CHANGED
|
@@ -6,6 +6,17 @@ declare module 'koishi' {
|
|
|
6
6
|
sm: ServerManager;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
declare class ServerManager extends Service {
|
|
10
|
+
servers: ForkScope[];
|
|
11
|
+
renderType: number;
|
|
12
|
+
dynamicLoopTime: number;
|
|
13
|
+
constructor(ctx: Context);
|
|
14
|
+
protected start(): void | Promise<void>;
|
|
15
|
+
registerPlugin: () => boolean;
|
|
16
|
+
disposePlugin: () => Promise<boolean>;
|
|
17
|
+
restartPlugin: () => Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
9
20
|
export interface Config {
|
|
10
21
|
require: {};
|
|
11
22
|
key: string;
|
|
@@ -25,6 +36,7 @@ export interface Config {
|
|
|
25
36
|
channelId: string;
|
|
26
37
|
dynamic: boolean;
|
|
27
38
|
live: boolean;
|
|
39
|
+
liveDanmaku: boolean;
|
|
28
40
|
atAll: boolean;
|
|
29
41
|
}>;
|
|
30
42
|
platform: string;
|
|
@@ -35,8 +47,7 @@ export interface Config {
|
|
|
35
47
|
dynamicCheckNumber: number;
|
|
36
48
|
dynamicLoopTime: '1分钟' | '2分钟' | '3分钟' | '5分钟' | '10分钟' | '20分钟';
|
|
37
49
|
live: {};
|
|
38
|
-
|
|
39
|
-
liveStartAtAll: boolean;
|
|
50
|
+
liveDetectMode: 'API' | 'WS';
|
|
40
51
|
restartPush: boolean;
|
|
41
52
|
pushTime: number;
|
|
42
53
|
danmakuPushTime: number;
|
|
@@ -55,15 +66,4 @@ export interface Config {
|
|
|
55
66
|
dynamicDebugMode: boolean;
|
|
56
67
|
}
|
|
57
68
|
export declare const Config: Schema<Config>;
|
|
58
|
-
declare class ServerManager extends Service {
|
|
59
|
-
servers: ForkScope[];
|
|
60
|
-
renderType: number;
|
|
61
|
-
dynamicLoopTime: number;
|
|
62
|
-
constructor(ctx: Context);
|
|
63
|
-
protected start(): void | Promise<void>;
|
|
64
|
-
registerPlugin: () => boolean;
|
|
65
|
-
disposePlugin: () => Promise<boolean>;
|
|
66
|
-
restartPlugin: () => Promise<boolean>;
|
|
67
|
-
}
|
|
68
|
-
export declare function apply(ctx: Context, config: Config): void;
|
|
69
69
|
export {};
|
package/lib/index.js
CHANGED
|
@@ -51,158 +51,6 @@ const blive_1 = __importDefault(require("./blive"));
|
|
|
51
51
|
exports.inject = ['puppeteer', 'database', 'notifier'];
|
|
52
52
|
exports.name = 'bilibili-notify';
|
|
53
53
|
let globalConfig;
|
|
54
|
-
exports.Config = koishi_1.Schema.object({
|
|
55
|
-
require: koishi_1.Schema.object({}).description('必填设置'),
|
|
56
|
-
key: koishi_1.Schema.string()
|
|
57
|
-
.pattern(/^[0-9a-f]{32}$/)
|
|
58
|
-
.role('secret')
|
|
59
|
-
.required()
|
|
60
|
-
.description('请输入一个32位小写字母的十六进制密钥(例如:9b8db7ae562b9864efefe06289cc5530),使用此密钥将你的B站登录信息存储在数据库中,请一定保存好此密钥。如果你忘记了此密钥,必须重新登录。你可以自行生成,或到这个网站生成:https://www.sexauth.com/'),
|
|
61
|
-
master: koishi_1.Schema.intersect([
|
|
62
|
-
koishi_1.Schema.object({
|
|
63
|
-
enable: koishi_1.Schema.boolean()
|
|
64
|
-
.default(false)
|
|
65
|
-
.description('是否开启主人账号功能,如果您的机器人没有私聊权限请不要开启此功能。开启后如果机器人运行错误会向您进行报告')
|
|
66
|
-
}).description('主人账号'),
|
|
67
|
-
koishi_1.Schema.union([
|
|
68
|
-
koishi_1.Schema.object({
|
|
69
|
-
enable: koishi_1.Schema.const(true).required(),
|
|
70
|
-
platform: koishi_1.Schema.union(['qq', 'qqguild', 'onebot', 'discord', 'red', 'telegram', 'satori', 'chronocat', 'lark'])
|
|
71
|
-
.description('请选择您的私人机器人平台,目前支持QQ、QQ群、OneBot、Discord、RedBot、Telegram、Satori、ChronoCat、Lark。从2.0版本开始,只能在一个平台下使用本插件'),
|
|
72
|
-
masterAccount: koishi_1.Schema.string()
|
|
73
|
-
.role('secret')
|
|
74
|
-
.required()
|
|
75
|
-
.description('主人账号,在Q群使用可直接使用QQ号,若在其他平台使用,请使用inspect插件获取自身ID'),
|
|
76
|
-
masterAccountGuildId: koishi_1.Schema.string()
|
|
77
|
-
.role('secret')
|
|
78
|
-
.description('主人账号所在的群组ID,只有在QQ频道、Discord这样的环境才需要填写,请使用inspect插件获取群组ID'),
|
|
79
|
-
}),
|
|
80
|
-
koishi_1.Schema.object({})
|
|
81
|
-
])
|
|
82
|
-
]),
|
|
83
|
-
basicSettings: koishi_1.Schema.object({}).description('基本设置'),
|
|
84
|
-
unlockSubLimits: koishi_1.Schema.boolean()
|
|
85
|
-
.default(false)
|
|
86
|
-
.description('解锁3个直播订阅限制,默认只允许订阅3位UP主。订阅过多用户可能有导致IP暂时被封禁的风险'),
|
|
87
|
-
automaticResend: koishi_1.Schema.boolean()
|
|
88
|
-
.default(true)
|
|
89
|
-
.description('是否开启自动重发功能,默认开启。开启后,如果推送失败,将会自动重发,尝试三次。关闭后,推送失败将不会再重发,直到下一次推送'),
|
|
90
|
-
renderType: koishi_1.Schema.union(['render', 'page'])
|
|
91
|
-
.role('')
|
|
92
|
-
.default('render')
|
|
93
|
-
.description('渲染类型,默认为render模式,渲染速度更快,但会出现乱码问题,若出现乱码问题,请切换到page模式。若使用自定义字体,建议选择render模式'),
|
|
94
|
-
userAgent: koishi_1.Schema.string()
|
|
95
|
-
.required()
|
|
96
|
-
.description('设置请求头User-Agen,请求出现-352时可以尝试修改,UA获取方法可参考:https://blog.csdn.net/qq_44503987/article/details/104929111'),
|
|
97
|
-
subTitle: koishi_1.Schema.object({}).description('手动订阅'),
|
|
98
|
-
sub: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
99
|
-
uid: koishi_1.Schema.string().description('订阅用户UID'),
|
|
100
|
-
dynamic: koishi_1.Schema.boolean().description('是否订阅用户动态'),
|
|
101
|
-
live: koishi_1.Schema.boolean().description('是否订阅用户直播'),
|
|
102
|
-
target: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
103
|
-
channelIdArr: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
104
|
-
channelId: koishi_1.Schema.string().description('频道/群组号'),
|
|
105
|
-
dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
|
|
106
|
-
live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
|
|
107
|
-
atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
|
|
108
|
-
})).description('频道/群组信息'),
|
|
109
|
-
platform: koishi_1.Schema.string().description('推送平台')
|
|
110
|
-
})).description('订阅用户需要发送的频道/群组信息')
|
|
111
|
-
})).role('table').description('手动输入订阅信息,方便自定义订阅内容,这里的订阅内容不会存入数据库。uid: 订阅用户UID,dynamic: 是否需要订阅动态,live: 是否需要订阅直播'),
|
|
112
|
-
dynamic: koishi_1.Schema.object({}).description('动态推送设置'),
|
|
113
|
-
dynamicUrl: koishi_1.Schema.boolean()
|
|
114
|
-
.default(false)
|
|
115
|
-
.description('发送动态时是否同时发送链接。注意:如果使用的是QQ官方机器人不能开启此项!'),
|
|
116
|
-
dynamicCheckNumber: koishi_1.Schema.number()
|
|
117
|
-
.min(2)
|
|
118
|
-
.max(10)
|
|
119
|
-
.role('slider')
|
|
120
|
-
.step(1)
|
|
121
|
-
.default(5)
|
|
122
|
-
.description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应+1。默认值为5条'),
|
|
123
|
-
dynamicLoopTime: koishi_1.Schema.union(['1分钟', '2分钟', '3分钟', '5分钟', '10分钟', '20分钟'])
|
|
124
|
-
.role('')
|
|
125
|
-
.default('2分钟')
|
|
126
|
-
.description('设定多久检测一次动态。若需动态的时效性,可以设置为1分钟。若订阅的UP主经常在短时间内连着发多条动态应该将该值提高,否则会出现动态漏推送和晚推送的问题,默认值为2分钟'),
|
|
127
|
-
live: koishi_1.Schema.object({}).description('直播推送设置'),
|
|
128
|
-
changeMasterInfoApi: koishi_1.Schema.boolean()
|
|
129
|
-
.default(false)
|
|
130
|
-
.description('是否切换获取主播信息API,在遇到错误getMasterInfo()时可以尝试切换'),
|
|
131
|
-
liveStartAtAll: koishi_1.Schema.boolean()
|
|
132
|
-
.default(false)
|
|
133
|
-
.description('直播开始时艾特全体成员,默认关闭'),
|
|
134
|
-
restartPush: koishi_1.Schema.boolean()
|
|
135
|
-
.default(true)
|
|
136
|
-
.description('插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启'),
|
|
137
|
-
pushTime: koishi_1.Schema.number()
|
|
138
|
-
.min(0)
|
|
139
|
-
.max(12)
|
|
140
|
-
.step(0.5)
|
|
141
|
-
.default(1)
|
|
142
|
-
.description('设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时'),
|
|
143
|
-
danmakuPushTime: koishi_1.Schema.number()
|
|
144
|
-
.min(0)
|
|
145
|
-
.max(10)
|
|
146
|
-
.step(0.5)
|
|
147
|
-
.default(0.5)
|
|
148
|
-
.description('设定间隔多长时间推送一次弹幕消息,单位为分钟,默认为半分钟'),
|
|
149
|
-
customLiveStart: koishi_1.Schema.string()
|
|
150
|
-
.default('-name开播啦 -link')
|
|
151
|
-
.description('自定义开播提示语,-name代表UP昵称,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name开播啦,会发送为xxxUP开播啦'),
|
|
152
|
-
customLive: koishi_1.Schema.string()
|
|
153
|
-
.description('自定义直播中提示语,-name代表UP昵称,-time代表开播时长,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name正在直播,会发送为xxxUP正在直播xxx'),
|
|
154
|
-
customLiveEnd: koishi_1.Schema.string()
|
|
155
|
-
.default('-name下播啦,本次直播了-time')
|
|
156
|
-
.description('自定义下播提示语,-name代表UP昵称,-time代表开播时长。例如-name下播啦,本次直播了-time,会发送为xxxUP下播啦,直播时长为xx小时xx分钟xx秒'),
|
|
157
|
-
hideDesc: koishi_1.Schema.boolean()
|
|
158
|
-
.default(false)
|
|
159
|
-
.description('是否隐藏UP主直播间简介,开启后推送的直播卡片将不再展示简介'),
|
|
160
|
-
style: koishi_1.Schema.object({}).description('美化设置'),
|
|
161
|
-
removeBorder: koishi_1.Schema.boolean()
|
|
162
|
-
.default(false)
|
|
163
|
-
.description('移除推送卡片边框'),
|
|
164
|
-
cardColorStart: koishi_1.Schema.string()
|
|
165
|
-
.pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
|
|
166
|
-
.default('#F38AB5')
|
|
167
|
-
.description('推送卡片的开始渐变背景色,请填入16进制颜色代码,参考网站:https://webkul.github.io/coolhue/'),
|
|
168
|
-
cardColorEnd: koishi_1.Schema.string()
|
|
169
|
-
.pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
|
|
170
|
-
.default('#F9CCDF')
|
|
171
|
-
.description('推送卡片的结束渐变背景色,请填入16进制颜色代码,参考网站:https://colorate.azurewebsites.net/'),
|
|
172
|
-
enableLargeFont: koishi_1.Schema.boolean()
|
|
173
|
-
.default(false)
|
|
174
|
-
.description('是否开启动态推送卡片大字体模式,默认为小字体。小字体更漂亮,但阅读比较吃力,大字体更易阅读,但相对没这么好看'),
|
|
175
|
-
font: koishi_1.Schema.string()
|
|
176
|
-
.description('推送卡片的字体样式,如果你想用你自己的字体可以在此填写,例如:Microsoft YaHei'),
|
|
177
|
-
filter: koishi_1.Schema.intersect([
|
|
178
|
-
koishi_1.Schema.object({
|
|
179
|
-
enable: koishi_1.Schema.boolean()
|
|
180
|
-
.default(false)
|
|
181
|
-
.description('是否开启动态屏蔽功能')
|
|
182
|
-
}).description('屏蔽设置'),
|
|
183
|
-
koishi_1.Schema.union([
|
|
184
|
-
koishi_1.Schema.object({
|
|
185
|
-
enable: koishi_1.Schema.const(true).required().experimental(),
|
|
186
|
-
notify: koishi_1.Schema.boolean()
|
|
187
|
-
.default(false)
|
|
188
|
-
.description('动态被屏蔽是否发送提示'),
|
|
189
|
-
regex: koishi_1.Schema.string()
|
|
190
|
-
.description('正则表达式屏蔽'),
|
|
191
|
-
keywords: koishi_1.Schema.array(String)
|
|
192
|
-
.description('关键字屏蔽,一个关键字为一项'),
|
|
193
|
-
forward: koishi_1.Schema.boolean()
|
|
194
|
-
.default(false)
|
|
195
|
-
.description("是否屏蔽转发动态"),
|
|
196
|
-
}),
|
|
197
|
-
koishi_1.Schema.object({})
|
|
198
|
-
])
|
|
199
|
-
]),
|
|
200
|
-
debug: koishi_1.Schema.object({}).description('调试设置'),
|
|
201
|
-
dynamicDebugMode: koishi_1.Schema.boolean()
|
|
202
|
-
.default(false)
|
|
203
|
-
.description('动态调试模式,开启后会在控制台输出动态推送的详细信息,用于调试')
|
|
204
|
-
.experimental()
|
|
205
|
-
});
|
|
206
54
|
class ServerManager extends koishi_1.Service {
|
|
207
55
|
// 服务
|
|
208
56
|
servers = [];
|
|
@@ -316,8 +164,7 @@ class ServerManager extends koishi_1.Service {
|
|
|
316
164
|
master: globalConfig.master,
|
|
317
165
|
unlockSubLimits: globalConfig.unlockSubLimits,
|
|
318
166
|
automaticResend: globalConfig.automaticResend,
|
|
319
|
-
|
|
320
|
-
liveStartAtAll: globalConfig.liveStartAtAll,
|
|
167
|
+
liveDetectMode: globalConfig.liveDetectMode,
|
|
321
168
|
restartPush: globalConfig.restartPush,
|
|
322
169
|
pushTime: globalConfig.pushTime,
|
|
323
170
|
customLiveStart: globalConfig.customLiveStart,
|
|
@@ -414,3 +261,157 @@ function apply(ctx, config) {
|
|
|
414
261
|
}
|
|
415
262
|
});
|
|
416
263
|
}
|
|
264
|
+
exports.Config = koishi_1.Schema.object({
|
|
265
|
+
require: koishi_1.Schema.object({}).description('必填设置'),
|
|
266
|
+
key: koishi_1.Schema.string()
|
|
267
|
+
.pattern(/^[0-9a-f]{32}$/)
|
|
268
|
+
.role('secret')
|
|
269
|
+
.required()
|
|
270
|
+
.description('请输入一个32位小写字母的十六进制密钥(例如:9b8db7ae562b9864efefe06289cc5530),使用此密钥将你的B站登录信息存储在数据库中,请一定保存好此密钥。如果你忘记了此密钥,必须重新登录。你可以自行生成,或到这个网站生成:https://www.sexauth.com/'),
|
|
271
|
+
master: koishi_1.Schema.intersect([
|
|
272
|
+
koishi_1.Schema.object({
|
|
273
|
+
enable: koishi_1.Schema.boolean()
|
|
274
|
+
.default(false)
|
|
275
|
+
.description('是否开启主人账号功能,如果您的机器人没有私聊权限请不要开启此功能。开启后如果机器人运行错误会向您进行报告')
|
|
276
|
+
}).description('主人账号'),
|
|
277
|
+
koishi_1.Schema.union([
|
|
278
|
+
koishi_1.Schema.object({
|
|
279
|
+
enable: koishi_1.Schema.const(true).required(),
|
|
280
|
+
platform: koishi_1.Schema.union(['qq', 'qqguild', 'onebot', 'discord', 'red', 'telegram', 'satori', 'chronocat', 'lark'])
|
|
281
|
+
.description('请选择您的私人机器人平台,目前支持QQ、QQ群、OneBot、Discord、RedBot、Telegram、Satori、ChronoCat、Lark。从2.0版本开始,只能在一个平台下使用本插件'),
|
|
282
|
+
masterAccount: koishi_1.Schema.string()
|
|
283
|
+
.role('secret')
|
|
284
|
+
.required()
|
|
285
|
+
.description('主人账号,在Q群使用可直接使用QQ号,若在其他平台使用,请使用inspect插件获取自身ID'),
|
|
286
|
+
masterAccountGuildId: koishi_1.Schema.string()
|
|
287
|
+
.role('secret')
|
|
288
|
+
.description('主人账号所在的群组ID,只有在QQ频道、Discord这样的环境才需要填写,请使用inspect插件获取群组ID'),
|
|
289
|
+
}),
|
|
290
|
+
koishi_1.Schema.object({})
|
|
291
|
+
])
|
|
292
|
+
]),
|
|
293
|
+
basicSettings: koishi_1.Schema.object({}).description('基本设置'),
|
|
294
|
+
unlockSubLimits: koishi_1.Schema.boolean()
|
|
295
|
+
.default(false)
|
|
296
|
+
.description('解锁3个直播订阅限制,默认只允许订阅3位UP主。订阅过多用户可能有导致IP暂时被封禁的风险'),
|
|
297
|
+
automaticResend: koishi_1.Schema.boolean()
|
|
298
|
+
.default(true)
|
|
299
|
+
.description('是否开启自动重发功能,默认开启。开启后,如果推送失败,将会自动重发,尝试三次。关闭后,推送失败将不会再重发,直到下一次推送'),
|
|
300
|
+
renderType: koishi_1.Schema.union(['render', 'page'])
|
|
301
|
+
.role('')
|
|
302
|
+
.default('render')
|
|
303
|
+
.description('渲染类型,默认为render模式,渲染速度更快,但会出现乱码问题,若出现乱码问题,请切换到page模式。若使用自定义字体,建议选择render模式'),
|
|
304
|
+
userAgent: koishi_1.Schema.string()
|
|
305
|
+
.required()
|
|
306
|
+
.description('设置请求头User-Agen,请求出现-352时可以尝试修改,UA获取方法可参考:https://blog.csdn.net/qq_44503987/article/details/104929111'),
|
|
307
|
+
subTitle: koishi_1.Schema.object({}).description('手动订阅'),
|
|
308
|
+
sub: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
309
|
+
uid: koishi_1.Schema.string().description('订阅用户UID'),
|
|
310
|
+
dynamic: koishi_1.Schema.boolean().description('是否订阅用户动态'),
|
|
311
|
+
live: koishi_1.Schema.boolean().description('是否订阅用户直播'),
|
|
312
|
+
target: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
313
|
+
channelIdArr: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
314
|
+
channelId: koishi_1.Schema.string().description('频道/群组号'),
|
|
315
|
+
dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
|
|
316
|
+
live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
|
|
317
|
+
liveDanmaku: koishi_1.Schema.boolean().description('该频道/群组是否推送弹幕消息'),
|
|
318
|
+
atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
|
|
319
|
+
})).description('频道/群组信息'),
|
|
320
|
+
platform: koishi_1.Schema.string().description('推送平台')
|
|
321
|
+
})).description('订阅用户需要发送的频道/群组信息')
|
|
322
|
+
})).role('table').description('手动输入订阅信息,方便自定义订阅内容,这里的订阅内容不会存入数据库。uid: 订阅用户UID,dynamic: 是否需要订阅动态,live: 是否需要订阅直播'),
|
|
323
|
+
dynamic: koishi_1.Schema.object({}).description('动态推送设置'),
|
|
324
|
+
dynamicUrl: koishi_1.Schema.boolean()
|
|
325
|
+
.default(false)
|
|
326
|
+
.description('发送动态时是否同时发送链接。注意:如果使用的是QQ官方机器人不能开启此项!'),
|
|
327
|
+
dynamicCheckNumber: koishi_1.Schema.number()
|
|
328
|
+
.min(2)
|
|
329
|
+
.max(10)
|
|
330
|
+
.role('slider')
|
|
331
|
+
.step(1)
|
|
332
|
+
.default(5)
|
|
333
|
+
.description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应+1。默认值为5条'),
|
|
334
|
+
dynamicLoopTime: koishi_1.Schema.union(['1分钟', '2分钟', '3分钟', '5分钟', '10分钟', '20分钟'])
|
|
335
|
+
.role('')
|
|
336
|
+
.default('2分钟')
|
|
337
|
+
.description('设定多久检测一次动态。若需动态的时效性,可以设置为1分钟。若订阅的UP主经常在短时间内连着发多条动态应该将该值提高,否则会出现动态漏推送和晚推送的问题,默认值为2分钟'),
|
|
338
|
+
live: koishi_1.Schema.object({}).description('直播推送设置'),
|
|
339
|
+
liveDetectMode: koishi_1.Schema.union([
|
|
340
|
+
koishi_1.Schema.const('WS').description('WebSocket模式:连接到对应的直播间,可推送弹幕消息,开播下播响应最快,但对订阅数有限制'),
|
|
341
|
+
koishi_1.Schema.const('API').description('API模式:请求对应直播间API,无法获取弹幕消息,开播下播响应慢,理论可无限订阅').experimental()
|
|
342
|
+
])
|
|
343
|
+
.role('radio')
|
|
344
|
+
.description('直播检测模式')
|
|
345
|
+
.default('WS'),
|
|
346
|
+
restartPush: koishi_1.Schema.boolean()
|
|
347
|
+
.default(true)
|
|
348
|
+
.description('插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启'),
|
|
349
|
+
pushTime: koishi_1.Schema.number()
|
|
350
|
+
.min(0)
|
|
351
|
+
.max(12)
|
|
352
|
+
.step(0.5)
|
|
353
|
+
.default(1)
|
|
354
|
+
.description('设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时'),
|
|
355
|
+
danmakuPushTime: koishi_1.Schema.number()
|
|
356
|
+
.min(0)
|
|
357
|
+
.max(10)
|
|
358
|
+
.step(0.5)
|
|
359
|
+
.default(0.5)
|
|
360
|
+
.description('设定间隔多长时间推送一次弹幕消息,单位为分钟,默认为半分钟'),
|
|
361
|
+
customLiveStart: koishi_1.Schema.string()
|
|
362
|
+
.default('-name开播啦 -link')
|
|
363
|
+
.description('自定义开播提示语,-name代表UP昵称,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name开播啦,会发送为xxxUP开播啦'),
|
|
364
|
+
customLive: koishi_1.Schema.string()
|
|
365
|
+
.description('自定义直播中提示语,-name代表UP昵称,-time代表开播时长,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name正在直播,会发送为xxxUP正在直播xxx'),
|
|
366
|
+
customLiveEnd: koishi_1.Schema.string()
|
|
367
|
+
.default('-name下播啦,本次直播了-time')
|
|
368
|
+
.description('自定义下播提示语,-name代表UP昵称,-time代表开播时长。例如-name下播啦,本次直播了-time,会发送为xxxUP下播啦,直播时长为xx小时xx分钟xx秒'),
|
|
369
|
+
hideDesc: koishi_1.Schema.boolean()
|
|
370
|
+
.default(false)
|
|
371
|
+
.description('是否隐藏UP主直播间简介,开启后推送的直播卡片将不再展示简介'),
|
|
372
|
+
style: koishi_1.Schema.object({}).description('美化设置'),
|
|
373
|
+
removeBorder: koishi_1.Schema.boolean()
|
|
374
|
+
.default(false)
|
|
375
|
+
.description('移除推送卡片边框'),
|
|
376
|
+
cardColorStart: koishi_1.Schema.string()
|
|
377
|
+
.pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
|
|
378
|
+
.default('#F38AB5')
|
|
379
|
+
.description('推送卡片的开始渐变背景色,请填入16进制颜色代码,参考网站:https://webkul.github.io/coolhue/'),
|
|
380
|
+
cardColorEnd: koishi_1.Schema.string()
|
|
381
|
+
.pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
|
|
382
|
+
.default('#F9CCDF')
|
|
383
|
+
.description('推送卡片的结束渐变背景色,请填入16进制颜色代码,参考网站:https://colorate.azurewebsites.net/'),
|
|
384
|
+
enableLargeFont: koishi_1.Schema.boolean()
|
|
385
|
+
.default(false)
|
|
386
|
+
.description('是否开启动态推送卡片大字体模式,默认为小字体。小字体更漂亮,但阅读比较吃力,大字体更易阅读,但相对没这么好看'),
|
|
387
|
+
font: koishi_1.Schema.string()
|
|
388
|
+
.description('推送卡片的字体样式,如果你想用你自己的字体可以在此填写,例如:Microsoft YaHei'),
|
|
389
|
+
filter: koishi_1.Schema.intersect([
|
|
390
|
+
koishi_1.Schema.object({
|
|
391
|
+
enable: koishi_1.Schema.boolean()
|
|
392
|
+
.default(false)
|
|
393
|
+
.description('是否开启动态屏蔽功能')
|
|
394
|
+
}).description('屏蔽设置'),
|
|
395
|
+
koishi_1.Schema.union([
|
|
396
|
+
koishi_1.Schema.object({
|
|
397
|
+
enable: koishi_1.Schema.const(true).required().experimental(),
|
|
398
|
+
notify: koishi_1.Schema.boolean()
|
|
399
|
+
.default(false)
|
|
400
|
+
.description('动态被屏蔽是否发送提示'),
|
|
401
|
+
regex: koishi_1.Schema.string()
|
|
402
|
+
.description('正则表达式屏蔽'),
|
|
403
|
+
keywords: koishi_1.Schema.array(String)
|
|
404
|
+
.description('关键字屏蔽,一个关键字为一项'),
|
|
405
|
+
forward: koishi_1.Schema.boolean()
|
|
406
|
+
.default(false)
|
|
407
|
+
.description("是否屏蔽转发动态"),
|
|
408
|
+
}),
|
|
409
|
+
koishi_1.Schema.object({})
|
|
410
|
+
])
|
|
411
|
+
]),
|
|
412
|
+
debug: koishi_1.Schema.object({}).description('调试设置'),
|
|
413
|
+
dynamicDebugMode: koishi_1.Schema.boolean()
|
|
414
|
+
.default(false)
|
|
415
|
+
.description('动态调试模式,开启后会在控制台输出动态推送的详细信息,用于调试')
|
|
416
|
+
.experimental()
|
|
417
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function Retry(options = { attempts: 3 }) {
|
|
4
|
+
return function (target, propertyKey, descriptor) {
|
|
5
|
+
const originalMethod = descriptor.value;
|
|
6
|
+
descriptor.value = async function (...args) {
|
|
7
|
+
let lastError;
|
|
8
|
+
for (let i = 0; i < options.attempts; i++) {
|
|
9
|
+
try {
|
|
10
|
+
return await originalMethod.apply(this, args);
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
lastError = error;
|
|
14
|
+
if (options.onFailure) {
|
|
15
|
+
await options.onFailure.call(this, lastError, i + 1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw lastError;
|
|
20
|
+
};
|
|
21
|
+
return descriptor;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.default = Retry;
|
|
@@ -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
package/readme.md
CHANGED
|
@@ -212,7 +212,16 @@
|
|
|
212
212
|
- ver 2.0.0-alpha.23 优化:将艾特全体成员消息单独发送
|
|
213
213
|
|
|
214
214
|
- ver 3.0.0-alpha.0 重构:直播 新增:直播弹幕推送到群
|
|
215
|
-
- ver 3.0.0-alpha.1
|
|
215
|
+
- ver 3.0.0-alpha.1 测试版本
|
|
216
|
+
- ver 3.0.0-alpha.2 修复:只订阅直播也会将该UP主的动态进行推送、推送过的动态过一段时间又会再次推送
|
|
217
|
+
- ver 3.0.0-alpha.3 修复:未开启弹幕推送也不会推送直播通知卡片
|
|
218
|
+
- ver 3.0.0-alpha.4 修复:使用了手动订阅,数据库中的订阅不会加载
|
|
219
|
+
- ver 3.0.0-alpha.5 修复:订阅的直播开播后,未开启弹幕推送会一直报错、主播开播推送下播卡片,直播时长显示NaN; 新增:直播检测模式选项; 优化:下播卡片内容
|
|
220
|
+
- ver 3.0.0-alpha.6 修复:连续发送两次直播中通知卡片; 优化:下播通知卡片
|
|
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 优化:加强直播推送对获取直播信息的错误处理
|
|
224
|
+
- ver 3.0.0-alpha.10 修复:连续推送两次开播通知
|
|
216
225
|
|
|
217
226
|
## 交流群
|
|
218
227
|
|