koishi-plugin-bilibili-notify 2.0.0-alpha.1 → 2.0.0-alpha.11
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.d.ts +1 -0
- package/lib/biliAPI.js +10 -0
- package/lib/comRegister.d.ts +28 -11
- package/lib/comRegister.js +383 -353
- package/lib/database.d.ts +1 -2
- package/lib/database.js +1 -2
- package/lib/generateImg.js +8 -9
- package/lib/index.d.ts +1 -2
- package/lib/index.js +9 -11
- package/package.json +1 -2
- package/readme.md +30 -11
package/lib/comRegister.js
CHANGED
|
@@ -10,15 +10,16 @@ const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
|
|
|
10
10
|
const koishi_1 = require("koishi");
|
|
11
11
|
// 导入qrcode
|
|
12
12
|
const qrcode_1 = __importDefault(require("qrcode"));
|
|
13
|
-
const jimp_1 = require("jimp");
|
|
14
13
|
var LiveType;
|
|
15
14
|
(function (LiveType) {
|
|
16
15
|
LiveType[LiveType["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
|
|
17
16
|
LiveType[LiveType["StartBroadcasting"] = 1] = "StartBroadcasting";
|
|
18
17
|
LiveType[LiveType["LiveBroadcast"] = 2] = "LiveBroadcast";
|
|
18
|
+
LiveType[LiveType["StopBroadcast"] = 3] = "StopBroadcast";
|
|
19
19
|
})(LiveType || (LiveType = {}));
|
|
20
20
|
class ComRegister {
|
|
21
21
|
static inject = ['ba', 'gi', 'database', 'sm'];
|
|
22
|
+
qqRelatedBotList = ['qq', 'onebot', 'red', 'satori', 'chronocat'];
|
|
22
23
|
logger;
|
|
23
24
|
config;
|
|
24
25
|
loginTimer;
|
|
@@ -26,8 +27,10 @@ class ComRegister {
|
|
|
26
27
|
rebootCount = 0;
|
|
27
28
|
subNotifier;
|
|
28
29
|
subManager = [];
|
|
30
|
+
// 检查登录数据库是否有数据
|
|
31
|
+
loginDBData;
|
|
29
32
|
// 机器人实例
|
|
30
|
-
|
|
33
|
+
privateBot;
|
|
31
34
|
// 动态销毁函数
|
|
32
35
|
dynamicDispose;
|
|
33
36
|
// 发送消息方式
|
|
@@ -36,26 +39,27 @@ class ComRegister {
|
|
|
36
39
|
constructor(ctx, config) {
|
|
37
40
|
this.logger = ctx.logger('cr');
|
|
38
41
|
this.config = config;
|
|
39
|
-
//
|
|
40
|
-
this.
|
|
41
|
-
if (!this.
|
|
42
|
+
// 拿到私人机器人实例
|
|
43
|
+
this.privateBot = ctx.bots.find(bot => bot.platform === config.master.platform);
|
|
44
|
+
if (!this.privateBot) {
|
|
42
45
|
ctx.notifier.create({
|
|
43
|
-
|
|
44
|
-
content: '未找到对应机器人实例,请检查配置是否正确或重新配置适配器!'
|
|
46
|
+
content: '您未配置私人机器人,将无法向您推送机器人状态!'
|
|
45
47
|
});
|
|
46
|
-
this.logger.error('
|
|
48
|
+
this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
|
|
47
49
|
}
|
|
50
|
+
// 检查登录数据库是否有数据
|
|
51
|
+
ctx.database.get('loginBili', 1, ['dynamic_group_id']).then(data => this.loginDBData = data[0]);
|
|
48
52
|
// 从数据库获取订阅
|
|
49
53
|
this.getSubFromDatabase(ctx);
|
|
50
54
|
// 判断消息发送方式
|
|
51
55
|
if (config.automaticResend) {
|
|
52
|
-
this.sendMsgFunc = async (
|
|
56
|
+
this.sendMsgFunc = async (bot, channelId, content) => {
|
|
53
57
|
// 多次尝试发送消息
|
|
54
58
|
const attempts = 3;
|
|
55
59
|
for (let i = 0; i < attempts; i++) {
|
|
56
60
|
try {
|
|
57
61
|
// 发送消息
|
|
58
|
-
await
|
|
62
|
+
await bot.sendMessage(channelId, content);
|
|
59
63
|
// 防止消息发送速度过快被忽略
|
|
60
64
|
await ctx.sleep(500);
|
|
61
65
|
// 成功发送消息,跳出循环
|
|
@@ -63,19 +67,19 @@ class ComRegister {
|
|
|
63
67
|
}
|
|
64
68
|
catch (e) {
|
|
65
69
|
if (i === attempts - 1) { // 已尝试三次
|
|
66
|
-
this.logger.error(`发送群组ID:${
|
|
70
|
+
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ` + e.message);
|
|
67
71
|
console.log(e);
|
|
68
|
-
this.sendPrivateMsg(`发送群组ID:${
|
|
72
|
+
this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
78
|
else {
|
|
75
|
-
this.sendMsgFunc = async (guild, content) => {
|
|
79
|
+
this.sendMsgFunc = async (bot, guild, content) => {
|
|
76
80
|
try {
|
|
77
81
|
// 发送消息
|
|
78
|
-
await
|
|
82
|
+
await bot.sendMessage(guild, content);
|
|
79
83
|
}
|
|
80
84
|
catch (e) {
|
|
81
85
|
this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
|
|
@@ -99,9 +103,30 @@ class ComRegister {
|
|
|
99
103
|
.usage('查看订阅管理对象')
|
|
100
104
|
.example('status sm')
|
|
101
105
|
.action(async () => {
|
|
102
|
-
|
|
106
|
+
this.logger.info(this.subManager);
|
|
103
107
|
return '查看控制台';
|
|
104
108
|
});
|
|
109
|
+
statusCom
|
|
110
|
+
.subcommand('.bot', '查询当前拥有的机器人信息', { hidden: true })
|
|
111
|
+
.usage('查询当前拥有的机器人信息')
|
|
112
|
+
.example('status bot 查询当前拥有的机器人信息')
|
|
113
|
+
.action(() => {
|
|
114
|
+
this.logger.info('开始输出BOT信息');
|
|
115
|
+
ctx.bots.forEach(bot => {
|
|
116
|
+
this.logger.info('--------------------------------');
|
|
117
|
+
this.logger.info('平台:' + bot.platform);
|
|
118
|
+
this.logger.info('名称:' + bot.user.name);
|
|
119
|
+
this.logger.info('--------------------------------');
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
statusCom
|
|
123
|
+
.subcommand('.env', '查询当前环境的信息', { hidden: true })
|
|
124
|
+
.usage('查询当前环境的信息')
|
|
125
|
+
.example('status env 查询当前环境的信息')
|
|
126
|
+
.action(async ({ session }) => {
|
|
127
|
+
await session.send(`Guild ID:${session.event.guild.id}`);
|
|
128
|
+
await session.send(`Channel ID: ${session.event.channel.id}`);
|
|
129
|
+
});
|
|
105
130
|
const biliCom = ctx.command('bili', 'bili-notify插件相关指令', { permissions: ['authority:3'] });
|
|
106
131
|
biliCom.subcommand('.login', '登录B站之后才可以进行之后的操作')
|
|
107
132
|
.usage('使用二维码登录,登录B站之后才可以进行之后的操作')
|
|
@@ -216,6 +241,7 @@ class ComRegister {
|
|
|
216
241
|
await session.send(this.unsubSingle(ctx, sub.uid, 1)); /* 1为取消订阅Dynamic */
|
|
217
242
|
// 将存在flag设置为true
|
|
218
243
|
exist = true;
|
|
244
|
+
// 结束循环
|
|
219
245
|
return;
|
|
220
246
|
}
|
|
221
247
|
// 取消全部订阅 执行dispose方法,销毁定时器
|
|
@@ -228,9 +254,12 @@ class ComRegister {
|
|
|
228
254
|
// 将订阅对象移出订阅关注组
|
|
229
255
|
const removeUserFromGroupData = await ctx.ba.removeUserFromGroup(sub.uid);
|
|
230
256
|
// 判断是否移出成功 22105关注对象为自己
|
|
231
|
-
if (removeUserFromGroupData.code !== 0
|
|
257
|
+
if (removeUserFromGroupData.code !== 0 && removeUserFromGroupData.code !== 22105) {
|
|
232
258
|
// 移出失败
|
|
233
259
|
await session.send('取消订阅对象失败,请稍后重试');
|
|
260
|
+
// 将存在flag设置为true
|
|
261
|
+
exist = true;
|
|
262
|
+
// 结束循环
|
|
234
263
|
return;
|
|
235
264
|
}
|
|
236
265
|
// id--
|
|
@@ -263,29 +292,19 @@ class ComRegister {
|
|
|
263
292
|
return subTable;
|
|
264
293
|
});
|
|
265
294
|
biliCom
|
|
266
|
-
.subcommand('.sub <mid:string> [...
|
|
295
|
+
.subcommand('.sub <mid:string> [...groupId:string]', '订阅用户动态和直播通知')
|
|
296
|
+
.option('multiplatform', '-m <value:string>', { type: /^[A-Za-z0-9]+@?(?:,[A-Za-z0-9]+@?)*\.[A-Za-z0-9]+(?:;[A-Za-z0-9]+@?(?:,[A-Za-z0-9]+@?)*\.[A-Za-z0-9]+)*$/ })
|
|
267
297
|
.option('live', '-l')
|
|
268
298
|
.option('dynamic', '-d')
|
|
269
|
-
.
|
|
270
|
-
.
|
|
271
|
-
.
|
|
299
|
+
.option('atAll', '-a')
|
|
300
|
+
.usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d')
|
|
301
|
+
.example('bili sub 1194210119 目标群号或频道号 -l -d 订阅UID为1194210119的UP主的动态和直播')
|
|
302
|
+
.action(async ({ session, options }, mid, ...groupId) => {
|
|
272
303
|
this.logger.info('调用bili.sub指令');
|
|
273
304
|
// 先判断是否订阅直播,再判断是否解锁订阅限制,最后判断直播订阅是否已超三个
|
|
274
305
|
if (options.live && !this.config.unlockSubLimits && (this.subManager.reduce((acc, cur) => acc + (cur.live ? 1 : 0), 0) >= 3)) {
|
|
275
306
|
return '直播订阅已达上限,请取消部分直播订阅后再进行订阅';
|
|
276
307
|
}
|
|
277
|
-
// 检查是否是不支持的平台
|
|
278
|
-
switch (session.event.platform) {
|
|
279
|
-
case 'lark':
|
|
280
|
-
case 'red':
|
|
281
|
-
case 'onebot':
|
|
282
|
-
case 'telegram':
|
|
283
|
-
case 'satori':
|
|
284
|
-
case 'chronocat':
|
|
285
|
-
case 'qq':
|
|
286
|
-
case 'qqguild': break;
|
|
287
|
-
default: return '暂不支持该平台';
|
|
288
|
-
}
|
|
289
308
|
// 检查是否登录
|
|
290
309
|
if (!(await this.checkIfIsLogin(ctx))) {
|
|
291
310
|
// 未登录直接返回
|
|
@@ -294,54 +313,97 @@ class ComRegister {
|
|
|
294
313
|
// 检查必选参数是否已填
|
|
295
314
|
if (!mid)
|
|
296
315
|
return '请输入用户uid';
|
|
297
|
-
//
|
|
298
|
-
const
|
|
299
|
-
//
|
|
300
|
-
if (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
// 订阅对象
|
|
317
|
+
const subUserData = await this.subUserInBili(ctx, mid);
|
|
318
|
+
// 判断是否订阅对象存在
|
|
319
|
+
if (!subUserData.flag)
|
|
320
|
+
return '订阅对象失败,请稍后重试!';
|
|
321
|
+
// 定义目标变量
|
|
322
|
+
let target = [];
|
|
323
|
+
// 判断是否使用了多群组推送
|
|
324
|
+
if (groupId.length > 0) {
|
|
325
|
+
// 定义channelIdArr
|
|
326
|
+
const channelIdArr = [];
|
|
327
|
+
// 遍历输入的群组
|
|
328
|
+
groupId.forEach(group => {
|
|
329
|
+
channelIdArr.push({
|
|
330
|
+
channelId: group,
|
|
331
|
+
atAll: options.atAll
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
target.push({
|
|
335
|
+
channelIdArr,
|
|
336
|
+
platform: session.event.platform
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
// 判断是否使用多平台功能
|
|
341
|
+
if (options.multiplatform) {
|
|
342
|
+
// 分割字符串,赋值给target
|
|
343
|
+
target = this.splitMultiPlatformStr(options.multiplatform);
|
|
317
344
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
345
|
+
// 判断是否使用了多平台
|
|
346
|
+
if (target) {
|
|
347
|
+
target.forEach(async ({ channelIdArr, platform }, index) => {
|
|
348
|
+
if (channelIdArr.length > 0) { // 输入了推送群号或频道号
|
|
349
|
+
// 拿到对应的bot
|
|
350
|
+
const bot = this.getBot(ctx, platform);
|
|
351
|
+
// 判断是否配置了对应平台的机器人
|
|
352
|
+
if (!ctx.bots.some(bot => bot.platform === platform)) {
|
|
353
|
+
await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
|
|
354
|
+
}
|
|
355
|
+
// 判断是否需要加入的群全部推送
|
|
356
|
+
if (channelIdArr[0].channelId !== 'all') {
|
|
357
|
+
// 定义满足条件的群组数组
|
|
358
|
+
const targetArr = [];
|
|
359
|
+
// 获取机器人加入的群组
|
|
360
|
+
const guildList = await bot.getGuildList();
|
|
361
|
+
// 遍历target数组
|
|
362
|
+
for (const channelId of channelIdArr) {
|
|
363
|
+
// 定义是否加入群组标志
|
|
364
|
+
let flag = false;
|
|
365
|
+
// 遍历群组
|
|
366
|
+
for (const guild of guildList.data) {
|
|
367
|
+
// 获取频道列表
|
|
368
|
+
const channelList = await bot.getChannelList(guild.id);
|
|
369
|
+
// 判断机器人是否加入群聊或频道
|
|
370
|
+
if (channelList.data.some(channel => channel.id === channelId.channelId)) {
|
|
371
|
+
// 加入群聊或频道
|
|
372
|
+
targetArr.push(channelId);
|
|
373
|
+
// 设置标志位为true
|
|
374
|
+
flag = true;
|
|
375
|
+
// 结束循环
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (!flag) {
|
|
380
|
+
// 不满足条件发送错误提示
|
|
381
|
+
await session.send(`您的机器未加入${channelId.channelId},无法对该群或频道进行推送`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// 判断targetArr是否为空
|
|
385
|
+
if (target.length === 0) {
|
|
386
|
+
// 为空则默认为当前环境
|
|
387
|
+
target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
|
|
388
|
+
// 没有满足条件的群组或频道
|
|
389
|
+
await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
|
|
390
|
+
}
|
|
391
|
+
// 将符合条件的群组添加到target中
|
|
392
|
+
target[index].channelIdArr = targetArr;
|
|
393
|
+
}
|
|
394
|
+
// 如果为all则全部推送,不需要进行处理
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
// 未填写群号或频道号,默认为当前环境
|
|
398
|
+
target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
|
|
399
|
+
// 发送提示消息
|
|
400
|
+
await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
|
|
401
|
+
}
|
|
402
|
+
});
|
|
321
403
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
// 订阅对象
|
|
326
|
-
const subUserData = await ctx.ba.follow(mid);
|
|
327
|
-
// 判断是否订阅成功
|
|
328
|
-
switch (subUserData.code) {
|
|
329
|
-
case -101: return '账号未登录,请使用指令bili login登录后再进行订阅操作';
|
|
330
|
-
case -102: return '账号被封停,无法进行订阅操作';
|
|
331
|
-
case 22002: return '因对方隐私设置,无法进行订阅操作';
|
|
332
|
-
case 22003: return '你已将对方拉黑,无法进行订阅操作';
|
|
333
|
-
case 22013: return '账号已注销,无法进行订阅操作';
|
|
334
|
-
case 40061: return '账号不存在,请检查uid输入是否正确或用户是否存在';
|
|
335
|
-
case 22001: break; // 订阅对象为自己 无需添加到分组
|
|
336
|
-
case 22014: // 已关注订阅对象 无需再次关注
|
|
337
|
-
case 0: { // 执行订阅成功
|
|
338
|
-
// 把订阅对象添加到分组中
|
|
339
|
-
const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, loginDBData.dynamic_group_id);
|
|
340
|
-
// 判断是否添加成功
|
|
341
|
-
if (copyUserToGroupData.code !== 0) {
|
|
342
|
-
// 添加失败
|
|
343
|
-
return '添加订阅对象到分组失败,请稍后重试';
|
|
344
|
-
}
|
|
404
|
+
else {
|
|
405
|
+
// 用户直接订阅,将当前环境赋值给target
|
|
406
|
+
target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
|
|
345
407
|
}
|
|
346
408
|
}
|
|
347
409
|
// 定义外围变量
|
|
@@ -379,88 +441,14 @@ class ComRegister {
|
|
|
379
441
|
// 返回错误信息
|
|
380
442
|
return msg;
|
|
381
443
|
}
|
|
382
|
-
// 定义目标群组id
|
|
383
|
-
let targetId;
|
|
384
|
-
// 定义目标群组id数组
|
|
385
|
-
let targetIdArr;
|
|
386
|
-
// 判断是否输入了QQ群号
|
|
387
|
-
if (guildId.length > 0) { // 输入了QQ群号
|
|
388
|
-
// 定义方法
|
|
389
|
-
const checkIfGuildHasJoined = async (bot) => {
|
|
390
|
-
// 获取机器人加入的群组
|
|
391
|
-
const guildList = await bot.getGuildList();
|
|
392
|
-
// 定义满足条件的群组数组
|
|
393
|
-
const targetArr = [];
|
|
394
|
-
// 判断群号是否符合条件
|
|
395
|
-
for (const guild of guildId) {
|
|
396
|
-
// 判断是否机器人加入了该群
|
|
397
|
-
if (guildList.data.some(cv => cv.id === guild)) { // 机器人加入了该群
|
|
398
|
-
// 保存到数组
|
|
399
|
-
targetArr.push(guild);
|
|
400
|
-
// 继续下一个循环
|
|
401
|
-
continue;
|
|
402
|
-
}
|
|
403
|
-
// 不满足条件发送错误提示
|
|
404
|
-
session.send(`您的机器未加入${guild},无法对该群进行推送`);
|
|
405
|
-
}
|
|
406
|
-
// 返回数组
|
|
407
|
-
return targetArr;
|
|
408
|
-
};
|
|
409
|
-
// 定义可用的群组数组
|
|
410
|
-
let okGuild = [];
|
|
411
|
-
// 判断是否需要加入的群全部推送
|
|
412
|
-
if (guildId[0] === 'all') {
|
|
413
|
-
// 判断是否有群机器人相关Bot
|
|
414
|
-
if (['qq', 'onebot', 'red', 'satori', 'chronocat'].includes(session.event.platform)) {
|
|
415
|
-
// 推送所有群组
|
|
416
|
-
okGuild.push('all');
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
// 发送错误提示并返回
|
|
420
|
-
session.send('您尚未配置任何QQ群相关机器人,不能对QQ群进行操作');
|
|
421
|
-
// 直接返回
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
// 判断是否有群机器人相关Bot
|
|
427
|
-
switch (session.event.platform) {
|
|
428
|
-
case 'qq':
|
|
429
|
-
case 'onebot':
|
|
430
|
-
case 'red':
|
|
431
|
-
case 'satori':
|
|
432
|
-
case 'chronocat': {
|
|
433
|
-
// 检查机器人是否加入该群
|
|
434
|
-
okGuild = await checkIfGuildHasJoined(this.bot);
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
default: {
|
|
438
|
-
// 发送错误提示并返回
|
|
439
|
-
session.send('您尚未配置任何QQ群相关机器人,不能对QQ群进行操作');
|
|
440
|
-
// 直接返回
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
// 将可用的目标赋值给数组
|
|
446
|
-
targetIdArr = okGuild;
|
|
447
|
-
// 将群号用空格进行分割
|
|
448
|
-
targetId = okGuild.join(' ');
|
|
449
|
-
}
|
|
450
|
-
else { // 没有输入QQ群号
|
|
451
|
-
// 为当前群聊环境进行推送
|
|
452
|
-
targetId = session.event.channel.id;
|
|
453
|
-
// 将目标id转换为数组进行赋值
|
|
454
|
-
targetIdArr = [session.event.channel.id];
|
|
455
|
-
}
|
|
456
444
|
// 获取data
|
|
457
445
|
const { data } = content;
|
|
458
446
|
// 判断是否需要订阅直播和动态
|
|
459
|
-
const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data);
|
|
447
|
+
const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data.live_room);
|
|
460
448
|
// 判断是否未订阅任何消息
|
|
461
|
-
if (!liveMsg && !dynamicMsg)
|
|
449
|
+
if (!liveMsg && !dynamicMsg)
|
|
462
450
|
return '您未订阅该UP的任何消息';
|
|
463
|
-
|
|
451
|
+
// 获取到对应的订阅对象
|
|
464
452
|
const subUser = this.subManager.find(sub => sub.uid === mid);
|
|
465
453
|
// 判断要订阅的用户是否已经存在于订阅管理对象中
|
|
466
454
|
if (subUser) {
|
|
@@ -475,44 +463,22 @@ class ComRegister {
|
|
|
475
463
|
}
|
|
476
464
|
// 获取直播房间号
|
|
477
465
|
const roomId = data.live_room?.roomid.toString();
|
|
478
|
-
// 保存到数据库中
|
|
479
|
-
const sub = await ctx.database.create('bilibili', {
|
|
480
|
-
uid: mid,
|
|
481
|
-
room_id: roomId,
|
|
482
|
-
dynamic: dynamicMsg ? 1 : 0,
|
|
483
|
-
video: 1,
|
|
484
|
-
live: liveMsg ? 1 : 0,
|
|
485
|
-
targetId,
|
|
486
|
-
platform: session.event.platform,
|
|
487
|
-
time: new Date()
|
|
488
|
-
});
|
|
489
|
-
// 订阅数+1
|
|
490
|
-
this.num++;
|
|
491
|
-
// 保存新订阅对象
|
|
492
|
-
this.subManager.push({
|
|
493
|
-
id: sub.id,
|
|
494
|
-
uid: mid,
|
|
495
|
-
targetIdArr,
|
|
496
|
-
roomId,
|
|
497
|
-
platform: session.event.platform,
|
|
498
|
-
live: liveMsg,
|
|
499
|
-
dynamic: dynamicMsg,
|
|
500
|
-
liveDispose: null
|
|
501
|
-
});
|
|
502
466
|
// 获取用户信息
|
|
503
467
|
let userData;
|
|
504
468
|
try {
|
|
505
|
-
const { data } = await ctx.ba.getMasterInfo(
|
|
469
|
+
const { data } = await ctx.ba.getMasterInfo(mid);
|
|
506
470
|
userData = data;
|
|
507
471
|
}
|
|
508
472
|
catch (e) {
|
|
509
473
|
this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
510
474
|
return '订阅出错啦,请重试';
|
|
511
475
|
}
|
|
512
|
-
|
|
476
|
+
// 定义live销毁函数
|
|
477
|
+
let liveDispose;
|
|
513
478
|
// 订阅直播
|
|
514
479
|
if (liveMsg) {
|
|
515
|
-
|
|
480
|
+
// 开始循环检测
|
|
481
|
+
liveDispose = ctx.setInterval(this.liveDetect(ctx, roomId, target), config.liveLoopTime * 1000);
|
|
516
482
|
// 发送订阅消息通知
|
|
517
483
|
await session.send(`订阅${userData.info.uname}直播通知`);
|
|
518
484
|
}
|
|
@@ -531,29 +497,32 @@ class ComRegister {
|
|
|
531
497
|
// 发送订阅消息通知
|
|
532
498
|
await session.send(`订阅${userData.info.uname}动态通知`);
|
|
533
499
|
}
|
|
500
|
+
// 保存到数据库中
|
|
501
|
+
const sub = await ctx.database.create('bilibili', {
|
|
502
|
+
uid: mid,
|
|
503
|
+
room_id: roomId,
|
|
504
|
+
dynamic: dynamicMsg ? 1 : 0,
|
|
505
|
+
live: liveMsg ? 1 : 0,
|
|
506
|
+
target: JSON.stringify(target),
|
|
507
|
+
platform: session.event.platform,
|
|
508
|
+
time: new Date()
|
|
509
|
+
});
|
|
510
|
+
// 订阅数+1
|
|
511
|
+
this.num++;
|
|
512
|
+
// 保存新订阅对象
|
|
513
|
+
this.subManager.push({
|
|
514
|
+
id: sub.id,
|
|
515
|
+
uid: mid,
|
|
516
|
+
roomId,
|
|
517
|
+
target,
|
|
518
|
+
platform: session.event.platform,
|
|
519
|
+
live: liveMsg,
|
|
520
|
+
dynamic: dynamicMsg,
|
|
521
|
+
liveDispose
|
|
522
|
+
});
|
|
534
523
|
// 新增订阅展示到控制台
|
|
535
524
|
this.updateSubNotifier(ctx);
|
|
536
525
|
});
|
|
537
|
-
biliCom
|
|
538
|
-
.subcommand('.live <roomId:string> <...guildId:string>', '订阅主播开播通知', { hidden: true })
|
|
539
|
-
.usage('订阅主播开播通知')
|
|
540
|
-
.example('bili live 26316137 订阅房间号为26316137的直播间')
|
|
541
|
-
.action(async (_, roomId, ...guildId) => {
|
|
542
|
-
this.logger.info('调用bili.live指令');
|
|
543
|
-
// 如果room_id为空则返回
|
|
544
|
-
if (!roomId)
|
|
545
|
-
return `${roomId}非法调用 dynamic 指令`; // 订阅主播房间号不能为空
|
|
546
|
-
if (!guildId)
|
|
547
|
-
return `${roomId}非法调用 dynamic 指令`; // 目标群组或频道不能为空
|
|
548
|
-
// 要订阅的对象不在订阅管理对象中,直接返回
|
|
549
|
-
const index = this.subManager.findIndex(sub => sub.roomId === roomId);
|
|
550
|
-
if (index === -1)
|
|
551
|
-
return '请勿直接调用该指令';
|
|
552
|
-
// 开始循环检测
|
|
553
|
-
const dispose = ctx.setInterval(this.liveDetect(ctx, roomId, guildId), config.liveLoopTime * 1000);
|
|
554
|
-
// 保存销毁函数
|
|
555
|
-
this.subManager[index].liveDispose = dispose;
|
|
556
|
-
});
|
|
557
526
|
biliCom
|
|
558
527
|
.subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
|
|
559
528
|
.usage('查询主播当前直播状态')
|
|
@@ -597,19 +566,6 @@ class ComRegister {
|
|
|
597
566
|
// pic不存在,说明使用的是page模式
|
|
598
567
|
await session.send(koishi_1.h.image(buffer, 'image/png'));
|
|
599
568
|
});
|
|
600
|
-
biliCom
|
|
601
|
-
.subcommand('.bot', '查询当前拥有的机器人信息', { hidden: true })
|
|
602
|
-
.usage('查询当前拥有的机器人信息')
|
|
603
|
-
.example('bili bot 查询当前拥有的机器人信息')
|
|
604
|
-
.action(() => {
|
|
605
|
-
this.logger.info('开始输出BOT信息');
|
|
606
|
-
ctx.bots.forEach(bot => {
|
|
607
|
-
this.logger.info('--------------------------------');
|
|
608
|
-
this.logger.info('平台:' + bot.platform);
|
|
609
|
-
this.logger.info('名称:' + bot.user.name);
|
|
610
|
-
this.logger.info('--------------------------------');
|
|
611
|
-
});
|
|
612
|
-
});
|
|
613
569
|
biliCom
|
|
614
570
|
.subcommand('.private', '向主人账号发送一条测试消息', { hidden: true })
|
|
615
571
|
.usage('向主人账号发送一条测试消息')
|
|
@@ -621,15 +577,28 @@ class ComRegister {
|
|
|
621
577
|
await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
|
|
622
578
|
});
|
|
623
579
|
}
|
|
580
|
+
splitMultiPlatformStr(str) {
|
|
581
|
+
return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
|
|
582
|
+
const channelIdArr = idStr.split(',').map(id => {
|
|
583
|
+
const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
|
|
584
|
+
const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
|
|
585
|
+
return { channelId, atAll };
|
|
586
|
+
});
|
|
587
|
+
return { channelIdArr, platform };
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
getBot(ctx, pf) {
|
|
591
|
+
return ctx.bots.find(bot => bot.platform === pf);
|
|
592
|
+
}
|
|
624
593
|
async sendPrivateMsg(content) {
|
|
625
594
|
if (this.config.master.enable) {
|
|
626
595
|
if (this.config.master.masterAccountGuildId) {
|
|
627
596
|
// 向机器人主人发送消息
|
|
628
|
-
await this.
|
|
597
|
+
await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
|
|
629
598
|
}
|
|
630
599
|
else {
|
|
631
600
|
// 向机器人主人发送消息
|
|
632
|
-
await this.
|
|
601
|
+
await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content);
|
|
633
602
|
}
|
|
634
603
|
}
|
|
635
604
|
}
|
|
@@ -674,22 +643,34 @@ class ComRegister {
|
|
|
674
643
|
// 结束
|
|
675
644
|
return;
|
|
676
645
|
}
|
|
677
|
-
async sendMsg(targets, content) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
646
|
+
async sendMsg(ctx, targets, content, live) {
|
|
647
|
+
for (const target of targets) {
|
|
648
|
+
// 获取机器人实例
|
|
649
|
+
const bot = this.getBot(ctx, target.platform);
|
|
650
|
+
// 定义需要发送的数组
|
|
651
|
+
let sendArr = [];
|
|
652
|
+
// 判断是否需要推送所有机器人加入的群
|
|
653
|
+
if (target.channelIdArr[0].channelId === 'all') {
|
|
654
|
+
// 获取所有guild
|
|
655
|
+
for (const guild of (await bot.getGuildList()).data) {
|
|
656
|
+
sendArr.push({ channelId: guild.id, atAll: target.channelIdArr[0].atAll });
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
sendArr = target.channelIdArr;
|
|
661
|
+
}
|
|
662
|
+
// 循环给每个群组发送
|
|
663
|
+
if (live) {
|
|
664
|
+
// 直播推送,需要判断是否为
|
|
665
|
+
for (const channel of sendArr) {
|
|
666
|
+
await this.sendMsgFunc(bot, channel.channelId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [content, channel.atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" })] }));
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
for (const channel of sendArr) {
|
|
671
|
+
await this.sendMsgFunc(bot, channel.channelId, content);
|
|
672
|
+
}
|
|
685
673
|
}
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
sendArr = targets;
|
|
689
|
-
}
|
|
690
|
-
// 循环给每个群组发送
|
|
691
|
-
for (const guild of sendArr) {
|
|
692
|
-
await this.sendMsgFunc(guild, content);
|
|
693
674
|
}
|
|
694
675
|
}
|
|
695
676
|
dynamicDetect(ctx) {
|
|
@@ -819,13 +800,13 @@ class ComRegister {
|
|
|
819
800
|
if (e.message === '出现关键词,屏蔽该动态') {
|
|
820
801
|
// 如果需要发送才发送
|
|
821
802
|
if (this.config.filter.notify) {
|
|
822
|
-
await this.sendMsg(sub.
|
|
803
|
+
await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
|
|
823
804
|
}
|
|
824
805
|
return;
|
|
825
806
|
}
|
|
826
807
|
if (e.message === '已屏蔽转发动态') {
|
|
827
808
|
if (this.config.filter.notify) {
|
|
828
|
-
await this.sendMsg(sub.
|
|
809
|
+
await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
|
|
829
810
|
}
|
|
830
811
|
return;
|
|
831
812
|
}
|
|
@@ -843,12 +824,12 @@ class ComRegister {
|
|
|
843
824
|
if (pic) {
|
|
844
825
|
this.logger.info('推送动态中,使用render模式');
|
|
845
826
|
// pic存在,使用的是render模式
|
|
846
|
-
await this.sendMsg(sub.
|
|
827
|
+
await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
|
|
847
828
|
}
|
|
848
829
|
else if (buffer) {
|
|
849
830
|
this.logger.info('推送动态中,使用page模式');
|
|
850
831
|
// pic不存在,说明使用的是page模式
|
|
851
|
-
await this.sendMsg(sub.
|
|
832
|
+
await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
|
|
852
833
|
}
|
|
853
834
|
else {
|
|
854
835
|
this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
|
|
@@ -1003,13 +984,13 @@ class ComRegister {
|
|
|
1003
984
|
if (e.message === '出现关键词,屏蔽该动态') {
|
|
1004
985
|
// 如果需要发送才发送
|
|
1005
986
|
if (this.config.filter.notify) {
|
|
1006
|
-
await this.sendMsg(sub.
|
|
987
|
+
await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
|
|
1007
988
|
}
|
|
1008
989
|
return;
|
|
1009
990
|
}
|
|
1010
991
|
if (e.message === '已屏蔽转发动态') {
|
|
1011
992
|
if (this.config.filter.notify) {
|
|
1012
|
-
await this.sendMsg(sub.
|
|
993
|
+
await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
|
|
1013
994
|
}
|
|
1014
995
|
return;
|
|
1015
996
|
}
|
|
@@ -1027,12 +1008,12 @@ class ComRegister {
|
|
|
1027
1008
|
if (pic) {
|
|
1028
1009
|
this.logger.info('推送动态中,使用render模式');
|
|
1029
1010
|
// pic存在,使用的是render模式
|
|
1030
|
-
await this.sendMsg(sub.
|
|
1011
|
+
await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
|
|
1031
1012
|
}
|
|
1032
1013
|
else if (buffer) {
|
|
1033
1014
|
this.logger.info('推送动态中,使用page模式');
|
|
1034
1015
|
// pic不存在,说明使用的是page模式
|
|
1035
|
-
await this.sendMsg(sub.
|
|
1016
|
+
await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
|
|
1036
1017
|
}
|
|
1037
1018
|
else {
|
|
1038
1019
|
this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
|
|
@@ -1046,7 +1027,7 @@ class ComRegister {
|
|
|
1046
1027
|
}
|
|
1047
1028
|
};
|
|
1048
1029
|
}
|
|
1049
|
-
liveDetect(ctx, roomId,
|
|
1030
|
+
liveDetect(ctx, roomId, target) {
|
|
1050
1031
|
let firstSubscription = true;
|
|
1051
1032
|
let timer = 0;
|
|
1052
1033
|
let open = false;
|
|
@@ -1056,80 +1037,40 @@ class ComRegister {
|
|
|
1056
1037
|
// 相当于锁的作用,防止上一个循环没处理完
|
|
1057
1038
|
let flag = true;
|
|
1058
1039
|
// 定义发送直播通知卡片方法
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
buffer = bufferv;
|
|
1075
|
-
// 成功则跳出循环
|
|
1076
|
-
break;
|
|
1077
|
-
}
|
|
1078
|
-
catch (e) {
|
|
1079
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
1080
|
-
this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
|
|
1081
|
-
// 发送私聊消息并重启服务
|
|
1082
|
-
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
// 推送直播信息
|
|
1087
|
-
// pic 存在,使用的是render模式
|
|
1088
|
-
if (pic) {
|
|
1089
|
-
const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg, liveType !== LiveType.StartBroadcasting ? `https://live.bilibili.com/${roomId}` : ''] });
|
|
1090
|
-
return await this.sendMsg(guildId, pic + msg);
|
|
1040
|
+
const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg) => {
|
|
1041
|
+
// 定义变量
|
|
1042
|
+
let pic;
|
|
1043
|
+
let buffer;
|
|
1044
|
+
// 多次尝试生成图片
|
|
1045
|
+
const attempts = 3;
|
|
1046
|
+
for (let i = 0; i < attempts; i++) {
|
|
1047
|
+
try {
|
|
1048
|
+
// 获取直播通知卡片
|
|
1049
|
+
const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
|
|
1050
|
+
// 赋值
|
|
1051
|
+
pic = picv;
|
|
1052
|
+
buffer = bufferv;
|
|
1053
|
+
// 成功则跳出循环
|
|
1054
|
+
break;
|
|
1091
1055
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
else {
|
|
1098
|
-
sendLiveNotifyCard = async (data, liveType, liveStartMsg, atAll) => {
|
|
1099
|
-
// 定义变量
|
|
1100
|
-
let pic;
|
|
1101
|
-
let buffer;
|
|
1102
|
-
// 多次尝试生成图片
|
|
1103
|
-
const attempts = 3;
|
|
1104
|
-
for (let i = 0; i < attempts; i++) {
|
|
1105
|
-
try {
|
|
1106
|
-
// 获取直播通知卡片
|
|
1107
|
-
const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
|
|
1108
|
-
// 赋值
|
|
1109
|
-
pic = picv;
|
|
1110
|
-
buffer = bufferv;
|
|
1111
|
-
// 成功则跳出循环
|
|
1112
|
-
break;
|
|
1113
|
-
}
|
|
1114
|
-
catch (e) {
|
|
1115
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
1116
|
-
this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
|
|
1117
|
-
// 发送私聊消息并重启服务
|
|
1118
|
-
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1119
|
-
}
|
|
1056
|
+
catch (e) {
|
|
1057
|
+
if (i === attempts - 1) { // 已尝试三次
|
|
1058
|
+
this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
|
|
1059
|
+
// 发送私聊消息并重启服务
|
|
1060
|
+
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1120
1061
|
}
|
|
1121
1062
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
}
|
|
1063
|
+
}
|
|
1064
|
+
// 推送直播信息
|
|
1065
|
+
// pic 存在,使用的是render模式
|
|
1066
|
+
if (pic) {
|
|
1067
|
+
const msg = liveNotifyMsg ? liveNotifyMsg : '';
|
|
1068
|
+
return await this.sendMsg(ctx, target, pic + msg, true);
|
|
1069
|
+
}
|
|
1070
|
+
// pic不存在,说明使用的是page模式
|
|
1071
|
+
const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg && liveNotifyMsg] });
|
|
1072
|
+
await this.sendMsg(ctx, target, msg, true);
|
|
1073
|
+
};
|
|
1133
1074
|
// 定义获取主播信息方法
|
|
1134
1075
|
let useMasterInfo;
|
|
1135
1076
|
if (this.config.changeMasterInfoApi) {
|
|
@@ -1217,22 +1158,10 @@ class ComRegister {
|
|
|
1217
1158
|
const liveEndMsg = this.config.customLiveEnd
|
|
1218
1159
|
.replace('-name', username)
|
|
1219
1160
|
.replace('-time', await ctx.gi.getTimeDifference(liveTime));
|
|
1220
|
-
//
|
|
1221
|
-
|
|
1222
|
-
//
|
|
1223
|
-
|
|
1224
|
-
resizedImage = await jimp_1.Jimp.read(userface).then(async (image) => {
|
|
1225
|
-
return await image.resize({ w: 100, h: 100 }).getBuffer(jimp_1.JimpMime.png);
|
|
1226
|
-
});
|
|
1227
|
-
}
|
|
1228
|
-
catch (e) {
|
|
1229
|
-
if (e.message === 'Unsupported MIME type: image/webp')
|
|
1230
|
-
console.log('主播使用的是webp格式头像,无法进行渲染');
|
|
1231
|
-
else
|
|
1232
|
-
console.log(e);
|
|
1233
|
-
}
|
|
1234
|
-
// 发送下播通知
|
|
1235
|
-
await this.sendMsg(guildId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [resizedImage && koishi_1.h.image(resizedImage, 'image/png'), " ", liveEndMsg] }));
|
|
1161
|
+
// 更改直播时长
|
|
1162
|
+
data.live_time = liveTime;
|
|
1163
|
+
// 发送@全体成员通知
|
|
1164
|
+
await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg);
|
|
1236
1165
|
}
|
|
1237
1166
|
// 未进循环,还未开播,继续循环
|
|
1238
1167
|
break;
|
|
@@ -1266,15 +1195,8 @@ class ComRegister {
|
|
|
1266
1195
|
.replace('-name', username)
|
|
1267
1196
|
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1268
1197
|
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`);
|
|
1269
|
-
//
|
|
1270
|
-
|
|
1271
|
-
// 发送@全体成员通知
|
|
1272
|
-
await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg, true);
|
|
1273
|
-
}
|
|
1274
|
-
else {
|
|
1275
|
-
// 发送直播通知卡片
|
|
1276
|
-
await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
|
|
1277
|
-
}
|
|
1198
|
+
// 发送消息
|
|
1199
|
+
await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
|
|
1278
1200
|
}
|
|
1279
1201
|
else { // 还在直播
|
|
1280
1202
|
if (this.config.pushTime > 0) {
|
|
@@ -1283,8 +1205,13 @@ class ComRegister {
|
|
|
1283
1205
|
if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
|
|
1284
1206
|
// 到时间重新计时
|
|
1285
1207
|
timer = 0;
|
|
1208
|
+
// 定义直播中通知消息
|
|
1209
|
+
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1210
|
+
.replace('-name', username)
|
|
1211
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1212
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : '';
|
|
1286
1213
|
// 发送直播通知卡片
|
|
1287
|
-
sendLiveNotifyCard(data, LiveType.LiveBroadcast);
|
|
1214
|
+
sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
|
|
1288
1215
|
}
|
|
1289
1216
|
}
|
|
1290
1217
|
// 否则继续循环
|
|
@@ -1306,10 +1233,10 @@ class ComRegister {
|
|
|
1306
1233
|
});
|
|
1307
1234
|
return table ? table : '没有订阅任何UP';
|
|
1308
1235
|
}
|
|
1309
|
-
async checkIfNeedSub(liveSub, dynamicSub, session,
|
|
1236
|
+
async checkIfNeedSub(liveSub, dynamicSub, session, liveRoomData) {
|
|
1310
1237
|
// 定义方法:用户直播间是否存在
|
|
1311
1238
|
const liveRoom = async () => {
|
|
1312
|
-
if (!
|
|
1239
|
+
if (!liveRoomData) {
|
|
1313
1240
|
// 未开通直播间
|
|
1314
1241
|
await session.send('该用户未开通直播间,无法订阅直播');
|
|
1315
1242
|
// 返回false
|
|
@@ -1370,6 +1297,97 @@ class ComRegister {
|
|
|
1370
1297
|
check();
|
|
1371
1298
|
});
|
|
1372
1299
|
}
|
|
1300
|
+
async subUserInBili(ctx, mid) {
|
|
1301
|
+
// 获取关注分组信息
|
|
1302
|
+
const checkGroupIsReady = async () => {
|
|
1303
|
+
// 判断是否有数据
|
|
1304
|
+
if (this.loginDBData.dynamic_group_id === '' || this.loginDBData.dynamic_group_id === null) {
|
|
1305
|
+
// 没有数据,没有创建分组,尝试创建分组
|
|
1306
|
+
const createGroupData = await ctx.ba.createGroup("订阅");
|
|
1307
|
+
// 如果分组已创建,则获取分组id
|
|
1308
|
+
if (createGroupData.code === 22106) {
|
|
1309
|
+
// 分组已存在,拿到之前的分组id
|
|
1310
|
+
const allGroupData = await ctx.ba.getAllGroup();
|
|
1311
|
+
// 遍历所有分组
|
|
1312
|
+
for (const group of allGroupData.data) {
|
|
1313
|
+
// 找到订阅分组
|
|
1314
|
+
if (group.name === '订阅') {
|
|
1315
|
+
// 拿到分组id
|
|
1316
|
+
this.loginDBData.dynamic_group_id = group.tagid;
|
|
1317
|
+
// 结束循环
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
else if (createGroupData.code !== 0) {
|
|
1323
|
+
console.log(createGroupData);
|
|
1324
|
+
// 创建分组失败
|
|
1325
|
+
return false;
|
|
1326
|
+
}
|
|
1327
|
+
// 创建成功,保存到数据库
|
|
1328
|
+
ctx.database.set('loginBili', 1, { dynamic_group_id: this.loginDBData.dynamic_group_id });
|
|
1329
|
+
// 创建成功
|
|
1330
|
+
return true;
|
|
1331
|
+
}
|
|
1332
|
+
return true;
|
|
1333
|
+
};
|
|
1334
|
+
// 判断分组是否准备好
|
|
1335
|
+
const flag = await checkGroupIsReady();
|
|
1336
|
+
// 判断是否创建成功
|
|
1337
|
+
if (!flag) {
|
|
1338
|
+
// 创建分组失败
|
|
1339
|
+
return { flag: false, msg: '创建分组失败,请尝试重启插件' };
|
|
1340
|
+
}
|
|
1341
|
+
// 获取分组明细
|
|
1342
|
+
const relationGroupDetailData = await ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
|
|
1343
|
+
// 判断分组信息是否获取成功
|
|
1344
|
+
if (relationGroupDetailData.code !== 0) {
|
|
1345
|
+
if (relationGroupDetailData.code === 22104) {
|
|
1346
|
+
// 将原先的分组id置空
|
|
1347
|
+
this.loginDBData.dynamic_group_id = null;
|
|
1348
|
+
// 分组不存在
|
|
1349
|
+
const flag = await checkGroupIsReady();
|
|
1350
|
+
// 判断是否创建成功
|
|
1351
|
+
if (!flag) {
|
|
1352
|
+
// 创建分组失败
|
|
1353
|
+
return { flag: false, msg: '创建分组失败,请尝试重启插件' };
|
|
1354
|
+
}
|
|
1355
|
+
return { flag: true, msg: '分组不存在,已重新创建分组' };
|
|
1356
|
+
}
|
|
1357
|
+
// 获取分组明细失败
|
|
1358
|
+
return { flag: false, msg: '获取分组明细失败' };
|
|
1359
|
+
}
|
|
1360
|
+
relationGroupDetailData.data.forEach(user => {
|
|
1361
|
+
if (user.mid === mid) {
|
|
1362
|
+
// 已关注订阅对象
|
|
1363
|
+
return { flag: true, msg: '订阅对象已存在于分组中' };
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1366
|
+
// 订阅对象
|
|
1367
|
+
const subUserData = await ctx.ba.follow(mid);
|
|
1368
|
+
// 判断是否订阅成功
|
|
1369
|
+
switch (subUserData.code) {
|
|
1370
|
+
case -101: return { flag: false, msg: '账号未登录,请使用指令bili login登录后再进行订阅操作' };
|
|
1371
|
+
case -102: return { flag: false, msg: '账号被封停,无法进行订阅操作' };
|
|
1372
|
+
case 22002: return { flag: false, msg: '因对方隐私设置,无法进行订阅操作' };
|
|
1373
|
+
case 22003: return { flag: false, msg: '你已将对方拉黑,无法进行订阅操作' };
|
|
1374
|
+
case 22013: return { flag: false, msg: '账号已注销,无法进行订阅操作' };
|
|
1375
|
+
case 40061: return { flag: false, msg: '账号不存在,请检查uid输入是否正确或用户是否存在' };
|
|
1376
|
+
case 22001: break; // 订阅对象为自己 无需添加到分组
|
|
1377
|
+
case 22014: // 已关注订阅对象 无需再次关注
|
|
1378
|
+
case 0: { // 执行订阅成功
|
|
1379
|
+
// 把订阅对象添加到分组中
|
|
1380
|
+
const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
|
|
1381
|
+
// 判断是否添加成功
|
|
1382
|
+
if (copyUserToGroupData.code !== 0) {
|
|
1383
|
+
// 添加失败
|
|
1384
|
+
return { flag: false, msg: '添加订阅对象到分组失败,请稍后重试' };
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
// 订阅成功
|
|
1389
|
+
return { flag: true, msg: '用户订阅成功' };
|
|
1390
|
+
}
|
|
1373
1391
|
async getSubFromDatabase(ctx) {
|
|
1374
1392
|
// 判断登录信息是否已加载完毕
|
|
1375
1393
|
await this.checkIfLoginInfoIsLoaded(ctx);
|
|
@@ -1397,8 +1415,21 @@ class ComRegister {
|
|
|
1397
1415
|
// 跳过下面的步骤
|
|
1398
1416
|
continue;
|
|
1399
1417
|
}
|
|
1418
|
+
// 判断用户是否在B站中订阅了
|
|
1419
|
+
const subUserData = await this.subUserInBili(ctx, sub.uid);
|
|
1420
|
+
// 判断是否订阅
|
|
1421
|
+
if (!subUserData.flag) {
|
|
1422
|
+
// log
|
|
1423
|
+
this.logger.warn(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
|
|
1424
|
+
// 发送私聊消息
|
|
1425
|
+
await this.sendPrivateMsg(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
|
|
1426
|
+
// 删除该条数据
|
|
1427
|
+
await ctx.database.remove('bilibili', { id: sub.id });
|
|
1428
|
+
// 跳过下面的步骤
|
|
1429
|
+
continue;
|
|
1430
|
+
}
|
|
1400
1431
|
// 获取推送目标数组
|
|
1401
|
-
const
|
|
1432
|
+
const target = JSON.parse(sub.target);
|
|
1402
1433
|
/* 判断数据库是否被篡改 */
|
|
1403
1434
|
// 获取用户信息
|
|
1404
1435
|
let content;
|
|
@@ -1448,7 +1479,7 @@ class ComRegister {
|
|
|
1448
1479
|
}
|
|
1449
1480
|
}
|
|
1450
1481
|
// 检测房间号是否被篡改
|
|
1451
|
-
if (sub.live && (!data.live_room || data.live_room.roomid
|
|
1482
|
+
if (sub.live && (!data.live_room || data.live_room.roomid != sub.room_id)) {
|
|
1452
1483
|
// 房间号被篡改,删除该订阅
|
|
1453
1484
|
await deleteSub();
|
|
1454
1485
|
// log
|
|
@@ -1462,10 +1493,10 @@ class ComRegister {
|
|
|
1462
1493
|
id: sub.id,
|
|
1463
1494
|
uid: sub.uid,
|
|
1464
1495
|
roomId: sub.room_id,
|
|
1465
|
-
|
|
1496
|
+
target,
|
|
1466
1497
|
platform: sub.platform,
|
|
1467
|
-
live:
|
|
1468
|
-
dynamic:
|
|
1498
|
+
live: sub.live === 1 ? true : false,
|
|
1499
|
+
dynamic: sub.dynamic === 1 ? true : false,
|
|
1469
1500
|
liveDispose: null
|
|
1470
1501
|
};
|
|
1471
1502
|
// 判断是否订阅直播
|
|
@@ -1482,7 +1513,7 @@ class ComRegister {
|
|
|
1482
1513
|
// 直播订阅数+1
|
|
1483
1514
|
liveSubNum++;
|
|
1484
1515
|
// 订阅直播,开始循环检测
|
|
1485
|
-
const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id,
|
|
1516
|
+
const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, target), this.config.liveLoopTime * 1000);
|
|
1486
1517
|
// 保存销毁函数
|
|
1487
1518
|
subManagerItem.liveDispose = dispose;
|
|
1488
1519
|
}
|
|
@@ -1517,7 +1548,7 @@ class ComRegister {
|
|
|
1517
1548
|
// num--
|
|
1518
1549
|
this.num--;
|
|
1519
1550
|
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1520
|
-
this.
|
|
1551
|
+
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1521
1552
|
};
|
|
1522
1553
|
try {
|
|
1523
1554
|
switch (type) {
|
|
@@ -1562,7 +1593,7 @@ class ComRegister {
|
|
|
1562
1593
|
// 取消订阅
|
|
1563
1594
|
this.subManager[index].dynamic = false;
|
|
1564
1595
|
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1565
|
-
this.
|
|
1596
|
+
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1566
1597
|
// 如果没有对这个UP的任何订阅,则移除
|
|
1567
1598
|
if (checkIfNoSubExist(sub)) {
|
|
1568
1599
|
// 从管理对象中移除
|
|
@@ -1583,7 +1614,7 @@ class ComRegister {
|
|
|
1583
1614
|
this.updateSubNotifier(ctx);
|
|
1584
1615
|
}
|
|
1585
1616
|
}
|
|
1586
|
-
|
|
1617
|
+
checkIfUserIsTheLastOneWhoSubDyn() {
|
|
1587
1618
|
if (this.subManager.some(sub => sub.dynamic)) {
|
|
1588
1619
|
// 停止动态监测
|
|
1589
1620
|
this.dynamicDispose();
|
|
@@ -1596,7 +1627,7 @@ class ComRegister {
|
|
|
1596
1627
|
if (sub.live)
|
|
1597
1628
|
await this.subManager[i].liveDispose();
|
|
1598
1629
|
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1599
|
-
this.
|
|
1630
|
+
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1600
1631
|
// 从数据库中删除订阅
|
|
1601
1632
|
await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
|
|
1602
1633
|
// 将该订阅对象从订阅管理对象中移除
|
|
@@ -1621,21 +1652,20 @@ class ComRegister {
|
|
|
1621
1652
|
}
|
|
1622
1653
|
(function (ComRegister) {
|
|
1623
1654
|
ComRegister.Config = koishi_1.Schema.object({
|
|
1624
|
-
platform: koishi_1.Schema.string(),
|
|
1625
1655
|
master: koishi_1.Schema.object({
|
|
1626
1656
|
enable: koishi_1.Schema.boolean(),
|
|
1657
|
+
platform: koishi_1.Schema.string(),
|
|
1627
1658
|
masterAccount: koishi_1.Schema.string(),
|
|
1628
1659
|
masterAccountGuildId: koishi_1.Schema.string()
|
|
1629
1660
|
}),
|
|
1630
1661
|
unlockSubLimits: koishi_1.Schema.boolean().required(),
|
|
1631
1662
|
automaticResend: koishi_1.Schema.boolean().required(),
|
|
1632
1663
|
changeMasterInfoApi: koishi_1.Schema.boolean().required(),
|
|
1633
|
-
liveStartAtAll: koishi_1.Schema.boolean().required(),
|
|
1634
1664
|
restartPush: koishi_1.Schema.boolean().required(),
|
|
1635
|
-
pushUrl: koishi_1.Schema.boolean().required(),
|
|
1636
1665
|
pushTime: koishi_1.Schema.number().required(),
|
|
1637
1666
|
liveLoopTime: koishi_1.Schema.number().default(10),
|
|
1638
1667
|
customLiveStart: koishi_1.Schema.string().required(),
|
|
1668
|
+
customLive: koishi_1.Schema.string(),
|
|
1639
1669
|
customLiveEnd: koishi_1.Schema.string().required(),
|
|
1640
1670
|
dynamicUrl: koishi_1.Schema.boolean().required(),
|
|
1641
1671
|
dynamicLoopTime: koishi_1.Schema.number().default(60),
|