koishi-plugin-bilibili-notify 1.3.7 → 2.0.0-alpha.0

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.
@@ -26,67 +26,36 @@ class ComRegister {
26
26
  rebootCount = 0;
27
27
  subNotifier;
28
28
  subManager = [];
29
- // QQ群机器人
30
- qqBot;
31
- // QQ频道机器人
32
- qqguildBot;
33
- // OneBot机器人
34
- oneBot;
35
- // Red机器人
36
- redBot;
37
- // Telegram机器人
38
- telegramBot;
39
- // Satori机器人
40
- satoriBot;
41
- // Chronocat机器人
42
- chronocatBot;
43
- // Lark机器人
44
- larkBot;
29
+ // 机器人实例
30
+ bot;
31
+ // 动态销毁函数
32
+ dynamicDispose;
45
33
  // 发送消息方式
46
34
  sendMsgFunc;
35
+ // 构造函数
47
36
  constructor(ctx, config) {
48
37
  this.logger = ctx.logger('cr');
49
38
  this.config = config;
50
- // 拿到各类机器人
51
- ctx.bots.forEach(bot => {
52
- switch (bot.platform) {
53
- case 'qq':
54
- this.qqBot = bot;
55
- break;
56
- case 'qqguild':
57
- this.qqguildBot = bot;
58
- break;
59
- case 'onebot':
60
- this.oneBot = bot;
61
- break;
62
- case 'red':
63
- this.redBot = bot;
64
- break;
65
- case 'telegram':
66
- this.telegramBot = bot;
67
- break;
68
- case 'satori':
69
- this.satoriBot = bot;
70
- break;
71
- case 'chronocat':
72
- this.chronocatBot = bot;
73
- break;
74
- case 'lark':
75
- this.larkBot = bot;
76
- break;
77
- }
78
- });
39
+ // 拿到机器人实例
40
+ this.bot = ctx.bots.find(bot => bot.platform === config.platform);
41
+ if (!this.bot) {
42
+ ctx.notifier.create({
43
+ type: 'danger',
44
+ content: '未找到对应机器人实例,请检查配置是否正确或重新配置适配器!'
45
+ });
46
+ this.logger.error('未找到对应机器人实例,请检查配置是否正确或重新配置适配器!');
47
+ }
79
48
  // 从数据库获取订阅
80
49
  this.getSubFromDatabase(ctx);
81
50
  // 判断消息发送方式
82
51
  if (config.automaticResend) {
83
- this.sendMsgFunc = async (guild, bot, content) => {
52
+ this.sendMsgFunc = async (guild, content) => {
84
53
  // 多次尝试发送消息
85
54
  const attempts = 3;
86
55
  for (let i = 0; i < attempts; i++) {
87
56
  try {
88
57
  // 发送消息
89
- await bot.sendMessage(guild, content);
58
+ await this.bot.sendMessage(guild, content);
90
59
  // 防止消息发送速度过快被忽略
91
60
  await ctx.sleep(500);
92
61
  // 成功发送消息,跳出循环
@@ -95,134 +64,44 @@ class ComRegister {
95
64
  catch (e) {
96
65
  if (i === attempts - 1) { // 已尝试三次
97
66
  this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
98
- this.sendPrivateMsg(bot, `发送群组ID:${guild}消息失败,请查看日志`);
67
+ console.log(e);
68
+ this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
99
69
  }
100
70
  }
101
71
  }
102
72
  };
103
73
  }
104
74
  else {
105
- this.sendMsgFunc = async (guild, bot, content) => {
75
+ this.sendMsgFunc = async (guild, content) => {
106
76
  try {
107
77
  // 发送消息
108
- await bot.sendMessage(guild, content);
78
+ await this.bot.sendMessage(guild, content);
109
79
  }
110
80
  catch (e) {
111
81
  this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
112
- await this.sendPrivateMsg(bot, `发送群组ID:${guild}消息失败,请查看日志`);
82
+ await this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
113
83
  }
114
84
  };
115
85
  }
116
- /* const testCom = ctx.command('test', { hidden: true, permissions: ['authority:5'] })
117
-
118
- testCom.subcommand('.cookies')
119
- .usage('测试指令,用于测试从数据库读取cookies')
120
- .action(async () => {
121
- this.logger.info('调用test cookies指令')
122
- // await ctx.ba.loadCookiesFromDatabase()
123
- console.log(JSON.parse(ctx.ba.getCookies()));
124
- })
125
-
126
- testCom
127
- .subcommand('.my')
128
- .usage('测试指令,用于测试获取自己信息')
129
- .example('test.my')
86
+ const statusCom = ctx.command('status', '插件状态相关指令', { permissions: ['authority:5'] });
87
+ statusCom.subcommand('.dyn', '查看动态监测运行状态')
88
+ .usage('查看动态监测运行状态')
89
+ .example('status dyn')
90
+ .action(() => {
91
+ if (this.dynamicDispose) {
92
+ return '动态监测正在运行';
93
+ }
94
+ else {
95
+ return '动态监测未运行';
96
+ }
97
+ });
98
+ statusCom.subcommand('.sm', '查看订阅管理对象')
99
+ .usage('查看订阅管理对象')
100
+ .example('status sm')
130
101
  .action(async () => {
131
- const content = await ctx.ba.getMyselfInfo()
132
- console.log(content);
133
- })
134
-
135
- testCom
136
- .subcommand('.user <mid:string>')
137
- .usage('测试指令,用于测试获取用户信息')
138
- .example('test.user 用户UID')
139
- .action(async (_, mid) => {
140
- const content = await ctx.ba.getUserInfo(mid)
141
- console.log(content);
142
- })
143
-
144
- testCom
145
- .subcommand('.time')
146
- .usage('测试时间接口')
147
- .example('test.time')
148
- .action(async ({ session }) => {
149
- session.send(await ctx.ba.getTimeNow())
150
- })
151
-
152
- testCom
153
- .subcommand('.gimg <uid:string> <index:number>')
154
- .usage('测试图片生成')
155
- .example('test.gimg')
156
- .action(async ({ session }, uid, index) => {
157
- // logger
158
- this.logger.info('调用test gimg指令')
159
- // 获取用户空间动态数据
160
- const { data } = await ctx.ba.getUserSpaceDynamic(uid)
161
- // 获取动态推送图片
162
- const { pic, buffer } = await ctx.gi.generateDynamicImg(data.items[index])
163
- // 如果pic存在,则直接返回pic
164
- if (pic) return pic
165
- // pic不存在,说明使用的是page模式
166
- await session.send(h.image(buffer, 'image/png'))
167
- })
168
-
169
- testCom
170
- .subcommand('.group')
171
- .usage('查看session groupId')
172
- .example('test group')
173
- .action(({ session }) => {
174
- console.log(session.event.channel);
175
- })
176
-
177
- testCom
178
- .subcommand('.session')
179
- .usage('查看seesion')
180
- .example('test session')
181
- .action(({ session }) => {
182
- console.log(session);
183
- })
184
-
185
- testCom
186
- .subcommand('.utc')
187
- .usage('获取当前UTC+8 Unix时间戳')
188
- .example('test utc')
189
- .action(async ({ session }) => {
190
- session.send((await ctx.ba.getServerUTCTime()).toString())
191
- })
192
-
193
- testCom
194
- .subcommand('.livestop', '发送下播提示语测试')
195
- .usage('发送下播提示语测试')
196
- .example('test livestop')
197
- .action(async ({ session }) => {
198
- // logger
199
- this.logger.info('调用test gimg指令')
200
- // 获取主播信息
201
- const { data } = await ctx.ba.getMasterInfo('686127')
202
- let resizedImage: Buffer
203
- try {
204
- resizedImage = await Jimp.read(data.info.face).then(async image => {
205
- return await image.resize(100, 100).getBufferAsync(Jimp.MIME_PNG)
206
- })
207
- } catch (e) {
208
- if (e.message === 'Unsupported MIME type: image/webp') console.log('主播使用的是webp格式头像,无法进行渲染');
209
- else console.log(e);
210
- }
211
- // 发送下播提示语
212
- await session.send(
213
- <>{resizedImage && h.image(resizedImage, 'image/png')} 主播{data.info.uname}已下播</>
214
- )
215
- })
216
-
217
- testCom
218
- .subcommand('.sendmsg', '测试发送消息方法')
219
- .usage('测试发送消息方法')
220
- .example('test sendmsg')
221
- .action(async ({ session }) => {
222
- // 获得对应bot
223
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session)
224
- // this.sendMsg(['all'], bot, 'Hello World')
225
- }) */
102
+ console.log(this.subManager);
103
+ return '查看控制台';
104
+ });
226
105
  const biliCom = ctx.command('bili', 'bili-notify插件相关指令', { permissions: ['authority:3'] });
227
106
  biliCom.subcommand('.login', '登录B站之后才可以进行之后的操作')
228
107
  .usage('使用二维码登录,登录B站之后才可以进行之后的操作')
@@ -340,16 +219,29 @@ class ComRegister {
340
219
  return;
341
220
  }
342
221
  // 取消全部订阅 执行dispose方法,销毁定时器
343
- if (sub.dynamic)
344
- this.subManager[i].dynamicDispose();
345
222
  if (sub.live)
346
223
  this.subManager[i].liveDispose();
347
224
  // 从数据库中删除订阅
348
225
  await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
349
226
  // 将该订阅对象从订阅管理对象中移除
350
227
  this.subManager.splice(i, 1);
228
+ // 将订阅对象移出订阅关注组
229
+ const removeUserFromGroupData = await ctx.ba.removeUserFromGroup(sub.uid);
230
+ // 判断是否移出成功
231
+ if (removeUserFromGroupData.code !== 0) {
232
+ // 移出失败
233
+ session.send('取消订阅对象失败,请稍后重试');
234
+ return;
235
+ }
351
236
  // id--
352
237
  this.num--;
238
+ // 判断是否还有动态订阅
239
+ if (this.dynamicDispose && !this.subManager.find((sub) => sub.dynamic === true)) { // 没有动态订阅
240
+ // 将动态检测关闭
241
+ this.dynamicDispose();
242
+ // 将动态监测置为空
243
+ this.dynamicDispose = null;
244
+ }
353
245
  // 发送成功通知
354
246
  session.send('已取消订阅该用户');
355
247
  // 更新控制台提示
@@ -395,27 +287,73 @@ class ComRegister {
395
287
  // 未登录直接返回
396
288
  return '请使用指令bili login登录后再进行订阅操作';
397
289
  }
398
- // 如果订阅人数超过三个则直接返回
399
- if (!config.unlockSubLimits && this.num >= 3)
400
- return '目前最多只能订阅三个人';
401
- // 检查必选参数是否有值
290
+ // 检查必选参数是否已填
402
291
  if (!mid)
403
292
  return '请输入用户uid';
404
- // 判断要订阅的用户是否已经存在于订阅管理对象中
405
- if (this.subManager && this.subManager.some(sub => sub.uid === mid)) {
406
- return '已订阅该用户,请勿重复订阅';
293
+ // 检查数据库是否有数据
294
+ const loginDBData = (await ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
295
+ // 判断是否有数据
296
+ if (loginDBData.dynamic_group_id === '' || loginDBData.dynamic_group_id === null) {
297
+ // 没有数据,没有创建分组,尝试创建分组
298
+ const createGroupData = await ctx.ba.createGroup("订阅");
299
+ // 如果分组已创建,则获取分组id
300
+ if (createGroupData.code === 22106) {
301
+ // 分组已存在,拿到之前的分组id
302
+ const allGroupData = await ctx.ba.getAllGroup();
303
+ // 遍历所有分组
304
+ for (const group of allGroupData.data) {
305
+ // 找到订阅分组
306
+ if (group.name === '订阅') {
307
+ // 拿到分组id
308
+ loginDBData.dynamic_group_id = group.tagid;
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ else if (createGroupData.code !== 0) {
314
+ // 创建分组失败
315
+ return '创建关注分组出错';
316
+ }
317
+ // 创建成功,保存到数据库
318
+ ctx.database.set('loginBili', 1, { dynamic_group_id: loginDBData.dynamic_group_id });
407
319
  }
408
- // 获取用户信息
320
+ // 订阅对象
321
+ const subUserData = await ctx.ba.follow(mid);
322
+ // 判断是否订阅成功
323
+ switch (subUserData.code) {
324
+ case -101: return '账号未登录,请使用指令bili login登录后再进行订阅操作';
325
+ case -102: return '账号被封停,无法进行订阅操作';
326
+ case 22002: return '因对方隐私设置,无法进行订阅操作';
327
+ case 22003: return '你已将对方拉黑,无法进行订阅操作';
328
+ case 22013: return '账号已注销,无法进行订阅操作';
329
+ case 40061: return '账号不存在,请检查uid输入是否正确或用户是否存在';
330
+ case 22001: break; // 订阅对象为自己 无需添加到分组
331
+ case 22014: // 已关注订阅对象 无需再次关注
332
+ case 0: { // 执行订阅成功
333
+ // 把订阅对象添加到分组中
334
+ const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, loginDBData.dynamic_group_id);
335
+ // 判断是否添加成功
336
+ if (copyUserToGroupData.code !== 0) {
337
+ // 添加失败
338
+ return '添加订阅对象到分组失败,请稍后重试';
339
+ }
340
+ }
341
+ }
342
+ // 定义外围变量
409
343
  let content;
410
344
  try {
345
+ // 获取用户信息
411
346
  content = await ctx.ba.getUserInfo(mid);
412
347
  }
413
348
  catch (e) {
349
+ // 返回错误信息
414
350
  return 'bili sub getUserInfo() 发生了错误,错误为:' + e.message;
415
351
  }
416
- // 判断是否有其他问题
352
+ // 判断是否成功获取用户信息
417
353
  if (content.code !== 0) {
354
+ // 定义错误消息
418
355
  let msg;
356
+ // 判断错误代码
419
357
  switch (content.code) {
420
358
  case -400:
421
359
  msg = '请求错误';
@@ -433,10 +371,13 @@ class ComRegister {
433
371
  msg = '未知错误,错误信息:' + content.message;
434
372
  break;
435
373
  }
374
+ // 返回错误信息
436
375
  return msg;
437
376
  }
438
- // 设置目标ID
377
+ // 定义目标群组id
439
378
  let targetId;
379
+ // 定义目标群组id数组
380
+ let targetIdArr;
440
381
  // 判断是否输入了QQ群号
441
382
  if (guildId.length > 0) { // 输入了QQ群号
442
383
  // 定义方法
@@ -447,6 +388,7 @@ class ComRegister {
447
388
  const targetArr = [];
448
389
  // 判断群号是否符合条件
449
390
  for (const guild of guildId) {
391
+ // 判断是否机器人加入了该群
450
392
  if (guildList.data.some(cv => cv.id === guild)) { // 机器人加入了该群
451
393
  // 保存到数组
452
394
  targetArr.push(guild);
@@ -465,6 +407,7 @@ class ComRegister {
465
407
  if (guildId[0] === 'all') {
466
408
  // 判断是否有群机器人相关Bot
467
409
  if (['qq', 'onebot', 'red', 'satori', 'chronocat'].includes(session.event.platform)) {
410
+ // 推送所有群组
468
411
  okGuild.push('all');
469
412
  }
470
413
  else {
@@ -477,24 +420,13 @@ class ComRegister {
477
420
  else {
478
421
  // 判断是否有群机器人相关Bot
479
422
  switch (session.event.platform) {
480
- case 'qq': {
481
- okGuild = await checkIfGuildHasJoined(this.qqBot);
482
- break;
483
- }
484
- case 'onebot': {
485
- okGuild = await checkIfGuildHasJoined(this.oneBot);
486
- break;
487
- }
488
- case 'red': {
489
- okGuild = await checkIfGuildHasJoined(this.redBot);
490
- break;
491
- }
492
- case 'satori': {
493
- okGuild = await checkIfGuildHasJoined(this.satoriBot);
494
- break;
495
- }
423
+ case 'qq':
424
+ case 'onebot':
425
+ case 'red':
426
+ case 'satori':
496
427
  case 'chronocat': {
497
- okGuild = await checkIfGuildHasJoined(this.chronocatBot);
428
+ // 检查机器人是否加入该群
429
+ okGuild = await checkIfGuildHasJoined(this.bot);
498
430
  break;
499
431
  }
500
432
  default: {
@@ -505,23 +437,39 @@ class ComRegister {
505
437
  }
506
438
  }
507
439
  }
440
+ // 将可用的目标赋值给数组
441
+ targetIdArr = okGuild;
508
442
  // 将群号用空格进行分割
509
443
  targetId = okGuild.join(' ');
510
444
  }
511
445
  else { // 没有输入QQ群号
512
446
  // 为当前群聊环境进行推送
513
447
  targetId = session.event.channel.id;
448
+ // 将目标id转换为数组进行赋值
449
+ targetIdArr = [session.event.channel.id];
514
450
  }
515
451
  // 获取data
516
452
  const { data } = content;
517
- // 判断是否需要订阅直播
518
- const liveMsg = await this.checkIfNeedSub(options.live, '直播', session, data);
519
- // 判断是否需要订阅动态
520
- const dynamicMsg = await this.checkIfNeedSub(options.dynamic, '动态', session);
453
+ // 判断是否需要订阅直播和动态
454
+ const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data);
455
+ console.log('Live MSG:', liveMsg);
456
+ console.log('Dynamic MSG:', dynamicMsg);
521
457
  // 判断是否未订阅任何消息
522
458
  if (!liveMsg && !dynamicMsg) {
523
459
  return '您未订阅该UP的任何消息';
524
460
  }
461
+ const subUser = this.subManager.find(sub => sub.uid === mid);
462
+ // 判断要订阅的用户是否已经存在于订阅管理对象中
463
+ if (subUser) {
464
+ // 已存在,判断是否重复订阅直播通知
465
+ if (liveMsg && subUser.live) {
466
+ return '已订阅该用户直播通知,请勿重复订阅';
467
+ }
468
+ // 已存在,判断是否重复订阅动态通知
469
+ if (dynamicMsg && subUser.dynamic) {
470
+ return '已订阅该用户动态通知,请勿重复订阅';
471
+ }
472
+ }
525
473
  // 获取直播房间号
526
474
  const roomId = data.live_room?.roomid.toString();
527
475
  // 保存到数据库中
@@ -537,18 +485,16 @@ class ComRegister {
537
485
  });
538
486
  // 订阅数+1
539
487
  this.num++;
540
- // 开始订阅
541
488
  // 保存新订阅对象
542
489
  this.subManager.push({
543
490
  id: sub.id,
544
491
  uid: mid,
545
- targetId,
492
+ targetIdArr,
546
493
  roomId,
547
494
  platform: session.event.platform,
548
495
  live: liveMsg,
549
496
  dynamic: dynamicMsg,
550
- liveDispose: null,
551
- dynamicDispose: null
497
+ liveDispose: null
552
498
  });
553
499
  // 获取用户信息
554
500
  let userData;
@@ -560,55 +506,40 @@ class ComRegister {
560
506
  this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
561
507
  return '订阅出错啦,请重试';
562
508
  }
563
- // 需要订阅直播
509
+ // 订阅直播
564
510
  if (liveMsg) {
565
511
  await session.execute(`bili live ${roomId} ${targetId.split(',').join(' ')}`);
566
512
  // 发送订阅消息通知
567
513
  await session.send(`订阅${userData.info.uname}直播通知`);
568
514
  }
569
- // 需要订阅动态
515
+ // 订阅动态
570
516
  if (dynamicMsg) {
571
- await session.execute(`bili dynamic ${mid} ${targetId.split(',').join(' ')}`);
517
+ // 判断是否开启动态监测
518
+ if (!this.dynamicDispose) {
519
+ // 开启动态监测
520
+ this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), config.dynamicLoopTime * 1000);
521
+ }
572
522
  // 发送订阅消息通知
573
523
  await session.send(`订阅${userData.info.uname}动态通知`);
574
524
  }
575
525
  // 新增订阅展示到控制台
576
526
  this.updateSubNotifier(ctx);
577
527
  });
578
- biliCom
528
+ /* biliCom
579
529
  .subcommand('.dynamic <uid:string> <...guildId:string>', '订阅用户动态推送', { hidden: true })
580
530
  .usage('订阅用户动态推送')
581
531
  .example('bili dynamic 1194210119 订阅UID为1194210119的动态')
582
- .action(async ({ session }, uid, ...guildId) => {
583
- this.logger.info('调用bili.dynamic指令');
584
- // 如果uid为空则返回
585
- if (!uid)
586
- return `${uid}非法调用 dynamic 指令`; // 用户uid不能为空
587
- if (!guildId)
588
- return `${uid}非法调用 dynamic 指令`; // 目标群组或频道不能为空
589
- // 寻找对应订阅管理对象
590
- const index = this.subManager.findIndex(sub => sub.uid === uid);
591
- // 不存在则直接返回
592
- if (index === -1)
593
- return '请勿直接调用该指令';
594
- // 获得对应bot
595
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session);
596
- // 开始循环检测
597
- let dispose;
598
- if (this.config.dynamicDebugMode) {
599
- dispose = ctx.setInterval(this.debug_dynamicDetect(ctx, bot, uid, guildId), config.dynamicLoopTime * 1000);
600
- }
601
- else {
602
- dispose = ctx.setInterval(this.dynamicDetect(ctx, bot, uid, guildId), config.dynamicLoopTime * 1000);
603
- }
604
- // 将销毁函数保存到订阅管理对象
605
- this.subManager[index].dynamicDispose = dispose;
606
- });
532
+ .action(async () => {
533
+ // Log
534
+ this.logger.info('调用bili.dynamic指令')
535
+ // 开始循环检测
536
+ this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), config.dynamicLoopTime * 1000)
537
+ }) */
607
538
  biliCom
608
539
  .subcommand('.live <roomId:string> <...guildId:string>', '订阅主播开播通知', { hidden: true })
609
540
  .usage('订阅主播开播通知')
610
541
  .example('bili live 26316137 订阅房间号为26316137的直播间')
611
- .action(async ({ session }, roomId, ...guildId) => {
542
+ .action(async (_, roomId, ...guildId) => {
612
543
  this.logger.info('调用bili.live指令');
613
544
  // 如果room_id为空则返回
614
545
  if (!roomId)
@@ -619,10 +550,8 @@ class ComRegister {
619
550
  const index = this.subManager.findIndex(sub => sub.roomId === roomId);
620
551
  if (index === -1)
621
552
  return '请勿直接调用该指令';
622
- // 获得对应bot
623
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session);
624
553
  // 开始循环检测
625
- const dispose = ctx.setInterval(this.liveDetect(ctx, bot, roomId, guildId), config.liveLoopTime * 1000);
554
+ const dispose = ctx.setInterval(this.liveDetect(ctx, roomId, guildId), config.liveLoopTime * 1000);
626
555
  // 保存销毁函数
627
556
  this.subManager[index].liveDispose = dispose;
628
557
  });
@@ -687,103 +616,31 @@ class ComRegister {
687
616
  .usage('向主人账号发送一条测试消息')
688
617
  .example('bili private 向主人账号发送一条测试消息')
689
618
  .action(async ({ session }) => {
690
- // 获得对应bot
691
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session);
692
619
  // 发送消息
693
- await this.sendPrivateMsg(bot, 'Hello World');
620
+ await this.sendPrivateMsg('Hello World');
694
621
  // 发送提示
695
622
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
696
623
  });
697
- /* biliCom
698
- .subcommand('.reboot', '测试插件自动重启功能', { hidden: true })
699
- .usage('测试插件自动重启功能')
700
- .example('bili reboot 测试插件自动重启功能')
701
- .action(async ({ session }) => {
702
- // 发送提示消息
703
- await session.send('测试biliAPI等服务自动重启功能')
704
- // 获得对应bot
705
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session)
706
- // 发送提示消息,重启服务
707
- await this.sendPrivateMsgAndStopService(ctx, bot, '测试biliAPI等服务自动重启功能')
708
- }) */
709
- /* biliCom
710
- .subcommand('.sendall', '测试给机器人加入的所有群发送消息', { hidden: true })
711
- .usage('测试给机器人加入的所有群发送消息')
712
- .example('bili sendall 测试给机器人加入的所有群发送消息')
713
- .action(async ({ session }) => {
714
- // 获得对应bot
715
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session)
716
- // 发送消息
717
- await this.sendMsg(ctx, ['all'], bot, 'Hello World')
718
- // 发送提示
719
- await session.send('已向机器人加入的所有群发送了消息')
720
- }) */
721
- /* biliCom
722
- .subcommand('.list', '获取机器人加入的所有群组', { hidden: true })
723
- .usage('获取当前机器人加入的所有群聊')
724
- .example('bili list 获取当前机器人加入的所有群聊')
725
- .action(async ({ session }) => {
726
- // 获取对应Bot
727
- const bot = this.getTheCorrespondingBotBasedOnTheSession(session)
728
- // 获取群列表
729
- const guildList = (await bot.getGuildList()).data
730
- // 遍历群列表
731
- guildList.map(item => this.logger.info(`已加入${item.id}`))
732
- }) */
733
- }
734
- getTheCorrespondingBotBasedOnTheSession(session) {
735
- // 获取对应Bot
736
- let bot;
737
- switch (session.event.platform) {
738
- case 'lark':
739
- bot = this.larkBot;
740
- break;
741
- case 'qq':
742
- bot = this.qqBot;
743
- break;
744
- case 'qqguild':
745
- bot = this.qqguildBot;
746
- break;
747
- case 'onebot':
748
- bot = this.oneBot;
749
- break;
750
- case 'red':
751
- bot = this.redBot;
752
- break;
753
- case 'telegram':
754
- bot = this.telegramBot;
755
- break;
756
- case 'satori':
757
- bot = this.satoriBot;
758
- break;
759
- case 'chronocat':
760
- bot = this.chronocatBot;
761
- break;
762
- default: {
763
- session.send('暂不支持该平台!');
764
- }
765
- }
766
- return bot;
767
624
  }
768
- async sendPrivateMsg(bot, content) {
625
+ async sendPrivateMsg(content) {
769
626
  if (this.config.master.enable) {
770
627
  if (this.config.master.masterAccountGuildId) {
771
628
  // 向机器人主人发送消息
772
- await bot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
629
+ await this.bot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
773
630
  }
774
631
  else {
775
632
  // 向机器人主人发送消息
776
- await bot.sendPrivateMessage(this.config.master.masterAccount, content);
633
+ await this.bot.sendPrivateMessage(this.config.master.masterAccount, content);
777
634
  }
778
635
  }
779
636
  }
780
- async sendPrivateMsgAndRebootService(ctx, bot) {
637
+ async sendPrivateMsgAndRebootService(ctx) {
781
638
  // 判断重启次数是否超过三次
782
639
  if (this.rebootCount >= 3) {
783
640
  // logger
784
641
  this.logger.error('已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件');
785
642
  // 重启失败,发送消息
786
- await this.sendPrivateMsg(bot, '已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件');
643
+ await this.sendPrivateMsg('已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件');
787
644
  // 关闭插件
788
645
  await ctx.sm.disposePlugin();
789
646
  // 结束
@@ -803,14 +660,14 @@ class ComRegister {
803
660
  // logger
804
661
  this.logger.error('重启插件失败,请检查机器人状态后使用指令 sys start 启动插件');
805
662
  // 重启失败,发送消息
806
- await this.sendPrivateMsg(bot, '重启插件失败,请检查机器人状态后使用指令 sys start 启动插件');
663
+ await this.sendPrivateMsg('重启插件失败,请检查机器人状态后使用指令 sys start 启动插件');
807
664
  // 关闭插件
808
665
  await ctx.sm.disposePlugin();
809
666
  }
810
667
  }
811
- async sendPrivateMsgAndStopService(ctx, bot) {
668
+ async sendPrivateMsgAndStopService(ctx) {
812
669
  // 发送消息
813
- await this.sendPrivateMsg(bot, '插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件');
670
+ await this.sendPrivateMsg('插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件');
814
671
  // logger
815
672
  this.logger.error('插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件');
816
673
  // 关闭插件
@@ -818,13 +675,13 @@ class ComRegister {
818
675
  // 结束
819
676
  return;
820
677
  }
821
- async sendMsg(targets, bot, content) {
678
+ async sendMsg(targets, content) {
822
679
  // 定义需要发送的数组
823
680
  let sendArr = [];
824
681
  // 判断是否需要推送所有机器人加入的群
825
682
  if (targets[0] === 'all') {
826
683
  // 获取所有guild
827
- for (const guild of (await bot.getGuildList()).data) {
684
+ for (const guild of (await this.bot.getGuildList()).data) {
828
685
  sendArr.push(guild.id);
829
686
  }
830
687
  }
@@ -833,14 +690,15 @@ class ComRegister {
833
690
  }
834
691
  // 循环给每个群组发送
835
692
  for (const guild of sendArr) {
836
- await this.sendMsgFunc(guild, bot, content);
693
+ await this.sendMsgFunc(guild, content);
837
694
  }
838
695
  }
839
- dynamicDetect(ctx, bot, uid, guildId) {
840
- let firstSubscription = true;
841
- let timePoint;
696
+ dynamicDetect(ctx) {
697
+ let detectSetup = true;
698
+ let updateBaseline;
842
699
  // 相当于锁的作用,防止上一个循环没处理完
843
700
  let flag = true;
701
+ // 返回一个闭包函数
844
702
  return async () => {
845
703
  // 判断上一个循环是否完成
846
704
  if (!flag)
@@ -848,30 +706,50 @@ class ComRegister {
848
706
  flag = false;
849
707
  // 无论是否执行成功都要释放锁
850
708
  try {
851
- // 第一次订阅判断
852
- if (firstSubscription) {
853
- // 设置第一次的时间点
854
- timePoint = ctx.ba.getTimeOfUTC8();
855
- // 设置第一次为false
856
- firstSubscription = false;
709
+ console.log(`初始化状态:${detectSetup}`);
710
+ // 检测启动初始化
711
+ if (detectSetup) {
712
+ // 获取动态信息
713
+ const data = await ctx.ba.getAllDynamic();
714
+ // 判断获取动态信息是否成功
715
+ if (data.code !== 0)
716
+ return;
717
+ console.log(`更新基线:${data.data.update_baseline}`);
718
+ // 设置更新基线
719
+ updateBaseline = data.data.update_baseline;
720
+ // 设置初始化为false
721
+ detectSetup = false;
722
+ // 初始化完成
857
723
  return;
858
724
  }
859
- // 获取用户空间动态数据
725
+ // 获取用户所有动态数据
726
+ let updateNum;
860
727
  let content;
861
728
  try {
862
- content = await ctx.ba.getUserSpaceDynamic(uid);
729
+ // 查询是否有新动态
730
+ const data = await ctx.ba.hasNewDynamic(updateBaseline);
731
+ updateNum = data.data.update_num;
732
+ console.log(`获取是否有新动态:`);
733
+ console.log(data);
734
+ // 没有新动态或获取动态信息失败直接返回
735
+ if (updateNum <= 0 || data.code !== 0)
736
+ return;
737
+ // 获取动态内容
738
+ content = await ctx.ba.getAllDynamic(updateBaseline);
739
+ console.log('获取动态内容:');
740
+ console.log(content.data.items[0]);
863
741
  }
864
742
  catch (e) {
865
743
  return this.logger.error('dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:' + e.message);
866
744
  }
867
- // 判断是否出现其他问题
745
+ // 判断获取动态内容是否成功
868
746
  if (content.code !== 0) {
869
747
  switch (content.code) {
870
748
  case -101: { // 账号未登录
871
749
  // 输出日志
872
750
  this.logger.error('账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
873
751
  // 发送私聊消息
874
- await this.sendPrivateMsg(bot, '账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
752
+ await this.sendPrivateMsg('账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
875
753
  // 停止服务
876
754
  await ctx.sm.disposePlugin();
877
755
  // 结束循环
@@ -881,7 +759,7 @@ class ComRegister {
881
759
  // 输出日志
882
760
  this.logger.error('账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
883
761
  // 发送私聊消息
884
- await this.sendPrivateMsg(bot, '账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
762
+ await this.sendPrivateMsg('账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
885
763
  // 停止服务
886
764
  await ctx.sm.disposePlugin();
887
765
  // 结束循环
@@ -892,273 +770,106 @@ class ComRegister {
892
770
  // 输出日志
893
771
  this.logger.error('获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message);
894
772
  // 发送私聊消息
895
- await this.sendPrivateMsg(bot, '获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
773
+ await this.sendPrivateMsg('获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
896
774
  // 结束循环
897
775
  break;
898
776
  }
899
777
  default: { // 未知错误
900
778
  // 发送私聊消息
901
- await this.sendPrivateMsg(bot, '获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
902
- // 取消订阅
903
- this.unsubAll(ctx, bot, uid);
779
+ await this.sendPrivateMsg('获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
904
780
  // 结束循环
905
781
  break;
906
782
  }
907
783
  }
908
784
  }
909
785
  // 获取数据内容
910
- const items = content.data.items;
911
- // 定义方法:更新时间点为最新发布动态的发布时间
912
- const updatePoint = (num) => {
913
- switch (num) {
914
- case 1: {
915
- if (items[0].modules.module_tag) { // 存在置顶动态
916
- timePoint = items[num].modules.module_author.pub_ts;
917
- }
918
- break;
919
- }
920
- case 0: timePoint = items[num].modules.module_author.pub_ts;
921
- }
922
- };
923
- // 发送请求 默认只查看配置文件规定数量的数据
924
- for (let num = this.config.dynamicCheckNumber - 1; num >= 0; num--) {
786
+ const data = content.data;
787
+ // 更新基线
788
+ updateBaseline = data.update_baseline;
789
+ console.log(`更新基线:${updateBaseline}`);
790
+ // 有新动态内容
791
+ const items = data.items;
792
+ // 检查更新的动态
793
+ for (let num = updateNum - 1; num >= 0; num--) {
794
+ // 有更新动态
795
+ console.log('有更新动态');
925
796
  // 没有动态内容则直接跳过
926
797
  if (!items[num])
927
798
  continue;
928
- // 寻找发布时间比时间点更晚的动态
929
- if (items[num].modules.module_author.pub_ts > timePoint) {
930
- // 定义变量
931
- let pic;
932
- let buffer;
933
- // 从动态数据中取出UP主名称和动态ID
934
- const upName = content.data.items[num].modules.module_author.name;
935
- const dynamicId = content.data.items[num].id_str;
936
- // 推送该条动态
937
- const attempts = 3;
938
- for (let i = 0; i < attempts; i++) {
939
- // 获取动态推送图片
940
- try {
941
- // 渲染图片
942
- const { pic: gimgPic, buffer: gimgBuffer } = await ctx.gi.generateDynamicImg(items[num]);
943
- // 赋值
944
- pic = gimgPic;
945
- buffer = gimgBuffer;
946
- // 成功则跳出循环
947
- break;
948
- }
949
- catch (e) {
950
- // 直播开播动态,不做处理
951
- if (e.message === '直播开播动态,不做处理')
952
- return updatePoint(num);
953
- if (e.message === '出现关键词,屏蔽该动态') {
954
- // 如果需要发送才发送
955
- if (this.config.filter.notify) {
956
- await this.sendMsg(guildId, bot, `${upName}发布了一条含有屏蔽关键字的动态`);
957
- }
958
- return updatePoint(num);
799
+ // 从动态数据中取出UP主名称、UID和动态ID
800
+ const upName = content.data.items[num].modules.module_author.name;
801
+ const upUID = items[num].modules.module_author.mid;
802
+ const dynamicId = content.data.items[num].id_str;
803
+ console.log(`寻找关注的UP主,当前动态UP主:${upName},UID:${upUID},动态ID:${dynamicId}`);
804
+ // 寻找关注的UP主的动态
805
+ this.subManager.forEach(async (sub) => {
806
+ console.log(`当前订阅UP主:${sub.uid}`);
807
+ // 判断是否是订阅的UP主
808
+ if (sub.uid == upUID) {
809
+ // 订阅该UP主,推送该动态
810
+ // 定义变量
811
+ let pic;
812
+ let buffer;
813
+ // 从动态数据中取出UP主名称和动态ID
814
+ const upName = content.data.items[num].modules.module_author.name;
815
+ const dynamicId = content.data.items[num].id_str;
816
+ console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
817
+ // 推送该条动态
818
+ const attempts = 3;
819
+ for (let i = 0; i < attempts; i++) {
820
+ // 获取动态推送图片
821
+ try {
822
+ // 渲染图片
823
+ const { pic: gimgPic, buffer: gimgBuffer } = await ctx.gi.generateDynamicImg(items[num]);
824
+ // 赋值
825
+ pic = gimgPic;
826
+ buffer = gimgBuffer;
827
+ // 成功则跳出循环
828
+ break;
959
829
  }
960
- if (e.message === '已屏蔽转发动态') {
961
- if (this.config.filter.notify) {
962
- await this.sendMsg(guildId, bot, `${upName}发布了一条转发动态,已屏蔽`);
830
+ catch (e) {
831
+ // 直播开播动态,不做处理
832
+ if (e.message === '直播开播动态,不做处理')
833
+ return;
834
+ if (e.message === '出现关键词,屏蔽该动态') {
835
+ // 如果需要发送才发送
836
+ if (this.config.filter.notify) {
837
+ await this.sendMsg(sub.targetIdArr, `${upName}发布了一条含有屏蔽关键字的动态`);
838
+ }
839
+ return;
840
+ }
841
+ if (e.message === '已屏蔽转发动态') {
842
+ if (this.config.filter.notify) {
843
+ await this.sendMsg(sub.targetIdArr, `${upName}发布了一条转发动态,已屏蔽`);
844
+ }
845
+ return;
846
+ }
847
+ // 未知错误
848
+ if (i === attempts - 1) {
849
+ this.logger.error('dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:' + e.message);
850
+ // 发送私聊消息并重启服务
851
+ return await this.sendPrivateMsgAndStopService(ctx);
963
852
  }
964
- return updatePoint(num);
965
- }
966
- // 未知错误
967
- if (i === attempts - 1) {
968
- this.logger.error('dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:' + e.message);
969
- // 发送私聊消息并重启服务
970
- return await this.sendPrivateMsgAndStopService(ctx, bot);
971
853
  }
972
854
  }
973
- }
974
- // 判断是否需要发送URL
975
- const dUrl = this.config.dynamicUrl ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}` : '';
976
- // 如果pic存在,则直接返回pic
977
- if (pic) {
978
- this.logger.info('推送动态中,使用render模式');
979
- // pic存在,使用的是render模式
980
- await this.sendMsg(guildId, bot, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
981
- }
982
- else if (buffer) {
983
- this.logger.info('推送动态中,使用page模式');
984
- // pic不存在,说明使用的是page模式
985
- await this.sendMsg(guildId, bot, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
986
- }
987
- else {
988
- this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
989
- }
990
- // 更新时间点
991
- updatePoint(num);
992
- }
993
- }
994
- }
995
- finally {
996
- flag = true;
997
- }
998
- };
999
- }
1000
- debug_dynamicDetect(ctx, bot, uid, guildId) {
1001
- let firstSubscription = true;
1002
- let timePoint;
1003
- // 相当于锁的作用,防止上一个循环没处理完
1004
- let flag = true;
1005
- return async () => {
1006
- // 判断上一个循环是否完成
1007
- if (!flag)
1008
- return;
1009
- flag = false;
1010
- // 无论是否执行成功都要释放锁
1011
- try {
1012
- // 第一次订阅判断
1013
- if (firstSubscription) {
1014
- this.logger.info(`UID:${uid}-动态监测开始`);
1015
- // 设置第一次的时间点
1016
- timePoint = ctx.ba.getTimeOfUTC8();
1017
- // 设置第一次为false
1018
- firstSubscription = false;
1019
- return;
1020
- }
1021
- this.logger.info(`UID:${uid}-获取动态信息中`);
1022
- // 获取用户空间动态数据
1023
- let content;
1024
- try {
1025
- content = await ctx.ba.getUserSpaceDynamic(uid);
1026
- }
1027
- catch (e) {
1028
- return this.logger.error(`UID:${uid}-dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
1029
- }
1030
- this.logger.info(`UID:${uid}-判断动态信息是否正确`);
1031
- // 判断是否出现其他问题
1032
- if (content.code !== 0) {
1033
- switch (content.code) {
1034
- case -101: { // 账号未登录
1035
- // 输出日志
1036
- this.logger.error('账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
1037
- // 发送私聊消息
1038
- await this.sendPrivateMsg(bot, '账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
1039
- // 停止服务
1040
- await ctx.sm.disposePlugin();
1041
- // 结束循环
1042
- break;
1043
- }
1044
- case -352: { // 风控
1045
- // 输出日志
1046
- this.logger.error('账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
1047
- // 发送私聊消息
1048
- await this.sendPrivateMsg(bot, '账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
1049
- // 停止服务
1050
- await ctx.sm.disposePlugin();
1051
- // 结束循环
1052
- break;
1053
- }
1054
- case 4101128:
1055
- case 4101129: { // 获取动态信息错误
1056
- // 输出日志
1057
- this.logger.error('获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message);
1058
- // 发送私聊消息
1059
- await this.sendPrivateMsg(bot, '获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
1060
- // 结束循环
1061
- break;
1062
- }
1063
- default: { // 未知错误
1064
- // 发送私聊消息
1065
- await this.sendPrivateMsg(bot, '获取动态信息错误,错误码为:' + content.code + ',错误为:' + content.message); // 未知错误
1066
- // 取消订阅
1067
- this.unsubAll(ctx, bot, uid);
1068
- // 结束循环
1069
- break;
1070
- }
1071
- }
1072
- }
1073
- // 获取数据内容
1074
- const items = content.data.items;
1075
- this.logger.info(`UID:${uid}-获取到的动态信息:${items.map(v => v.basic.rid_str).join('、')}`);
1076
- // 定义方法:更新时间点为最新发布动态的发布时间
1077
- const updatePoint = (num) => {
1078
- switch (num) {
1079
- case 1: {
1080
- if (items[0].modules.module_tag) { // 存在置顶动态
1081
- timePoint = items[num].modules.module_author.pub_ts;
855
+ // 判断是否需要发送URL
856
+ const dUrl = this.config.dynamicUrl ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}` : '';
857
+ // 如果pic存在,则直接返回pic
858
+ if (pic) {
859
+ this.logger.info('推送动态中,使用render模式');
860
+ // pic存在,使用的是render模式
861
+ await this.sendMsg(sub.targetIdArr, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1082
862
  }
1083
- break;
1084
- }
1085
- case 0: timePoint = items[num].modules.module_author.pub_ts;
1086
- }
1087
- };
1088
- // 发送请求 默认只查看配置文件规定数量的数据
1089
- for (let num = this.config.dynamicCheckNumber - 1; num >= 0; num--) {
1090
- // 没有动态内容则直接跳过
1091
- if (!items[num])
1092
- continue;
1093
- // 寻找发布时间比时间点更晚的动态
1094
- if (items[num].modules.module_author.pub_ts > timePoint) {
1095
- this.logger.info(`UID:${uid}-即将推送的动态:${items[num].basic.rid_str}`);
1096
- // 定义变量
1097
- let pic;
1098
- let buffer;
1099
- // 从动态数据中取出UP主名称和动态ID
1100
- const upName = content.data.items[num].modules.module_author.name;
1101
- const dynamicId = content.data.items[num].id_str;
1102
- // 推送该条动态
1103
- const attempts = 3;
1104
- this.logger.info(`UID:${uid}-尝试渲染推送图片`);
1105
- for (let i = 0; i < attempts; i++) {
1106
- // 获取动态推送图片
1107
- try {
1108
- // 渲染图片
1109
- const { pic: gimgPic, buffer: gimgBuffer } = await ctx.gi.generateDynamicImg(items[num]);
1110
- // 赋值
1111
- pic = gimgPic;
1112
- buffer = gimgBuffer;
1113
- // 成功则跳出循环
1114
- break;
863
+ else if (buffer) {
864
+ this.logger.info('推送动态中,使用page模式');
865
+ // pic不存在,说明使用的是page模式
866
+ await this.sendMsg(sub.targetIdArr, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1115
867
  }
1116
- catch (e) {
1117
- // 直播开播动态,不做处理
1118
- if (e.message === '直播开播动态,不做处理')
1119
- return updatePoint(num);
1120
- if (e.message === '出现关键词,屏蔽该动态') {
1121
- // 如果需要发送才发送
1122
- if (this.config.filter.notify) {
1123
- await this.sendMsg(guildId, bot, `${upName}发布了一条含有屏蔽关键字的动态`);
1124
- }
1125
- return updatePoint(num);
1126
- }
1127
- if (e.message === '已屏蔽转发动态') {
1128
- if (this.config.filter.notify) {
1129
- await this.sendMsg(guildId, bot, `${upName}发布了一条转发动态,已屏蔽`);
1130
- }
1131
- return updatePoint(num);
1132
- }
1133
- // 未知错误
1134
- if (i === attempts - 1) {
1135
- this.logger.error('dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:' + e.message);
1136
- // 发送私聊消息并重启服务
1137
- return await this.sendPrivateMsgAndStopService(ctx, bot);
1138
- }
868
+ else {
869
+ this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
1139
870
  }
1140
871
  }
1141
- this.logger.info(`UID:${uid}-尝试推送动态卡片`);
1142
- // 判断是否需要发送URL
1143
- const dUrl = this.config.dynamicUrl ? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}` : '';
1144
- // 如果pic存在,则直接返回pic
1145
- if (pic) {
1146
- this.logger.info(`UID:${uid}-推送动态中,使用render模式`);
1147
- // pic存在,使用的是render模式
1148
- await this.sendMsg(guildId, bot, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1149
- }
1150
- else if (buffer) {
1151
- this.logger.info(`UID:${uid}-推送动态中,使用page模式`);
1152
- // pic不存在,说明使用的是page模式
1153
- await this.sendMsg(guildId, bot, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1154
- }
1155
- else {
1156
- this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
1157
- }
1158
- // 更新时间点
1159
- updatePoint(num);
1160
- this.logger.info(`UID:${uid}-推送动态完成`);
1161
- }
872
+ });
1162
873
  }
1163
874
  }
1164
875
  finally {
@@ -1166,7 +877,7 @@ class ComRegister {
1166
877
  }
1167
878
  };
1168
879
  }
1169
- liveDetect(ctx, bot, roomId, guildId) {
880
+ liveDetect(ctx, roomId, guildId) {
1170
881
  let firstSubscription = true;
1171
882
  let timer = 0;
1172
883
  let open = false;
@@ -1199,7 +910,7 @@ class ComRegister {
1199
910
  if (i === attempts - 1) { // 已尝试三次
1200
911
  this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1201
912
  // 发送私聊消息并重启服务
1202
- return await this.sendPrivateMsgAndStopService(ctx, bot);
913
+ return await this.sendPrivateMsgAndStopService(ctx);
1203
914
  }
1204
915
  }
1205
916
  }
@@ -1207,11 +918,11 @@ class ComRegister {
1207
918
  // pic 存在,使用的是render模式
1208
919
  if (pic) {
1209
920
  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}` : ''] });
1210
- return await this.sendMsg(guildId, bot, pic + msg);
921
+ return await this.sendMsg(guildId, pic + msg);
1211
922
  }
1212
923
  // pic不存在,说明使用的是page模式
1213
924
  const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg, liveType !== LiveType.StartBroadcasting ? `https://live.bilibili.com/${roomId}` : ''] });
1214
- await this.sendMsg(guildId, bot, msg);
925
+ await this.sendMsg(guildId, msg);
1215
926
  };
1216
927
  }
1217
928
  else {
@@ -1235,7 +946,7 @@ class ComRegister {
1235
946
  if (i === attempts - 1) { // 已尝试三次
1236
947
  this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1237
948
  // 发送私聊消息并重启服务
1238
- return await this.sendPrivateMsgAndStopService(ctx, bot);
949
+ return await this.sendPrivateMsgAndStopService(ctx);
1239
950
  }
1240
951
  }
1241
952
  }
@@ -1243,11 +954,11 @@ class ComRegister {
1243
954
  // pic 存在,使用的是render模式
1244
955
  if (pic) {
1245
956
  const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg] });
1246
- return await this.sendMsg(guildId, bot, pic + msg);
957
+ return await this.sendMsg(guildId, pic + msg);
1247
958
  }
1248
959
  // pic不存在,说明使用的是page模式
1249
960
  const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg] });
1250
- await this.sendMsg(guildId, bot, msg);
961
+ await this.sendMsg(guildId, msg);
1251
962
  };
1252
963
  }
1253
964
  // 定义获取主播信息方法
@@ -1287,7 +998,7 @@ class ComRegister {
1287
998
  this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
1288
999
  if (i === attempts - 1) { // 已尝试三次
1289
1000
  // 发送私聊消息并重启服务
1290
- return await this.sendPrivateMsgAndStopService(ctx, bot);
1001
+ return await this.sendPrivateMsgAndStopService(ctx);
1291
1002
  }
1292
1003
  }
1293
1004
  }
@@ -1308,7 +1019,7 @@ class ComRegister {
1308
1019
  this.logger.error('liveDetect getMasterInfo() 发生了错误,错误为:' + e.message);
1309
1020
  if (i === attempts - 1) { // 已尝试三次
1310
1021
  // 发送私聊消息并重启服务
1311
- return await this.sendPrivateMsgAndStopService(ctx, bot);
1022
+ return await this.sendPrivateMsgAndStopService(ctx);
1312
1023
  }
1313
1024
  }
1314
1025
  }
@@ -1352,7 +1063,7 @@ class ComRegister {
1352
1063
  console.log(e);
1353
1064
  }
1354
1065
  // 发送下播通知
1355
- await this.sendMsg(guildId, bot, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [resizedImage && koishi_1.h.image(resizedImage, 'image/png'), " ", liveEndMsg] }));
1066
+ await this.sendMsg(guildId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [resizedImage && koishi_1.h.image(resizedImage, 'image/png'), " ", liveEndMsg] }));
1356
1067
  }
1357
1068
  // 未进循环,还未开播,继续循环
1358
1069
  break;
@@ -1377,7 +1088,7 @@ class ComRegister {
1377
1088
  this.logger.error('liveDetect open getMasterInfo() 发生了错误,错误为:' + e.message);
1378
1089
  if (i === attempts - 1) { // 已尝试三次
1379
1090
  // 发送私聊消息并重启服务
1380
- return await this.sendPrivateMsgAndStopService(ctx, bot);
1091
+ return await this.sendPrivateMsgAndStopService(ctx);
1381
1092
  }
1382
1093
  }
1383
1094
  }
@@ -1426,40 +1137,29 @@ class ComRegister {
1426
1137
  });
1427
1138
  return table ? table : '没有订阅任何UP';
1428
1139
  }
1429
- async checkIfNeedSub(comNeed, subType, session, data) {
1430
- if (comNeed) {
1431
- if (subType === '直播' && !data.live_room) {
1140
+ async checkIfNeedSub(liveSub, dynamicSub, session, data) {
1141
+ // 定义方法:用户直播间是否存在
1142
+ const liveRoom = async () => {
1143
+ if (!data.live_room) {
1144
+ // 未开通直播间
1432
1145
  await session.send('该用户未开通直播间,无法订阅直播');
1146
+ // 返回false
1433
1147
  return false;
1434
1148
  }
1435
- return true;
1436
- }
1437
- let input; // 用户输入
1438
- // 询问用户是否需要订阅直播
1439
- while (true) {
1440
- session.send(`是否需要订阅${subType}?需要输入 y 不需要输入 n `);
1441
- input = await session.prompt();
1442
- if (!input) {
1443
- await session.send('输入超时请重新订阅');
1444
- continue;
1445
- }
1446
- switch (input) {
1447
- case 'y': { // 需要订阅直播
1448
- // 如果用户没有开通直播间则无法订阅
1449
- if (subType === '直播' && !data.live_room) {
1450
- await session.send('该用户未开通直播间,无法订阅直播');
1451
- return false;
1452
- }
1453
- // 开启直播订阅
1454
- return true;
1455
- }
1456
- // 不需要
1457
- case 'n': return false;
1458
- default: { // 输入了其他的内容
1459
- session.send('输入有误,请输入 y 或 n');
1460
- }
1461
- }
1149
+ };
1150
+ // 如果两者都为true或者都为false则直接返回
1151
+ if ((liveSub && dynamicSub) || (!liveSub && !dynamicSub))
1152
+ return [true, true];
1153
+ // 如果只订阅直播
1154
+ if (liveSub) {
1155
+ // 判断是否存在直播间
1156
+ if (await liveRoom())
1157
+ return [false, false];
1158
+ // 返回
1159
+ return [true, false];
1462
1160
  }
1161
+ // 只订阅动态
1162
+ return [false, true];
1463
1163
  }
1464
1164
  updateSubNotifier(ctx) {
1465
1165
  // 更新控制台提示
@@ -1509,21 +1209,8 @@ class ComRegister {
1509
1209
  return;
1510
1210
  // 从数据库中获取数据
1511
1211
  const subData = await ctx.database.get('bilibili', { id: { $gt: 0 } });
1512
- // 设定订阅数量
1513
- this.num = subData.length;
1514
- // 如果订阅数量超过三个则数据库被非法修改
1515
- if (!this.config.unlockSubLimits && this.num > 3) {
1516
- // 在控制台提示重新订阅
1517
- ctx.notifier.create({
1518
- type: 'danger',
1519
- content: '您未解锁订阅限制,且订阅数大于3人,请您手动删除bilibili表中多余的数据后重启本插件'
1520
- });
1521
- return;
1522
- }
1523
1212
  // 循环遍历
1524
1213
  for (const sub of subData) {
1525
- // 定义Bot
1526
- let bot;
1527
1214
  // 判断是否存在没有任何订阅的数据
1528
1215
  if (!sub.dynamic && !sub.live) { // 存在未订阅任何项目的数据
1529
1216
  // 删除该条数据
@@ -1534,45 +1221,8 @@ class ComRegister {
1534
1221
  continue;
1535
1222
  }
1536
1223
  // 获取推送目标数组
1537
- const targetArr = sub.targetId.split(' ');
1538
- // 拿到对应bot
1539
- switch (sub.platform) {
1540
- case 'lark':
1541
- bot = this.larkBot;
1542
- break;
1543
- case 'qq':
1544
- bot = this.qqBot;
1545
- break;
1546
- case 'qqguild':
1547
- bot = this.qqguildBot;
1548
- break;
1549
- case 'onebot':
1550
- bot = this.oneBot;
1551
- break;
1552
- case 'red':
1553
- bot = this.redBot;
1554
- break;
1555
- case 'telegram':
1556
- bot = this.telegramBot;
1557
- break;
1558
- case 'satori':
1559
- bot = this.satoriBot;
1560
- break;
1561
- case 'chronocat':
1562
- bot = this.chronocatBot;
1563
- break;
1564
- default: {
1565
- // 本条数据被篡改,删除该条订阅
1566
- ctx.database.remove('bilibili', { id: sub.id });
1567
- // 不支持的协议
1568
- this.logger.info(`UID:${sub.uid} 出现不支持的协议,该条数据被篡改,自动取消订阅`);
1569
- // 发送消息
1570
- await this.sendPrivateMsg(bot, `UID:${sub.uid} 出现不支持的协议,该条数据被篡改,自动取消订阅`);
1571
- // 继续下个循环
1572
- continue;
1573
- }
1574
- }
1575
- // 判断数据库是否被篡改
1224
+ const targetIdArr = sub.targetId.split(' ');
1225
+ /* 判断数据库是否被篡改 */
1576
1226
  // 获取用户信息
1577
1227
  let content;
1578
1228
  const attempts = 3;
@@ -1587,7 +1237,7 @@ class ComRegister {
1587
1237
  this.logger.error('getSubFromDatabase() getUserInfo() 发生了错误,错误为:' + e.message);
1588
1238
  if (i === attempts - 1) { // 已尝试三次
1589
1239
  // 发送私聊消息并重启服务
1590
- return await this.sendPrivateMsgAndStopService(ctx, bot);
1240
+ return await this.sendPrivateMsgAndStopService(ctx);
1591
1241
  }
1592
1242
  }
1593
1243
  }
@@ -1598,14 +1248,14 @@ class ComRegister {
1598
1248
  // 从数据库删除该条数据
1599
1249
  await ctx.database.remove('bilibili', { id: sub.id });
1600
1250
  // 给用户发送提示
1601
- await this.sendPrivateMsg(bot, `UID:${sub.uid} 数据库内容被篡改,已取消对该UP主的订阅`);
1251
+ await this.sendPrivateMsg(`UID:${sub.uid} 数据库内容被篡改,已取消对该UP主的订阅`);
1602
1252
  };
1603
1253
  // 判断是否有其他问题
1604
1254
  if (content.code !== 0) {
1605
1255
  switch (content.code) {
1606
1256
  case -352:
1607
1257
  case -403: {
1608
- await this.sendPrivateMsg(bot, '你的登录信息已过期,请重新登录Bilibili');
1258
+ await this.sendPrivateMsg('你的登录信息已过期,请重新登录Bilibili');
1609
1259
  return;
1610
1260
  }
1611
1261
  case -400:
@@ -1613,7 +1263,7 @@ class ComRegister {
1613
1263
  default: {
1614
1264
  await deleteSub();
1615
1265
  // PrivateMsg
1616
- await this.sendPrivateMsg(bot, `UID:${sub.uid} 数据出现问题,自动取消订阅`);
1266
+ await this.sendPrivateMsg(`UID:${sub.uid} 数据出现问题,自动取消订阅`);
1617
1267
  // log
1618
1268
  this.logger.info(`UID:${sub.uid} 数据出现问题,自动取消订阅`);
1619
1269
  return;
@@ -1627,7 +1277,7 @@ class ComRegister {
1627
1277
  // log
1628
1278
  this.logger.info(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1629
1279
  // Send msg
1630
- await this.sendPrivateMsg(bot, `UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1280
+ await this.sendPrivateMsg(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1631
1281
  return;
1632
1282
  }
1633
1283
  // 构建订阅对象
@@ -1635,92 +1285,98 @@ class ComRegister {
1635
1285
  id: sub.id,
1636
1286
  uid: sub.uid,
1637
1287
  roomId: sub.room_id,
1638
- targetId: sub.targetId,
1288
+ targetIdArr,
1639
1289
  platform: sub.platform,
1640
1290
  live: +sub.live === 1 ? true : false,
1641
1291
  dynamic: +sub.dynamic === 1 ? true : false,
1642
- liveDispose: null,
1643
- dynamicDispose: null
1292
+ liveDispose: null
1644
1293
  };
1645
- // 判断需要订阅的服务
1646
- if (sub.dynamic) { // 需要订阅动态
1647
- let dispose;
1648
- // 开始循环检测
1649
- if (this.config.dynamicDebugMode) {
1650
- dispose = ctx.setInterval(this.debug_dynamicDetect(ctx, bot, sub.uid, targetArr), this.config.dynamicLoopTime * 1000);
1651
- }
1652
- else {
1653
- dispose = ctx.setInterval(this.dynamicDetect(ctx, bot, sub.uid, targetArr), this.config.dynamicLoopTime * 1000);
1654
- }
1655
- // 保存销毁函数
1656
- subManagerItem.dynamicDispose = dispose;
1657
- }
1658
1294
  if (sub.live) { // 需要订阅直播
1659
1295
  // 开始循环检测
1660
- const dispose = ctx.setInterval(this.liveDetect(ctx, bot, sub.room_id, targetArr), this.config.liveLoopTime * 1000);
1296
+ const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, targetIdArr), this.config.liveLoopTime * 1000);
1661
1297
  // 保存销毁函数
1662
1298
  subManagerItem.liveDispose = dispose;
1663
1299
  }
1664
1300
  // 保存新订阅对象
1665
1301
  this.subManager.push(subManagerItem);
1666
1302
  }
1303
+ // 检查是否有订阅对象需要动态监测
1304
+ if (this.subManager.some(sub => sub.dynamic)) {
1305
+ // 开始动态监测
1306
+ this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), 10000 /* this.config.dynamicLoopTime * 1000 */);
1307
+ }
1667
1308
  // 在控制台中显示订阅对象
1668
1309
  this.updateSubNotifier(ctx);
1669
1310
  }
1670
1311
  unsubSingle(ctx, id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
1671
- let index;
1672
- const checkIfNoSubExist = (index) => {
1673
- if (!this.subManager[index].dynamic && !this.subManager[index].live) {
1674
- // 获取要删除行的id
1675
- const id = this.subManager[index].id;
1676
- // 从管理对象中移除
1677
- this.subManager.splice(index, 1);
1678
- // 从数据库中删除
1679
- ctx.database.remove('bilibili', [id]);
1680
- // num--
1681
- this.num--;
1682
- return '已取消订阅该用户';
1683
- }
1684
- return null;
1312
+ // 定义返回消息
1313
+ let msg;
1314
+ // 定义方法:检查是否没有任何订阅
1315
+ const checkIfNoSubExist = (sub) => !sub.dynamic && !sub.live;
1316
+ // 定义方法:将订阅对象从订阅管理对象中移除
1317
+ const removeSub = (index) => {
1318
+ // 从管理对象中移除
1319
+ this.subManager.splice(index, 1);
1320
+ // 从数据库中删除
1321
+ ctx.database.remove('bilibili', [this.subManager[index].id]);
1322
+ // num--
1323
+ this.num--;
1324
+ // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1325
+ this.checkIfUserThatIsSubDynAndUnsub();
1685
1326
  };
1686
1327
  try {
1687
1328
  switch (type) {
1688
1329
  case 0: { // 取消Live订阅
1689
- index = this.subManager.findIndex(sub => sub.roomId === id);
1690
- if (index === -1)
1691
- return '未订阅该用户,无需取消订阅';
1330
+ // 获取订阅对象所在的索引
1331
+ const index = this.subManager.findIndex(sub => sub.roomId === id);
1332
+ // 获取订阅对象
1333
+ const sub = this.subManager.find(sub => sub.roomId === id);
1334
+ // 判断是否存在订阅对象
1335
+ if (!sub) {
1336
+ msg = '未订阅该用户,无需取消订阅';
1337
+ return msg;
1338
+ }
1692
1339
  // 取消订阅
1693
- if (this.subManager[index].live)
1694
- this.subManager[index].liveDispose();
1695
- this.subManager[index].liveDispose = null;
1696
- this.subManager[index].live = false;
1340
+ if (sub.live)
1341
+ sub.liveDispose();
1342
+ sub.liveDispose = null;
1343
+ sub.live = false;
1697
1344
  // 如果没有对这个UP的任何订阅,则移除
1698
- const info = checkIfNoSubExist(index);
1699
- if (info)
1700
- return info;
1345
+ if (checkIfNoSubExist(sub)) {
1346
+ // 从管理对象中移除
1347
+ removeSub(index);
1348
+ return '已取消订阅该用户';
1349
+ }
1701
1350
  // 更新数据库
1702
1351
  ctx.database.upsert('bilibili', [{
1703
- id: +`${this.subManager[index].id}`,
1352
+ id: +`${sub.id}`,
1704
1353
  live: 0
1705
1354
  }]);
1706
1355
  return '已取消订阅Live';
1707
1356
  }
1708
1357
  case 1: { // 取消Dynamic订阅
1709
- index = this.subManager.findIndex(sub => sub.uid === id);
1710
- if (index === -1)
1711
- return '未订阅该用户,无需取消订阅';
1358
+ // 获取订阅对象所在的索引
1359
+ const index = this.subManager.findIndex(sub => sub.uid === id);
1360
+ // 获取订阅对象
1361
+ const sub = this.subManager.find(sub => sub.uid === id);
1362
+ // 判断是否存在订阅对象
1363
+ if (!sub) {
1364
+ msg = '未订阅该用户,无需取消订阅';
1365
+ return msg;
1366
+ }
1712
1367
  // 取消订阅
1713
- if (this.subManager[index].dynamic)
1714
- this.subManager[index].dynamicDispose();
1715
- this.subManager[index].dynamicDispose = null;
1716
1368
  this.subManager[index].dynamic = false;
1369
+ // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1370
+ this.checkIfUserThatIsSubDynAndUnsub();
1717
1371
  // 如果没有对这个UP的任何订阅,则移除
1718
- const info = checkIfNoSubExist(index);
1719
- if (info)
1720
- return info;
1372
+ if (checkIfNoSubExist(sub)) {
1373
+ // 从管理对象中移除
1374
+ removeSub(index);
1375
+ return '已取消订阅该用户';
1376
+ }
1721
1377
  // 更新数据库
1722
1378
  ctx.database.upsert('bilibili', [{
1723
- id: +`${this.subManager[index].id}`,
1379
+ id: sub.id,
1724
1380
  dynamic: 0
1725
1381
  }]);
1726
1382
  return '已取消订阅Dynamic';
@@ -1732,13 +1388,20 @@ class ComRegister {
1732
1388
  this.updateSubNotifier(ctx);
1733
1389
  }
1734
1390
  }
1735
- unsubAll(ctx, bot, uid) {
1391
+ checkIfUserThatIsSubDynAndUnsub() {
1392
+ if (this.subManager.some(sub => sub.dynamic)) {
1393
+ // 停止动态监测
1394
+ this.dynamicDispose();
1395
+ this.dynamicDispose = null;
1396
+ }
1397
+ }
1398
+ unsubAll(ctx, uid) {
1736
1399
  this.subManager.filter(sub => sub.uid === uid).map(async (sub, i) => {
1737
1400
  // 取消全部订阅 执行dispose方法,销毁定时器
1738
- if (sub.dynamic)
1739
- await this.subManager[i].dynamicDispose();
1740
1401
  if (sub.live)
1741
1402
  await this.subManager[i].liveDispose();
1403
+ // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1404
+ this.checkIfUserThatIsSubDynAndUnsub();
1742
1405
  // 从数据库中删除订阅
1743
1406
  await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
1744
1407
  // 将该订阅对象从订阅管理对象中移除
@@ -1746,7 +1409,7 @@ class ComRegister {
1746
1409
  // id--
1747
1410
  this.num--;
1748
1411
  // 发送成功通知
1749
- this.sendPrivateMsg(bot, `UID:${uid},已取消订阅该用户`);
1412
+ this.sendPrivateMsg(`UID:${uid},已取消订阅该用户`);
1750
1413
  // 更新控制台提示
1751
1414
  this.updateSubNotifier(ctx);
1752
1415
  });
@@ -1763,6 +1426,7 @@ class ComRegister {
1763
1426
  }
1764
1427
  (function (ComRegister) {
1765
1428
  ComRegister.Config = koishi_1.Schema.object({
1429
+ platform: koishi_1.Schema.string(),
1766
1430
  master: koishi_1.Schema.object({
1767
1431
  enable: koishi_1.Schema.boolean(),
1768
1432
  masterAccount: koishi_1.Schema.string(),