koishi-plugin-bilibili-notify 2.0.0-alpha.8 → 2.0.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.
package/lib/biliAPI.d.ts CHANGED
@@ -26,6 +26,7 @@ declare class BiliAPI extends Service {
26
26
  }): Promise<string>;
27
27
  encrypt(text: string): string;
28
28
  decrypt(text: string): string;
29
+ getLiveRoomInfoStreamKey(roomId: string): Promise<any>;
29
30
  getServerUTCTime(): Promise<number>;
30
31
  getTimeNow(): Promise<any>;
31
32
  getAllGroup(): Promise<any>;
package/lib/biliAPI.js CHANGED
@@ -41,6 +41,8 @@ const MODIFY_GROUP_MEMBER = 'https://api.bilibili.com/x/relation/tags/addUsers';
41
41
  const GET_ALL_GROUP = 'https://api.bilibili.com/x/relation/tags';
42
42
  const COPY_USER_TO_GROUP = 'https://api.bilibili.com/x/relation/tags/copyUsers';
43
43
  const GET_RELATION_GROUP_DETAIL = 'https://api.bilibili.com/x/relation/tag';
44
+ // 直播
45
+ const GET_LIVE_ROOM_INFO_STREAM_KEY = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo';
44
46
  class BiliAPI extends koishi_1.Service {
45
47
  static inject = ['database', 'notifier'];
46
48
  jar;
@@ -103,6 +105,17 @@ class BiliAPI extends koishi_1.Service {
103
105
  return decrypted.toString();
104
106
  }
105
107
  // BA API
108
+ async getLiveRoomInfoStreamKey(roomId) {
109
+ try {
110
+ // 获取直播间信息流密钥
111
+ const { data } = await this.client.get(`${GET_LIVE_ROOM_INFO_STREAM_KEY}?id=${roomId}`);
112
+ // 返回data
113
+ return data;
114
+ }
115
+ catch (e) {
116
+ throw new Error('网络异常,本次请求失败!');
117
+ }
118
+ }
106
119
  async getServerUTCTime() {
107
120
  try {
108
121
  const { data } = await this.client.get(GET_SERVER_UTC_TIME);
@@ -1,8 +1,14 @@
1
1
  import { Bot, Context, FlatPick, Logger, Schema, Session } from "koishi";
2
2
  import { Notifier } from "@koishijs/plugin-notifier";
3
3
  import { LoginBili } from "./database";
4
+ type ChannelIdArr = Array<{
5
+ channelId: string;
6
+ dynamic: boolean;
7
+ live: boolean;
8
+ atAll: boolean;
9
+ }>;
4
10
  type TargetItem = {
5
- idArr: Array<string>;
11
+ channelIdArr: ChannelIdArr;
6
12
  platform: string;
7
13
  };
8
14
  type Target = Array<TargetItem>;
@@ -30,17 +36,15 @@ declare class ComRegister {
30
36
  loginDBData: FlatPick<LoginBili, "dynamic_group_id">;
31
37
  privateBot: Bot<Context>;
32
38
  dynamicDispose: Function;
33
- sendMsgFunc: (bot: Bot<Context, any>, guild: string, content: any) => Promise<void>;
39
+ sendMsgFunc: (bot: Bot<Context, any>, channelId: string, content: any) => Promise<void>;
34
40
  constructor(ctx: Context, config: ComRegister.Config);
35
- splitMultiPlatformStr(str: string): Array<{
36
- idArr: Array<string>;
37
- platform: string;
38
- }>;
41
+ init(ctx: Context, config: ComRegister.Config): Promise<void>;
42
+ splitMultiPlatformStr(str: string): Target;
39
43
  getBot(ctx: Context, pf: string): Bot<Context, any>;
40
44
  sendPrivateMsg(content: string): Promise<void>;
41
45
  sendPrivateMsgAndRebootService(ctx: Context): Promise<void>;
42
46
  sendPrivateMsgAndStopService(ctx: Context): Promise<void>;
43
- sendMsg(ctx: Context, targets: Target, content: any): Promise<void>;
47
+ sendMsg(ctx: Context, targets: Target, content: any, live?: boolean): Promise<void>;
44
48
  dynamicDetect(ctx: Context): () => Promise<void>;
45
49
  debug_dynamicDetect(ctx: Context): () => Promise<void>;
46
50
  liveDetect(ctx: Context, roomId: string, target: Target): () => Promise<void>;
@@ -52,7 +56,10 @@ declare class ComRegister {
52
56
  flag: boolean;
53
57
  msg: string;
54
58
  }>;
55
- getSubFromDatabase(ctx: Context): Promise<void>;
59
+ loadSubFromConfig(ctx: Context, subs: ComRegister.Config["sub"]): Promise<void>;
60
+ loadSubFromDatabase(ctx: Context): Promise<void>;
61
+ checkIfDynamicDetectIsNeeded(ctx: Context): void;
62
+ enableDynamicDetect(ctx: Context): void;
56
63
  unsubSingle(ctx: Context, id: string, type: number): string;
57
64
  checkIfUserIsTheLastOneWhoSubDyn(): void;
58
65
  unsubAll(ctx: Context, uid: string): void;
@@ -60,6 +67,20 @@ declare class ComRegister {
60
67
  }
61
68
  declare namespace ComRegister {
62
69
  interface Config {
70
+ sub: Array<{
71
+ uid: string;
72
+ dynamic: boolean;
73
+ live: boolean;
74
+ target: Array<{
75
+ channelIdArr: Array<{
76
+ channelId: string;
77
+ dynamic: boolean;
78
+ live: boolean;
79
+ atAll: boolean;
80
+ }>;
81
+ platform: string;
82
+ }>;
83
+ }>;
63
84
  master: {
64
85
  enable: boolean;
65
86
  platform: string;
@@ -69,7 +90,6 @@ declare namespace ComRegister {
69
90
  unlockSubLimits: boolean;
70
91
  automaticResend: boolean;
71
92
  changeMasterInfoApi: boolean;
72
- liveStartAtAll: boolean;
73
93
  restartPush: boolean;
74
94
  pushTime: number;
75
95
  liveLoopTime: number;
@@ -37,56 +37,9 @@ class ComRegister {
37
37
  sendMsgFunc;
38
38
  // 构造函数
39
39
  constructor(ctx, config) {
40
- this.logger = ctx.logger('cr');
41
- this.config = config;
42
- // 拿到私人机器人实例
43
- this.privateBot = ctx.bots.find(bot => bot.platform === config.master.platform);
44
- if (!this.privateBot) {
45
- ctx.notifier.create({
46
- content: '您未配置私人机器人,将无法向您推送机器人状态!'
47
- });
48
- this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
49
- }
50
- // 检查登录数据库是否有数据
51
- ctx.database.get('loginBili', 1, ['dynamic_group_id']).then(data => this.loginDBData = data[0]);
52
- // 从数据库获取订阅
53
- this.getSubFromDatabase(ctx);
54
- // 判断消息发送方式
55
- if (config.automaticResend) {
56
- this.sendMsgFunc = async (bot, guild, content) => {
57
- // 多次尝试发送消息
58
- const attempts = 3;
59
- for (let i = 0; i < attempts; i++) {
60
- try {
61
- // 发送消息
62
- await bot.sendMessage(guild, content);
63
- // 防止消息发送速度过快被忽略
64
- await ctx.sleep(500);
65
- // 成功发送消息,跳出循环
66
- break;
67
- }
68
- catch (e) {
69
- if (i === attempts - 1) { // 已尝试三次
70
- this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
71
- console.log(e);
72
- this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
73
- }
74
- }
75
- }
76
- };
77
- }
78
- else {
79
- this.sendMsgFunc = async (bot, guild, content) => {
80
- try {
81
- // 发送消息
82
- await bot.sendMessage(guild, content);
83
- }
84
- catch (e) {
85
- this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
86
- await this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
87
- }
88
- };
89
- }
40
+ // 初始化
41
+ this.init(ctx, config);
42
+ // 注册指令
90
43
  const statusCom = ctx.command('status', '插件状态相关指令', { permissions: ['authority:5'] });
91
44
  statusCom.subcommand('.dyn', '查看动态监测运行状态')
92
45
  .usage('查看动态监测运行状态')
@@ -198,7 +151,7 @@ class ComRegister {
198
151
  // 销毁定时器
199
152
  this.loginTimer();
200
153
  // 订阅之前的订阅
201
- await this.getSubFromDatabase(ctx);
154
+ await this.loadSubFromDatabase(ctx);
202
155
  // 清除控制台通知
203
156
  ctx.ba.disposeNotifier();
204
157
  // 发送成功登录推送
@@ -265,12 +218,7 @@ class ComRegister {
265
218
  // id--
266
219
  this.num--;
267
220
  // 判断是否还有动态订阅
268
- if (this.dynamicDispose && !this.subManager.find((sub) => sub.dynamic === true)) { // 没有动态订阅
269
- // 将动态检测关闭
270
- this.dynamicDispose();
271
- // 将动态监测置为空
272
- this.dynamicDispose = null;
273
- }
221
+ this.checkIfUserIsTheLastOneWhoSubDyn();
274
222
  // 发送成功通知
275
223
  await session.send('已取消订阅该用户');
276
224
  // 更新控制台提示
@@ -292,13 +240,14 @@ class ComRegister {
292
240
  return subTable;
293
241
  });
294
242
  biliCom
295
- .subcommand('.sub <mid: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]+)*\.[A-Za-z0-9]+(?:,[A-Za-z0-9]+)*)*$/ })
243
+ .subcommand('.sub <mid:string> [...groupId:string]', '订阅用户动态和直播通知')
244
+ .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]+))*$/ })
297
245
  .option('live', '-l')
298
246
  .option('dynamic', '-d')
299
- .usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d。若没有加任何参数,之后会向你单独询问,尖括号中为必选参数,中括号为可选参数,目标群号若不填,则默认为当前群聊')
300
- .example('bili sub 1194210119 目标QQ群号(实验性) -l -d 订阅UID为1194210119的UP主的动态和直播')
301
- .action(async ({ session, options }, mid) => {
247
+ .option('atAll', '-a')
248
+ .usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d')
249
+ .example('bili sub 1194210119 目标群号或频道号 -l -d 订阅UID为1194210119的UP主的动态和直播')
250
+ .action(async ({ session, options }, mid, ...groupId) => {
302
251
  this.logger.info('调用bili.sub指令');
303
252
  // 先判断是否订阅直播,再判断是否解锁订阅限制,最后判断直播订阅是否已超三个
304
253
  if (options.live && !this.config.unlockSubLimits && (this.subManager.reduce((acc, cur) => acc + (cur.live ? 1 : 0), 0) >= 3)) {
@@ -317,67 +266,98 @@ class ComRegister {
317
266
  // 判断是否订阅对象存在
318
267
  if (!subUserData.flag)
319
268
  return '订阅对象失败,请稍后重试!';
320
- let target;
321
- // 判断是否使用多平台功能
322
- if (options.multiplatform) {
323
- // 分割字符串,赋值给target
324
- target = this.splitMultiPlatformStr(options.multiplatform);
269
+ // 定义目标变量
270
+ let target = [];
271
+ // 判断是否使用了多群组推送
272
+ if (groupId.length > 0) {
273
+ // 定义channelIdArr
274
+ const channelIdArr = [];
275
+ // 遍历输入的群组
276
+ groupId.forEach(group => {
277
+ channelIdArr.push({
278
+ channelId: group,
279
+ dynamic: true,
280
+ live: true,
281
+ atAll: options.atAll
282
+ });
283
+ });
284
+ target.push({
285
+ channelIdArr,
286
+ platform: session.event.platform
287
+ });
325
288
  }
326
- if (target) {
327
- target.forEach(async ({ idArr, platform }, index) => {
328
- if (idArr.length > 0) { // 输入了推送群号或频道号
329
- // 拿到对应的bot
330
- const bot = this.getBot(ctx, platform);
331
- // 判断是否配置了对应平台的机器人
332
- if (!ctx.bots.some(bot => bot.platform === platform)) {
333
- await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
334
- }
335
- // 判断是否需要加入的群全部推送
336
- if (idArr[0] !== 'all') {
337
- // 定义满足条件的群组数组
338
- const targetArr = [];
339
- // 获取机器人加入的群组
340
- const guildList = await bot.getGuildList();
341
- // 遍历群组
342
- for (const guild of guildList.data) {
343
- // 获取频道
344
- const channelList = await bot.getChannelList(guild.id);
345
- // 判断群号是否符合条件
346
- for (const id of idArr) {
347
- // 判断是否机器人加入了该群
348
- if (channelList.data.some(channel => channel.id === id)) { // 机器人加入了该群
349
- // 保存到数组
350
- targetArr.push(id);
351
- // 继续下一个循环
352
- continue;
289
+ else {
290
+ // 判断是否使用多平台功能
291
+ if (options.multiplatform) {
292
+ // 分割字符串,赋值给target
293
+ target = this.splitMultiPlatformStr(options.multiplatform);
294
+ }
295
+ // 判断是否使用了多平台
296
+ if (target.length > 0) {
297
+ for (const [index, { channelIdArr, platform }] of target.entries()) {
298
+ if (channelIdArr.length > 0) { // 输入了推送群号或频道号
299
+ // 拿到对应的bot
300
+ const bot = this.getBot(ctx, platform);
301
+ // 判断是否配置了对应平台的机器人
302
+ if (!ctx.bots.some(bot => bot.platform === platform)) {
303
+ // 发送提示消息
304
+ await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
305
+ // 直接返回
306
+ return;
307
+ }
308
+ // 判断是否需要加入的群全部推送
309
+ if (channelIdArr[0].channelId !== 'all') {
310
+ // 定义满足条件的群组数组
311
+ const targetArr = [];
312
+ // 获取机器人加入的群组
313
+ const guildList = await bot.getGuildList();
314
+ // 遍历target数组
315
+ for (const channelId of channelIdArr) {
316
+ // 定义是否加入群组标志
317
+ let flag = false;
318
+ // 遍历群组
319
+ for (const guild of guildList.data) {
320
+ // 获取频道列表
321
+ const channelList = await bot.getChannelList(guild.id);
322
+ // 判断机器人是否加入群聊或频道
323
+ if (channelList.data.some(channel => channel.id === channelId.channelId)) {
324
+ // 加入群聊或频道
325
+ targetArr.push(channelId);
326
+ // 设置标志位为true
327
+ flag = true;
328
+ // 结束循环
329
+ break;
330
+ }
331
+ }
332
+ if (!flag) {
333
+ // 不满足条件发送错误提示
334
+ await session.send(`您的机器未加入${channelId.channelId},无法对该群或频道进行推送`);
353
335
  }
354
- // 不满足条件发送错误提示
355
- await session.send(`您的机器未加入${id},无法对该群或频道进行推送`);
356
336
  }
337
+ // 判断targetArr是否为空
338
+ if (target.length === 0) {
339
+ // 为空则默认为当前环境
340
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
341
+ // 没有满足条件的群组或频道
342
+ await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
343
+ }
344
+ // 将符合条件的群组添加到target中
345
+ target[index].channelIdArr = targetArr;
357
346
  }
358
- // 判断targetArr是否为空
359
- if (targetArr.length === 0) {
360
- // 为空则默认为当前环境
361
- target = [{ idArr: [session.event.channel.id], platform: session.event.platform }];
362
- // 没有满足条件的群组或频道
363
- await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
364
- }
365
- // 将符合条件的群组添加到target中
366
- target[index].idArr = targetArr;
347
+ // 如果为all则全部推送,不需要进行处理
348
+ }
349
+ else {
350
+ // 未填写群号或频道号,默认为当前环境
351
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
352
+ // 发送提示消息
353
+ await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
367
354
  }
368
- // 如果为all则全部推送,不需要进行修改
369
- }
370
- else {
371
- // 未填写群号或频道号,默认为当前环境
372
- target = [{ idArr: [session.event.channel.id], platform: session.event.platform }];
373
- // 发送提示消息
374
- await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
375
355
  }
376
- });
377
- }
378
- else {
379
- // 用户直接订阅,将当前环境赋值给target
380
- target = [{ idArr: [session.event.channel.id], platform: session.event.platform }];
356
+ }
357
+ else {
358
+ // 用户直接订阅,将当前环境赋值给target
359
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
360
+ }
381
361
  }
382
362
  // 定义外围变量
383
363
  let content;
@@ -459,13 +439,7 @@ class ComRegister {
459
439
  if (dynamicMsg) {
460
440
  // 判断是否开启动态监测
461
441
  if (!this.dynamicDispose) {
462
- // 开启动态监测
463
- if (this.config.dynamicDebugMode) {
464
- this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), config.dynamicLoopTime * 1000);
465
- }
466
- else {
467
- this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), config.dynamicLoopTime * 1000);
468
- }
442
+ this.enableDynamicDetect(ctx);
469
443
  }
470
444
  // 发送订阅消息通知
471
445
  await session.send(`订阅${userData.info.uname}动态通知`);
@@ -475,7 +449,6 @@ class ComRegister {
475
449
  uid: mid,
476
450
  room_id: roomId,
477
451
  dynamic: dynamicMsg ? 1 : 0,
478
- video: 1,
479
452
  live: liveMsg ? 1 : 0,
480
453
  target: JSON.stringify(target),
481
454
  platform: session.event.platform,
@@ -497,23 +470,6 @@ class ComRegister {
497
470
  // 新增订阅展示到控制台
498
471
  this.updateSubNotifier(ctx);
499
472
  });
500
- /* biliCom
501
- .subcommand('.live <roomId:string> <...guildId:string>', '订阅主播开播通知', { hidden: true })
502
- .usage('订阅主播开播通知')
503
- .example('bili live 26316137 订阅房间号为26316137的直播间')
504
- .action(async (_, roomId, ...guildId) => {
505
- this.logger.info('调用bili.live指令')
506
- // 如果room_id为空则返回
507
- if (!roomId) return `${roomId}非法调用 dynamic 指令` // 订阅主播房间号不能为空
508
- if (!guildId) return `${roomId}非法调用 dynamic 指令` // 目标群组或频道不能为空
509
- // 要订阅的对象不在订阅管理对象中,直接返回
510
- const index = this.subManager.findIndex(sub => sub.roomId === roomId)
511
- if (index === -1) return '请勿直接调用该指令'
512
- // 开始循环检测
513
- const dispose = ctx.setInterval(this.liveDetect(ctx, roomId, guildId, this.subManager[index].platform), config.liveLoopTime * 1000)
514
- // 保存销毁函数
515
- this.subManager[index].liveDispose = dispose
516
- }) */
517
473
  biliCom
518
474
  .subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
519
475
  .usage('查询主播当前直播状态')
@@ -568,10 +524,74 @@ class ComRegister {
568
524
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
569
525
  });
570
526
  }
527
+ async init(ctx, config) {
528
+ // 设置logger
529
+ this.logger = ctx.logger('cr');
530
+ // 将config设置给类属性
531
+ this.config = config;
532
+ // 拿到私人机器人实例
533
+ this.privateBot = ctx.bots.find(bot => bot.platform === config.master.platform);
534
+ if (!this.privateBot) {
535
+ ctx.notifier.create({
536
+ content: '您未配置私人机器人,将无法向您推送机器人状态!'
537
+ });
538
+ this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
539
+ }
540
+ // 检查登录数据库是否有数据
541
+ this.loginDBData = (await ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
542
+ // 从配置获取订阅
543
+ config.sub && await this.loadSubFromConfig(ctx, config.sub);
544
+ // 从数据库获取订阅
545
+ await this.loadSubFromDatabase(ctx);
546
+ // 判断消息发送方式
547
+ if (config.automaticResend) {
548
+ this.sendMsgFunc = async (bot, channelId, content) => {
549
+ // 多次尝试发送消息
550
+ const attempts = 3;
551
+ for (let i = 0; i < attempts; i++) {
552
+ try {
553
+ // 发送消息
554
+ await bot.sendMessage(channelId, content);
555
+ // 防止消息发送速度过快被忽略
556
+ await ctx.sleep(500);
557
+ // 成功发送消息,跳出循环
558
+ break;
559
+ }
560
+ catch (e) {
561
+ if (i === attempts - 1) { // 已尝试三次
562
+ this.logger.error(`发送群组ID:${channelId}消息失败!原因: ` + e.message);
563
+ console.log(e);
564
+ this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
565
+ }
566
+ }
567
+ }
568
+ };
569
+ }
570
+ else {
571
+ this.sendMsgFunc = async (bot, guild, content) => {
572
+ try {
573
+ // 发送消息
574
+ await bot.sendMessage(guild, content);
575
+ }
576
+ catch (e) {
577
+ this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
578
+ await this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
579
+ }
580
+ };
581
+ }
582
+ // 检查是否需要动态监测
583
+ this.checkIfDynamicDetectIsNeeded(ctx);
584
+ // 在控制台中显示订阅对象
585
+ this.updateSubNotifier(ctx);
586
+ }
571
587
  splitMultiPlatformStr(str) {
572
588
  return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
573
- const idArr = idStr.split(',');
574
- return { idArr, platform };
589
+ const channelIdArr = idStr.split(',').map(id => {
590
+ const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
591
+ const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
592
+ return { channelId, dynamic: true, live: true, atAll };
593
+ });
594
+ return { channelIdArr, platform };
575
595
  });
576
596
  }
577
597
  getBot(ctx, pf) {
@@ -630,31 +650,58 @@ class ComRegister {
630
650
  // 结束
631
651
  return;
632
652
  }
633
- async sendMsg(ctx, targets, content) {
653
+ async sendMsg(ctx, targets, content, live) {
634
654
  for (const target of targets) {
635
655
  // 获取机器人实例
636
656
  const bot = this.getBot(ctx, target.platform);
637
657
  // 定义需要发送的数组
638
658
  let sendArr = [];
639
659
  // 判断是否需要推送所有机器人加入的群
640
- if (target.idArr[0] === 'all') {
660
+ if (target.channelIdArr[0].channelId === 'all') {
641
661
  // 获取所有guild
642
662
  for (const guild of (await bot.getGuildList()).data) {
643
- sendArr.push(guild.id);
663
+ sendArr.push({
664
+ channelId: guild.id,
665
+ dynamic: target.channelIdArr[0].dynamic,
666
+ live: target.channelIdArr[0].live,
667
+ atAll: target.channelIdArr[0].atAll
668
+ });
644
669
  }
645
670
  }
646
671
  else {
647
- sendArr = target.idArr;
672
+ sendArr = target.channelIdArr;
648
673
  }
649
- // 循环给每个群组发送
650
- for (const guild of sendArr) {
651
- await this.sendMsgFunc(bot, guild, content);
674
+ // 判断是否是直播开播推送,如果是则需要进一步判断是否需要艾特群体成员
675
+ if (live) {
676
+ // 直播开播推送,判断是否需要艾特全体成员
677
+ for (const channel of sendArr) {
678
+ // 判断是否需要推送直播消息
679
+ if (channel.live) {
680
+ await this.sendMsgFunc(bot, channel.channelId, content);
681
+ }
682
+ // 判断是否需要艾特全体成员
683
+ if (channel.atAll) {
684
+ await this.sendMsgFunc(bot, channel.channelId, (0, jsx_runtime_1.jsx)("at", { type: "all" }));
685
+ }
686
+ }
687
+ }
688
+ else {
689
+ for (const channel of sendArr) {
690
+ // 判断是否需要推送动态消息和直播消息
691
+ if (channel.dynamic || channel.live) {
692
+ await this.sendMsgFunc(bot, channel.channelId, content);
693
+ }
694
+ }
652
695
  }
653
696
  }
654
697
  }
655
698
  dynamicDetect(ctx) {
699
+ // 检测初始化变量
656
700
  let detectSetup = true;
701
+ // 更新基线
657
702
  let updateBaseline;
703
+ // 第一条动态的动态ID
704
+ let dynamicIdStr;
658
705
  // 相当于锁的作用,防止上一个循环没处理完
659
706
  let flag = true;
660
707
  // 返回一个闭包函数
@@ -751,14 +798,23 @@ class ComRegister {
751
798
  // 寻找关注的UP主的动态
752
799
  this.subManager.forEach(async (sub) => {
753
800
  // 判断是否是订阅的UP主
754
- if (sub.uid == upUID) {
755
- // 订阅该UP主,推送该动态
801
+ if (sub.dynamic && sub.uid == upUID) { // 订阅该UP主,推送该动态
802
+ // 判断更新动态是否为1条
803
+ if (updateNum === 1) {
804
+ // 判断dynamicIdStr是否有值,是否与当前动态ID一致
805
+ if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
806
+ // 重复动态,不再推送,直接返回
807
+ return;
808
+ }
809
+ // 存储该动态ID
810
+ dynamicIdStr = items[num].id_str;
811
+ }
756
812
  // 定义变量
757
813
  let pic;
758
814
  let buffer;
759
815
  // 从动态数据中取出UP主名称和动态ID
760
- const upName = content.data.items[num].modules.module_author.name;
761
- const dynamicId = content.data.items[num].id_str;
816
+ const upName = items[num].modules.module_author.name;
817
+ const dynamicId = items[num].id_str;
762
818
  // 推送该条动态
763
819
  const attempts = 3;
764
820
  for (let i = 0; i < attempts; i++) {
@@ -823,8 +879,12 @@ class ComRegister {
823
879
  };
824
880
  }
825
881
  debug_dynamicDetect(ctx) {
882
+ // 检测初始化变量
826
883
  let detectSetup = true;
884
+ // 更新基线
827
885
  let updateBaseline;
886
+ // 第一条动态的动态ID
887
+ let dynamicIdStr;
828
888
  // 相当于锁的作用,防止上一个循环没处理完
829
889
  let flag = true;
830
890
  // 返回一个闭包函数
@@ -934,14 +994,23 @@ class ComRegister {
934
994
  this.subManager.forEach(async (sub) => {
935
995
  console.log(`当前订阅UP主:${sub.uid}`);
936
996
  // 判断是否是订阅的UP主
937
- if (sub.uid == upUID) {
938
- // 订阅该UP主,推送该动态
997
+ if (sub.dynamic && sub.uid == upUID) { // 订阅该UP主,推送该动态
998
+ // 判断更新动态是否为1条
999
+ if (updateNum === 1) {
1000
+ // 判断dynamicIdStr是否有值,是否与当前动态ID一致
1001
+ if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
1002
+ // 重复动态,不再推送,直接返回
1003
+ return;
1004
+ }
1005
+ // 存储该动态ID
1006
+ dynamicIdStr = items[num].id_str;
1007
+ }
939
1008
  // 定义变量
940
1009
  let pic;
941
1010
  let buffer;
942
1011
  // 从动态数据中取出UP主名称和动态ID
943
- const upName = content.data.items[num].modules.module_author.name;
944
- const dynamicId = content.data.items[num].id_str;
1012
+ const upName = items[num].modules.module_author.name;
1013
+ const dynamicId = items[num].id_str;
945
1014
  console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
946
1015
  // 推送该条动态
947
1016
  const attempts = 3;
@@ -1016,7 +1085,7 @@ class ComRegister {
1016
1085
  // 相当于锁的作用,防止上一个循环没处理完
1017
1086
  let flag = true;
1018
1087
  // 定义发送直播通知卡片方法
1019
- const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg, atAll) => {
1088
+ const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg) => {
1020
1089
  // 定义变量
1021
1090
  let pic;
1022
1091
  let buffer;
@@ -1043,12 +1112,21 @@ class ComRegister {
1043
1112
  // 推送直播信息
1044
1113
  // pic 存在,使用的是render模式
1045
1114
  if (pic) {
1046
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveNotifyMsg && liveNotifyMsg] });
1047
- return await this.sendMsg(ctx, target, pic + msg);
1115
+ // 只有在开播时才艾特全体成员
1116
+ if (liveType === LiveType.StartBroadcasting) {
1117
+ return await this.sendMsg(ctx, target, pic + (liveNotifyMsg ?? ''), true);
1118
+ }
1119
+ // 正常不需要艾特全体成员
1120
+ return await this.sendMsg(ctx, target, pic + (liveNotifyMsg ?? ''));
1048
1121
  }
1049
1122
  // pic不存在,说明使用的是page模式
1050
- 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" }), liveNotifyMsg && liveNotifyMsg] });
1051
- await this.sendMsg(ctx, target, pic + msg);
1123
+ const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg || ''] });
1124
+ // 只有在开播时才艾特全体成员
1125
+ if (liveType === LiveType.StartBroadcasting) {
1126
+ return await this.sendMsg(ctx, target, msg, true);
1127
+ }
1128
+ // 正常不需要艾特全体成员
1129
+ return await this.sendMsg(ctx, target, msg);
1052
1130
  };
1053
1131
  // 定义获取主播信息方法
1054
1132
  let useMasterInfo;
@@ -1116,9 +1194,14 @@ class ComRegister {
1116
1194
  if (data.live_status === 1) { // 当前正在直播
1117
1195
  // 设置开播时间
1118
1196
  liveTime = data.live_time;
1197
+ // 设置直播中消息
1198
+ const liveMsg = this.config.customLive ? this.config.customLive
1199
+ .replace('-name', username)
1200
+ .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1201
+ .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1119
1202
  // 发送直播通知卡片
1120
1203
  if (this.config.restartPush)
1121
- sendLiveNotifyCard(data, LiveType.LiveBroadcast);
1204
+ sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1122
1205
  // 改变开播状态
1123
1206
  open = true;
1124
1207
  } // 未开播,直接返回
@@ -1134,9 +1217,9 @@ class ComRegister {
1134
1217
  // 下播了将定时器清零
1135
1218
  timer = 0;
1136
1219
  // 定义下播通知消息
1137
- const liveEndMsg = this.config.customLiveEnd
1220
+ const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1138
1221
  .replace('-name', username)
1139
- .replace('-time', await ctx.gi.getTimeDifference(liveTime));
1222
+ .replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null;
1140
1223
  // 更改直播时长
1141
1224
  data.live_time = liveTime;
1142
1225
  // 发送@全体成员通知
@@ -1169,20 +1252,13 @@ class ComRegister {
1169
1252
  }
1170
1253
  }
1171
1254
  }
1172
- // 定义开播通知语
1173
- const liveStartMsg = this.config.customLiveStart
1255
+ // 定义开播通知语
1256
+ const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1174
1257
  .replace('-name', username)
1175
1258
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1176
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`);
1177
- // 判断是否需要@全体成员
1178
- if (this.config.liveStartAtAll) {
1179
- // 发送@全体成员通知
1180
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg, true);
1181
- }
1182
- else {
1183
- // 发送直播通知卡片
1184
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1185
- }
1259
+ .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1260
+ // 发送消息
1261
+ await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1186
1262
  }
1187
1263
  else { // 还在直播
1188
1264
  if (this.config.pushTime > 0) {
@@ -1195,7 +1271,7 @@ class ComRegister {
1195
1271
  const liveMsg = this.config.customLive ? this.config.customLive
1196
1272
  .replace('-name', username)
1197
1273
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1198
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : '';
1274
+ .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1199
1275
  // 发送直播通知卡片
1200
1276
  sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1201
1277
  }
@@ -1374,7 +1450,67 @@ class ComRegister {
1374
1450
  // 订阅成功
1375
1451
  return { flag: true, msg: '用户订阅成功' };
1376
1452
  }
1377
- async getSubFromDatabase(ctx) {
1453
+ async loadSubFromConfig(ctx, subs) {
1454
+ for (const sub of subs) {
1455
+ // 定义Data
1456
+ let data;
1457
+ // 定义直播销毁函数
1458
+ let liveDispose;
1459
+ // 判断是否需要订阅直播
1460
+ if (sub.live) {
1461
+ // 获取用户信息
1462
+ let content;
1463
+ // 设置重试次数
1464
+ const attempts = 3;
1465
+ for (let i = 0; i < attempts; i++) {
1466
+ try {
1467
+ // 获取用户信息
1468
+ content = await ctx.ba.getUserInfo(sub.uid);
1469
+ // 成功则跳出循环
1470
+ break;
1471
+ }
1472
+ catch (e) {
1473
+ this.logger.error('getSubFromDatabase() getUserInfo() 发生了错误,错误为:' + e.message);
1474
+ if (i === attempts - 1) { // 已尝试三次
1475
+ // 发送私聊消息并重启服务
1476
+ return await this.sendPrivateMsgAndStopService(ctx);
1477
+ }
1478
+ }
1479
+ }
1480
+ // 获取data
1481
+ data = content.data;
1482
+ // 检查roomid是否存在
1483
+ if (!data.live_room) {
1484
+ // 用户没有开通直播间,无法订阅直播
1485
+ sub.live = false;
1486
+ // 发送提示
1487
+ this.logger.warn(`UID:${sub.uid} 用户没有开通直播间,无法订阅直播!`);
1488
+ }
1489
+ // 判断是否订阅直播
1490
+ if (sub.live) {
1491
+ // 订阅直播
1492
+ liveDispose = ctx.setInterval(this.liveDetect(ctx, data.live_room.roomid, sub.target), this.config.liveLoopTime * 1000);
1493
+ }
1494
+ }
1495
+ // 在B站中订阅该对象
1496
+ const subInfo = await this.subUserInBili(ctx, sub.uid);
1497
+ // 判断订阅是否成功
1498
+ if (!subInfo.flag)
1499
+ this.logger.warn(subInfo.msg);
1500
+ // 将该订阅添加到sm中
1501
+ this.subManager.push({
1502
+ id: +sub.uid,
1503
+ uid: sub.uid,
1504
+ roomId: sub.live ? data.live_room.roomid : '',
1505
+ target: sub.target,
1506
+ platform: '',
1507
+ live: sub.live,
1508
+ dynamic: sub.dynamic,
1509
+ liveDispose
1510
+ });
1511
+ }
1512
+ }
1513
+ async loadSubFromDatabase(ctx) {
1378
1514
  // 判断登录信息是否已加载完毕
1379
1515
  await this.checkIfLoginInfoIsLoaded(ctx);
1380
1516
  // 如果未登录,则直接返回
@@ -1472,6 +1608,7 @@ class ComRegister {
1472
1608
  this.logger.info(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1473
1609
  // Send msg
1474
1610
  await this.sendPrivateMsg(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1611
+ // 直接返回
1475
1612
  return;
1476
1613
  }
1477
1614
  // 构建订阅对象
@@ -1481,19 +1618,20 @@ class ComRegister {
1481
1618
  roomId: sub.room_id,
1482
1619
  target,
1483
1620
  platform: sub.platform,
1484
- live: +sub.live === 1 ? true : false,
1485
- dynamic: +sub.dynamic === 1 ? true : false,
1621
+ live: sub.live === 1 ? true : false,
1622
+ dynamic: sub.dynamic === 1 ? true : false,
1486
1623
  liveDispose: null
1487
1624
  };
1488
1625
  // 判断是否订阅直播
1489
1626
  if (sub.live) {
1490
1627
  // 判断订阅直播数是否超过限制
1491
1628
  if (!this.config.unlockSubLimits && liveSubNum >= 3) {
1629
+ // 将live改为false
1492
1630
  subManagerItem.live = false;
1493
1631
  // log
1494
1632
  this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1495
1633
  // 发送错误消息
1496
- this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1634
+ await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1497
1635
  }
1498
1636
  else {
1499
1637
  // 直播订阅数+1
@@ -1507,18 +1645,20 @@ class ComRegister {
1507
1645
  // 保存新订阅对象
1508
1646
  this.subManager.push(subManagerItem);
1509
1647
  }
1648
+ }
1649
+ checkIfDynamicDetectIsNeeded(ctx) {
1510
1650
  // 检查是否有订阅对象需要动态监测
1511
- if (this.subManager.some(sub => sub.dynamic)) {
1512
- // 开始动态监测
1513
- if (this.config.dynamicDebugMode) {
1514
- this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), 10000);
1515
- }
1516
- else {
1517
- this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), 10000 /* this.config.dynamicLoopTime * 1000 */);
1518
- }
1651
+ if (this.subManager.some(sub => sub.dynamic))
1652
+ this.enableDynamicDetect(ctx);
1653
+ }
1654
+ enableDynamicDetect(ctx) {
1655
+ // 开始动态监测
1656
+ if (this.config.dynamicDebugMode) {
1657
+ this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), this.config.dynamicLoopTime * 1000);
1658
+ }
1659
+ else {
1660
+ this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), this.config.dynamicLoopTime * 1000);
1519
1661
  }
1520
- // 在控制台中显示订阅对象
1521
- this.updateSubNotifier(ctx);
1522
1662
  }
1523
1663
  unsubSingle(ctx, id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
1524
1664
  // 定义返回消息
@@ -1601,7 +1741,7 @@ class ComRegister {
1601
1741
  }
1602
1742
  }
1603
1743
  checkIfUserIsTheLastOneWhoSubDyn() {
1604
- if (this.subManager.some(sub => sub.dynamic)) {
1744
+ if (this.dynamicDispose && !this.subManager.some(sub => sub.dynamic)) {
1605
1745
  // 停止动态监测
1606
1746
  this.dynamicDispose();
1607
1747
  this.dynamicDispose = null;
@@ -1638,6 +1778,20 @@ class ComRegister {
1638
1778
  }
1639
1779
  (function (ComRegister) {
1640
1780
  ComRegister.Config = koishi_1.Schema.object({
1781
+ sub: koishi_1.Schema.array(koishi_1.Schema.object({
1782
+ uid: koishi_1.Schema.string().description('订阅用户UID'),
1783
+ dynamic: koishi_1.Schema.boolean().description('是否订阅用户动态'),
1784
+ live: koishi_1.Schema.boolean().description('是否订阅用户直播'),
1785
+ target: koishi_1.Schema.array(koishi_1.Schema.object({
1786
+ channelIdArr: koishi_1.Schema.array(koishi_1.Schema.object({
1787
+ channelId: koishi_1.Schema.string().description('频道/群组号'),
1788
+ dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
1789
+ live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
1790
+ atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
1791
+ })).description('频道/群组信息'),
1792
+ platform: koishi_1.Schema.string().description('推送平台')
1793
+ })).description('订阅用户需要发送的频道/群组信息')
1794
+ })).role('table').description('手动输入订阅信息,方便自定义订阅内容,这里的订阅内容不会存入数据库。uid: 订阅用户UID,dynamic: 是否需要订阅动态,live: 是否需要订阅直播'),
1641
1795
  master: koishi_1.Schema.object({
1642
1796
  enable: koishi_1.Schema.boolean(),
1643
1797
  platform: koishi_1.Schema.string(),
@@ -1647,7 +1801,6 @@ class ComRegister {
1647
1801
  unlockSubLimits: koishi_1.Schema.boolean().required(),
1648
1802
  automaticResend: koishi_1.Schema.boolean().required(),
1649
1803
  changeMasterInfoApi: koishi_1.Schema.boolean().required(),
1650
- liveStartAtAll: koishi_1.Schema.boolean().required(),
1651
1804
  restartPush: koishi_1.Schema.boolean().required(),
1652
1805
  pushTime: koishi_1.Schema.number().required(),
1653
1806
  liveLoopTime: koishi_1.Schema.number().default(10),
package/lib/database.d.ts CHANGED
@@ -10,7 +10,6 @@ export interface Bilibili {
10
10
  uid: string;
11
11
  room_id: string;
12
12
  dynamic: number;
13
- video: number;
14
13
  live: number;
15
14
  target: string;
16
15
  platform: string;
package/lib/database.js CHANGED
@@ -10,7 +10,6 @@ function apply(ctx) {
10
10
  uid: 'string',
11
11
  room_id: 'string',
12
12
  dynamic: 'unsigned',
13
- video: 'unsigned',
14
13
  live: 'unsigned',
15
14
  target: 'string',
16
15
  platform: 'string',
@@ -176,7 +176,7 @@ class GenerateImg extends koishi_1.Service {
176
176
  </div>
177
177
  ${this.giConfig.hideDesc ? '' : `<p class="card-text">${data.description ? data.description : '这个主播很懒,什么都简介都没写'}</p>`}
178
178
  <p class="card-link">
179
- <span>人气:${data.online > 10000 ? `${(data.online / 10000).toFixed(1)}万` : data.online}</span>
179
+ ${liveStatus !== 3 ? `<span>人气:${data.online > 10000 ? `${(data.online / 10000).toFixed(1)}万` : data.online}</span>` : ''}
180
180
  <span>分区名称:${data.area_name}</span>
181
181
  </p>
182
182
  <p class="card-link">
package/lib/index.d.ts CHANGED
@@ -15,6 +15,21 @@ export interface Config {
15
15
  automaticResend: boolean;
16
16
  renderType: 'render' | 'page';
17
17
  userAgent: string;
18
+ subTitle: {};
19
+ sub: Array<{
20
+ uid: string;
21
+ dynamic: boolean;
22
+ live: boolean;
23
+ target: Array<{
24
+ channelIdArr: Array<{
25
+ channelId: string;
26
+ dynamic: boolean;
27
+ live: boolean;
28
+ atAll: boolean;
29
+ }>;
30
+ platform: string;
31
+ }>;
32
+ }>;
18
33
  dynamic: {};
19
34
  dynamicUrl: boolean;
20
35
  dynamicCheckNumber: number;
package/lib/index.js CHANGED
@@ -93,6 +93,21 @@ exports.Config = koishi_1.Schema.object({
93
93
  userAgent: koishi_1.Schema.string()
94
94
  .required()
95
95
  .description('设置请求头User-Agen,请求出现-352时可以尝试修改,UA获取方法可参考:https://blog.csdn.net/qq_44503987/article/details/104929111'),
96
+ subTitle: koishi_1.Schema.object({}).description('手动订阅'),
97
+ sub: koishi_1.Schema.array(koishi_1.Schema.object({
98
+ uid: koishi_1.Schema.string().description('订阅用户UID'),
99
+ dynamic: koishi_1.Schema.boolean().description('是否订阅用户动态'),
100
+ live: koishi_1.Schema.boolean().description('是否订阅用户直播'),
101
+ target: koishi_1.Schema.array(koishi_1.Schema.object({
102
+ channelIdArr: koishi_1.Schema.array(koishi_1.Schema.object({
103
+ channelId: koishi_1.Schema.string().description('频道/群组号'),
104
+ dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
105
+ live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
106
+ atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
107
+ })).description('频道/群组信息'),
108
+ platform: koishi_1.Schema.string().description('推送平台')
109
+ })).description('订阅用户需要发送的频道/群组信息')
110
+ })).role('table').description('手动输入订阅信息,方便自定义订阅内容,这里的订阅内容不会存入数据库。uid: 订阅用户UID,dynamic: 是否需要订阅动态,live: 是否需要订阅直播'),
96
111
  dynamic: koishi_1.Schema.object({}).description('动态推送设置'),
97
112
  dynamicUrl: koishi_1.Schema.boolean()
98
113
  .default(false)
@@ -290,6 +305,7 @@ class ServerManager extends koishi_1.Service {
290
305
  });
291
306
  // CR = ComRegister
292
307
  const cr = this.ctx.plugin(comRegister_1.default, {
308
+ sub: globalConfig.sub,
293
309
  master: globalConfig.master,
294
310
  unlockSubLimits: globalConfig.unlockSubLimits,
295
311
  automaticResend: globalConfig.automaticResend,
@@ -298,6 +314,7 @@ class ServerManager extends koishi_1.Service {
298
314
  restartPush: globalConfig.restartPush,
299
315
  pushTime: globalConfig.pushTime,
300
316
  customLiveStart: globalConfig.customLiveStart,
317
+ customLive: globalConfig.customLive,
301
318
  customLiveEnd: globalConfig.customLiveEnd,
302
319
  dynamicCheckNumber: globalConfig.dynamicCheckNumber,
303
320
  dynamicLoopTime: this.dynamicLoopTime,
@@ -341,9 +358,9 @@ class ServerManager extends koishi_1.Service {
341
358
  await this.disposePlugin();
342
359
  // 隔一秒启动插件
343
360
  return new Promise(resolve => {
344
- this.ctx.setTimeout(async () => {
361
+ this.ctx.setTimeout(() => {
345
362
  try {
346
- await this.registerPlugin();
363
+ this.registerPlugin();
347
364
  }
348
365
  catch (e) {
349
366
  this.logger.error('重启插件失败', e);
@@ -359,7 +376,7 @@ function apply(ctx, config) {
359
376
  globalConfig = config;
360
377
  // 设置提示
361
378
  ctx.notifier.create({
362
- content: '从2.0.0-alpha.7以前版本更新需重新订阅'
379
+ content: '从2.0.0-alpha.9以前版本更新需重新订阅'
363
380
  });
364
381
  ctx.notifier.create({
365
382
  content: '请使用Auth插件创建超级管理员账号,没有权限将无法使用该插件提供的指令。'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-bilibili-notify",
3
3
  "description": "Koishi bilibili notify plugin",
4
- "version": "2.0.0-alpha.8",
4
+ "version": "2.0.0",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
@@ -53,15 +53,19 @@
53
53
 
54
54
  订阅UP主:订阅你想要推送的UP主
55
55
 
56
- - 使用指令 `bili sub <uid>` 订阅需要订阅的UP主
56
+ - 使用指令 `bili sub <uid> [...groupId]` 订阅需要订阅的UP主
57
57
  - 参数说明:
58
58
  - `uid` 为必填参数,为 `up主` 的 `uid`
59
- - 选项说明:`bili sub <uid>` 有三个选项:-l -d -m
59
+ - `groupId` 为可选参数,为需要推送的群号/频道号,可输入多个群号
60
+ - 选项说明:`bili sub <uid>` 有四个选项:-l -d -m -a
60
61
  - `-l` 为订阅UP主直播间,包括直播开播通知,定时推送直播内容,下播通知
61
62
  - `-d` 为订阅UP主动态推送,目前实现推送的动态类型有:普通图文动态,转发动态,直播预约动态
62
- - `-m` 为多平台动态推送,格式为:群号/频道号,群号/频道号,群号/频道号.平台名;群号/频道号,群号/频道号.平台号
63
+ - `-m` 为多平台动态推送,格式为:群号/频道号,群号/频道号,群号/频道号.平台名;群号/频道号,群号/频道号.平台号。如果群号/频道号为 `all` 代表推送该平台下的所有群聊或/频道。在群号/频道号后加 `@` 则代表这个群聊/频道需要@全体成员。订阅TG群组时请使用 `bili sub xxx -m "xxxxxxx"` 这样的格式
64
+ - `-a` 为是否艾特全体成员,对 `-m` 参数不生效
65
+
63
66
  例如:
64
- `-m 3247293,324389,89874324.qq;EDBWIUBIU.qqguild;79324792,3247892.onebot`
67
+ `-m 3247293,324389,89874324.qq;EDBWIUBIU.qqguild;79324792,3247892.onebot` 代表推送QQ下3247293,324389,89874324这三个群聊,QQ频道下EDBWIUBIU这个频道,Onebot平台下79324792,3247892这两个群聊
68
+ `-m 3247293,324389@,89874324.qq` 代表推送QQ下3247293,324389,89874324这三个群聊,其中群聊324389需要艾特全体成员
65
69
  所有分隔符均为英文符号
66
70
 
67
71
  - 例如:
@@ -69,6 +73,7 @@
69
73
  - `bili sub 1194210119 -d` 订阅UID为1194210119的UP主动态推送
70
74
  - `bili sub 1194210119 -l` 订阅UID为1194210119的UP主直播间
71
75
  - `bili sub 1194210119 -m 3247293,324389,89874324.qq;all.onebot;EHUIWDBUAWD.qqguild` 订阅UID为1194210119的UP主,向群号为3247293,324389,89874324的QQ群,所有onebot平台下的群聊,频道号为EHUIWDBUAWD的QQ频道平台进行推送
76
+ - `bili sub 1194210119 -a` 订阅UID为1194210119的UP主动态推送和直播间并艾特全体成员
72
77
 
73
78
  取消订阅UP主:取消订阅不需要推送的UP主
74
79
 
@@ -190,6 +195,22 @@
190
195
  - ver 2.0.0-alpha.6 修复:直播推送发送失败的bug
191
196
  - ver 2.0.0-alpha.7 重构:现已支持同一UP多平台推送
192
197
  - ver 2.0.0-alpha.8 新增:重新订阅提示
198
+ - ver 2.0.0-alpha.9 修复:订阅反复提示未加入群组的bug,实际已加入
199
+ - ver 2.0.0-alpha.10 新增:可对每个群聊针对性设置是否艾特全体成员 优化:直播下播通知
200
+ - ver 2.0.0-alpha.11 回档:订阅时可直接接收群号/频道号 修复:直播过程推送消息不成功的bug
201
+ - ver 2.0.0-alpha.12 更改:开启艾特全体成员后,只有在开播时才艾特全体成员
202
+ - ver 2.0.0-alpha.13 修复:无法对TG群组的特殊频道号进行订阅处理;提示 `您未配置对应平台的机器人,不能在该平台进行订阅操作` 仍进行订阅操作
203
+ - ver 2.0.0-alpha.14 修复:订阅TG群组时提示输入无效
204
+ - ver 2.0.0-alpha.15 新增:手动订阅功能 修复:一些潜在的bug
205
+ - ver 2.0.0-alpha.16 优化:手动订阅功能
206
+ - ver 2.0.0-alpha.17 修复:直接订阅当前环境不会推送
207
+ - ver 2.0.0-alpha.18 修复:手动订阅无法推送直播通知;自定义直播中通知语不会发送
208
+ - ver 2.0.0-alpha.19 修复:开播通知后带false;下播通知卡片人气位置显示false
209
+ - ver 2.0.0-alpha.20 修复:直播推送失败 `Error with request send_group_msg`
210
+ - ver 2.0.0-alpha.21 修复:在某些场景下仍会出现 `2.0.0-alpha.19` 和 `2.0.0-alpha.20` 版本已修复的问题
211
+ - ver 2.0.0-alpha.22 移除:不需要的服务
212
+ - ver 2.0.0-alpha.23 优化:将艾特全体成员消息单独发送
213
+ - ver 2.0.0 修复:只订阅直播也会将该UP主的动态进行推送、推送过的动态过一段时间又会再次推送
193
214
 
194
215
  ## 交流群
195
216