koishi-plugin-bilibili-notify 2.0.0 → 3.0.0-alpha.1
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 +16 -0
- package/lib/biliAPI.js +28 -0
- package/lib/blive.d.ts +23 -0
- package/lib/blive.js +74 -0
- package/lib/comRegister.d.ts +19 -1
- package/lib/comRegister.js +412 -118
- package/lib/index.d.ts +1 -0
- package/lib/index.js +13 -1
- package/package.json +2 -1
- package/readme.md +3 -1
package/lib/biliAPI.d.ts
CHANGED
|
@@ -26,6 +26,21 @@ declare class BiliAPI extends Service {
|
|
|
26
26
|
}): Promise<string>;
|
|
27
27
|
encrypt(text: string): string;
|
|
28
28
|
decrypt(text: string): string;
|
|
29
|
+
getTheUserWhoIsLiveStreaming(): Promise<{
|
|
30
|
+
count: number;
|
|
31
|
+
group: string;
|
|
32
|
+
items: [
|
|
33
|
+
{
|
|
34
|
+
face: string;
|
|
35
|
+
is_reserve_recall: boolean;
|
|
36
|
+
jump_url: string;
|
|
37
|
+
mid: number;
|
|
38
|
+
room_id: number;
|
|
39
|
+
title: string;
|
|
40
|
+
uname: string;
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
}>;
|
|
29
44
|
getLiveRoomInfoStreamKey(roomId: string): Promise<any>;
|
|
30
45
|
getServerUTCTime(): Promise<number>;
|
|
31
46
|
getTimeNow(): Promise<any>;
|
|
@@ -54,6 +69,7 @@ declare class BiliAPI extends Service {
|
|
|
54
69
|
createNewClient(): void;
|
|
55
70
|
getTimeOfUTC8(): number;
|
|
56
71
|
getCookies(): string;
|
|
72
|
+
getCookiesForHeader(): Promise<string>;
|
|
57
73
|
getLoginInfoIsLoaded(): boolean;
|
|
58
74
|
getLoginInfoFromDB(): Promise<{
|
|
59
75
|
cookies: any;
|
package/lib/biliAPI.js
CHANGED
|
@@ -34,6 +34,8 @@ const GET_LIVE_ROOM_INFO = 'https://api.live.bilibili.com/room/v1/Room/get_info'
|
|
|
34
34
|
const GET_MASTER_INFO = 'https://api.live.bilibili.com/live_user/v1/Master/info';
|
|
35
35
|
const GET_TIME_NOW = 'https://api.bilibili.com/x/report/click/now';
|
|
36
36
|
const GET_SERVER_UTC_TIME = 'https://interface.bilibili.com/serverdate.js';
|
|
37
|
+
// 最近更新UP
|
|
38
|
+
const GET_LATEST_UPDATED_UPS = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/portal';
|
|
37
39
|
// 操作
|
|
38
40
|
const MODIFY_RELATION = 'https://api.bilibili.com/x/relation/modify';
|
|
39
41
|
const CREATE_GROUP = 'https://api.bilibili.com/x/relation/tag/create';
|
|
@@ -105,6 +107,17 @@ class BiliAPI extends koishi_1.Service {
|
|
|
105
107
|
return decrypted.toString();
|
|
106
108
|
}
|
|
107
109
|
// BA API
|
|
110
|
+
async getTheUserWhoIsLiveStreaming() {
|
|
111
|
+
try {
|
|
112
|
+
// 获取直播间信息流密钥
|
|
113
|
+
const { data: { live_users } } = await this.client.get(GET_LATEST_UPDATED_UPS);
|
|
114
|
+
// 返回data
|
|
115
|
+
return live_users;
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
throw new Error('网络异常,本次请求失败!');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
108
121
|
async getLiveRoomInfoStreamKey(roomId) {
|
|
109
122
|
try {
|
|
110
123
|
// 获取直播间信息流密钥
|
|
@@ -375,6 +388,21 @@ class BiliAPI extends koishi_1.Service {
|
|
|
375
388
|
const cookies = JSON.stringify(this.jar.serializeSync().cookies);
|
|
376
389
|
return cookies;
|
|
377
390
|
}
|
|
391
|
+
async getCookiesForHeader() {
|
|
392
|
+
try {
|
|
393
|
+
// 获取cookies对象
|
|
394
|
+
const cookies = this.jar.serializeSync().cookies;
|
|
395
|
+
// 将每个 cookie 对象转换为 "key=value" 形式,并用 "; " 连接起来
|
|
396
|
+
const cookieHeader = cookies
|
|
397
|
+
.map(cookie => `${cookie.key}=${cookie.value}`)
|
|
398
|
+
.join('; ');
|
|
399
|
+
return cookieHeader;
|
|
400
|
+
}
|
|
401
|
+
catch (e) {
|
|
402
|
+
console.error("无效的 JSON 格式:", e);
|
|
403
|
+
return "";
|
|
404
|
+
}
|
|
405
|
+
}
|
|
378
406
|
getLoginInfoIsLoaded() {
|
|
379
407
|
return this.loginInfoIsLoaded;
|
|
380
408
|
}
|
package/lib/blive.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Awaitable, Context, Schema, Service } from "koishi";
|
|
2
|
+
import { type MsgHandler } from 'blive-message-listener';
|
|
3
|
+
declare module 'koishi' {
|
|
4
|
+
interface Context {
|
|
5
|
+
bl: BLive;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
declare class BLive extends Service {
|
|
9
|
+
static inject: string[];
|
|
10
|
+
private listenerRecord;
|
|
11
|
+
private timerRecord;
|
|
12
|
+
constructor(ctx: Context);
|
|
13
|
+
protected stop(): Awaitable<void>;
|
|
14
|
+
startLiveRoomListener(roomId: string, handler: MsgHandler, pushOnceEveryTens: () => void): Promise<void>;
|
|
15
|
+
closeListener(roomId: string): void;
|
|
16
|
+
}
|
|
17
|
+
declare namespace BLive {
|
|
18
|
+
interface Config {
|
|
19
|
+
danmakuPushTime: number;
|
|
20
|
+
}
|
|
21
|
+
const Config: Schema<Config>;
|
|
22
|
+
}
|
|
23
|
+
export default BLive;
|
package/lib/blive.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const koishi_1 = require("koishi");
|
|
4
|
+
const blive_message_listener_1 = require("blive-message-listener");
|
|
5
|
+
class BLive extends koishi_1.Service {
|
|
6
|
+
// 必要服务
|
|
7
|
+
static inject = ['ba'];
|
|
8
|
+
// 定义类属性
|
|
9
|
+
listenerRecord = {};
|
|
10
|
+
timerRecord = {};
|
|
11
|
+
constructor(ctx) {
|
|
12
|
+
super(ctx, 'bl');
|
|
13
|
+
}
|
|
14
|
+
// 注册插件dispose逻辑
|
|
15
|
+
stop() {
|
|
16
|
+
// 清除所有监听器
|
|
17
|
+
for (const key of Object.keys(this.listenerRecord)) {
|
|
18
|
+
this.closeListener(key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async startLiveRoomListener(roomId, handler, pushOnceEveryTens) {
|
|
22
|
+
// 获取cookieStr
|
|
23
|
+
const cookiesStr = await this.ctx.ba.getCookiesForHeader();
|
|
24
|
+
// 获取自身信息
|
|
25
|
+
const mySelfInfo = await this.ctx.ba.getMyselfInfo();
|
|
26
|
+
// 创建实例并保存到Record中
|
|
27
|
+
this.listenerRecord[roomId] = (0, blive_message_listener_1.startListen)(parseInt(roomId), handler, {
|
|
28
|
+
ws: {
|
|
29
|
+
headers: {
|
|
30
|
+
Cookie: cookiesStr
|
|
31
|
+
},
|
|
32
|
+
uid: mySelfInfo.data.mid
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// 默认30s推送一次弹幕消息到群组并将dispose函数保存到Record中
|
|
36
|
+
this.timerRecord[roomId] = this.ctx.setInterval(pushOnceEveryTens, this.config.danmakuPushTime * 1000 * 60);
|
|
37
|
+
}
|
|
38
|
+
closeListener(roomId) {
|
|
39
|
+
// 判断直播间监听器是否关闭
|
|
40
|
+
if (!this.listenerRecord || !this.listenerRecord[roomId] || !this.listenerRecord[roomId].closed) {
|
|
41
|
+
// 输出logger
|
|
42
|
+
this.logger.info('直播间监听器无需关闭');
|
|
43
|
+
}
|
|
44
|
+
// 判断消息发送定时器是否关闭
|
|
45
|
+
if (!this.timerRecord || !this.timerRecord[roomId]) {
|
|
46
|
+
// 输出logger
|
|
47
|
+
this.logger.info('消息发送定时器无需关闭');
|
|
48
|
+
}
|
|
49
|
+
// 关闭直播间监听器
|
|
50
|
+
this.listenerRecord[roomId].close();
|
|
51
|
+
// 关闭消息发送定时器
|
|
52
|
+
this.timerRecord[roomId]();
|
|
53
|
+
// 判断是否关闭成功
|
|
54
|
+
if (this.listenerRecord[roomId].closed) {
|
|
55
|
+
// 删除直播间监听器
|
|
56
|
+
delete this.listenerRecord[roomId];
|
|
57
|
+
// 删除消息发送定时器
|
|
58
|
+
delete this.timerRecord[roomId];
|
|
59
|
+
// 输出logger
|
|
60
|
+
this.logger.info('直播间监听已关闭');
|
|
61
|
+
// 直接返回
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// 未关闭成功
|
|
65
|
+
this.logger.warn('直播间监听未成功关闭');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
69
|
+
(function (BLive) {
|
|
70
|
+
BLive.Config = koishi_1.Schema.object({
|
|
71
|
+
danmakuPushTime: koishi_1.Schema.number().required()
|
|
72
|
+
});
|
|
73
|
+
})(BLive || (BLive = {}));
|
|
74
|
+
exports.default = BLive;
|
package/lib/comRegister.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
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
|
+
declare enum LiveType {
|
|
5
|
+
NotLiveBroadcast = 0,
|
|
6
|
+
StartBroadcasting = 1,
|
|
7
|
+
LiveBroadcast = 2,
|
|
8
|
+
StopBroadcast = 3
|
|
9
|
+
}
|
|
4
10
|
type ChannelIdArr = Array<{
|
|
5
11
|
channelId: string;
|
|
6
12
|
dynamic: boolean;
|
|
@@ -47,7 +53,19 @@ declare class ComRegister {
|
|
|
47
53
|
sendMsg(ctx: Context, targets: Target, content: any, live?: boolean): Promise<void>;
|
|
48
54
|
dynamicDetect(ctx: Context): () => Promise<void>;
|
|
49
55
|
debug_dynamicDetect(ctx: Context): () => Promise<void>;
|
|
50
|
-
|
|
56
|
+
sendLiveNotifyCard(ctx: Context, info: {
|
|
57
|
+
username: string;
|
|
58
|
+
userface: string;
|
|
59
|
+
target: Target;
|
|
60
|
+
data: any;
|
|
61
|
+
}, liveType: LiveType, liveNotifyMsg?: string): Promise<void>;
|
|
62
|
+
useMasterInfo(ctx: Context, uid: string): Promise<{
|
|
63
|
+
username: string;
|
|
64
|
+
userface: string;
|
|
65
|
+
}>;
|
|
66
|
+
useLiveRoomInfo(ctx: Context, roomId: string): Promise<any>;
|
|
67
|
+
liveDetectWithAPI(ctx: Context): Promise<() => Promise<void>>;
|
|
68
|
+
liveDetectWithListener(ctx: Context, roomId: string, target: Target): void;
|
|
51
69
|
subShow(): string;
|
|
52
70
|
checkIfNeedSub(liveSub: boolean, dynamicSub: boolean, session: Session, liveRoomData: any): Promise<Array<boolean>>;
|
|
53
71
|
updateSubNotifier(ctx: Context): void;
|
package/lib/comRegister.js
CHANGED
|
@@ -18,7 +18,7 @@ var LiveType;
|
|
|
18
18
|
LiveType[LiveType["StopBroadcast"] = 3] = "StopBroadcast";
|
|
19
19
|
})(LiveType || (LiveType = {}));
|
|
20
20
|
class ComRegister {
|
|
21
|
-
static inject = ['ba', 'gi', 'database', 'sm'];
|
|
21
|
+
static inject = ['ba', 'gi', 'database', 'bl', 'sm'];
|
|
22
22
|
qqRelatedBotList = ['qq', 'onebot', 'red', 'satori', 'chronocat'];
|
|
23
23
|
logger;
|
|
24
24
|
config;
|
|
@@ -430,8 +430,8 @@ class ComRegister {
|
|
|
430
430
|
let liveDispose;
|
|
431
431
|
// 订阅直播
|
|
432
432
|
if (liveMsg) {
|
|
433
|
-
//
|
|
434
|
-
|
|
433
|
+
// 连接到服务器
|
|
434
|
+
this.liveDetectWithListener(ctx, roomId, target);
|
|
435
435
|
// 发送订阅消息通知
|
|
436
436
|
await session.send(`订阅${userData.info.uname}直播通知`);
|
|
437
437
|
}
|
|
@@ -1075,137 +1075,148 @@ class ComRegister {
|
|
|
1075
1075
|
}
|
|
1076
1076
|
};
|
|
1077
1077
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
let
|
|
1082
|
-
let
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
for (let i = 0; i < attempts; i++) {
|
|
1095
|
-
try {
|
|
1096
|
-
// 获取直播通知卡片
|
|
1097
|
-
const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
|
|
1098
|
-
// 赋值
|
|
1099
|
-
pic = picv;
|
|
1100
|
-
buffer = bufferv;
|
|
1101
|
-
// 成功则跳出循环
|
|
1102
|
-
break;
|
|
1103
|
-
}
|
|
1104
|
-
catch (e) {
|
|
1105
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
1106
|
-
this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
|
|
1107
|
-
// 发送私聊消息并重启服务
|
|
1108
|
-
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1078
|
+
// 定义发送直播通知卡片方法
|
|
1079
|
+
async sendLiveNotifyCard(ctx, info, liveType, liveNotifyMsg) {
|
|
1080
|
+
// 定义变量
|
|
1081
|
+
let pic;
|
|
1082
|
+
let buffer;
|
|
1083
|
+
// 多次尝试生成图片
|
|
1084
|
+
const attempts = 3;
|
|
1085
|
+
for (let i = 0; i < attempts; i++) {
|
|
1086
|
+
try {
|
|
1087
|
+
// 获取直播通知卡片
|
|
1088
|
+
const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(info.data, info.username, info.userface, liveType);
|
|
1089
|
+
// 赋值
|
|
1090
|
+
pic = picv;
|
|
1091
|
+
buffer = bufferv;
|
|
1092
|
+
// 成功则跳出循环
|
|
1093
|
+
break;
|
|
1111
1094
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
return await this.sendMsg(ctx, target, pic + (liveNotifyMsg ?? ''), true);
|
|
1095
|
+
catch (e) {
|
|
1096
|
+
if (i === attempts - 1) { // 已尝试三次
|
|
1097
|
+
this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
|
|
1098
|
+
// 发送私聊消息并重启服务
|
|
1099
|
+
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1118
1100
|
}
|
|
1119
|
-
// 正常不需要艾特全体成员
|
|
1120
|
-
return await this.sendMsg(ctx, target, pic + (liveNotifyMsg ?? ''));
|
|
1121
1101
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1102
|
+
}
|
|
1103
|
+
// 推送直播信息
|
|
1104
|
+
// pic 存在,使用的是render模式
|
|
1105
|
+
if (pic) {
|
|
1124
1106
|
// 只有在开播时才艾特全体成员
|
|
1125
1107
|
if (liveType === LiveType.StartBroadcasting) {
|
|
1126
|
-
return await this.sendMsg(ctx, target,
|
|
1108
|
+
return await this.sendMsg(ctx, info.target, pic + (liveNotifyMsg ?? ''), true);
|
|
1127
1109
|
}
|
|
1128
1110
|
// 正常不需要艾特全体成员
|
|
1129
|
-
return await this.sendMsg(ctx, target,
|
|
1130
|
-
};
|
|
1131
|
-
// 定义获取主播信息方法
|
|
1132
|
-
let useMasterInfo;
|
|
1133
|
-
if (this.config.changeMasterInfoApi) {
|
|
1134
|
-
useMasterInfo = async (uid) => {
|
|
1135
|
-
const { data } = await ctx.ba.getUserInfo(uid);
|
|
1136
|
-
username = data.name;
|
|
1137
|
-
userface = data.face;
|
|
1138
|
-
};
|
|
1111
|
+
return await this.sendMsg(ctx, info.target, pic + (liveNotifyMsg ?? ''));
|
|
1139
1112
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1113
|
+
// pic不存在,说明使用的是page模式
|
|
1114
|
+
const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg || ''] });
|
|
1115
|
+
// 只有在开播时才艾特全体成员
|
|
1116
|
+
if (liveType === LiveType.StartBroadcasting) {
|
|
1117
|
+
return await this.sendMsg(ctx, info.target, msg, true);
|
|
1118
|
+
}
|
|
1119
|
+
// 正常不需要艾特全体成员
|
|
1120
|
+
return await this.sendMsg(ctx, info.target, msg);
|
|
1121
|
+
}
|
|
1122
|
+
// 定义获取主播信息方法
|
|
1123
|
+
async useMasterInfo(ctx, uid) {
|
|
1124
|
+
const { data: { info } } = await ctx.ba.getMasterInfo(uid);
|
|
1125
|
+
return { username: info.name, userface: info.face };
|
|
1126
|
+
}
|
|
1127
|
+
async useLiveRoomInfo(ctx, roomId) {
|
|
1128
|
+
// 发送请求获取直播间信息
|
|
1129
|
+
let content;
|
|
1130
|
+
const attempts = 3;
|
|
1131
|
+
for (let i = 0; i < attempts; i++) {
|
|
1132
|
+
try {
|
|
1133
|
+
// 发送请求获取room信息
|
|
1134
|
+
content = await ctx.ba.getLiveRoomInfo(roomId);
|
|
1135
|
+
// 成功则跳出循环
|
|
1136
|
+
break;
|
|
1137
|
+
}
|
|
1138
|
+
catch (e) {
|
|
1139
|
+
this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
|
|
1140
|
+
if (i === attempts - 1) { // 已尝试三次
|
|
1141
|
+
// 发送私聊消息并重启服务
|
|
1142
|
+
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1146
1145
|
}
|
|
1146
|
+
return content.data;
|
|
1147
|
+
}
|
|
1148
|
+
/* liveDetect(
|
|
1149
|
+
ctx: Context,
|
|
1150
|
+
roomId: string,
|
|
1151
|
+
target: Target
|
|
1152
|
+
) {
|
|
1153
|
+
let firstSubscription: boolean = true;
|
|
1154
|
+
let timer: number = 0;
|
|
1155
|
+
let open: boolean = false;
|
|
1156
|
+
let liveTime: string;
|
|
1157
|
+
let username: string
|
|
1158
|
+
let userface: string
|
|
1159
|
+
// 相当于锁的作用,防止上一个循环没处理完
|
|
1160
|
+
let flag: boolean = true
|
|
1161
|
+
|
|
1147
1162
|
return async () => {
|
|
1148
1163
|
// 如果flag为false则说明前面的代码还未执行完,则直接返回
|
|
1149
|
-
if (!flag)
|
|
1150
|
-
|
|
1151
|
-
flag = false;
|
|
1164
|
+
if (!flag) return
|
|
1165
|
+
flag = false
|
|
1152
1166
|
// 无论是否执行成功都要释放锁
|
|
1153
1167
|
try {
|
|
1154
1168
|
// 发送请求检测直播状态
|
|
1155
|
-
let content
|
|
1156
|
-
const attempts = 3
|
|
1169
|
+
let content: any
|
|
1170
|
+
const attempts = 3
|
|
1157
1171
|
for (let i = 0; i < attempts; i++) {
|
|
1158
1172
|
try {
|
|
1159
1173
|
// 发送请求获取room信息
|
|
1160
|
-
content = await ctx.ba.getLiveRoomInfo(roomId)
|
|
1174
|
+
content = await ctx.ba.getLiveRoomInfo(roomId)
|
|
1161
1175
|
// 成功则跳出循环
|
|
1162
|
-
break
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
|
|
1176
|
+
break
|
|
1177
|
+
} catch (e) {
|
|
1178
|
+
this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message)
|
|
1166
1179
|
if (i === attempts - 1) { // 已尝试三次
|
|
1167
1180
|
// 发送私聊消息并重启服务
|
|
1168
|
-
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1181
|
+
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1169
1182
|
}
|
|
1170
1183
|
}
|
|
1171
1184
|
}
|
|
1172
|
-
const { data } = content
|
|
1185
|
+
const { data } = content
|
|
1173
1186
|
// 判断是否是第一次订阅
|
|
1174
1187
|
if (firstSubscription) {
|
|
1175
|
-
firstSubscription = false
|
|
1188
|
+
firstSubscription = false
|
|
1176
1189
|
// 获取主播信息
|
|
1177
|
-
const attempts = 3
|
|
1190
|
+
const attempts = 3
|
|
1178
1191
|
for (let i = 0; i < attempts; i++) {
|
|
1179
1192
|
try {
|
|
1180
1193
|
// 发送请求获取主播信息
|
|
1181
|
-
await useMasterInfo(data.uid)
|
|
1194
|
+
await useMasterInfo(data.uid)
|
|
1182
1195
|
// 成功则跳出循环
|
|
1183
|
-
break
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
this.logger.error('liveDetect getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
1196
|
+
break
|
|
1197
|
+
} catch (e) {
|
|
1198
|
+
this.logger.error('liveDetect getMasterInfo() 发生了错误,错误为:' + e.message)
|
|
1187
1199
|
if (i === attempts - 1) { // 已尝试三次
|
|
1188
1200
|
// 发送私聊消息并重启服务
|
|
1189
|
-
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1201
|
+
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1190
1202
|
}
|
|
1191
1203
|
}
|
|
1192
1204
|
}
|
|
1193
1205
|
// 判断直播状态
|
|
1194
1206
|
if (data.live_status === 1) { // 当前正在直播
|
|
1195
1207
|
// 设置开播时间
|
|
1196
|
-
liveTime = data.live_time
|
|
1208
|
+
liveTime = data.live_time
|
|
1197
1209
|
// 设置直播中消息
|
|
1198
1210
|
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1199
1211
|
.replace('-name', username)
|
|
1200
1212
|
.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
|
|
1213
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
|
|
1202
1214
|
// 发送直播通知卡片
|
|
1203
|
-
if (this.config.restartPush)
|
|
1204
|
-
sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
|
|
1215
|
+
if (this.config.restartPush) sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg)
|
|
1205
1216
|
// 改变开播状态
|
|
1206
|
-
open = true
|
|
1217
|
+
open = true
|
|
1207
1218
|
} // 未开播,直接返回
|
|
1208
|
-
return
|
|
1219
|
+
return
|
|
1209
1220
|
}
|
|
1210
1221
|
// 检查直播状态
|
|
1211
1222
|
switch (data.live_status) {
|
|
@@ -1213,67 +1224,65 @@ class ComRegister {
|
|
|
1213
1224
|
case 2: { // 状态 0 和 2 说明未开播
|
|
1214
1225
|
if (open) { // 之前开播,现在下播了
|
|
1215
1226
|
// 更改直播状态
|
|
1216
|
-
open = false
|
|
1227
|
+
open = false
|
|
1217
1228
|
// 下播了将定时器清零
|
|
1218
|
-
timer = 0
|
|
1229
|
+
timer = 0
|
|
1219
1230
|
// 定义下播通知消息
|
|
1220
1231
|
const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
|
|
1221
1232
|
.replace('-name', username)
|
|
1222
|
-
.replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null
|
|
1233
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null
|
|
1223
1234
|
// 更改直播时长
|
|
1224
|
-
data.live_time = liveTime
|
|
1225
|
-
//
|
|
1226
|
-
await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg)
|
|
1235
|
+
data.live_time = liveTime
|
|
1236
|
+
// 推送下播通知
|
|
1237
|
+
await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg)
|
|
1227
1238
|
}
|
|
1228
1239
|
// 未进循环,还未开播,继续循环
|
|
1229
|
-
break
|
|
1240
|
+
break
|
|
1230
1241
|
}
|
|
1231
1242
|
case 1: {
|
|
1232
1243
|
if (!open) { // 之前未开播,现在开播了
|
|
1233
1244
|
// 更改直播状态
|
|
1234
|
-
open = true
|
|
1245
|
+
open = true
|
|
1235
1246
|
// 设置开播时间
|
|
1236
|
-
liveTime = data.live_time
|
|
1247
|
+
liveTime = data.live_time
|
|
1237
1248
|
// 获取主播信息
|
|
1238
|
-
const attempts = 3
|
|
1249
|
+
const attempts = 3
|
|
1239
1250
|
for (let i = 0; i < attempts; i++) {
|
|
1240
1251
|
try {
|
|
1241
1252
|
// 主播信息不会变,开播时刷新一次即可
|
|
1242
1253
|
// 发送请求获取主播信息
|
|
1243
|
-
await useMasterInfo(data.uid)
|
|
1254
|
+
await useMasterInfo(data.uid)
|
|
1244
1255
|
// 成功则跳出循环
|
|
1245
|
-
break
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
this.logger.error('liveDetect open getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
1256
|
+
break
|
|
1257
|
+
} catch (e) {
|
|
1258
|
+
this.logger.error('liveDetect open getMasterInfo() 发生了错误,错误为:' + e.message)
|
|
1249
1259
|
if (i === attempts - 1) { // 已尝试三次
|
|
1250
1260
|
// 发送私聊消息并重启服务
|
|
1251
|
-
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1261
|
+
return await this.sendPrivateMsgAndStopService(ctx)
|
|
1252
1262
|
}
|
|
1253
1263
|
}
|
|
1254
1264
|
}
|
|
1255
|
-
// 定义开播通知语
|
|
1265
|
+
// 定义开播通知语
|
|
1256
1266
|
const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
|
|
1257
1267
|
.replace('-name', username)
|
|
1258
1268
|
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1259
|
-
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
|
|
1269
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
|
|
1260
1270
|
// 发送消息
|
|
1261
|
-
await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg)
|
|
1262
|
-
}
|
|
1263
|
-
else { // 还在直播
|
|
1271
|
+
await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg)
|
|
1272
|
+
} else { // 还在直播
|
|
1264
1273
|
if (this.config.pushTime > 0) {
|
|
1265
|
-
timer
|
|
1274
|
+
timer++
|
|
1266
1275
|
// 开始记录时间
|
|
1267
1276
|
if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
|
|
1268
1277
|
// 到时间重新计时
|
|
1269
|
-
timer = 0
|
|
1278
|
+
timer = 0
|
|
1270
1279
|
// 定义直播中通知消息
|
|
1271
1280
|
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1272
1281
|
.replace('-name', username)
|
|
1273
1282
|
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1274
|
-
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
|
|
1283
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
|
|
1275
1284
|
// 发送直播通知卡片
|
|
1276
|
-
sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg)
|
|
1285
|
+
sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg)
|
|
1277
1286
|
}
|
|
1278
1287
|
}
|
|
1279
1288
|
// 否则继续循环
|
|
@@ -1281,12 +1290,299 @@ class ComRegister {
|
|
|
1281
1290
|
}
|
|
1282
1291
|
}
|
|
1283
1292
|
}
|
|
1293
|
+
finally {
|
|
1294
|
+
// 执行完方法体不论如何都把flag设置为true
|
|
1295
|
+
flag = true
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
} */
|
|
1299
|
+
async liveDetectWithAPI(ctx) {
|
|
1300
|
+
// 定义变量:第一次订阅
|
|
1301
|
+
let firstSubscription = true;
|
|
1302
|
+
// 定义变量:timer计时器
|
|
1303
|
+
let timer = 0;
|
|
1304
|
+
// 相当于锁的作用,防止上一个循环没处理完
|
|
1305
|
+
let flag = true;
|
|
1306
|
+
// 定义订阅对象Record 0未开播 1正在直播 2轮播中
|
|
1307
|
+
const liveRecord = {};
|
|
1308
|
+
// 初始化subRecord
|
|
1309
|
+
this.subManager.forEach(sub => {
|
|
1310
|
+
// 判断是否订阅直播
|
|
1311
|
+
if (sub.live) {
|
|
1312
|
+
// 将该订阅添加到subRecord中
|
|
1313
|
+
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
// 定义函数: 发送请求获取直播状态
|
|
1317
|
+
const useLiveStatus = async (roomId) => {
|
|
1318
|
+
let content;
|
|
1319
|
+
const attempts = 3;
|
|
1320
|
+
for (let i = 0; i < attempts; i++) {
|
|
1321
|
+
try {
|
|
1322
|
+
// 发送请求获取room信息
|
|
1323
|
+
content = await ctx.ba.getLiveRoomInfo(roomId);
|
|
1324
|
+
// 成功则跳出循环
|
|
1325
|
+
break;
|
|
1326
|
+
}
|
|
1327
|
+
catch (e) {
|
|
1328
|
+
this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
|
|
1329
|
+
if (i === attempts - 1) { // 已尝试三次
|
|
1330
|
+
// 发送私聊消息并重启服务
|
|
1331
|
+
return await this.sendPrivateMsgAndStopService(ctx);
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
// 返回data
|
|
1336
|
+
return content.data;
|
|
1337
|
+
};
|
|
1338
|
+
return async () => {
|
|
1339
|
+
// 如果flag为false则说明前面的代码还未执行完,则直接返回
|
|
1340
|
+
if (!flag)
|
|
1341
|
+
return;
|
|
1342
|
+
// 将标志位置为false
|
|
1343
|
+
flag = false;
|
|
1344
|
+
try {
|
|
1345
|
+
// 获取正在直播对象
|
|
1346
|
+
const liveUsers = await ctx.ba.getTheUserWhoIsLiveStreaming();
|
|
1347
|
+
// 判断是否是第一次订阅
|
|
1348
|
+
if (firstSubscription) {
|
|
1349
|
+
// 将第一次订阅置为false
|
|
1350
|
+
firstSubscription = false;
|
|
1351
|
+
// 先判断是否有UP主正在直播
|
|
1352
|
+
if (liveUsers.count > 0) {
|
|
1353
|
+
// 遍历liveUsers
|
|
1354
|
+
liveUsers.items.forEach(async (item) => {
|
|
1355
|
+
// 判断是否有订阅对象正在直播
|
|
1356
|
+
if (liveRecord[item.mid]) {
|
|
1357
|
+
// 获取当前用户直播间信息
|
|
1358
|
+
const data = await useLiveStatus(item.room_id.toString());
|
|
1359
|
+
// 设置开播时间
|
|
1360
|
+
liveRecord[item.mid].liveTime = data.live_time;
|
|
1361
|
+
// 设置直播中消息
|
|
1362
|
+
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1363
|
+
.replace('-name', item.uname)
|
|
1364
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1365
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1366
|
+
// 发送直播通知卡片
|
|
1367
|
+
if (this.config.restartPush)
|
|
1368
|
+
this.sendLiveNotifyCard(ctx, {
|
|
1369
|
+
username: item.uname,
|
|
1370
|
+
userface: item.face,
|
|
1371
|
+
target: liveRecord[item.mid].target,
|
|
1372
|
+
data
|
|
1373
|
+
}, LiveType.LiveBroadcast, liveMsg);
|
|
1374
|
+
// 改变开播状态
|
|
1375
|
+
liveRecord[item.mid].liveStatus = 1;
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
// 没有正在直播的订阅对象,直接返回
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
// 获取当前订阅直播的数量
|
|
1383
|
+
const currentLiveSubs = this.subManager.filter(sub => sub.live);
|
|
1384
|
+
// 获取当前liveRecord里的订阅数量
|
|
1385
|
+
const currentLiveRecordKeys = Object.keys(liveRecord);
|
|
1386
|
+
// 判断是否能匹配双方数量
|
|
1387
|
+
if (currentLiveRecordKeys.length < currentLiveSubs.length) {
|
|
1388
|
+
// 遍历currentLiveSubs
|
|
1389
|
+
for (const sub of currentLiveSubs) {
|
|
1390
|
+
// 判断liveRecord中缺少了哪些订阅
|
|
1391
|
+
if (!liveRecord[sub.uid]) {
|
|
1392
|
+
// 获取当前用户直播间信息
|
|
1393
|
+
const data = await useLiveStatus(sub.roomId.toString());
|
|
1394
|
+
switch (data.live_status) {
|
|
1395
|
+
case 0:
|
|
1396
|
+
case 2: { // 未开播
|
|
1397
|
+
// 添加到liveRecord中
|
|
1398
|
+
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1399
|
+
// break
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1402
|
+
case 1: { //正在直播
|
|
1403
|
+
// 添加到liveRecord中
|
|
1404
|
+
liveRecord[sub.uid] = { liveStatus: 1, liveTime: data.live_time, target: sub.target };
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
if (currentLiveRecordKeys.length > currentLiveSubs.length) {
|
|
1411
|
+
// 创建Set
|
|
1412
|
+
const setCurrentLiveSubs = new Set(currentLiveSubs.map(sub => sub.uid));
|
|
1413
|
+
// 找出 currentLiveRecordKeys中比currentLiveSubs 多的元素
|
|
1414
|
+
const extraInCurrentLiveSubs = currentLiveRecordKeys.filter(key => !setCurrentLiveSubs.has(key));
|
|
1415
|
+
// 遍历 extraInCurrentLiveSubs
|
|
1416
|
+
for (const subUID of extraInCurrentLiveSubs) {
|
|
1417
|
+
// 删除记录
|
|
1418
|
+
delete liveRecord[subUID];
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
// 遍历liveUsers
|
|
1422
|
+
liveUsers.items.forEach(async (item) => {
|
|
1423
|
+
// 判断是否有正在直播的订阅对象
|
|
1424
|
+
if (liveRecord[item.mid]) { // 有正在直播的订阅对象
|
|
1425
|
+
// 获取当前用户直播间信息
|
|
1426
|
+
const data = await useLiveStatus(item.room_id.toString());
|
|
1427
|
+
// 判断开播状态
|
|
1428
|
+
switch (liveRecord[item.mid].liveStatus) {
|
|
1429
|
+
case 0: { // 之前未开播,现在开播了
|
|
1430
|
+
// 设置开播时间
|
|
1431
|
+
liveRecord[item.mid].liveTime = data.live_time;
|
|
1432
|
+
// 定义开播通知语
|
|
1433
|
+
const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
|
|
1434
|
+
.replace('-name', item.uname)
|
|
1435
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1436
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1437
|
+
// 发送直播通知卡片
|
|
1438
|
+
if (this.config.restartPush)
|
|
1439
|
+
this.sendLiveNotifyCard(ctx, {
|
|
1440
|
+
username: item.uname,
|
|
1441
|
+
userface: item.face,
|
|
1442
|
+
target: liveRecord[item.mid].target,
|
|
1443
|
+
data
|
|
1444
|
+
}, LiveType.LiveBroadcast, liveStartMsg);
|
|
1445
|
+
// 改变开播状态
|
|
1446
|
+
liveRecord[item.mid].liveStatus = 1;
|
|
1447
|
+
// 结束
|
|
1448
|
+
break;
|
|
1449
|
+
}
|
|
1450
|
+
case 1: { // 仍在直播
|
|
1451
|
+
if (this.config.pushTime > 0) {
|
|
1452
|
+
timer++;
|
|
1453
|
+
// 开始记录时间
|
|
1454
|
+
if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
|
|
1455
|
+
// 到时间重新计时
|
|
1456
|
+
timer = 0;
|
|
1457
|
+
// 定义直播中通知消息
|
|
1458
|
+
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1459
|
+
.replace('-name', item.uname)
|
|
1460
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1461
|
+
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1462
|
+
// 发送直播通知卡片
|
|
1463
|
+
this.sendLiveNotifyCard(ctx, {
|
|
1464
|
+
username: item.uname,
|
|
1465
|
+
userface: item.face,
|
|
1466
|
+
target: liveRecord[item.mid].target,
|
|
1467
|
+
data
|
|
1468
|
+
}, LiveType.LiveBroadcast, liveMsg);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1284
1476
|
finally {
|
|
1285
1477
|
// 执行完方法体不论如何都把flag设置为true
|
|
1286
1478
|
flag = true;
|
|
1287
1479
|
}
|
|
1288
1480
|
};
|
|
1289
1481
|
}
|
|
1482
|
+
liveDetectWithListener(ctx, roomId, target) {
|
|
1483
|
+
// 定义开播时间
|
|
1484
|
+
let liveTime;
|
|
1485
|
+
// 定义定时推送定时器
|
|
1486
|
+
let pushAtTimeTimer;
|
|
1487
|
+
// 定义弹幕存放数组
|
|
1488
|
+
const currentLiveDanmakuArr = [];
|
|
1489
|
+
const temporaryLiveDanmakuArr = [];
|
|
1490
|
+
// 定义定时推送函数
|
|
1491
|
+
const pushAtTime = async () => {
|
|
1492
|
+
// 获取直播间信息
|
|
1493
|
+
const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
|
|
1494
|
+
// 获取主播信息
|
|
1495
|
+
const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
|
|
1496
|
+
// 定义直播中通知消息
|
|
1497
|
+
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1498
|
+
.replace('-name', masterInfo.username)
|
|
1499
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1500
|
+
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1501
|
+
// 发送直播通知卡片
|
|
1502
|
+
await this.sendLiveNotifyCard(liveRoomInfo, {
|
|
1503
|
+
username: masterInfo.username,
|
|
1504
|
+
userface: masterInfo.userface,
|
|
1505
|
+
target,
|
|
1506
|
+
data: liveRoomInfo
|
|
1507
|
+
}, LiveType.LiveBroadcast, liveMsg);
|
|
1508
|
+
};
|
|
1509
|
+
// 定义10秒推送函数
|
|
1510
|
+
const pushOnceEveryTenS = () => {
|
|
1511
|
+
// 判断数组是否有内容
|
|
1512
|
+
if (temporaryLiveDanmakuArr.length > 0) {
|
|
1513
|
+
// 发送消息
|
|
1514
|
+
this.sendMsg(ctx, target, temporaryLiveDanmakuArr.join('\n'));
|
|
1515
|
+
// 将临时消息数组清空
|
|
1516
|
+
temporaryLiveDanmakuArr.length = 0;
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
// 构建消息处理函数
|
|
1520
|
+
const handler = {
|
|
1521
|
+
onOpen: () => {
|
|
1522
|
+
this.logger.info('直播间连接成功');
|
|
1523
|
+
},
|
|
1524
|
+
onClose: () => {
|
|
1525
|
+
this.logger.info('直播间连接已断开');
|
|
1526
|
+
},
|
|
1527
|
+
onIncomeDanmu: ({ body }) => {
|
|
1528
|
+
// 处理消息,只需要UP主名字和消息内容
|
|
1529
|
+
const content = `${body.user.uname}:${body.content}`;
|
|
1530
|
+
// 保存消息到数组
|
|
1531
|
+
currentLiveDanmakuArr.push(content);
|
|
1532
|
+
temporaryLiveDanmakuArr.push(content);
|
|
1533
|
+
},
|
|
1534
|
+
onIncomeSuperChat: (msg) => {
|
|
1535
|
+
console.log(msg.id, msg.body);
|
|
1536
|
+
},
|
|
1537
|
+
onLiveStart: async () => {
|
|
1538
|
+
// 获取直播间信息
|
|
1539
|
+
const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
|
|
1540
|
+
// 获取主播信息
|
|
1541
|
+
const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
|
|
1542
|
+
// 定义下播通知消息
|
|
1543
|
+
const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
|
|
1544
|
+
.replace('-name', masterInfo.username)
|
|
1545
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null;
|
|
1546
|
+
// 更改直播时长
|
|
1547
|
+
liveRoomInfo.live_time = liveTime;
|
|
1548
|
+
// 推送下播通知
|
|
1549
|
+
await this.sendLiveNotifyCard(liveRoomInfo, {
|
|
1550
|
+
username: masterInfo.username,
|
|
1551
|
+
userface: masterInfo.userface,
|
|
1552
|
+
target,
|
|
1553
|
+
data: liveRoomInfo
|
|
1554
|
+
}, LiveType.StopBroadcast, liveEndMsg);
|
|
1555
|
+
// 关闭定时器
|
|
1556
|
+
pushAtTimeTimer();
|
|
1557
|
+
// 定时器变量置空
|
|
1558
|
+
pushAtTimeTimer = null;
|
|
1559
|
+
},
|
|
1560
|
+
onLiveEnd: async () => {
|
|
1561
|
+
// 获取直播间消息
|
|
1562
|
+
const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
|
|
1563
|
+
// 获取主播信息
|
|
1564
|
+
const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
|
|
1565
|
+
// 设置开播时间
|
|
1566
|
+
liveTime = liveRoomInfo.live_time;
|
|
1567
|
+
// 开启推送定时器
|
|
1568
|
+
pushAtTimeTimer = ctx.setInterval(pushAtTime, 3600 * 1000);
|
|
1569
|
+
// 定义开播通知语
|
|
1570
|
+
const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
|
|
1571
|
+
.replace('-name', masterInfo.username)
|
|
1572
|
+
.replace('-time', await ctx.gi.getTimeDifference(liveTime))
|
|
1573
|
+
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1574
|
+
// 推送通知卡片
|
|
1575
|
+
await this.sendLiveNotifyCard(ctx, {
|
|
1576
|
+
username: masterInfo.username,
|
|
1577
|
+
userface: masterInfo.userface,
|
|
1578
|
+
target,
|
|
1579
|
+
data: liveRoomInfo
|
|
1580
|
+
}, LiveType.StartBroadcasting, liveStartMsg);
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
// 启动直播间弹幕监测
|
|
1584
|
+
ctx.bl.startLiveRoomListener(roomId, handler, pushOnceEveryTenS);
|
|
1585
|
+
}
|
|
1290
1586
|
subShow() {
|
|
1291
1587
|
// 在控制台中显示订阅对象
|
|
1292
1588
|
let table = ``;
|
|
@@ -1489,7 +1785,7 @@ class ComRegister {
|
|
|
1489
1785
|
// 判断是否订阅直播
|
|
1490
1786
|
if (sub.live) {
|
|
1491
1787
|
// 订阅直播
|
|
1492
|
-
|
|
1788
|
+
this.liveDetectWithListener(ctx, data.live_room.roomid, sub.target);
|
|
1493
1789
|
}
|
|
1494
1790
|
}
|
|
1495
1791
|
// 在B站中订阅该对象
|
|
@@ -1637,9 +1933,7 @@ class ComRegister {
|
|
|
1637
1933
|
// 直播订阅数+1
|
|
1638
1934
|
liveSubNum++;
|
|
1639
1935
|
// 订阅直播,开始循环检测
|
|
1640
|
-
|
|
1641
|
-
// 保存销毁函数
|
|
1642
|
-
subManagerItem.liveDispose = dispose;
|
|
1936
|
+
this.liveDetectWithListener(ctx, sub.room_id, target);
|
|
1643
1937
|
}
|
|
1644
1938
|
}
|
|
1645
1939
|
// 保存新订阅对象
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -47,6 +47,7 @@ const Database = __importStar(require("./database"));
|
|
|
47
47
|
// import Service
|
|
48
48
|
const generateImg_1 = __importDefault(require("./generateImg"));
|
|
49
49
|
const biliAPI_1 = __importDefault(require("./biliAPI"));
|
|
50
|
+
const blive_1 = __importDefault(require("./blive"));
|
|
50
51
|
exports.inject = ['puppeteer', 'database', 'notifier'];
|
|
51
52
|
exports.name = 'bilibili-notify';
|
|
52
53
|
let globalConfig;
|
|
@@ -138,7 +139,13 @@ exports.Config = koishi_1.Schema.object({
|
|
|
138
139
|
.max(12)
|
|
139
140
|
.step(0.5)
|
|
140
141
|
.default(1)
|
|
141
|
-
.description('
|
|
142
|
+
.description('设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时'),
|
|
143
|
+
danmakuPushTime: koishi_1.Schema.number()
|
|
144
|
+
.min(0)
|
|
145
|
+
.max(10)
|
|
146
|
+
.step(0.5)
|
|
147
|
+
.default(0.5)
|
|
148
|
+
.description('设定间隔多长时间推送一次弹幕消息,单位为分钟,默认为半分钟'),
|
|
142
149
|
customLiveStart: koishi_1.Schema.string()
|
|
143
150
|
.default('-name开播啦 -link')
|
|
144
151
|
.description('自定义开播提示语,-name代表UP昵称,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name开播啦,会发送为xxxUP开播啦'),
|
|
@@ -322,8 +329,13 @@ class ServerManager extends koishi_1.Service {
|
|
|
322
329
|
filter: globalConfig.filter,
|
|
323
330
|
dynamicDebugMode: globalConfig.dynamicDebugMode
|
|
324
331
|
});
|
|
332
|
+
// BL = BLive
|
|
333
|
+
const bl = this.ctx.plugin(blive_1.default, {
|
|
334
|
+
danmakuPushTime: globalConfig.danmakuPushTime
|
|
335
|
+
});
|
|
325
336
|
// 添加服务
|
|
326
337
|
this.servers.push(ba);
|
|
338
|
+
this.servers.push(bl);
|
|
327
339
|
this.servers.push(gi);
|
|
328
340
|
this.servers.push(cr);
|
|
329
341
|
}
|
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": "
|
|
4
|
+
"version": "3.0.0-alpha.1",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Akokko <admin@akokko.com>"
|
|
7
7
|
],
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"axios": "^1.7.9",
|
|
31
31
|
"axios-cookiejar-support": "^5.0.5",
|
|
32
|
+
"blive-message-listener": "^0.5.0",
|
|
32
33
|
"jsdom": "^24.1.3",
|
|
33
34
|
"luxon": "^3.5.0",
|
|
34
35
|
"md5": "^2.3.0",
|
package/readme.md
CHANGED
|
@@ -210,7 +210,9 @@
|
|
|
210
210
|
- ver 2.0.0-alpha.21 修复:在某些场景下仍会出现 `2.0.0-alpha.19` 和 `2.0.0-alpha.20` 版本已修复的问题
|
|
211
211
|
- ver 2.0.0-alpha.22 移除:不需要的服务
|
|
212
212
|
- ver 2.0.0-alpha.23 优化:将艾特全体成员消息单独发送
|
|
213
|
-
|
|
213
|
+
|
|
214
|
+
- ver 3.0.0-alpha.0 重构:直播 新增:直播弹幕推送到群
|
|
215
|
+
- ver 3.0.0-alpha.1 修复:只订阅直播也会将该UP主的动态进行推送、推送过的动态过一段时间又会再次推送
|
|
214
216
|
|
|
215
217
|
## 交流群
|
|
216
218
|
|