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 +1 -0
- package/lib/biliAPI.js +13 -0
- package/lib/comRegister.d.ts +29 -9
- package/lib/comRegister.js +348 -201
- 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} +24 -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,73 +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
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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
|
-
//
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
|
580
|
-
|
|
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.
|
|
660
|
+
if (target.channelIdArr[0].channelId === 'all') {
|
|
647
661
|
// 获取所有guild
|
|
648
662
|
for (const guild of (await bot.getGuildList()).data) {
|
|
649
|
-
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
|
+
});
|
|
650
669
|
}
|
|
651
670
|
}
|
|
652
671
|
else {
|
|
653
|
-
sendArr = target.
|
|
672
|
+
sendArr = target.channelIdArr;
|
|
654
673
|
}
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
|
|
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
|
-
//
|
|
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 =
|
|
767
|
-
const dynamicId =
|
|
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
|
-
//
|
|
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 =
|
|
950
|
-
const dynamicId =
|
|
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
|
|
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
|
-
|
|
1053
|
-
|
|
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'),
|
|
1057
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
1491
|
-
dynamic:
|
|
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
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
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
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
|
|
|
@@ -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
|
|