koishi-plugin-bilibili-notify 3.0.0-alpha.6 → 3.0.0-alpha.8
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 -186
- package/lib/comRegister.js +80 -59
- 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 +2 -0
package/lib/biliAPI.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
2
8
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
10
|
};
|
|
@@ -14,6 +20,7 @@ const tough_cookie_1 = require("tough-cookie");
|
|
|
14
20
|
const axios_cookiejar_support_1 = require("axios-cookiejar-support");
|
|
15
21
|
const jsdom_1 = require("jsdom");
|
|
16
22
|
const luxon_1 = require("luxon");
|
|
23
|
+
const retry_1 = __importDefault(require("./utils/retry"));
|
|
17
24
|
const mixinKeyEncTab = [
|
|
18
25
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
|
|
19
26
|
33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
|
|
@@ -108,183 +115,113 @@ class BiliAPI extends koishi_1.Service {
|
|
|
108
115
|
}
|
|
109
116
|
// BA API
|
|
110
117
|
async getTheUserWhoIsLiveStreaming() {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return live_users;
|
|
116
|
-
}
|
|
117
|
-
catch (e) {
|
|
118
|
-
throw new Error('网络异常,本次请求失败!');
|
|
119
|
-
}
|
|
118
|
+
// 获取直播间信息流密钥
|
|
119
|
+
const { data: { live_users } } = await this.client.get(GET_LATEST_UPDATED_UPS);
|
|
120
|
+
// 返回data
|
|
121
|
+
return live_users;
|
|
120
122
|
}
|
|
121
123
|
async getLiveRoomInfoStreamKey(roomId) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return data;
|
|
127
|
-
}
|
|
128
|
-
catch (e) {
|
|
129
|
-
throw new Error('网络异常,本次请求失败!');
|
|
130
|
-
}
|
|
124
|
+
// 获取直播间信息流密钥
|
|
125
|
+
const { data } = await this.client.get(`${GET_LIVE_ROOM_INFO_STREAM_KEY}?id=${roomId}`);
|
|
126
|
+
// 返回data
|
|
127
|
+
return data;
|
|
131
128
|
}
|
|
132
129
|
async getServerUTCTime() {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return timestamp / 1000;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
throw new Error('解析服务器时间失败!');
|
|
143
|
-
}
|
|
130
|
+
const { data } = await this.client.get(GET_SERVER_UTC_TIME);
|
|
131
|
+
const regex = /Date\.UTC\((.*?)\)/;
|
|
132
|
+
const match = data.match(regex);
|
|
133
|
+
if (match) {
|
|
134
|
+
const timestamp = new Function(`return Date.UTC(${match[1]})`)();
|
|
135
|
+
return timestamp / 1000;
|
|
144
136
|
}
|
|
145
|
-
|
|
146
|
-
throw new Error('
|
|
137
|
+
else {
|
|
138
|
+
throw new Error('解析服务器时间失败!');
|
|
147
139
|
}
|
|
148
140
|
}
|
|
149
141
|
async getTimeNow() {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return data;
|
|
153
|
-
}
|
|
154
|
-
catch (e) {
|
|
155
|
-
throw new Error('网络异常,本次请求失败!');
|
|
156
|
-
}
|
|
142
|
+
const { data } = await this.client.get(GET_TIME_NOW);
|
|
143
|
+
return data;
|
|
157
144
|
}
|
|
158
145
|
async getAllGroup() {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return data;
|
|
162
|
-
}
|
|
163
|
-
catch (e) {
|
|
164
|
-
throw new Error('网络异常,本次请求失败!');
|
|
165
|
-
}
|
|
146
|
+
const { data } = await this.client.get(GET_ALL_GROUP);
|
|
147
|
+
return data;
|
|
166
148
|
}
|
|
167
149
|
async removeUserFromGroup(mid) {
|
|
168
150
|
// 获取csrf
|
|
169
151
|
const csrf = this.getCSRF();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return data;
|
|
182
|
-
}
|
|
183
|
-
catch (e) {
|
|
184
|
-
throw new Error('网络异常,本次请求失败!');
|
|
185
|
-
}
|
|
152
|
+
// 将用户mid添加到groupId
|
|
153
|
+
const { data } = await this.client.post(MODIFY_GROUP_MEMBER, {
|
|
154
|
+
fids: mid,
|
|
155
|
+
tagids: 0,
|
|
156
|
+
csrf
|
|
157
|
+
}, {
|
|
158
|
+
headers: {
|
|
159
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return data;
|
|
186
163
|
}
|
|
187
164
|
async copyUserToGroup(mid, groupId) {
|
|
188
165
|
// 获取csrf
|
|
189
166
|
const csrf = this.getCSRF();
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return data;
|
|
202
|
-
}
|
|
203
|
-
catch (e) {
|
|
204
|
-
throw new Error('网络异常,本次请求失败!');
|
|
205
|
-
}
|
|
167
|
+
// 将用户mid添加到groupId
|
|
168
|
+
const { data } = await this.client.post(COPY_USER_TO_GROUP, {
|
|
169
|
+
fids: mid,
|
|
170
|
+
tagids: groupId,
|
|
171
|
+
csrf
|
|
172
|
+
}, {
|
|
173
|
+
headers: {
|
|
174
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return data;
|
|
206
178
|
}
|
|
207
179
|
async getUserSpaceDynamic(mid) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return data;
|
|
211
|
-
}
|
|
212
|
-
catch (e) {
|
|
213
|
-
throw new Error('网络异常,本次请求失败!');
|
|
214
|
-
}
|
|
180
|
+
const { data } = await this.client.get(`${GET_USER_SPACE_DYNAMIC_LIST}?host_mid=${mid}`);
|
|
181
|
+
return data;
|
|
215
182
|
}
|
|
216
183
|
async createGroup(tag) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return data;
|
|
227
|
-
}
|
|
228
|
-
catch (e) {
|
|
229
|
-
throw new Error('网络异常,本次请求失败!');
|
|
230
|
-
}
|
|
184
|
+
const { data } = await this.client.post(CREATE_GROUP, {
|
|
185
|
+
tag,
|
|
186
|
+
csrf: this.getCSRF()
|
|
187
|
+
}, {
|
|
188
|
+
headers: {
|
|
189
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return data;
|
|
231
193
|
}
|
|
232
194
|
async getAllDynamic(updateBaseline) {
|
|
233
195
|
let url = GET_ALL_DYNAMIC_LIST;
|
|
234
196
|
updateBaseline && (url += `?update_baseline=${updateBaseline}`);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return data;
|
|
238
|
-
}
|
|
239
|
-
catch (e) {
|
|
240
|
-
throw new Error('网络异常,本次请求失败!');
|
|
241
|
-
}
|
|
197
|
+
const { data } = await this.client.get(url);
|
|
198
|
+
return data;
|
|
242
199
|
}
|
|
243
200
|
async hasNewDynamic(updateBaseline) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return data;
|
|
247
|
-
}
|
|
248
|
-
catch (e) {
|
|
249
|
-
throw new Error('网络异常,本次请求失败!');
|
|
250
|
-
}
|
|
201
|
+
const { data } = await this.client.get(`${HAS_NEW_DYNAMIC}?update_baseline=${updateBaseline}`);
|
|
202
|
+
return data;
|
|
251
203
|
}
|
|
252
204
|
async follow(fid) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return data;
|
|
265
|
-
}
|
|
266
|
-
catch (e) {
|
|
267
|
-
throw new Error('网络异常,本次请求失败!');
|
|
268
|
-
}
|
|
205
|
+
const { data } = await this.client.post(MODIFY_RELATION, {
|
|
206
|
+
fid,
|
|
207
|
+
act: 1,
|
|
208
|
+
re_src: 11,
|
|
209
|
+
csrf: this.getCSRF()
|
|
210
|
+
}, {
|
|
211
|
+
headers: {
|
|
212
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return data;
|
|
269
216
|
}
|
|
270
217
|
async getRelationGroupDetail(tagid) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
return data;
|
|
274
|
-
}
|
|
275
|
-
catch (e) {
|
|
276
|
-
throw new Error('网络异常,本次请求失败!');
|
|
277
|
-
}
|
|
218
|
+
const { data } = await this.client.get(`${GET_RELATION_GROUP_DETAIL}?tagid=${tagid}`);
|
|
219
|
+
return data;
|
|
278
220
|
}
|
|
279
221
|
// Check if Token need refresh
|
|
280
222
|
async getCookieInfo(refreshToken) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return data;
|
|
284
|
-
}
|
|
285
|
-
catch (e) {
|
|
286
|
-
throw new Error('网络异常,本次请求失败!');
|
|
287
|
-
}
|
|
223
|
+
const { data } = await this.client.get(`${GET_COOKIES_INFO}?csrf=${refreshToken}`);
|
|
224
|
+
return data;
|
|
288
225
|
}
|
|
289
226
|
async getUserInfo(mid) {
|
|
290
227
|
//如果为番剧出差的UID,则不从远程接口拉取数据,直接传回一段精简过的有效数据
|
|
@@ -292,15 +229,9 @@ class BiliAPI extends koishi_1.Service {
|
|
|
292
229
|
console.log("检测到番剧出差UID,跳过远程用户接口访问");
|
|
293
230
|
return bangumiTripData;
|
|
294
231
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return data;
|
|
299
|
-
}
|
|
300
|
-
catch (e) {
|
|
301
|
-
console.warn(e);
|
|
302
|
-
throw new Error('网络异常,本次请求失败!');
|
|
303
|
-
}
|
|
232
|
+
const wbi = await this.getWbi({ mid });
|
|
233
|
+
const { data } = await this.client.get(`${GET_USER_INFO}?${wbi}`);
|
|
234
|
+
return data;
|
|
304
235
|
}
|
|
305
236
|
// 获取最新的 img_key 和 sub_key
|
|
306
237
|
async getWbiKeys() {
|
|
@@ -312,49 +243,24 @@ class BiliAPI extends koishi_1.Service {
|
|
|
312
243
|
};
|
|
313
244
|
}
|
|
314
245
|
async getMyselfInfo() {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return data;
|
|
318
|
-
}
|
|
319
|
-
catch (e) {
|
|
320
|
-
throw new Error('网络异常,本次请求失败!');
|
|
321
|
-
}
|
|
246
|
+
const { data } = await this.client.get(GET_MYSELF_INFO);
|
|
247
|
+
return data;
|
|
322
248
|
}
|
|
323
249
|
async getLoginQRCode() {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return data;
|
|
327
|
-
}
|
|
328
|
-
catch (e) {
|
|
329
|
-
throw new Error('网络异常,本次请求失败!');
|
|
330
|
-
}
|
|
250
|
+
const { data } = await this.client.get(GET_LOGIN_QRCODE);
|
|
251
|
+
return data;
|
|
331
252
|
}
|
|
332
253
|
async getLoginStatus(qrcodeKey) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return data;
|
|
336
|
-
}
|
|
337
|
-
catch (e) {
|
|
338
|
-
throw new Error('网络异常,本次请求失败!');
|
|
339
|
-
}
|
|
254
|
+
const { data } = await this.client.get(`${GET_LOGIN_STATUS}?qrcode_key=${qrcodeKey}`);
|
|
255
|
+
return data;
|
|
340
256
|
}
|
|
341
257
|
async getLiveRoomInfo(roomId) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
return data;
|
|
345
|
-
}
|
|
346
|
-
catch (e) {
|
|
347
|
-
throw new Error('网络异常,本次请求失败!');
|
|
348
|
-
}
|
|
258
|
+
const { data } = await this.client.get(`${GET_LIVE_ROOM_INFO}?room_id=${roomId}`);
|
|
259
|
+
return data;
|
|
349
260
|
}
|
|
350
261
|
async getMasterInfo(mid) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return data;
|
|
354
|
-
}
|
|
355
|
-
catch (e) {
|
|
356
|
-
throw new Error('网络异常,本次请求失败!');
|
|
357
|
-
}
|
|
262
|
+
const { data } = await this.client.get(`${GET_MASTER_INFO}?uid=${mid}`);
|
|
263
|
+
return data;
|
|
358
264
|
}
|
|
359
265
|
disposeNotifier() { if (this.loginNotifier)
|
|
360
266
|
this.loginNotifier.dispose(); }
|
|
@@ -644,6 +550,174 @@ class BiliAPI extends koishi_1.Service {
|
|
|
644
550
|
// 没有问题,cookies已更新完成
|
|
645
551
|
}
|
|
646
552
|
}
|
|
553
|
+
__decorate([
|
|
554
|
+
(0, retry_1.default)({
|
|
555
|
+
attempts: 3,
|
|
556
|
+
onFailure(error, attempts) {
|
|
557
|
+
this.logger.error(`getTheUserWhoIsLiveStreaming() 第${attempts}次失败: ${error.message}`);
|
|
558
|
+
},
|
|
559
|
+
})
|
|
560
|
+
], BiliAPI.prototype, "getTheUserWhoIsLiveStreaming", null);
|
|
561
|
+
__decorate([
|
|
562
|
+
(0, retry_1.default)({
|
|
563
|
+
attempts: 3,
|
|
564
|
+
onFailure(error, attempts) {
|
|
565
|
+
this.logger.error(`getLiveRoomInfoStreamKey() 第${attempts}次失败: ${error.message}`);
|
|
566
|
+
},
|
|
567
|
+
})
|
|
568
|
+
], BiliAPI.prototype, "getLiveRoomInfoStreamKey", null);
|
|
569
|
+
__decorate([
|
|
570
|
+
(0, retry_1.default)({
|
|
571
|
+
attempts: 3,
|
|
572
|
+
onFailure(error, attempts) {
|
|
573
|
+
this.logger.error(`getServerUTCTime() 第${attempts}次失败: ${error.message}`);
|
|
574
|
+
},
|
|
575
|
+
})
|
|
576
|
+
], BiliAPI.prototype, "getServerUTCTime", null);
|
|
577
|
+
__decorate([
|
|
578
|
+
(0, retry_1.default)({
|
|
579
|
+
attempts: 3,
|
|
580
|
+
onFailure(error, attempts) {
|
|
581
|
+
this.logger.error(`getTimeNow() 第${attempts}次失败: ${error.message}`);
|
|
582
|
+
},
|
|
583
|
+
})
|
|
584
|
+
], BiliAPI.prototype, "getTimeNow", null);
|
|
585
|
+
__decorate([
|
|
586
|
+
(0, retry_1.default)({
|
|
587
|
+
attempts: 3,
|
|
588
|
+
onFailure(error, attempts) {
|
|
589
|
+
this.logger.error(`getAllGroup() 第${attempts}次失败: ${error.message}`);
|
|
590
|
+
},
|
|
591
|
+
})
|
|
592
|
+
], BiliAPI.prototype, "getAllGroup", null);
|
|
593
|
+
__decorate([
|
|
594
|
+
(0, retry_1.default)({
|
|
595
|
+
attempts: 3,
|
|
596
|
+
onFailure(error, attempts) {
|
|
597
|
+
this.logger.error(`removeUserFromGroup() 第${attempts}次失败: ${error.message}`);
|
|
598
|
+
},
|
|
599
|
+
})
|
|
600
|
+
], BiliAPI.prototype, "removeUserFromGroup", null);
|
|
601
|
+
__decorate([
|
|
602
|
+
(0, retry_1.default)({
|
|
603
|
+
attempts: 3,
|
|
604
|
+
onFailure(error, attempts) {
|
|
605
|
+
this.logger.error(`copyUserToGroup() 第${attempts}次失败: ${error.message}`);
|
|
606
|
+
},
|
|
607
|
+
})
|
|
608
|
+
], BiliAPI.prototype, "copyUserToGroup", null);
|
|
609
|
+
__decorate([
|
|
610
|
+
(0, retry_1.default)({
|
|
611
|
+
attempts: 3,
|
|
612
|
+
onFailure(error, attempts) {
|
|
613
|
+
this.logger.error(`getUserSpaceDynamic() 第${attempts}次失败: ${error.message}`);
|
|
614
|
+
},
|
|
615
|
+
})
|
|
616
|
+
], BiliAPI.prototype, "getUserSpaceDynamic", null);
|
|
617
|
+
__decorate([
|
|
618
|
+
(0, retry_1.default)({
|
|
619
|
+
attempts: 3,
|
|
620
|
+
onFailure(error, attempts) {
|
|
621
|
+
this.logger.error(`createGroup() 第${attempts}次失败: ${error.message}`);
|
|
622
|
+
},
|
|
623
|
+
})
|
|
624
|
+
], BiliAPI.prototype, "createGroup", null);
|
|
625
|
+
__decorate([
|
|
626
|
+
(0, retry_1.default)({
|
|
627
|
+
attempts: 3,
|
|
628
|
+
onFailure(error, attempts) {
|
|
629
|
+
this.logger.error(`getAllDynamic() 第${attempts}次失败: ${error.message}`);
|
|
630
|
+
},
|
|
631
|
+
})
|
|
632
|
+
], BiliAPI.prototype, "getAllDynamic", null);
|
|
633
|
+
__decorate([
|
|
634
|
+
(0, retry_1.default)({
|
|
635
|
+
attempts: 3,
|
|
636
|
+
onFailure(error, attempts) {
|
|
637
|
+
this.logger.error(`hasNewDynamic() 第${attempts}次失败: ${error.message}`);
|
|
638
|
+
},
|
|
639
|
+
})
|
|
640
|
+
], BiliAPI.prototype, "hasNewDynamic", null);
|
|
641
|
+
__decorate([
|
|
642
|
+
(0, retry_1.default)({
|
|
643
|
+
attempts: 3,
|
|
644
|
+
onFailure(error, attempts) {
|
|
645
|
+
this.logger.error(`follow() 第${attempts}次失败: ${error.message}`);
|
|
646
|
+
},
|
|
647
|
+
})
|
|
648
|
+
], BiliAPI.prototype, "follow", null);
|
|
649
|
+
__decorate([
|
|
650
|
+
(0, retry_1.default)({
|
|
651
|
+
attempts: 3,
|
|
652
|
+
onFailure(error, attempts) {
|
|
653
|
+
this.logger.error(`getRelationGroupDetail() 第${attempts}次失败: ${error.message}`);
|
|
654
|
+
},
|
|
655
|
+
})
|
|
656
|
+
], BiliAPI.prototype, "getRelationGroupDetail", null);
|
|
657
|
+
__decorate([
|
|
658
|
+
(0, retry_1.default)({
|
|
659
|
+
attempts: 3,
|
|
660
|
+
onFailure(error, attempts) {
|
|
661
|
+
this.logger.error(`getCookieInfo() 第${attempts}次失败: ${error.message}`);
|
|
662
|
+
},
|
|
663
|
+
})
|
|
664
|
+
], BiliAPI.prototype, "getCookieInfo", null);
|
|
665
|
+
__decorate([
|
|
666
|
+
(0, retry_1.default)({
|
|
667
|
+
attempts: 3,
|
|
668
|
+
onFailure(error, attempts) {
|
|
669
|
+
this.logger.error(`getUserInfo() 第${attempts}次失败: ${error.message}`);
|
|
670
|
+
},
|
|
671
|
+
})
|
|
672
|
+
], BiliAPI.prototype, "getUserInfo", null);
|
|
673
|
+
__decorate([
|
|
674
|
+
(0, retry_1.default)({
|
|
675
|
+
attempts: 3,
|
|
676
|
+
onFailure(error, attempts) {
|
|
677
|
+
this.logger.error(`getWbiKeys() 第${attempts}次失败: ${error.message}`);
|
|
678
|
+
},
|
|
679
|
+
})
|
|
680
|
+
], BiliAPI.prototype, "getWbiKeys", null);
|
|
681
|
+
__decorate([
|
|
682
|
+
(0, retry_1.default)({
|
|
683
|
+
attempts: 3,
|
|
684
|
+
onFailure(error, attempts) {
|
|
685
|
+
this.logger.error(`getMyselfInfo() 第${attempts}次失败: ${error.message}`);
|
|
686
|
+
},
|
|
687
|
+
})
|
|
688
|
+
], BiliAPI.prototype, "getMyselfInfo", null);
|
|
689
|
+
__decorate([
|
|
690
|
+
(0, retry_1.default)({
|
|
691
|
+
attempts: 3,
|
|
692
|
+
onFailure(error, attempts) {
|
|
693
|
+
this.logger.error(`getLoginQRCode() 第${attempts}次失败: ${error.message}`);
|
|
694
|
+
},
|
|
695
|
+
})
|
|
696
|
+
], BiliAPI.prototype, "getLoginQRCode", null);
|
|
697
|
+
__decorate([
|
|
698
|
+
(0, retry_1.default)({
|
|
699
|
+
attempts: 3,
|
|
700
|
+
onFailure(error, attempts) {
|
|
701
|
+
this.logger.error(`getLoginStatus() 第${attempts}次失败: ${error.message}`);
|
|
702
|
+
},
|
|
703
|
+
})
|
|
704
|
+
], BiliAPI.prototype, "getLoginStatus", null);
|
|
705
|
+
__decorate([
|
|
706
|
+
(0, retry_1.default)({
|
|
707
|
+
attempts: 3,
|
|
708
|
+
onFailure(error, attempts) {
|
|
709
|
+
this.logger.error(`getLiveRoomInfo() 第${attempts}次失败: ${error.message}`);
|
|
710
|
+
},
|
|
711
|
+
})
|
|
712
|
+
], BiliAPI.prototype, "getLiveRoomInfo", null);
|
|
713
|
+
__decorate([
|
|
714
|
+
(0, retry_1.default)({
|
|
715
|
+
attempts: 3,
|
|
716
|
+
onFailure(error, attempts) {
|
|
717
|
+
this.logger.error(`getMasterInfo() 第${attempts}次失败: ${error.message}`);
|
|
718
|
+
},
|
|
719
|
+
})
|
|
720
|
+
], BiliAPI.prototype, "getMasterInfo", null);
|
|
647
721
|
(function (BiliAPI) {
|
|
648
722
|
BiliAPI.Config = koishi_1.Schema.object({
|
|
649
723
|
userAgent: koishi_1.Schema.string(),
|
package/lib/comRegister.js
CHANGED
|
@@ -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 {
|
|
@@ -439,23 +440,23 @@ class ComRegister {
|
|
|
439
440
|
this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
440
441
|
return '订阅出错啦,请重试';
|
|
441
442
|
}
|
|
443
|
+
const liveDetectModeSelector = {
|
|
444
|
+
API: async () => {
|
|
445
|
+
// 判断是否已开启直播检测
|
|
446
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
447
|
+
// 开启直播检测并保存销毁函数
|
|
448
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
WS: async () => {
|
|
452
|
+
// 连接到服务器
|
|
453
|
+
await this.liveDetectWithListener(roomId, target);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
442
456
|
// 订阅直播
|
|
443
457
|
if (liveMsg) {
|
|
444
458
|
// 判断直播订阅方式
|
|
445
|
-
|
|
446
|
-
case "API": {
|
|
447
|
-
// 判断是否已开启直播检测
|
|
448
|
-
if (!this.liveDispose) { // 未开启直播检测
|
|
449
|
-
// 开启直播检测并保存销毁函数
|
|
450
|
-
this.liveDispose = await this.liveDetectWithAPI();
|
|
451
|
-
}
|
|
452
|
-
break;
|
|
453
|
-
}
|
|
454
|
-
case "WS": {
|
|
455
|
-
// 连接到服务器
|
|
456
|
-
await this.liveDetectWithListener(roomId, target);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
459
460
|
// 发送订阅消息通知
|
|
460
461
|
await session.send(`订阅${userData.info.uname}直播通知`);
|
|
461
462
|
}
|
|
@@ -463,6 +464,7 @@ class ComRegister {
|
|
|
463
464
|
if (dynamicMsg) {
|
|
464
465
|
// 判断是否开启动态监测
|
|
465
466
|
if (!this.dynamicDispose) {
|
|
467
|
+
// 开启动态监测
|
|
466
468
|
this.enableDynamicDetect();
|
|
467
469
|
}
|
|
468
470
|
// 发送订阅消息通知
|
|
@@ -1391,10 +1393,18 @@ class ComRegister {
|
|
|
1391
1393
|
// 定义弹幕存放数组
|
|
1392
1394
|
const currentLiveDanmakuArr = [];
|
|
1393
1395
|
const temporaryLiveDanmakuArr = [];
|
|
1396
|
+
// 定义开播状态
|
|
1397
|
+
let liveStatus = false;
|
|
1394
1398
|
// 处理target
|
|
1399
|
+
// 定义channelIdArr总长度
|
|
1400
|
+
let channelIdArrLen = 0;
|
|
1395
1401
|
// 找到频道/群组对应的
|
|
1396
1402
|
const danmakuPushTargetArr = target.map(channel => {
|
|
1403
|
+
// 获取符合条件的target
|
|
1397
1404
|
const liveDanmakuArr = channel.channelIdArr.filter(channelId => channelId.liveDanmaku);
|
|
1405
|
+
// 将当前liveDanmakuArr的长度+到channelIdArrLen中
|
|
1406
|
+
channelIdArrLen += liveDanmakuArr.length;
|
|
1407
|
+
// 返回符合的target
|
|
1398
1408
|
return {
|
|
1399
1409
|
channelIdArr: liveDanmakuArr,
|
|
1400
1410
|
platform: channel.platform
|
|
@@ -1422,7 +1432,7 @@ class ComRegister {
|
|
|
1422
1432
|
// 定义弹幕推送函数
|
|
1423
1433
|
const danmakuPushFunc = () => {
|
|
1424
1434
|
// 判断数组是否有内容
|
|
1425
|
-
if (
|
|
1435
|
+
if (channelIdArrLen > 0 && temporaryLiveDanmakuArr.length > 0) {
|
|
1426
1436
|
// 发送消息
|
|
1427
1437
|
this.sendMsg(danmakuPushTargetArr, temporaryLiveDanmakuArr.join('\n'));
|
|
1428
1438
|
// 将临时消息数组清空
|
|
@@ -1462,6 +1472,9 @@ class ComRegister {
|
|
|
1462
1472
|
temporaryLiveDanmakuArr.push(content);
|
|
1463
1473
|
},
|
|
1464
1474
|
onLiveStart: async () => {
|
|
1475
|
+
// 判断是否已经开播
|
|
1476
|
+
if (liveStatus)
|
|
1477
|
+
return;
|
|
1465
1478
|
// 获取直播间信息
|
|
1466
1479
|
const liveRoomInfo = await this.useLiveRoomInfo(roomId);
|
|
1467
1480
|
// 获取主播信息
|
|
@@ -1473,7 +1486,7 @@ class ComRegister {
|
|
|
1473
1486
|
.replace('-name', masterInfo.username)
|
|
1474
1487
|
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
|
|
1475
1488
|
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1476
|
-
//
|
|
1489
|
+
// 推送开播通知
|
|
1477
1490
|
await this.sendLiveNotifyCard({
|
|
1478
1491
|
username: masterInfo.username,
|
|
1479
1492
|
userface: masterInfo.userface,
|
|
@@ -1485,6 +1498,8 @@ class ComRegister {
|
|
|
1485
1498
|
// 开始直播,开启定时器
|
|
1486
1499
|
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1487
1500
|
}
|
|
1501
|
+
// 设置开播状态为true
|
|
1502
|
+
liveStatus = true;
|
|
1488
1503
|
},
|
|
1489
1504
|
onLiveEnd: async () => {
|
|
1490
1505
|
// 获取直播间消息
|
|
@@ -1508,6 +1523,8 @@ class ComRegister {
|
|
|
1508
1523
|
pushAtTimeTimer();
|
|
1509
1524
|
// 将推送定时器变量置空
|
|
1510
1525
|
pushAtTimeTimer = null;
|
|
1526
|
+
// 将直播状态设置为false
|
|
1527
|
+
liveStatus = false;
|
|
1511
1528
|
}
|
|
1512
1529
|
};
|
|
1513
1530
|
// 启动直播间弹幕监测
|
|
@@ -1536,6 +1553,8 @@ class ComRegister {
|
|
|
1536
1553
|
// 开始直播,开启定时器
|
|
1537
1554
|
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1538
1555
|
}
|
|
1556
|
+
// 设置直播状态为true
|
|
1557
|
+
liveStatus = true;
|
|
1539
1558
|
}
|
|
1540
1559
|
}
|
|
1541
1560
|
subShow() {
|
|
@@ -1735,23 +1754,24 @@ class ComRegister {
|
|
|
1735
1754
|
// 发送提示
|
|
1736
1755
|
this.logger.warn(`UID:${sub.uid} 用户没有开通直播间,无法订阅直播!`);
|
|
1737
1756
|
}
|
|
1738
|
-
//
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
//
|
|
1744
|
-
|
|
1745
|
-
// 开启直播检测并保存销毁函数
|
|
1746
|
-
this.liveDispose = await this.liveDetectWithAPI();
|
|
1747
|
-
}
|
|
1748
|
-
break;
|
|
1749
|
-
}
|
|
1750
|
-
case "WS": {
|
|
1751
|
-
// 连接到服务器
|
|
1752
|
-
await this.liveDetectWithListener(data.live_room.roomid, sub.target);
|
|
1757
|
+
//
|
|
1758
|
+
const liveDetectModeSelector = {
|
|
1759
|
+
API: async () => {
|
|
1760
|
+
// 判断是否已开启直播检测
|
|
1761
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
1762
|
+
// 开启直播检测并保存销毁函数
|
|
1763
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
1753
1764
|
}
|
|
1765
|
+
},
|
|
1766
|
+
WS: async () => {
|
|
1767
|
+
// 连接到服务器
|
|
1768
|
+
await this.liveDetectWithListener(data.live_room.roomid, sub.target);
|
|
1754
1769
|
}
|
|
1770
|
+
};
|
|
1771
|
+
// 判断是否订阅直播
|
|
1772
|
+
if (sub.live) {
|
|
1773
|
+
// 启动直播监测
|
|
1774
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
1755
1775
|
}
|
|
1756
1776
|
}
|
|
1757
1777
|
// 在B站中订阅该对象
|
|
@@ -1872,36 +1892,37 @@ class ComRegister {
|
|
|
1872
1892
|
dynamic: sub.dynamic === 1 ? true : false,
|
|
1873
1893
|
liveDispose: null
|
|
1874
1894
|
};
|
|
1875
|
-
//
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
//
|
|
1881
|
-
|
|
1882
|
-
// 开启直播检测并保存销毁函数
|
|
1883
|
-
this.liveDispose = await this.liveDetectWithAPI();
|
|
1884
|
-
}
|
|
1885
|
-
break;
|
|
1895
|
+
// 定义直播模式监测器
|
|
1896
|
+
const liveDetectModeSelector = {
|
|
1897
|
+
API: async () => {
|
|
1898
|
+
// 判断是否已开启直播检测
|
|
1899
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
1900
|
+
// 开启直播检测并保存销毁函数
|
|
1901
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
1886
1902
|
}
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
+
},
|
|
1904
|
+
WS: async () => {
|
|
1905
|
+
// 判断订阅直播数是否超过限制
|
|
1906
|
+
if (!this.config.unlockSubLimits && liveSubNum >= 3) {
|
|
1907
|
+
// 将live改为false
|
|
1908
|
+
subManagerItem.live = false;
|
|
1909
|
+
// log
|
|
1910
|
+
this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1911
|
+
// 发送错误消息
|
|
1912
|
+
await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1913
|
+
}
|
|
1914
|
+
else {
|
|
1915
|
+
// 直播订阅数+1
|
|
1916
|
+
liveSubNum++;
|
|
1917
|
+
// 订阅直播,开始循环检测
|
|
1918
|
+
await this.liveDetectWithListener(sub.room_id, target);
|
|
1903
1919
|
}
|
|
1904
1920
|
}
|
|
1921
|
+
};
|
|
1922
|
+
// 判断是否订阅直播
|
|
1923
|
+
if (sub.live) {
|
|
1924
|
+
// 启动直播监测
|
|
1925
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
1905
1926
|
}
|
|
1906
1927
|
// 保存新订阅对象
|
|
1907
1928
|
this.subManager.push(subManagerItem);
|
|
@@ -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
|
@@ -218,6 +218,8 @@
|
|
|
218
218
|
- ver 3.0.0-alpha.4 修复:使用了手动订阅,数据库中的订阅不会加载
|
|
219
219
|
- ver 3.0.0-alpha.5 修复:订阅的直播开播后,未开启弹幕推送会一直报错、主播开播推送下播卡片,直播时长显示NaN; 新增:直播检测模式选项; 优化:下播卡片内容
|
|
220
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 修复:开播通知连续发送两次,登录后不会加载手动订阅中的订阅; 优化:网络请求报错
|
|
221
223
|
|
|
222
224
|
## 交流群
|
|
223
225
|
|