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 +1 -0
- package/lib/biliAPI.js +13 -0
- package/lib/comRegister.d.ts +29 -9
- package/lib/comRegister.js +349 -196
- package/lib/database.d.ts +0 -1
- package/lib/database.js +0 -1
- package/lib/generateImg.js +1 -1
- package/lib/index.d.ts +15 -0
- package/lib/index.js +20 -3
- package/package.json +1 -1
- package/{README.md → readme.md} +25 -4
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);
|
package/lib/comRegister.d.ts
CHANGED
|
@@ -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
|
-
|
|
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>,
|
|
39
|
+
sendMsgFunc: (bot: Bot<Context, any>, channelId: string, content: any) => Promise<void>;
|
|
34
40
|
constructor(ctx: Context, config: ComRegister.Config);
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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;
|
package/lib/comRegister.js
CHANGED
|
@@ -37,56 +37,9 @@ class ComRegister {
|
|
|
37
37
|
sendMsgFunc;
|
|
38
38
|
// 构造函数
|
|
39
39
|
constructor(ctx, config) {
|
|
40
|
-
|
|
41
|
-
this.
|
|
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.
|
|
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
|
-
|
|
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]
|
|
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
|
-
.
|
|
300
|
-
.
|
|
301
|
-
.
|
|
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
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
|
574
|
-
|
|
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.
|
|
660
|
+
if (target.channelIdArr[0].channelId === 'all') {
|
|
641
661
|
// 获取所有guild
|
|
642
662
|
for (const guild of (await bot.getGuildList()).data) {
|
|
643
|
-
sendArr.push(
|
|
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.
|
|
672
|
+
sendArr = target.channelIdArr;
|
|
648
673
|
}
|
|
649
|
-
//
|
|
650
|
-
|
|
651
|
-
|
|
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
|
-
//
|
|
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 =
|
|
761
|
-
const dynamicId =
|
|
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
|
-
//
|
|
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 =
|
|
944
|
-
const dynamicId =
|
|
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
|
|
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
|
-
|
|
1047
|
-
|
|
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'),
|
|
1051
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
1485
|
-
dynamic:
|
|
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
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
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
package/lib/database.js
CHANGED
package/lib/generateImg.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
361
|
+
this.ctx.setTimeout(() => {
|
|
345
362
|
try {
|
|
346
|
-
|
|
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.
|
|
379
|
+
content: '从2.0.0-alpha.9以前版本更新需重新订阅'
|
|
363
380
|
});
|
|
364
381
|
ctx.notifier.create({
|
|
365
382
|
content: '请使用Auth插件创建超级管理员账号,没有权限将无法使用该插件提供的指令。'
|
package/package.json
CHANGED
package/{README.md → readme.md}
RENAMED
|
@@ -53,15 +53,19 @@
|
|
|
53
53
|
|
|
54
54
|
订阅UP主:订阅你想要推送的UP主
|
|
55
55
|
|
|
56
|
-
- 使用指令 `bili sub <uid
|
|
56
|
+
- 使用指令 `bili sub <uid> [...groupId]` 订阅需要订阅的UP主
|
|
57
57
|
- 参数说明:
|
|
58
58
|
- `uid` 为必填参数,为 `up主` 的 `uid`
|
|
59
|
-
-
|
|
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
|
|