koishi-plugin-bilibili-notify 2.0.0-alpha.9 → 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,73 +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
- // 遍历target数组
342
- for (const id of idArr) {
343
- // 定义是否加入群组标志
344
- let flag = false;
345
- // 遍历群组
346
- for (const guild of guildList.data) {
347
- // 获取频道列表
348
- const channelList = await bot.getChannelList(guild.id);
349
- // 判断机器人是否加入群聊或频道
350
- if (channelList.data.some(channel => channel.id === id)) {
351
- // 加入群聊或频道
352
- targetArr.push(id);
353
- // 设置标志位为true
354
- flag = true;
355
- // 结束循环
356
- break;
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},无法对该群或频道进行推送`);
357
335
  }
358
336
  }
359
- if (!flag) {
360
- // 不满足条件发送错误提示
361
- await session.send(`您的机器未加入${id},无法对该群或频道进行推送`);
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('没有满足条件的群组或频道,默认订阅到当前聊天环境');
362
343
  }
344
+ // 将符合条件的群组添加到target中
345
+ target[index].channelIdArr = targetArr;
363
346
  }
364
- // 判断targetArr是否为空
365
- if (target.length === 0) {
366
- // 为空则默认为当前环境
367
- target = [{ idArr: [session.event.channel.id], platform: session.event.platform }];
368
- // 没有满足条件的群组或频道
369
- await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
370
- }
371
- // 将符合条件的群组添加到target中
372
- 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('没有填写群号或频道号,默认订阅到当前聊天环境');
373
354
  }
374
- // 如果为all则全部推送,不需要进行修改
375
- }
376
- else {
377
- // 未填写群号或频道号,默认为当前环境
378
- target = [{ idArr: [session.event.channel.id], platform: session.event.platform }];
379
- // 发送提示消息
380
- await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
381
355
  }
382
- });
383
- }
384
- else {
385
- // 用户直接订阅,将当前环境赋值给target
386
- 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
+ }
387
361
  }
388
362
  // 定义外围变量
389
363
  let content;
@@ -465,13 +439,7 @@ class ComRegister {
465
439
  if (dynamicMsg) {
466
440
  // 判断是否开启动态监测
467
441
  if (!this.dynamicDispose) {
468
- // 开启动态监测
469
- if (this.config.dynamicDebugMode) {
470
- this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), config.dynamicLoopTime * 1000);
471
- }
472
- else {
473
- this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), config.dynamicLoopTime * 1000);
474
- }
442
+ this.enableDynamicDetect(ctx);
475
443
  }
476
444
  // 发送订阅消息通知
477
445
  await session.send(`订阅${userData.info.uname}动态通知`);
@@ -481,7 +449,6 @@ class ComRegister {
481
449
  uid: mid,
482
450
  room_id: roomId,
483
451
  dynamic: dynamicMsg ? 1 : 0,
484
- video: 1,
485
452
  live: liveMsg ? 1 : 0,
486
453
  target: JSON.stringify(target),
487
454
  platform: session.event.platform,
@@ -503,23 +470,6 @@ class ComRegister {
503
470
  // 新增订阅展示到控制台
504
471
  this.updateSubNotifier(ctx);
505
472
  });
506
- /* biliCom
507
- .subcommand('.live <roomId:string> <...guildId:string>', '订阅主播开播通知', { hidden: true })
508
- .usage('订阅主播开播通知')
509
- .example('bili live 26316137 订阅房间号为26316137的直播间')
510
- .action(async (_, roomId, ...guildId) => {
511
- this.logger.info('调用bili.live指令')
512
- // 如果room_id为空则返回
513
- if (!roomId) return `${roomId}非法调用 dynamic 指令` // 订阅主播房间号不能为空
514
- if (!guildId) return `${roomId}非法调用 dynamic 指令` // 目标群组或频道不能为空
515
- // 要订阅的对象不在订阅管理对象中,直接返回
516
- const index = this.subManager.findIndex(sub => sub.roomId === roomId)
517
- if (index === -1) return '请勿直接调用该指令'
518
- // 开始循环检测
519
- const dispose = ctx.setInterval(this.liveDetect(ctx, roomId, guildId, this.subManager[index].platform), config.liveLoopTime * 1000)
520
- // 保存销毁函数
521
- this.subManager[index].liveDispose = dispose
522
- }) */
523
473
  biliCom
524
474
  .subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
525
475
  .usage('查询主播当前直播状态')
@@ -574,10 +524,74 @@ class ComRegister {
574
524
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
575
525
  });
576
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
+ }
577
587
  splitMultiPlatformStr(str) {
578
588
  return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
579
- const idArr = idStr.split(',');
580
- 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 };
581
595
  });
582
596
  }
583
597
  getBot(ctx, pf) {
@@ -636,31 +650,58 @@ class ComRegister {
636
650
  // 结束
637
651
  return;
638
652
  }
639
- async sendMsg(ctx, targets, content) {
653
+ async sendMsg(ctx, targets, content, live) {
640
654
  for (const target of targets) {
641
655
  // 获取机器人实例
642
656
  const bot = this.getBot(ctx, target.platform);
643
657
  // 定义需要发送的数组
644
658
  let sendArr = [];
645
659
  // 判断是否需要推送所有机器人加入的群
646
- if (target.idArr[0] === 'all') {
660
+ if (target.channelIdArr[0].channelId === 'all') {
647
661
  // 获取所有guild
648
662
  for (const guild of (await bot.getGuildList()).data) {
649
- 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
+ });
650
669
  }
651
670
  }
652
671
  else {
653
- sendArr = target.idArr;
672
+ sendArr = target.channelIdArr;
654
673
  }
655
- // 循环给每个群组发送
656
- for (const guild of sendArr) {
657
- 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
+ }
658
695
  }
659
696
  }
660
697
  }
661
698
  dynamicDetect(ctx) {
699
+ // 检测初始化变量
662
700
  let detectSetup = true;
701
+ // 更新基线
663
702
  let updateBaseline;
703
+ // 第一条动态的动态ID
704
+ let dynamicIdStr;
664
705
  // 相当于锁的作用,防止上一个循环没处理完
665
706
  let flag = true;
666
707
  // 返回一个闭包函数
@@ -757,14 +798,23 @@ class ComRegister {
757
798
  // 寻找关注的UP主的动态
758
799
  this.subManager.forEach(async (sub) => {
759
800
  // 判断是否是订阅的UP主
760
- if (sub.uid == upUID) {
761
- // 订阅该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
+ }
762
812
  // 定义变量
763
813
  let pic;
764
814
  let buffer;
765
815
  // 从动态数据中取出UP主名称和动态ID
766
- const upName = content.data.items[num].modules.module_author.name;
767
- const dynamicId = content.data.items[num].id_str;
816
+ const upName = items[num].modules.module_author.name;
817
+ const dynamicId = items[num].id_str;
768
818
  // 推送该条动态
769
819
  const attempts = 3;
770
820
  for (let i = 0; i < attempts; i++) {
@@ -829,8 +879,12 @@ class ComRegister {
829
879
  };
830
880
  }
831
881
  debug_dynamicDetect(ctx) {
882
+ // 检测初始化变量
832
883
  let detectSetup = true;
884
+ // 更新基线
833
885
  let updateBaseline;
886
+ // 第一条动态的动态ID
887
+ let dynamicIdStr;
834
888
  // 相当于锁的作用,防止上一个循环没处理完
835
889
  let flag = true;
836
890
  // 返回一个闭包函数
@@ -940,14 +994,23 @@ class ComRegister {
940
994
  this.subManager.forEach(async (sub) => {
941
995
  console.log(`当前订阅UP主:${sub.uid}`);
942
996
  // 判断是否是订阅的UP主
943
- if (sub.uid == upUID) {
944
- // 订阅该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
+ }
945
1008
  // 定义变量
946
1009
  let pic;
947
1010
  let buffer;
948
1011
  // 从动态数据中取出UP主名称和动态ID
949
- const upName = content.data.items[num].modules.module_author.name;
950
- const dynamicId = content.data.items[num].id_str;
1012
+ const upName = items[num].modules.module_author.name;
1013
+ const dynamicId = items[num].id_str;
951
1014
  console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
952
1015
  // 推送该条动态
953
1016
  const attempts = 3;
@@ -1022,7 +1085,7 @@ class ComRegister {
1022
1085
  // 相当于锁的作用,防止上一个循环没处理完
1023
1086
  let flag = true;
1024
1087
  // 定义发送直播通知卡片方法
1025
- const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg, atAll) => {
1088
+ const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg) => {
1026
1089
  // 定义变量
1027
1090
  let pic;
1028
1091
  let buffer;
@@ -1049,12 +1112,21 @@ class ComRegister {
1049
1112
  // 推送直播信息
1050
1113
  // pic 存在,使用的是render模式
1051
1114
  if (pic) {
1052
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveNotifyMsg && liveNotifyMsg] });
1053
- 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 ?? ''));
1054
1121
  }
1055
1122
  // pic不存在,说明使用的是page模式
1056
- 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] });
1057
- 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);
1058
1130
  };
1059
1131
  // 定义获取主播信息方法
1060
1132
  let useMasterInfo;
@@ -1122,9 +1194,14 @@ class ComRegister {
1122
1194
  if (data.live_status === 1) { // 当前正在直播
1123
1195
  // 设置开播时间
1124
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;
1125
1202
  // 发送直播通知卡片
1126
1203
  if (this.config.restartPush)
1127
- sendLiveNotifyCard(data, LiveType.LiveBroadcast);
1204
+ sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1128
1205
  // 改变开播状态
1129
1206
  open = true;
1130
1207
  } // 未开播,直接返回
@@ -1140,9 +1217,9 @@ class ComRegister {
1140
1217
  // 下播了将定时器清零
1141
1218
  timer = 0;
1142
1219
  // 定义下播通知消息
1143
- const liveEndMsg = this.config.customLiveEnd
1220
+ const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1144
1221
  .replace('-name', username)
1145
- .replace('-time', await ctx.gi.getTimeDifference(liveTime));
1222
+ .replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null;
1146
1223
  // 更改直播时长
1147
1224
  data.live_time = liveTime;
1148
1225
  // 发送@全体成员通知
@@ -1175,20 +1252,13 @@ class ComRegister {
1175
1252
  }
1176
1253
  }
1177
1254
  }
1178
- // 定义开播通知语
1179
- const liveStartMsg = this.config.customLiveStart
1255
+ // 定义开播通知语
1256
+ const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1180
1257
  .replace('-name', username)
1181
1258
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1182
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`);
1183
- // 判断是否需要@全体成员
1184
- if (this.config.liveStartAtAll) {
1185
- // 发送@全体成员通知
1186
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg, true);
1187
- }
1188
- else {
1189
- // 发送直播通知卡片
1190
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1191
- }
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);
1192
1262
  }
1193
1263
  else { // 还在直播
1194
1264
  if (this.config.pushTime > 0) {
@@ -1201,7 +1271,7 @@ class ComRegister {
1201
1271
  const liveMsg = this.config.customLive ? this.config.customLive
1202
1272
  .replace('-name', username)
1203
1273
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1204
- .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;
1205
1275
  // 发送直播通知卡片
1206
1276
  sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1207
1277
  }
@@ -1380,7 +1450,67 @@ class ComRegister {
1380
1450
  // 订阅成功
1381
1451
  return { flag: true, msg: '用户订阅成功' };
1382
1452
  }
1383
- 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) {
1384
1514
  // 判断登录信息是否已加载完毕
1385
1515
  await this.checkIfLoginInfoIsLoaded(ctx);
1386
1516
  // 如果未登录,则直接返回
@@ -1478,6 +1608,7 @@ class ComRegister {
1478
1608
  this.logger.info(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1479
1609
  // Send msg
1480
1610
  await this.sendPrivateMsg(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
1611
+ // 直接返回
1481
1612
  return;
1482
1613
  }
1483
1614
  // 构建订阅对象
@@ -1487,19 +1618,20 @@ class ComRegister {
1487
1618
  roomId: sub.room_id,
1488
1619
  target,
1489
1620
  platform: sub.platform,
1490
- live: +sub.live === 1 ? true : false,
1491
- dynamic: +sub.dynamic === 1 ? true : false,
1621
+ live: sub.live === 1 ? true : false,
1622
+ dynamic: sub.dynamic === 1 ? true : false,
1492
1623
  liveDispose: null
1493
1624
  };
1494
1625
  // 判断是否订阅直播
1495
1626
  if (sub.live) {
1496
1627
  // 判断订阅直播数是否超过限制
1497
1628
  if (!this.config.unlockSubLimits && liveSubNum >= 3) {
1629
+ // 将live改为false
1498
1630
  subManagerItem.live = false;
1499
1631
  // log
1500
1632
  this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1501
1633
  // 发送错误消息
1502
- this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1634
+ await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1503
1635
  }
1504
1636
  else {
1505
1637
  // 直播订阅数+1
@@ -1513,18 +1645,20 @@ class ComRegister {
1513
1645
  // 保存新订阅对象
1514
1646
  this.subManager.push(subManagerItem);
1515
1647
  }
1648
+ }
1649
+ checkIfDynamicDetectIsNeeded(ctx) {
1516
1650
  // 检查是否有订阅对象需要动态监测
1517
- if (this.subManager.some(sub => sub.dynamic)) {
1518
- // 开始动态监测
1519
- if (this.config.dynamicDebugMode) {
1520
- this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), 10000);
1521
- }
1522
- else {
1523
- this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), 10000 /* this.config.dynamicLoopTime * 1000 */);
1524
- }
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);
1525
1661
  }
1526
- // 在控制台中显示订阅对象
1527
- this.updateSubNotifier(ctx);
1528
1662
  }
1529
1663
  unsubSingle(ctx, id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
1530
1664
  // 定义返回消息
@@ -1607,7 +1741,7 @@ class ComRegister {
1607
1741
  }
1608
1742
  }
1609
1743
  checkIfUserIsTheLastOneWhoSubDyn() {
1610
- if (this.subManager.some(sub => sub.dynamic)) {
1744
+ if (this.dynamicDispose && !this.subManager.some(sub => sub.dynamic)) {
1611
1745
  // 停止动态监测
1612
1746
  this.dynamicDispose();
1613
1747
  this.dynamicDispose = null;
@@ -1644,6 +1778,20 @@ class ComRegister {
1644
1778
  }
1645
1779
  (function (ComRegister) {
1646
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: 是否需要订阅直播'),
1647
1795
  master: koishi_1.Schema.object({
1648
1796
  enable: koishi_1.Schema.boolean(),
1649
1797
  platform: koishi_1.Schema.string(),
@@ -1653,7 +1801,6 @@ class ComRegister {
1653
1801
  unlockSubLimits: koishi_1.Schema.boolean().required(),
1654
1802
  automaticResend: koishi_1.Schema.boolean().required(),
1655
1803
  changeMasterInfoApi: koishi_1.Schema.boolean().required(),
1656
- liveStartAtAll: koishi_1.Schema.boolean().required(),
1657
1804
  restartPush: koishi_1.Schema.boolean().required(),
1658
1805
  pushTime: koishi_1.Schema.number().required(),
1659
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.9",
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
 
@@ -191,6 +196,21 @@
191
196
  - ver 2.0.0-alpha.7 重构:现已支持同一UP多平台推送
192
197
  - ver 2.0.0-alpha.8 新增:重新订阅提示
193
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主的动态进行推送、推送过的动态过一段时间又会再次推送
194
214
 
195
215
  ## 交流群
196
216