koishi-plugin-bilibili-notify 3.5.0-alpha.1 → 3.6.0-alpha.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/index.cjs +259 -129
- package/lib/index.d.cts +37 -1
- package/lib/index.d.mts +37 -1
- package/lib/index.mjs +251 -121
- package/package.json +3 -1
package/lib/index.cjs
CHANGED
|
@@ -40,6 +40,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
40
40
|
//#endregion
|
|
41
41
|
let koishi = require("koishi");
|
|
42
42
|
require("@koishijs/plugin-notifier");
|
|
43
|
+
let __koishijs_plugin_console = require("@koishijs/plugin-console");
|
|
44
|
+
let node_path = require("node:path");
|
|
43
45
|
require("@koishijs/plugin-help");
|
|
44
46
|
let blive_message_listener = require("blive-message-listener");
|
|
45
47
|
let qrcode = require("qrcode");
|
|
@@ -49,7 +51,6 @@ let luxon = require("luxon");
|
|
|
49
51
|
let __node_rs_jieba = require("@node-rs/jieba");
|
|
50
52
|
let __node_rs_jieba_dict = require("@node-rs/jieba/dict");
|
|
51
53
|
require("koishi-plugin-puppeteer");
|
|
52
|
-
let node_path = require("node:path");
|
|
53
54
|
let node_url = require("node:url");
|
|
54
55
|
let md5 = require("md5");
|
|
55
56
|
md5 = __toESM(md5);
|
|
@@ -70,7 +71,7 @@ openai = __toESM(openai);
|
|
|
70
71
|
const BAConfigSchema = koishi.Schema.object({
|
|
71
72
|
require: koishi.Schema.object({}).description("必填设置"),
|
|
72
73
|
key: koishi.Schema.string().pattern(/^[0-9a-f]{32}$/).role("secret").required().description("请输入一个32位小写字母的十六进制密钥(例如:9b8db7ae562b9864efefe06289cc5530),使用此密钥将你的B站登录信息存储在数据库中,请一定保存好此密钥。如果你忘记了此密钥,必须重新登录。你可以自行生成,或到这个网站生成:https://www.sexauth.com/"),
|
|
73
|
-
master: koishi.Schema.intersect([koishi.Schema.object({ enable: koishi.Schema.boolean().default(false).description("
|
|
74
|
+
master: koishi.Schema.intersect([koishi.Schema.object({ enable: koishi.Schema.boolean().default(false).description("是否开启主人账号功能,开启后如果机器人运行错误会向您进行报告。如果您的机器人没有私聊权限请不要开启此功能") }).description("主人账号"), koishi.Schema.union([koishi.Schema.object({
|
|
74
75
|
enable: koishi.Schema.const(true).required(),
|
|
75
76
|
platform: koishi.Schema.union([
|
|
76
77
|
"qq",
|
|
@@ -98,19 +99,19 @@ const BAConfigSchema = koishi.Schema.object({
|
|
|
98
99
|
subTitle: koishi.Schema.object({}).description("订阅配置"),
|
|
99
100
|
advancedSub: koishi.Schema.boolean().default(false).description("是否开启高级订阅,高级订阅是独立于本插件的一个专门用于订阅配置的插件,用于高度自定义订阅消息。若开启高级订阅,请打开该选项并下载插件 bilibili-notify-advanced-subscription"),
|
|
100
101
|
subs: koishi.Schema.array(koishi.Schema.object({
|
|
101
|
-
name: koishi.Schema.string().required().description("
|
|
102
|
+
name: koishi.Schema.string().required().description("UP昵称"),
|
|
102
103
|
uid: koishi.Schema.string().required().description("UID和roomid"),
|
|
103
104
|
dynamic: koishi.Schema.boolean().default(true).description("动态"),
|
|
104
|
-
dynamicAtAll: koishi.Schema.boolean().default(false).description("
|
|
105
|
+
dynamicAtAll: koishi.Schema.boolean().default(false).description("动态@全体"),
|
|
105
106
|
live: koishi.Schema.boolean().default(true).description("直播"),
|
|
106
|
-
liveAtAll: koishi.Schema.boolean().default(true).description("
|
|
107
|
+
liveAtAll: koishi.Schema.boolean().default(true).description("直播@全体"),
|
|
107
108
|
liveGuardBuy: koishi.Schema.boolean().default(false).description("上舰消息"),
|
|
108
109
|
superchat: koishi.Schema.boolean().default(false).description("SC消息"),
|
|
109
110
|
wordcloud: koishi.Schema.boolean().default(true).description("弹幕词云"),
|
|
110
111
|
liveSummary: koishi.Schema.boolean().default(true).description("直播总结"),
|
|
111
112
|
platform: koishi.Schema.string().required().description("平台名"),
|
|
112
113
|
target: koishi.Schema.string().required().description("群号/频道号")
|
|
113
|
-
})).role("table").description("
|
|
114
|
+
})).role("table").description("请在这里填写订阅信息;UP昵称是必填项,影响通知时显示的UP主昵称;UID和roomid,请填写订阅用户的UID,如果经常在初始化插件遇到风控问题,请补充直播间房间号,使用英文逗号分隔例如:1234567,114514;平台名,请填写adapter-xxxx中的xxxx,例如你的机器人使用的是adapter-onebot就填写onebot;群号/频道号,直接填写即可,如果有多个群聊或频道请使用英文逗号分隔,例如:1234567,2345678"),
|
|
114
115
|
dynamic: koishi.Schema.object({}).description("动态推送设置"),
|
|
115
116
|
dynamicUrl: koishi.Schema.boolean().default(false).description("发送动态时是否同时发送链接。注意:如果使用的是QQ官方机器人不能开启此项!"),
|
|
116
117
|
dynamicCron: koishi.Schema.string().default("*/2 * * * *").description("动态监测时间,请填入cron表达式,请勿填入过短时间"),
|
|
@@ -164,6 +165,67 @@ const BAConfigSchema = koishi.Schema.object({
|
|
|
164
165
|
dynamicDebugMode: koishi.Schema.boolean().default(false).description("动态调试模式,开启后会在控制台输出动态推送的详细信息,用于调试")
|
|
165
166
|
});
|
|
166
167
|
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/type/index.ts
|
|
170
|
+
let LiveType = /* @__PURE__ */ function(LiveType$1) {
|
|
171
|
+
LiveType$1[LiveType$1["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
|
|
172
|
+
LiveType$1[LiveType$1["StartBroadcasting"] = 1] = "StartBroadcasting";
|
|
173
|
+
LiveType$1[LiveType$1["LiveBroadcast"] = 2] = "LiveBroadcast";
|
|
174
|
+
LiveType$1[LiveType$1["StopBroadcast"] = 3] = "StopBroadcast";
|
|
175
|
+
LiveType$1[LiveType$1["FirstLiveBroadcast"] = 4] = "FirstLiveBroadcast";
|
|
176
|
+
return LiveType$1;
|
|
177
|
+
}({});
|
|
178
|
+
let PushType = /* @__PURE__ */ function(PushType$1) {
|
|
179
|
+
PushType$1[PushType$1["Live"] = 0] = "Live";
|
|
180
|
+
PushType$1[PushType$1["Dynamic"] = 1] = "Dynamic";
|
|
181
|
+
PushType$1[PushType$1["DynamicAtAll"] = 2] = "DynamicAtAll";
|
|
182
|
+
PushType$1[PushType$1["StartBroadcasting"] = 3] = "StartBroadcasting";
|
|
183
|
+
PushType$1[PushType$1["LiveGuardBuy"] = 4] = "LiveGuardBuy";
|
|
184
|
+
PushType$1[PushType$1["WordCloudAndLiveSummary"] = 5] = "WordCloudAndLiveSummary";
|
|
185
|
+
PushType$1[PushType$1["Superchat"] = 6] = "Superchat";
|
|
186
|
+
return PushType$1;
|
|
187
|
+
}({});
|
|
188
|
+
const PushTypeMsg = {
|
|
189
|
+
[PushType.Live]: "直播推送",
|
|
190
|
+
[PushType.Dynamic]: "动态推送",
|
|
191
|
+
[PushType.DynamicAtAll]: "动态推送+At全体",
|
|
192
|
+
[PushType.StartBroadcasting]: "开播推送",
|
|
193
|
+
[PushType.LiveGuardBuy]: "上舰推送",
|
|
194
|
+
[PushType.WordCloudAndLiveSummary]: "弹幕词云和直播总结推送",
|
|
195
|
+
[PushType.Superchat]: "SC推送"
|
|
196
|
+
};
|
|
197
|
+
let BiliLoginStatus = /* @__PURE__ */ function(BiliLoginStatus$1) {
|
|
198
|
+
BiliLoginStatus$1[BiliLoginStatus$1["NOT_LOGIN"] = 0] = "NOT_LOGIN";
|
|
199
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOADING_LOGIN_INFO"] = 1] = "LOADING_LOGIN_INFO";
|
|
200
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_QR"] = 2] = "LOGIN_QR";
|
|
201
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGING_QR"] = 3] = "LOGGING_QR";
|
|
202
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGING_IN"] = 4] = "LOGGING_IN";
|
|
203
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGED_IN"] = 5] = "LOGGED_IN";
|
|
204
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_SUCCESS"] = 6] = "LOGIN_SUCCESS";
|
|
205
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_FAILED"] = 7] = "LOGIN_FAILED";
|
|
206
|
+
return BiliLoginStatus$1;
|
|
207
|
+
}({});
|
|
208
|
+
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region src/data_server.ts
|
|
211
|
+
/** biome-ignore-all assist/source/organizeImports: <import> */
|
|
212
|
+
var BilibiliNotifyDataServer = class extends __koishijs_plugin_console.DataService {
|
|
213
|
+
biliData = {
|
|
214
|
+
status: BiliLoginStatus.LOADING_LOGIN_INFO,
|
|
215
|
+
msg: "正在加载登录信息..."
|
|
216
|
+
};
|
|
217
|
+
constructor(ctx) {
|
|
218
|
+
super(ctx, "bilibili-notify");
|
|
219
|
+
ctx.on("bilibili-notify/login-status-report", (data) => {
|
|
220
|
+
this.biliData = data;
|
|
221
|
+
this.refresh();
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
async get() {
|
|
225
|
+
return this.biliData;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
167
229
|
//#endregion
|
|
168
230
|
//#region src/utils/index.ts
|
|
169
231
|
/**
|
|
@@ -204,7 +266,7 @@ async function withRetry(fn, maxAttempts = 3, delayMs = 1e3) {
|
|
|
204
266
|
} catch (error) {
|
|
205
267
|
attempt++;
|
|
206
268
|
if (attempt >= maxAttempts) throw error;
|
|
207
|
-
await new Promise((resolve$
|
|
269
|
+
await new Promise((resolve$2) => setTimeout(resolve$2, delayMs * attempt));
|
|
208
270
|
}
|
|
209
271
|
}
|
|
210
272
|
function replaceButKeep(oldObj, newObj, keepKeys) {
|
|
@@ -213,36 +275,6 @@ function replaceButKeep(oldObj, newObj, keepKeys) {
|
|
|
213
275
|
return result;
|
|
214
276
|
}
|
|
215
277
|
|
|
216
|
-
//#endregion
|
|
217
|
-
//#region src/type/index.ts
|
|
218
|
-
let LiveType = /* @__PURE__ */ function(LiveType$1) {
|
|
219
|
-
LiveType$1[LiveType$1["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
|
|
220
|
-
LiveType$1[LiveType$1["StartBroadcasting"] = 1] = "StartBroadcasting";
|
|
221
|
-
LiveType$1[LiveType$1["LiveBroadcast"] = 2] = "LiveBroadcast";
|
|
222
|
-
LiveType$1[LiveType$1["StopBroadcast"] = 3] = "StopBroadcast";
|
|
223
|
-
LiveType$1[LiveType$1["FirstLiveBroadcast"] = 4] = "FirstLiveBroadcast";
|
|
224
|
-
return LiveType$1;
|
|
225
|
-
}({});
|
|
226
|
-
let PushType = /* @__PURE__ */ function(PushType$1) {
|
|
227
|
-
PushType$1[PushType$1["Live"] = 0] = "Live";
|
|
228
|
-
PushType$1[PushType$1["Dynamic"] = 1] = "Dynamic";
|
|
229
|
-
PushType$1[PushType$1["DynamicAtAll"] = 2] = "DynamicAtAll";
|
|
230
|
-
PushType$1[PushType$1["StartBroadcasting"] = 3] = "StartBroadcasting";
|
|
231
|
-
PushType$1[PushType$1["LiveGuardBuy"] = 4] = "LiveGuardBuy";
|
|
232
|
-
PushType$1[PushType$1["WordCloudAndLiveSummary"] = 5] = "WordCloudAndLiveSummary";
|
|
233
|
-
PushType$1[PushType$1["Superchat"] = 6] = "Superchat";
|
|
234
|
-
return PushType$1;
|
|
235
|
-
}({});
|
|
236
|
-
const PushTypeMsg = {
|
|
237
|
-
[PushType.Live]: "直播推送",
|
|
238
|
-
[PushType.Dynamic]: "动态推送",
|
|
239
|
-
[PushType.DynamicAtAll]: "动态推送+At全体",
|
|
240
|
-
[PushType.StartBroadcasting]: "开播推送",
|
|
241
|
-
[PushType.LiveGuardBuy]: "上舰推送",
|
|
242
|
-
[PushType.WordCloudAndLiveSummary]: "弹幕词云和直播总结推送",
|
|
243
|
-
[PushType.Superchat]: "SC推送"
|
|
244
|
-
};
|
|
245
|
-
|
|
246
278
|
//#endregion
|
|
247
279
|
//#region src/stop_words.ts
|
|
248
280
|
const stopwords = new Set([
|
|
@@ -442,68 +474,6 @@ var ComRegister = class ComRegister {
|
|
|
442
474
|
await session.send(`Channel ID: ${session.event.channel.id}`);
|
|
443
475
|
});
|
|
444
476
|
const biliCom = ctx.command("bili", "bili-notify插件相关指令", { permissions: ["authority:3"] });
|
|
445
|
-
biliCom.subcommand(".login", "登录B站之后才可以进行之后的操作").usage("使用二维码登录,登录B站之后才可以进行之后的操作").example("bili login").action(async ({ session }) => {
|
|
446
|
-
this.logger.info("调用bili login指令");
|
|
447
|
-
let content;
|
|
448
|
-
try {
|
|
449
|
-
content = await ctx["bilibili-notify-api"].getLoginQRCode();
|
|
450
|
-
} catch (_) {
|
|
451
|
-
return "bili login getLoginQRCode() 本次网络请求失败";
|
|
452
|
-
}
|
|
453
|
-
if (content.code !== 0) return await session.send("出问题咯!");
|
|
454
|
-
qrcode.default.toBuffer(content.data.url, {
|
|
455
|
-
errorCorrectionLevel: "H",
|
|
456
|
-
type: "png",
|
|
457
|
-
margin: 1,
|
|
458
|
-
color: {
|
|
459
|
-
dark: "#000000",
|
|
460
|
-
light: "#FFFFFF"
|
|
461
|
-
}
|
|
462
|
-
}, async (err, buffer) => {
|
|
463
|
-
if (err) return await session.send("二维码生成出错,请重新尝试");
|
|
464
|
-
await session.send(koishi.h.image(buffer, "image/jpeg"));
|
|
465
|
-
});
|
|
466
|
-
if (this.loginTimer) this.loginTimer();
|
|
467
|
-
let flag = true;
|
|
468
|
-
this.loginTimer = ctx.setInterval(async () => {
|
|
469
|
-
try {
|
|
470
|
-
if (!flag) return;
|
|
471
|
-
flag = false;
|
|
472
|
-
let loginContent;
|
|
473
|
-
try {
|
|
474
|
-
loginContent = await ctx["bilibili-notify-api"].getLoginStatus(content.data.qrcode_key);
|
|
475
|
-
} catch (e) {
|
|
476
|
-
this.logger.error(e);
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
if (loginContent.code !== 0) {
|
|
480
|
-
this.loginTimer();
|
|
481
|
-
return await session.send("登录失败请重试");
|
|
482
|
-
}
|
|
483
|
-
if (loginContent.data.code === 86038) {
|
|
484
|
-
this.loginTimer();
|
|
485
|
-
return await session.send("二维码已失效,请重新登录");
|
|
486
|
-
}
|
|
487
|
-
if (loginContent.data.code === 0) {
|
|
488
|
-
const encryptedCookies = ctx["bilibili-notify-api"].encrypt(ctx["bilibili-notify-api"].getCookies());
|
|
489
|
-
const encryptedRefreshToken = ctx["bilibili-notify-api"].encrypt(loginContent.data.refresh_token);
|
|
490
|
-
await ctx.database.upsert("loginBili", [{
|
|
491
|
-
id: 1,
|
|
492
|
-
bili_cookies: encryptedCookies,
|
|
493
|
-
bili_refresh_token: encryptedRefreshToken
|
|
494
|
-
}]);
|
|
495
|
-
this.loginDBData = (await this.ctx.database.get("loginBili", 1))[0];
|
|
496
|
-
await this.ctx["bilibili-notify-api"].loadCookiesFromDatabase();
|
|
497
|
-
await this.checkIfLoginInfoIsLoaded();
|
|
498
|
-
this.loginTimer();
|
|
499
|
-
ctx["bilibili-notify-api"].disposeNotifier();
|
|
500
|
-
await session.send("登录成功,请重启插件");
|
|
501
|
-
}
|
|
502
|
-
} finally {
|
|
503
|
-
flag = true;
|
|
504
|
-
}
|
|
505
|
-
}, 1e3);
|
|
506
|
-
});
|
|
507
477
|
biliCom.subcommand(".list", "展示订阅对象").usage("展示订阅对象").example("bili list").action(() => {
|
|
508
478
|
return this.subShow();
|
|
509
479
|
});
|
|
@@ -521,7 +491,7 @@ var ComRegister = class ComRegister {
|
|
|
521
491
|
break;
|
|
522
492
|
}
|
|
523
493
|
subLiveUsers.push({
|
|
524
|
-
uid: Number.parseInt(uid),
|
|
494
|
+
uid: Number.parseInt(uid, 10),
|
|
525
495
|
uname: sub.uname,
|
|
526
496
|
onLive
|
|
527
497
|
});
|
|
@@ -746,6 +716,7 @@ var ComRegister = class ComRegister {
|
|
|
746
716
|
this.logger = this.ctx.logger("bilibili-notify-core");
|
|
747
717
|
this.logger.info("初始化插件中...");
|
|
748
718
|
this.config = config;
|
|
719
|
+
this.registeringForEvents();
|
|
749
720
|
this.privateBot = this.ctx.bots.find((bot) => bot.platform === config.master.platform);
|
|
750
721
|
if (!this.privateBot) this.ctx.notifier.create({ content: "您未配置私人机器人,将无法向您推送机器人状态!" });
|
|
751
722
|
this.loginDBData = (await this.ctx.database.get("loginBili", 1, ["dynamic_group_id"]))[0];
|
|
@@ -754,9 +725,19 @@ var ComRegister = class ComRegister {
|
|
|
754
725
|
this.logger.info("账号未登录,请登录");
|
|
755
726
|
return;
|
|
756
727
|
}
|
|
728
|
+
const personalInfo = await this.ctx["bilibili-notify-api"].getMyselfInfo();
|
|
729
|
+
if (personalInfo.code !== 0) this.ctx.emit("bilibili-notify/login-status-report", {
|
|
730
|
+
status: BiliLoginStatus.LOGGED_IN,
|
|
731
|
+
msg: "已登录,但获取个人信息失败"
|
|
732
|
+
});
|
|
733
|
+
const myCardInfo = await this.ctx["bilibili-notify-api"].getUserCardInfo(personalInfo.data.mid.toString(), true);
|
|
734
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
735
|
+
status: BiliLoginStatus.LOGGED_IN,
|
|
736
|
+
msg: "已登录",
|
|
737
|
+
data: myCardInfo.data
|
|
738
|
+
});
|
|
757
739
|
this.mergeStopWords(config.wordcloudStopWords);
|
|
758
740
|
this.initAllManager();
|
|
759
|
-
this.registeringForEvents();
|
|
760
741
|
if (config.advancedSub) {
|
|
761
742
|
this.logger.info("开启高级订阅,等待加载订阅...");
|
|
762
743
|
this.ctx.emit("bilibili-notify/ready-to-recive");
|
|
@@ -766,6 +747,107 @@ var ComRegister = class ComRegister {
|
|
|
766
747
|
} else this.logger.info("初始化完毕,未添加任何订阅!");
|
|
767
748
|
}
|
|
768
749
|
registeringForEvents() {
|
|
750
|
+
this.ctx.console.addListener("bilibili-notify/start-login", async () => {
|
|
751
|
+
this.logger.info("调用bili login指令");
|
|
752
|
+
let content;
|
|
753
|
+
try {
|
|
754
|
+
content = await this.ctx["bilibili-notify-api"].getLoginQRCode();
|
|
755
|
+
} catch (_) {
|
|
756
|
+
return "bili login getLoginQRCode() 本次网络请求失败";
|
|
757
|
+
}
|
|
758
|
+
if (content.code !== 0) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
759
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
760
|
+
msg: "获取二维码失败"
|
|
761
|
+
});
|
|
762
|
+
qrcode.default.toBuffer(content.data.url, {
|
|
763
|
+
errorCorrectionLevel: "H",
|
|
764
|
+
type: "png",
|
|
765
|
+
margin: 1,
|
|
766
|
+
color: {
|
|
767
|
+
dark: "#000000",
|
|
768
|
+
light: "#FFFFFF"
|
|
769
|
+
}
|
|
770
|
+
}, async (err, buffer) => {
|
|
771
|
+
if (err) {
|
|
772
|
+
this.logger.error("生成二维码失败", err);
|
|
773
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
774
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
775
|
+
msg: "生成二维码失败"
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
const url = "data:image/png;base64," + Buffer.from(buffer).toString("base64");
|
|
779
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
780
|
+
status: BiliLoginStatus.LOGIN_QR,
|
|
781
|
+
msg: "请使用Bilibili App扫码登录",
|
|
782
|
+
data: url
|
|
783
|
+
});
|
|
784
|
+
});
|
|
785
|
+
if (this.loginTimer) this.loginTimer();
|
|
786
|
+
let flag = true;
|
|
787
|
+
this.loginTimer = this.ctx.setInterval(async () => {
|
|
788
|
+
try {
|
|
789
|
+
if (!flag) return;
|
|
790
|
+
flag = false;
|
|
791
|
+
let loginContent;
|
|
792
|
+
try {
|
|
793
|
+
loginContent = await this.ctx["bilibili-notify-api"].getLoginStatus(content.data.qrcode_key);
|
|
794
|
+
} catch (e) {
|
|
795
|
+
this.logger.error(e);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
if (loginContent.data.code === 86101) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
799
|
+
status: BiliLoginStatus.LOGGING_QR,
|
|
800
|
+
msg: "未扫码"
|
|
801
|
+
});
|
|
802
|
+
if (loginContent.data.code === 86090) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
803
|
+
status: BiliLoginStatus.LOGGING_QR,
|
|
804
|
+
msg: "二维码已扫码未确认"
|
|
805
|
+
});
|
|
806
|
+
if (loginContent.data.code === 86038) {
|
|
807
|
+
this.loginTimer();
|
|
808
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
809
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
810
|
+
msg: "二维码已失效,请重新登录"
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
if (loginContent.data.code === 0) {
|
|
814
|
+
const encryptedCookies = this.ctx["bilibili-notify-api"].encrypt(this.ctx["bilibili-notify-api"].getCookies());
|
|
815
|
+
const encryptedRefreshToken = this.ctx["bilibili-notify-api"].encrypt(loginContent.data.refresh_token);
|
|
816
|
+
await this.ctx.database.upsert("loginBili", [{
|
|
817
|
+
id: 1,
|
|
818
|
+
bili_cookies: encryptedCookies,
|
|
819
|
+
bili_refresh_token: encryptedRefreshToken
|
|
820
|
+
}]);
|
|
821
|
+
this.loginDBData = (await this.ctx.database.get("loginBili", 1))[0];
|
|
822
|
+
await this.ctx["bilibili-notify-api"].loadCookiesFromDatabase();
|
|
823
|
+
await this.checkIfLoginInfoIsLoaded();
|
|
824
|
+
this.loginTimer();
|
|
825
|
+
this.ctx["bilibili-notify-api"].disposeNotifier();
|
|
826
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
827
|
+
status: BiliLoginStatus.LOGIN_SUCCESS,
|
|
828
|
+
msg: "已登录,请点击按钮重启插件(5s后自动重启)"
|
|
829
|
+
});
|
|
830
|
+
await this.ctx["bilibili-notify"].restartPlugin();
|
|
831
|
+
}
|
|
832
|
+
if (loginContent.code !== 0) {
|
|
833
|
+
this.loginTimer();
|
|
834
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
835
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
836
|
+
msg: "登录失败,请重试"
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
} finally {
|
|
840
|
+
flag = true;
|
|
841
|
+
}
|
|
842
|
+
}, 1e3);
|
|
843
|
+
});
|
|
844
|
+
this.ctx.console.addListener("bilibili-notify/restart-plugin", async () => {
|
|
845
|
+
await this.ctx["bilibili-notify"].restartPlugin();
|
|
846
|
+
});
|
|
847
|
+
this.ctx.console.addListener("bilibili-notify/request-cors", async (url) => {
|
|
848
|
+
const buffer = await (await fetch(url)).arrayBuffer();
|
|
849
|
+
return "data:image/png;base64," + Buffer.from(buffer).toString("base64");
|
|
850
|
+
});
|
|
769
851
|
this.ctx.on("dispose", () => {
|
|
770
852
|
if (this.loginTimer) this.loginTimer();
|
|
771
853
|
if (this.dynamicJob) this.dynamicJob.stop();
|
|
@@ -1336,7 +1418,7 @@ var ComRegister = class ComRegister {
|
|
|
1336
1418
|
return await this.broadcastToTargets(uid, msg, liveType === LiveType.StartBroadcasting ? PushType.StartBroadcasting : PushType.Live);
|
|
1337
1419
|
}
|
|
1338
1420
|
async segmentDanmaku(danmaku, danmakuWeightRecord) {
|
|
1339
|
-
this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !this.stopwords.has(word)).
|
|
1421
|
+
this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !this.stopwords.has(word)).forEach((w) => {
|
|
1340
1422
|
danmakuWeightRecord[w] = (danmakuWeightRecord[w] || 0) + 1;
|
|
1341
1423
|
});
|
|
1342
1424
|
}
|
|
@@ -1416,8 +1498,12 @@ var ComRegister = class ComRegister {
|
|
|
1416
1498
|
return customLiveSummary.replace("-dmc", `${danmakuSenderCount}`).replace("-mdn", masterInfo.medalName).replace("-dca", `${danmakuCount}`).replace("-un1", top5DanmakuSender[0][0]).replace("-dc1", `${top5DanmakuSender[0][1]}`).replace("-un2", top5DanmakuSender[1][0]).replace("-dc2", `${top5DanmakuSender[1][1]}`).replace("-un3", top5DanmakuSender[2][0]).replace("-dc3", `${top5DanmakuSender[2][1]}`).replace("-un4", top5DanmakuSender[3][0]).replace("-dc4", `${top5DanmakuSender[3][1]}`).replace("-un5", top5DanmakuSender[4][0]).replace("-dc5", `${top5DanmakuSender[4][1]}`).replaceAll("\\n", "\n");
|
|
1417
1499
|
})();
|
|
1418
1500
|
await this.broadcastToTargets(sub.uid, [img, summary], PushType.WordCloudAndLiveSummary);
|
|
1419
|
-
Object.keys(danmakuWeightRecord).forEach((key) =>
|
|
1420
|
-
|
|
1501
|
+
Object.keys(danmakuWeightRecord).forEach((key) => {
|
|
1502
|
+
delete danmakuWeightRecord[key];
|
|
1503
|
+
});
|
|
1504
|
+
Object.keys(danmakuSenderRecord).forEach((key) => {
|
|
1505
|
+
delete danmakuSenderRecord[key];
|
|
1506
|
+
});
|
|
1421
1507
|
};
|
|
1422
1508
|
const pushAtTimeFunc = async () => {
|
|
1423
1509
|
if (!await useLiveRoomInfo(LiveType.LiveBroadcast) && !await useMasterInfo(LiveType.LiveBroadcast)) {
|
|
@@ -1635,10 +1721,10 @@ var ComRegister = class ComRegister {
|
|
|
1635
1721
|
this.subNotifier = this.ctx.notifier.create(table);
|
|
1636
1722
|
}
|
|
1637
1723
|
async checkIfLoginInfoIsLoaded() {
|
|
1638
|
-
return new Promise((resolve$
|
|
1724
|
+
return new Promise((resolve$2) => {
|
|
1639
1725
|
const check = () => {
|
|
1640
1726
|
if (!this.ctx["bilibili-notify-api"].getLoginInfoIsLoaded()) this.ctx.setTimeout(check, 500);
|
|
1641
|
-
else resolve$
|
|
1727
|
+
else resolve$2("success");
|
|
1642
1728
|
};
|
|
1643
1729
|
check();
|
|
1644
1730
|
});
|
|
@@ -1998,7 +2084,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
|
|
|
1998
2084
|
margin: 0;
|
|
1999
2085
|
padding: 0;
|
|
2000
2086
|
box-sizing: border-box;
|
|
2001
|
-
font-family:
|
|
2087
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2002
2088
|
}
|
|
2003
2089
|
|
|
2004
2090
|
html {
|
|
@@ -2161,7 +2247,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
|
|
|
2161
2247
|
margin: 0;
|
|
2162
2248
|
padding: 0;
|
|
2163
2249
|
box-sizing: border-box;
|
|
2164
|
-
font-family:
|
|
2250
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2165
2251
|
}
|
|
2166
2252
|
|
|
2167
2253
|
html {
|
|
@@ -2597,7 +2683,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
|
|
|
2597
2683
|
margin: 0;
|
|
2598
2684
|
padding: 0;
|
|
2599
2685
|
box-sizing: border-box;
|
|
2600
|
-
font-family:
|
|
2686
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2601
2687
|
}
|
|
2602
2688
|
|
|
2603
2689
|
html {
|
|
@@ -2960,7 +3046,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
|
|
|
2960
3046
|
margin: 0;
|
|
2961
3047
|
padding: 0;
|
|
2962
3048
|
box-sizing: border-box;
|
|
2963
|
-
font-family:
|
|
3049
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2964
3050
|
}
|
|
2965
3051
|
|
|
2966
3052
|
html {
|
|
@@ -3419,7 +3505,7 @@ var GenerateImg = class GenerateImg extends koishi.Service {
|
|
|
3419
3505
|
margin: 0;
|
|
3420
3506
|
padding: 0;
|
|
3421
3507
|
box-sizing: border-box;
|
|
3422
|
-
font-family:
|
|
3508
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
3423
3509
|
}
|
|
3424
3510
|
|
|
3425
3511
|
html {
|
|
@@ -3672,6 +3758,7 @@ const GET_LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info"
|
|
|
3672
3758
|
const GET_MASTER_INFO = "https://api.live.bilibili.com/live_user/v1/Master/info";
|
|
3673
3759
|
const GET_TIME_NOW = "https://api.bilibili.com/x/report/click/now";
|
|
3674
3760
|
const GET_SERVER_UTC_TIME = "https://interface.bilibili.com/serverdate.js";
|
|
3761
|
+
const GET_USER_CARD_INFO = "https://api.bilibili.com/x/web-interface/card";
|
|
3675
3762
|
const GET_LATEST_UPDATED_UPS = "https://api.bilibili.com/x/polymer/web-dynamic/v1/portal";
|
|
3676
3763
|
const GET_ONLINE_GOLD_RANK = "https://api.live.bilibili.com//xlive/general-interface/v1/rank/getOnlineGoldRank";
|
|
3677
3764
|
const GET_USER_INFO_IN_LIVE = "https://api.live.bilibili.com/xlive/app-ucenter/v2/card/user";
|
|
@@ -4092,6 +4179,32 @@ var BiliAPI = class extends koishi.Service {
|
|
|
4092
4179
|
retries: 3
|
|
4093
4180
|
});
|
|
4094
4181
|
}
|
|
4182
|
+
async getUserCardInfo(mid, photo) {
|
|
4183
|
+
const run = async () => {
|
|
4184
|
+
let url = `${GET_USER_CARD_INFO}?mid=${mid}`;
|
|
4185
|
+
if (photo) url += "&photo=true";
|
|
4186
|
+
const { data } = await this.client.get(url);
|
|
4187
|
+
return data;
|
|
4188
|
+
};
|
|
4189
|
+
return await this.pRetry(run, {
|
|
4190
|
+
onFailedAttempt: (error) => {
|
|
4191
|
+
this.logger.error(`getUserInfoInLive() 第${error.attemptNumber}次失败: ${error.message}`);
|
|
4192
|
+
},
|
|
4193
|
+
retries: 3
|
|
4194
|
+
});
|
|
4195
|
+
}
|
|
4196
|
+
async getCORSContent(url) {
|
|
4197
|
+
const run = async () => {
|
|
4198
|
+
const { data } = await this.client.get(url);
|
|
4199
|
+
return data;
|
|
4200
|
+
};
|
|
4201
|
+
return await this.pRetry(run, {
|
|
4202
|
+
onFailedAttempt: (error) => {
|
|
4203
|
+
this.logger.error(`getUserInfoInLive() 第${error.attemptNumber}次失败: ${error.message}`);
|
|
4204
|
+
},
|
|
4205
|
+
retries: 3
|
|
4206
|
+
});
|
|
4207
|
+
}
|
|
4095
4208
|
async chatWithAI(content) {
|
|
4096
4209
|
return await this.aiClient.chat.completions.create({
|
|
4097
4210
|
model: this.apiConfig.ai.model,
|
|
@@ -4195,9 +4308,9 @@ var BiliAPI = class extends koishi.Service {
|
|
|
4195
4308
|
async getLoginInfoFromDB() {
|
|
4196
4309
|
const data = (await this.ctx.database.get("loginBili", 1))[0];
|
|
4197
4310
|
if (data === void 0) {
|
|
4198
|
-
this.
|
|
4199
|
-
|
|
4200
|
-
|
|
4311
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
4312
|
+
status: BiliLoginStatus.NOT_LOGIN,
|
|
4313
|
+
msg: "您尚未登录,请登录后使用插件"
|
|
4201
4314
|
});
|
|
4202
4315
|
return {
|
|
4203
4316
|
cookies: null,
|
|
@@ -4212,9 +4325,9 @@ var BiliAPI = class extends koishi.Service {
|
|
|
4212
4325
|
refresh_token: decryptedRefreshToken
|
|
4213
4326
|
};
|
|
4214
4327
|
} catch (_) {
|
|
4215
|
-
this.
|
|
4216
|
-
|
|
4217
|
-
|
|
4328
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
4329
|
+
status: BiliLoginStatus.NOT_LOGIN,
|
|
4330
|
+
msg: "数据库被篡改,请重新登录"
|
|
4218
4331
|
});
|
|
4219
4332
|
await this.ctx.database.remove("loginBili", [1]);
|
|
4220
4333
|
return {
|
|
@@ -4288,16 +4401,13 @@ var BiliAPI = class extends koishi.Service {
|
|
|
4288
4401
|
if (!cookies || !refresh_token) return;
|
|
4289
4402
|
const csrf = cookies.find((cookie) => {
|
|
4290
4403
|
if (cookie.key === "bili_jct") return true;
|
|
4404
|
+
return false;
|
|
4291
4405
|
}).value;
|
|
4292
4406
|
this.checkIfTokenNeedRefresh(refresh_token, csrf);
|
|
4293
4407
|
}, 36e5);
|
|
4294
4408
|
}
|
|
4295
4409
|
async checkIfTokenNeedRefresh(refreshToken, csrf, times = 3) {
|
|
4296
4410
|
const notifyAndError = async (info) => {
|
|
4297
|
-
this.loginNotifier = this.ctx.notifier.create({
|
|
4298
|
-
type: "warning",
|
|
4299
|
-
content: info
|
|
4300
|
-
});
|
|
4301
4411
|
await this.createNewClient();
|
|
4302
4412
|
this.refreshCookieTimer();
|
|
4303
4413
|
throw new Error(info);
|
|
@@ -4352,6 +4462,7 @@ var BiliAPI = class extends koishi.Service {
|
|
|
4352
4462
|
}]);
|
|
4353
4463
|
const newCsrf = this.jar.serializeSync().cookies.find((cookie) => {
|
|
4354
4464
|
if (cookie.key === "bili_jct") return true;
|
|
4465
|
+
return false;
|
|
4355
4466
|
}).value;
|
|
4356
4467
|
const { data: aceeptData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/confirm/refresh", {
|
|
4357
4468
|
csrf: newCsrf,
|
|
@@ -4456,12 +4567,26 @@ var bili_live_default = BLive;
|
|
|
4456
4567
|
const inject = [
|
|
4457
4568
|
"puppeteer",
|
|
4458
4569
|
"database",
|
|
4459
|
-
"notifier"
|
|
4570
|
+
"notifier",
|
|
4571
|
+
"console"
|
|
4460
4572
|
];
|
|
4461
4573
|
const name = "bilibili-notify";
|
|
4462
4574
|
const usage = `
|
|
4463
|
-
|
|
4464
|
-
|
|
4575
|
+
<h1>Bilibili-Notify</h1>
|
|
4576
|
+
<p>使用问题请加群咨询 801338523</p>
|
|
4577
|
+
|
|
4578
|
+
---
|
|
4579
|
+
|
|
4580
|
+
使用说明:
|
|
4581
|
+
- 请仔细阅读subs的配置说明,并在订阅配置中填写正确的 UID 和订阅类型
|
|
4582
|
+
- 订阅类型包括:动态、直播等
|
|
4583
|
+
|
|
4584
|
+
注意事项:
|
|
4585
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4586
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4587
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4588
|
+
|
|
4589
|
+
---
|
|
4465
4590
|
`;
|
|
4466
4591
|
let globalConfig;
|
|
4467
4592
|
var ServerManager = class extends koishi.Service {
|
|
@@ -4541,10 +4666,10 @@ var ServerManager = class extends koishi.Service {
|
|
|
4541
4666
|
};
|
|
4542
4667
|
disposePlugin = async () => {
|
|
4543
4668
|
if (this.servers.length === 0) return false;
|
|
4544
|
-
await new Promise((resolve$
|
|
4669
|
+
await new Promise((resolve$2) => {
|
|
4545
4670
|
for (const fork of this.servers) fork.dispose();
|
|
4546
4671
|
this.servers = [];
|
|
4547
|
-
resolve$
|
|
4672
|
+
resolve$2("ok");
|
|
4548
4673
|
});
|
|
4549
4674
|
return true;
|
|
4550
4675
|
};
|
|
@@ -4554,15 +4679,15 @@ var ServerManager = class extends koishi.Service {
|
|
|
4554
4679
|
return false;
|
|
4555
4680
|
}
|
|
4556
4681
|
await this.disposePlugin();
|
|
4557
|
-
return new Promise((resolve$
|
|
4682
|
+
return new Promise((resolve$2) => {
|
|
4558
4683
|
this.ctx.setTimeout(() => {
|
|
4559
4684
|
try {
|
|
4560
4685
|
this.registerPlugin();
|
|
4561
4686
|
} catch (e) {
|
|
4562
4687
|
this.logger.error("重启插件失败", e);
|
|
4563
|
-
resolve$
|
|
4688
|
+
resolve$2(false);
|
|
4564
4689
|
}
|
|
4565
|
-
resolve$
|
|
4690
|
+
resolve$2(true);
|
|
4566
4691
|
}, 1e3);
|
|
4567
4692
|
});
|
|
4568
4693
|
};
|
|
@@ -4571,6 +4696,11 @@ function apply(ctx, config) {
|
|
|
4571
4696
|
globalConfig = config;
|
|
4572
4697
|
ctx.plugin(database_exports);
|
|
4573
4698
|
ctx.plugin(ServerManager);
|
|
4699
|
+
ctx.plugin(BilibiliNotifyDataServer);
|
|
4700
|
+
ctx.console.addEntry({
|
|
4701
|
+
dev: (0, node_path.resolve)(__dirname, "../client/index.ts"),
|
|
4702
|
+
prod: (0, node_path.resolve)(__dirname, "../dist")
|
|
4703
|
+
});
|
|
4574
4704
|
ctx.middleware((session, next) => {
|
|
4575
4705
|
if (session.content === "恶魔兔,启动!") return session.send("启动不了一点");
|
|
4576
4706
|
return next();
|
package/lib/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context, ForkScope, Schema, Service } from "koishi";
|
|
2
|
+
import { DataService } from "@koishijs/plugin-console";
|
|
2
3
|
|
|
3
4
|
//#region src/config.d.ts
|
|
4
5
|
interface BAConfig {
|
|
@@ -121,11 +122,33 @@ type Subscription = {
|
|
|
121
122
|
customGuardBuy: CustomGuardBuy;
|
|
122
123
|
};
|
|
123
124
|
type Subscriptions = Record<string, Subscription>;
|
|
125
|
+
declare enum BiliLoginStatus {
|
|
126
|
+
NOT_LOGIN = 0,
|
|
127
|
+
LOADING_LOGIN_INFO = 1,
|
|
128
|
+
LOGIN_QR = 2,
|
|
129
|
+
LOGGING_QR = 3,
|
|
130
|
+
LOGGING_IN = 4,
|
|
131
|
+
LOGGED_IN = 5,
|
|
132
|
+
LOGIN_SUCCESS = 6,
|
|
133
|
+
LOGIN_FAILED = 7,
|
|
134
|
+
}
|
|
135
|
+
type BiliDataServer = {
|
|
136
|
+
status: BiliLoginStatus;
|
|
137
|
+
msg: string;
|
|
138
|
+
data?: any;
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/data_server.d.ts
|
|
142
|
+
declare class BilibiliNotifyDataServer extends DataService<BiliDataServer> {
|
|
143
|
+
private biliData;
|
|
144
|
+
constructor(ctx: Context);
|
|
145
|
+
get(): Promise<BiliDataServer>;
|
|
146
|
+
}
|
|
124
147
|
//#endregion
|
|
125
148
|
//#region src/index.d.ts
|
|
126
149
|
declare const inject: string[];
|
|
127
150
|
declare const name = "bilibili-notify";
|
|
128
|
-
declare const usage = "\n
|
|
151
|
+
declare const usage = "\n<h1>Bilibili-Notify</h1>\n<p>\u4F7F\u7528\u95EE\u9898\u8BF7\u52A0\u7FA4\u54A8\u8BE2 801338523</p>\n\n---\n\n\u4F7F\u7528\u8BF4\u660E\uFF1A\n- \u8BF7\u4ED4\u7EC6\u9605\u8BFBsubs\u7684\u914D\u7F6E\u8BF4\u660E\uFF0C\u5E76\u5728\u8BA2\u9605\u914D\u7F6E\u4E2D\u586B\u5199\u6B63\u786E\u7684 UID \u548C\u8BA2\u9605\u7C7B\u578B\n- \u8BA2\u9605\u7C7B\u578B\u5305\u62EC\uFF1A\u52A8\u6001\u3001\u76F4\u64AD\u7B49\n\n\u6CE8\u610F\u4E8B\u9879\uFF1A\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n\n---\n";
|
|
129
152
|
declare module "koishi" {
|
|
130
153
|
interface Context {
|
|
131
154
|
"bilibili-notify": ServerManager;
|
|
@@ -133,6 +156,19 @@ declare module "koishi" {
|
|
|
133
156
|
interface Events {
|
|
134
157
|
"bilibili-notify/advanced-sub"(subs: Subscriptions): void;
|
|
135
158
|
"bilibili-notify/ready-to-recive"(): void;
|
|
159
|
+
"bilibili-notify/login-status-report"(data: BiliDataServer): void;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
declare module "@koishijs/plugin-console" {
|
|
163
|
+
namespace Console {
|
|
164
|
+
interface Services {
|
|
165
|
+
"bilibili-notify": BilibiliNotifyDataServer;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
interface Events {
|
|
169
|
+
"bilibili-notify/start-login"(): void;
|
|
170
|
+
"bilibili-notify/restart-plugin"(): void;
|
|
171
|
+
"bilibili-notify/request-cors"(url: string): any;
|
|
136
172
|
}
|
|
137
173
|
}
|
|
138
174
|
declare class ServerManager extends Service {
|
package/lib/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context, ForkScope, Schema, Service } from "koishi";
|
|
2
|
+
import { DataService } from "@koishijs/plugin-console";
|
|
2
3
|
|
|
3
4
|
//#region src/config.d.ts
|
|
4
5
|
interface BAConfig {
|
|
@@ -121,11 +122,33 @@ type Subscription = {
|
|
|
121
122
|
customGuardBuy: CustomGuardBuy;
|
|
122
123
|
};
|
|
123
124
|
type Subscriptions = Record<string, Subscription>;
|
|
125
|
+
declare enum BiliLoginStatus {
|
|
126
|
+
NOT_LOGIN = 0,
|
|
127
|
+
LOADING_LOGIN_INFO = 1,
|
|
128
|
+
LOGIN_QR = 2,
|
|
129
|
+
LOGGING_QR = 3,
|
|
130
|
+
LOGGING_IN = 4,
|
|
131
|
+
LOGGED_IN = 5,
|
|
132
|
+
LOGIN_SUCCESS = 6,
|
|
133
|
+
LOGIN_FAILED = 7,
|
|
134
|
+
}
|
|
135
|
+
type BiliDataServer = {
|
|
136
|
+
status: BiliLoginStatus;
|
|
137
|
+
msg: string;
|
|
138
|
+
data?: any;
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/data_server.d.ts
|
|
142
|
+
declare class BilibiliNotifyDataServer extends DataService<BiliDataServer> {
|
|
143
|
+
private biliData;
|
|
144
|
+
constructor(ctx: Context);
|
|
145
|
+
get(): Promise<BiliDataServer>;
|
|
146
|
+
}
|
|
124
147
|
//#endregion
|
|
125
148
|
//#region src/index.d.ts
|
|
126
149
|
declare const inject: string[];
|
|
127
150
|
declare const name = "bilibili-notify";
|
|
128
|
-
declare const usage = "\n
|
|
151
|
+
declare const usage = "\n<h1>Bilibili-Notify</h1>\n<p>\u4F7F\u7528\u95EE\u9898\u8BF7\u52A0\u7FA4\u54A8\u8BE2 801338523</p>\n\n---\n\n\u4F7F\u7528\u8BF4\u660E\uFF1A\n- \u8BF7\u4ED4\u7EC6\u9605\u8BFBsubs\u7684\u914D\u7F6E\u8BF4\u660E\uFF0C\u5E76\u5728\u8BA2\u9605\u914D\u7F6E\u4E2D\u586B\u5199\u6B63\u786E\u7684 UID \u548C\u8BA2\u9605\u7C7B\u578B\n- \u8BA2\u9605\u7C7B\u578B\u5305\u62EC\uFF1A\u52A8\u6001\u3001\u76F4\u64AD\u7B49\n\n\u6CE8\u610F\u4E8B\u9879\uFF1A\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n- \u5982\u679C\u4F60\u4F7F\u7528\u7684\u662F onebot \u673A\u5668\u4EBA\uFF0C\u5E73\u53F0\u540D\u8BF7\u586B\u5199 onebot \u800C\u4E0D\u662F qq\n\n---\n";
|
|
129
152
|
declare module "koishi" {
|
|
130
153
|
interface Context {
|
|
131
154
|
"bilibili-notify": ServerManager;
|
|
@@ -133,6 +156,19 @@ declare module "koishi" {
|
|
|
133
156
|
interface Events {
|
|
134
157
|
"bilibili-notify/advanced-sub"(subs: Subscriptions): void;
|
|
135
158
|
"bilibili-notify/ready-to-recive"(): void;
|
|
159
|
+
"bilibili-notify/login-status-report"(data: BiliDataServer): void;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
declare module "@koishijs/plugin-console" {
|
|
163
|
+
namespace Console {
|
|
164
|
+
interface Services {
|
|
165
|
+
"bilibili-notify": BilibiliNotifyDataServer;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
interface Events {
|
|
169
|
+
"bilibili-notify/start-login"(): void;
|
|
170
|
+
"bilibili-notify/restart-plugin"(): void;
|
|
171
|
+
"bilibili-notify/request-cors"(url: string): any;
|
|
136
172
|
}
|
|
137
173
|
}
|
|
138
174
|
declare class ServerManager extends Service {
|
package/lib/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { Schema, Service, Universal, h } from "koishi";
|
|
3
3
|
import "@koishijs/plugin-notifier";
|
|
4
|
+
import { DataService } from "@koishijs/plugin-console";
|
|
5
|
+
import { resolve } from "node:path";
|
|
4
6
|
import "@koishijs/plugin-help";
|
|
5
7
|
import { GuardLevel, startListen } from "blive-message-listener";
|
|
6
8
|
import QRCode from "qrcode";
|
|
@@ -9,7 +11,6 @@ import { DateTime } from "luxon";
|
|
|
9
11
|
import { Jieba } from "@node-rs/jieba";
|
|
10
12
|
import { dict } from "@node-rs/jieba/dict";
|
|
11
13
|
import "koishi-plugin-puppeteer";
|
|
12
|
-
import { resolve } from "node:path";
|
|
13
14
|
import { pathToFileURL } from "node:url";
|
|
14
15
|
import md5 from "md5";
|
|
15
16
|
import crypto from "node:crypto";
|
|
@@ -41,7 +42,7 @@ var __export = (all, symbols) => {
|
|
|
41
42
|
const BAConfigSchema = Schema.object({
|
|
42
43
|
require: Schema.object({}).description("必填设置"),
|
|
43
44
|
key: Schema.string().pattern(/^[0-9a-f]{32}$/).role("secret").required().description("请输入一个32位小写字母的十六进制密钥(例如:9b8db7ae562b9864efefe06289cc5530),使用此密钥将你的B站登录信息存储在数据库中,请一定保存好此密钥。如果你忘记了此密钥,必须重新登录。你可以自行生成,或到这个网站生成:https://www.sexauth.com/"),
|
|
44
|
-
master: Schema.intersect([Schema.object({ enable: Schema.boolean().default(false).description("
|
|
45
|
+
master: Schema.intersect([Schema.object({ enable: Schema.boolean().default(false).description("是否开启主人账号功能,开启后如果机器人运行错误会向您进行报告。如果您的机器人没有私聊权限请不要开启此功能") }).description("主人账号"), Schema.union([Schema.object({
|
|
45
46
|
enable: Schema.const(true).required(),
|
|
46
47
|
platform: Schema.union([
|
|
47
48
|
"qq",
|
|
@@ -69,19 +70,19 @@ const BAConfigSchema = Schema.object({
|
|
|
69
70
|
subTitle: Schema.object({}).description("订阅配置"),
|
|
70
71
|
advancedSub: Schema.boolean().default(false).description("是否开启高级订阅,高级订阅是独立于本插件的一个专门用于订阅配置的插件,用于高度自定义订阅消息。若开启高级订阅,请打开该选项并下载插件 bilibili-notify-advanced-subscription"),
|
|
71
72
|
subs: Schema.array(Schema.object({
|
|
72
|
-
name: Schema.string().required().description("
|
|
73
|
+
name: Schema.string().required().description("UP昵称"),
|
|
73
74
|
uid: Schema.string().required().description("UID和roomid"),
|
|
74
75
|
dynamic: Schema.boolean().default(true).description("动态"),
|
|
75
|
-
dynamicAtAll: Schema.boolean().default(false).description("
|
|
76
|
+
dynamicAtAll: Schema.boolean().default(false).description("动态@全体"),
|
|
76
77
|
live: Schema.boolean().default(true).description("直播"),
|
|
77
|
-
liveAtAll: Schema.boolean().default(true).description("
|
|
78
|
+
liveAtAll: Schema.boolean().default(true).description("直播@全体"),
|
|
78
79
|
liveGuardBuy: Schema.boolean().default(false).description("上舰消息"),
|
|
79
80
|
superchat: Schema.boolean().default(false).description("SC消息"),
|
|
80
81
|
wordcloud: Schema.boolean().default(true).description("弹幕词云"),
|
|
81
82
|
liveSummary: Schema.boolean().default(true).description("直播总结"),
|
|
82
83
|
platform: Schema.string().required().description("平台名"),
|
|
83
84
|
target: Schema.string().required().description("群号/频道号")
|
|
84
|
-
})).role("table").description("
|
|
85
|
+
})).role("table").description("请在这里填写订阅信息;UP昵称是必填项,影响通知时显示的UP主昵称;UID和roomid,请填写订阅用户的UID,如果经常在初始化插件遇到风控问题,请补充直播间房间号,使用英文逗号分隔例如:1234567,114514;平台名,请填写adapter-xxxx中的xxxx,例如你的机器人使用的是adapter-onebot就填写onebot;群号/频道号,直接填写即可,如果有多个群聊或频道请使用英文逗号分隔,例如:1234567,2345678"),
|
|
85
86
|
dynamic: Schema.object({}).description("动态推送设置"),
|
|
86
87
|
dynamicUrl: Schema.boolean().default(false).description("发送动态时是否同时发送链接。注意:如果使用的是QQ官方机器人不能开启此项!"),
|
|
87
88
|
dynamicCron: Schema.string().default("*/2 * * * *").description("动态监测时间,请填入cron表达式,请勿填入过短时间"),
|
|
@@ -135,6 +136,67 @@ const BAConfigSchema = Schema.object({
|
|
|
135
136
|
dynamicDebugMode: Schema.boolean().default(false).description("动态调试模式,开启后会在控制台输出动态推送的详细信息,用于调试")
|
|
136
137
|
});
|
|
137
138
|
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/type/index.ts
|
|
141
|
+
let LiveType = /* @__PURE__ */ function(LiveType$1) {
|
|
142
|
+
LiveType$1[LiveType$1["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
|
|
143
|
+
LiveType$1[LiveType$1["StartBroadcasting"] = 1] = "StartBroadcasting";
|
|
144
|
+
LiveType$1[LiveType$1["LiveBroadcast"] = 2] = "LiveBroadcast";
|
|
145
|
+
LiveType$1[LiveType$1["StopBroadcast"] = 3] = "StopBroadcast";
|
|
146
|
+
LiveType$1[LiveType$1["FirstLiveBroadcast"] = 4] = "FirstLiveBroadcast";
|
|
147
|
+
return LiveType$1;
|
|
148
|
+
}({});
|
|
149
|
+
let PushType = /* @__PURE__ */ function(PushType$1) {
|
|
150
|
+
PushType$1[PushType$1["Live"] = 0] = "Live";
|
|
151
|
+
PushType$1[PushType$1["Dynamic"] = 1] = "Dynamic";
|
|
152
|
+
PushType$1[PushType$1["DynamicAtAll"] = 2] = "DynamicAtAll";
|
|
153
|
+
PushType$1[PushType$1["StartBroadcasting"] = 3] = "StartBroadcasting";
|
|
154
|
+
PushType$1[PushType$1["LiveGuardBuy"] = 4] = "LiveGuardBuy";
|
|
155
|
+
PushType$1[PushType$1["WordCloudAndLiveSummary"] = 5] = "WordCloudAndLiveSummary";
|
|
156
|
+
PushType$1[PushType$1["Superchat"] = 6] = "Superchat";
|
|
157
|
+
return PushType$1;
|
|
158
|
+
}({});
|
|
159
|
+
const PushTypeMsg = {
|
|
160
|
+
[PushType.Live]: "直播推送",
|
|
161
|
+
[PushType.Dynamic]: "动态推送",
|
|
162
|
+
[PushType.DynamicAtAll]: "动态推送+At全体",
|
|
163
|
+
[PushType.StartBroadcasting]: "开播推送",
|
|
164
|
+
[PushType.LiveGuardBuy]: "上舰推送",
|
|
165
|
+
[PushType.WordCloudAndLiveSummary]: "弹幕词云和直播总结推送",
|
|
166
|
+
[PushType.Superchat]: "SC推送"
|
|
167
|
+
};
|
|
168
|
+
let BiliLoginStatus = /* @__PURE__ */ function(BiliLoginStatus$1) {
|
|
169
|
+
BiliLoginStatus$1[BiliLoginStatus$1["NOT_LOGIN"] = 0] = "NOT_LOGIN";
|
|
170
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOADING_LOGIN_INFO"] = 1] = "LOADING_LOGIN_INFO";
|
|
171
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_QR"] = 2] = "LOGIN_QR";
|
|
172
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGING_QR"] = 3] = "LOGGING_QR";
|
|
173
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGING_IN"] = 4] = "LOGGING_IN";
|
|
174
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGGED_IN"] = 5] = "LOGGED_IN";
|
|
175
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_SUCCESS"] = 6] = "LOGIN_SUCCESS";
|
|
176
|
+
BiliLoginStatus$1[BiliLoginStatus$1["LOGIN_FAILED"] = 7] = "LOGIN_FAILED";
|
|
177
|
+
return BiliLoginStatus$1;
|
|
178
|
+
}({});
|
|
179
|
+
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/data_server.ts
|
|
182
|
+
/** biome-ignore-all assist/source/organizeImports: <import> */
|
|
183
|
+
var BilibiliNotifyDataServer = class extends DataService {
|
|
184
|
+
biliData = {
|
|
185
|
+
status: BiliLoginStatus.LOADING_LOGIN_INFO,
|
|
186
|
+
msg: "正在加载登录信息..."
|
|
187
|
+
};
|
|
188
|
+
constructor(ctx) {
|
|
189
|
+
super(ctx, "bilibili-notify");
|
|
190
|
+
ctx.on("bilibili-notify/login-status-report", (data) => {
|
|
191
|
+
this.biliData = data;
|
|
192
|
+
this.refresh();
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
async get() {
|
|
196
|
+
return this.biliData;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
138
200
|
//#endregion
|
|
139
201
|
//#region src/utils/index.ts
|
|
140
202
|
/**
|
|
@@ -184,36 +246,6 @@ function replaceButKeep(oldObj, newObj, keepKeys) {
|
|
|
184
246
|
return result;
|
|
185
247
|
}
|
|
186
248
|
|
|
187
|
-
//#endregion
|
|
188
|
-
//#region src/type/index.ts
|
|
189
|
-
let LiveType = /* @__PURE__ */ function(LiveType$1) {
|
|
190
|
-
LiveType$1[LiveType$1["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
|
|
191
|
-
LiveType$1[LiveType$1["StartBroadcasting"] = 1] = "StartBroadcasting";
|
|
192
|
-
LiveType$1[LiveType$1["LiveBroadcast"] = 2] = "LiveBroadcast";
|
|
193
|
-
LiveType$1[LiveType$1["StopBroadcast"] = 3] = "StopBroadcast";
|
|
194
|
-
LiveType$1[LiveType$1["FirstLiveBroadcast"] = 4] = "FirstLiveBroadcast";
|
|
195
|
-
return LiveType$1;
|
|
196
|
-
}({});
|
|
197
|
-
let PushType = /* @__PURE__ */ function(PushType$1) {
|
|
198
|
-
PushType$1[PushType$1["Live"] = 0] = "Live";
|
|
199
|
-
PushType$1[PushType$1["Dynamic"] = 1] = "Dynamic";
|
|
200
|
-
PushType$1[PushType$1["DynamicAtAll"] = 2] = "DynamicAtAll";
|
|
201
|
-
PushType$1[PushType$1["StartBroadcasting"] = 3] = "StartBroadcasting";
|
|
202
|
-
PushType$1[PushType$1["LiveGuardBuy"] = 4] = "LiveGuardBuy";
|
|
203
|
-
PushType$1[PushType$1["WordCloudAndLiveSummary"] = 5] = "WordCloudAndLiveSummary";
|
|
204
|
-
PushType$1[PushType$1["Superchat"] = 6] = "Superchat";
|
|
205
|
-
return PushType$1;
|
|
206
|
-
}({});
|
|
207
|
-
const PushTypeMsg = {
|
|
208
|
-
[PushType.Live]: "直播推送",
|
|
209
|
-
[PushType.Dynamic]: "动态推送",
|
|
210
|
-
[PushType.DynamicAtAll]: "动态推送+At全体",
|
|
211
|
-
[PushType.StartBroadcasting]: "开播推送",
|
|
212
|
-
[PushType.LiveGuardBuy]: "上舰推送",
|
|
213
|
-
[PushType.WordCloudAndLiveSummary]: "弹幕词云和直播总结推送",
|
|
214
|
-
[PushType.Superchat]: "SC推送"
|
|
215
|
-
};
|
|
216
|
-
|
|
217
249
|
//#endregion
|
|
218
250
|
//#region src/stop_words.ts
|
|
219
251
|
const stopwords = new Set([
|
|
@@ -413,68 +445,6 @@ var ComRegister = class ComRegister {
|
|
|
413
445
|
await session.send(`Channel ID: ${session.event.channel.id}`);
|
|
414
446
|
});
|
|
415
447
|
const biliCom = ctx.command("bili", "bili-notify插件相关指令", { permissions: ["authority:3"] });
|
|
416
|
-
biliCom.subcommand(".login", "登录B站之后才可以进行之后的操作").usage("使用二维码登录,登录B站之后才可以进行之后的操作").example("bili login").action(async ({ session }) => {
|
|
417
|
-
this.logger.info("调用bili login指令");
|
|
418
|
-
let content;
|
|
419
|
-
try {
|
|
420
|
-
content = await ctx["bilibili-notify-api"].getLoginQRCode();
|
|
421
|
-
} catch (_) {
|
|
422
|
-
return "bili login getLoginQRCode() 本次网络请求失败";
|
|
423
|
-
}
|
|
424
|
-
if (content.code !== 0) return await session.send("出问题咯!");
|
|
425
|
-
QRCode.toBuffer(content.data.url, {
|
|
426
|
-
errorCorrectionLevel: "H",
|
|
427
|
-
type: "png",
|
|
428
|
-
margin: 1,
|
|
429
|
-
color: {
|
|
430
|
-
dark: "#000000",
|
|
431
|
-
light: "#FFFFFF"
|
|
432
|
-
}
|
|
433
|
-
}, async (err, buffer) => {
|
|
434
|
-
if (err) return await session.send("二维码生成出错,请重新尝试");
|
|
435
|
-
await session.send(h.image(buffer, "image/jpeg"));
|
|
436
|
-
});
|
|
437
|
-
if (this.loginTimer) this.loginTimer();
|
|
438
|
-
let flag = true;
|
|
439
|
-
this.loginTimer = ctx.setInterval(async () => {
|
|
440
|
-
try {
|
|
441
|
-
if (!flag) return;
|
|
442
|
-
flag = false;
|
|
443
|
-
let loginContent;
|
|
444
|
-
try {
|
|
445
|
-
loginContent = await ctx["bilibili-notify-api"].getLoginStatus(content.data.qrcode_key);
|
|
446
|
-
} catch (e) {
|
|
447
|
-
this.logger.error(e);
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
if (loginContent.code !== 0) {
|
|
451
|
-
this.loginTimer();
|
|
452
|
-
return await session.send("登录失败请重试");
|
|
453
|
-
}
|
|
454
|
-
if (loginContent.data.code === 86038) {
|
|
455
|
-
this.loginTimer();
|
|
456
|
-
return await session.send("二维码已失效,请重新登录");
|
|
457
|
-
}
|
|
458
|
-
if (loginContent.data.code === 0) {
|
|
459
|
-
const encryptedCookies = ctx["bilibili-notify-api"].encrypt(ctx["bilibili-notify-api"].getCookies());
|
|
460
|
-
const encryptedRefreshToken = ctx["bilibili-notify-api"].encrypt(loginContent.data.refresh_token);
|
|
461
|
-
await ctx.database.upsert("loginBili", [{
|
|
462
|
-
id: 1,
|
|
463
|
-
bili_cookies: encryptedCookies,
|
|
464
|
-
bili_refresh_token: encryptedRefreshToken
|
|
465
|
-
}]);
|
|
466
|
-
this.loginDBData = (await this.ctx.database.get("loginBili", 1))[0];
|
|
467
|
-
await this.ctx["bilibili-notify-api"].loadCookiesFromDatabase();
|
|
468
|
-
await this.checkIfLoginInfoIsLoaded();
|
|
469
|
-
this.loginTimer();
|
|
470
|
-
ctx["bilibili-notify-api"].disposeNotifier();
|
|
471
|
-
await session.send("登录成功,请重启插件");
|
|
472
|
-
}
|
|
473
|
-
} finally {
|
|
474
|
-
flag = true;
|
|
475
|
-
}
|
|
476
|
-
}, 1e3);
|
|
477
|
-
});
|
|
478
448
|
biliCom.subcommand(".list", "展示订阅对象").usage("展示订阅对象").example("bili list").action(() => {
|
|
479
449
|
return this.subShow();
|
|
480
450
|
});
|
|
@@ -492,7 +462,7 @@ var ComRegister = class ComRegister {
|
|
|
492
462
|
break;
|
|
493
463
|
}
|
|
494
464
|
subLiveUsers.push({
|
|
495
|
-
uid: Number.parseInt(uid),
|
|
465
|
+
uid: Number.parseInt(uid, 10),
|
|
496
466
|
uname: sub.uname,
|
|
497
467
|
onLive
|
|
498
468
|
});
|
|
@@ -717,6 +687,7 @@ var ComRegister = class ComRegister {
|
|
|
717
687
|
this.logger = this.ctx.logger("bilibili-notify-core");
|
|
718
688
|
this.logger.info("初始化插件中...");
|
|
719
689
|
this.config = config;
|
|
690
|
+
this.registeringForEvents();
|
|
720
691
|
this.privateBot = this.ctx.bots.find((bot) => bot.platform === config.master.platform);
|
|
721
692
|
if (!this.privateBot) this.ctx.notifier.create({ content: "您未配置私人机器人,将无法向您推送机器人状态!" });
|
|
722
693
|
this.loginDBData = (await this.ctx.database.get("loginBili", 1, ["dynamic_group_id"]))[0];
|
|
@@ -725,9 +696,19 @@ var ComRegister = class ComRegister {
|
|
|
725
696
|
this.logger.info("账号未登录,请登录");
|
|
726
697
|
return;
|
|
727
698
|
}
|
|
699
|
+
const personalInfo = await this.ctx["bilibili-notify-api"].getMyselfInfo();
|
|
700
|
+
if (personalInfo.code !== 0) this.ctx.emit("bilibili-notify/login-status-report", {
|
|
701
|
+
status: BiliLoginStatus.LOGGED_IN,
|
|
702
|
+
msg: "已登录,但获取个人信息失败"
|
|
703
|
+
});
|
|
704
|
+
const myCardInfo = await this.ctx["bilibili-notify-api"].getUserCardInfo(personalInfo.data.mid.toString(), true);
|
|
705
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
706
|
+
status: BiliLoginStatus.LOGGED_IN,
|
|
707
|
+
msg: "已登录",
|
|
708
|
+
data: myCardInfo.data
|
|
709
|
+
});
|
|
728
710
|
this.mergeStopWords(config.wordcloudStopWords);
|
|
729
711
|
this.initAllManager();
|
|
730
|
-
this.registeringForEvents();
|
|
731
712
|
if (config.advancedSub) {
|
|
732
713
|
this.logger.info("开启高级订阅,等待加载订阅...");
|
|
733
714
|
this.ctx.emit("bilibili-notify/ready-to-recive");
|
|
@@ -737,6 +718,107 @@ var ComRegister = class ComRegister {
|
|
|
737
718
|
} else this.logger.info("初始化完毕,未添加任何订阅!");
|
|
738
719
|
}
|
|
739
720
|
registeringForEvents() {
|
|
721
|
+
this.ctx.console.addListener("bilibili-notify/start-login", async () => {
|
|
722
|
+
this.logger.info("调用bili login指令");
|
|
723
|
+
let content;
|
|
724
|
+
try {
|
|
725
|
+
content = await this.ctx["bilibili-notify-api"].getLoginQRCode();
|
|
726
|
+
} catch (_) {
|
|
727
|
+
return "bili login getLoginQRCode() 本次网络请求失败";
|
|
728
|
+
}
|
|
729
|
+
if (content.code !== 0) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
730
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
731
|
+
msg: "获取二维码失败"
|
|
732
|
+
});
|
|
733
|
+
QRCode.toBuffer(content.data.url, {
|
|
734
|
+
errorCorrectionLevel: "H",
|
|
735
|
+
type: "png",
|
|
736
|
+
margin: 1,
|
|
737
|
+
color: {
|
|
738
|
+
dark: "#000000",
|
|
739
|
+
light: "#FFFFFF"
|
|
740
|
+
}
|
|
741
|
+
}, async (err, buffer) => {
|
|
742
|
+
if (err) {
|
|
743
|
+
this.logger.error("生成二维码失败", err);
|
|
744
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
745
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
746
|
+
msg: "生成二维码失败"
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
const url = "data:image/png;base64," + Buffer.from(buffer).toString("base64");
|
|
750
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
751
|
+
status: BiliLoginStatus.LOGIN_QR,
|
|
752
|
+
msg: "请使用Bilibili App扫码登录",
|
|
753
|
+
data: url
|
|
754
|
+
});
|
|
755
|
+
});
|
|
756
|
+
if (this.loginTimer) this.loginTimer();
|
|
757
|
+
let flag = true;
|
|
758
|
+
this.loginTimer = this.ctx.setInterval(async () => {
|
|
759
|
+
try {
|
|
760
|
+
if (!flag) return;
|
|
761
|
+
flag = false;
|
|
762
|
+
let loginContent;
|
|
763
|
+
try {
|
|
764
|
+
loginContent = await this.ctx["bilibili-notify-api"].getLoginStatus(content.data.qrcode_key);
|
|
765
|
+
} catch (e) {
|
|
766
|
+
this.logger.error(e);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
if (loginContent.data.code === 86101) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
770
|
+
status: BiliLoginStatus.LOGGING_QR,
|
|
771
|
+
msg: "未扫码"
|
|
772
|
+
});
|
|
773
|
+
if (loginContent.data.code === 86090) return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
774
|
+
status: BiliLoginStatus.LOGGING_QR,
|
|
775
|
+
msg: "二维码已扫码未确认"
|
|
776
|
+
});
|
|
777
|
+
if (loginContent.data.code === 86038) {
|
|
778
|
+
this.loginTimer();
|
|
779
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
780
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
781
|
+
msg: "二维码已失效,请重新登录"
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
if (loginContent.data.code === 0) {
|
|
785
|
+
const encryptedCookies = this.ctx["bilibili-notify-api"].encrypt(this.ctx["bilibili-notify-api"].getCookies());
|
|
786
|
+
const encryptedRefreshToken = this.ctx["bilibili-notify-api"].encrypt(loginContent.data.refresh_token);
|
|
787
|
+
await this.ctx.database.upsert("loginBili", [{
|
|
788
|
+
id: 1,
|
|
789
|
+
bili_cookies: encryptedCookies,
|
|
790
|
+
bili_refresh_token: encryptedRefreshToken
|
|
791
|
+
}]);
|
|
792
|
+
this.loginDBData = (await this.ctx.database.get("loginBili", 1))[0];
|
|
793
|
+
await this.ctx["bilibili-notify-api"].loadCookiesFromDatabase();
|
|
794
|
+
await this.checkIfLoginInfoIsLoaded();
|
|
795
|
+
this.loginTimer();
|
|
796
|
+
this.ctx["bilibili-notify-api"].disposeNotifier();
|
|
797
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
798
|
+
status: BiliLoginStatus.LOGIN_SUCCESS,
|
|
799
|
+
msg: "已登录,请点击按钮重启插件(5s后自动重启)"
|
|
800
|
+
});
|
|
801
|
+
await this.ctx["bilibili-notify"].restartPlugin();
|
|
802
|
+
}
|
|
803
|
+
if (loginContent.code !== 0) {
|
|
804
|
+
this.loginTimer();
|
|
805
|
+
return this.ctx.emit("bilibili-notify/login-status-report", {
|
|
806
|
+
status: BiliLoginStatus.LOGIN_FAILED,
|
|
807
|
+
msg: "登录失败,请重试"
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
} finally {
|
|
811
|
+
flag = true;
|
|
812
|
+
}
|
|
813
|
+
}, 1e3);
|
|
814
|
+
});
|
|
815
|
+
this.ctx.console.addListener("bilibili-notify/restart-plugin", async () => {
|
|
816
|
+
await this.ctx["bilibili-notify"].restartPlugin();
|
|
817
|
+
});
|
|
818
|
+
this.ctx.console.addListener("bilibili-notify/request-cors", async (url) => {
|
|
819
|
+
const buffer = await (await fetch(url)).arrayBuffer();
|
|
820
|
+
return "data:image/png;base64," + Buffer.from(buffer).toString("base64");
|
|
821
|
+
});
|
|
740
822
|
this.ctx.on("dispose", () => {
|
|
741
823
|
if (this.loginTimer) this.loginTimer();
|
|
742
824
|
if (this.dynamicJob) this.dynamicJob.stop();
|
|
@@ -1307,7 +1389,7 @@ var ComRegister = class ComRegister {
|
|
|
1307
1389
|
return await this.broadcastToTargets(uid, msg, liveType === LiveType.StartBroadcasting ? PushType.StartBroadcasting : PushType.Live);
|
|
1308
1390
|
}
|
|
1309
1391
|
async segmentDanmaku(danmaku, danmakuWeightRecord) {
|
|
1310
|
-
this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !this.stopwords.has(word)).
|
|
1392
|
+
this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !this.stopwords.has(word)).forEach((w) => {
|
|
1311
1393
|
danmakuWeightRecord[w] = (danmakuWeightRecord[w] || 0) + 1;
|
|
1312
1394
|
});
|
|
1313
1395
|
}
|
|
@@ -1387,8 +1469,12 @@ var ComRegister = class ComRegister {
|
|
|
1387
1469
|
return customLiveSummary.replace("-dmc", `${danmakuSenderCount}`).replace("-mdn", masterInfo.medalName).replace("-dca", `${danmakuCount}`).replace("-un1", top5DanmakuSender[0][0]).replace("-dc1", `${top5DanmakuSender[0][1]}`).replace("-un2", top5DanmakuSender[1][0]).replace("-dc2", `${top5DanmakuSender[1][1]}`).replace("-un3", top5DanmakuSender[2][0]).replace("-dc3", `${top5DanmakuSender[2][1]}`).replace("-un4", top5DanmakuSender[3][0]).replace("-dc4", `${top5DanmakuSender[3][1]}`).replace("-un5", top5DanmakuSender[4][0]).replace("-dc5", `${top5DanmakuSender[4][1]}`).replaceAll("\\n", "\n");
|
|
1388
1470
|
})();
|
|
1389
1471
|
await this.broadcastToTargets(sub.uid, [img, summary], PushType.WordCloudAndLiveSummary);
|
|
1390
|
-
Object.keys(danmakuWeightRecord).forEach((key) =>
|
|
1391
|
-
|
|
1472
|
+
Object.keys(danmakuWeightRecord).forEach((key) => {
|
|
1473
|
+
delete danmakuWeightRecord[key];
|
|
1474
|
+
});
|
|
1475
|
+
Object.keys(danmakuSenderRecord).forEach((key) => {
|
|
1476
|
+
delete danmakuSenderRecord[key];
|
|
1477
|
+
});
|
|
1392
1478
|
};
|
|
1393
1479
|
const pushAtTimeFunc = async () => {
|
|
1394
1480
|
if (!await useLiveRoomInfo(LiveType.LiveBroadcast) && !await useMasterInfo(LiveType.LiveBroadcast)) {
|
|
@@ -1969,7 +2055,7 @@ var GenerateImg = class GenerateImg extends Service {
|
|
|
1969
2055
|
margin: 0;
|
|
1970
2056
|
padding: 0;
|
|
1971
2057
|
box-sizing: border-box;
|
|
1972
|
-
font-family:
|
|
2058
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
1973
2059
|
}
|
|
1974
2060
|
|
|
1975
2061
|
html {
|
|
@@ -2132,7 +2218,7 @@ var GenerateImg = class GenerateImg extends Service {
|
|
|
2132
2218
|
margin: 0;
|
|
2133
2219
|
padding: 0;
|
|
2134
2220
|
box-sizing: border-box;
|
|
2135
|
-
font-family:
|
|
2221
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2136
2222
|
}
|
|
2137
2223
|
|
|
2138
2224
|
html {
|
|
@@ -2568,7 +2654,7 @@ var GenerateImg = class GenerateImg extends Service {
|
|
|
2568
2654
|
margin: 0;
|
|
2569
2655
|
padding: 0;
|
|
2570
2656
|
box-sizing: border-box;
|
|
2571
|
-
font-family:
|
|
2657
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2572
2658
|
}
|
|
2573
2659
|
|
|
2574
2660
|
html {
|
|
@@ -2931,7 +3017,7 @@ var GenerateImg = class GenerateImg extends Service {
|
|
|
2931
3017
|
margin: 0;
|
|
2932
3018
|
padding: 0;
|
|
2933
3019
|
box-sizing: border-box;
|
|
2934
|
-
font-family:
|
|
3020
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
2935
3021
|
}
|
|
2936
3022
|
|
|
2937
3023
|
html {
|
|
@@ -3390,7 +3476,7 @@ var GenerateImg = class GenerateImg extends Service {
|
|
|
3390
3476
|
margin: 0;
|
|
3391
3477
|
padding: 0;
|
|
3392
3478
|
box-sizing: border-box;
|
|
3393
|
-
font-family:
|
|
3479
|
+
font-family: "${this.giConfig.font}", "Microsoft YaHei", "Source Han Sans", "Noto Sans CJK", sans-serif;
|
|
3394
3480
|
}
|
|
3395
3481
|
|
|
3396
3482
|
html {
|
|
@@ -3643,6 +3729,7 @@ const GET_LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info"
|
|
|
3643
3729
|
const GET_MASTER_INFO = "https://api.live.bilibili.com/live_user/v1/Master/info";
|
|
3644
3730
|
const GET_TIME_NOW = "https://api.bilibili.com/x/report/click/now";
|
|
3645
3731
|
const GET_SERVER_UTC_TIME = "https://interface.bilibili.com/serverdate.js";
|
|
3732
|
+
const GET_USER_CARD_INFO = "https://api.bilibili.com/x/web-interface/card";
|
|
3646
3733
|
const GET_LATEST_UPDATED_UPS = "https://api.bilibili.com/x/polymer/web-dynamic/v1/portal";
|
|
3647
3734
|
const GET_ONLINE_GOLD_RANK = "https://api.live.bilibili.com//xlive/general-interface/v1/rank/getOnlineGoldRank";
|
|
3648
3735
|
const GET_USER_INFO_IN_LIVE = "https://api.live.bilibili.com/xlive/app-ucenter/v2/card/user";
|
|
@@ -4063,6 +4150,32 @@ var BiliAPI = class extends Service {
|
|
|
4063
4150
|
retries: 3
|
|
4064
4151
|
});
|
|
4065
4152
|
}
|
|
4153
|
+
async getUserCardInfo(mid, photo) {
|
|
4154
|
+
const run = async () => {
|
|
4155
|
+
let url = `${GET_USER_CARD_INFO}?mid=${mid}`;
|
|
4156
|
+
if (photo) url += "&photo=true";
|
|
4157
|
+
const { data } = await this.client.get(url);
|
|
4158
|
+
return data;
|
|
4159
|
+
};
|
|
4160
|
+
return await this.pRetry(run, {
|
|
4161
|
+
onFailedAttempt: (error) => {
|
|
4162
|
+
this.logger.error(`getUserInfoInLive() 第${error.attemptNumber}次失败: ${error.message}`);
|
|
4163
|
+
},
|
|
4164
|
+
retries: 3
|
|
4165
|
+
});
|
|
4166
|
+
}
|
|
4167
|
+
async getCORSContent(url) {
|
|
4168
|
+
const run = async () => {
|
|
4169
|
+
const { data } = await this.client.get(url);
|
|
4170
|
+
return data;
|
|
4171
|
+
};
|
|
4172
|
+
return await this.pRetry(run, {
|
|
4173
|
+
onFailedAttempt: (error) => {
|
|
4174
|
+
this.logger.error(`getUserInfoInLive() 第${error.attemptNumber}次失败: ${error.message}`);
|
|
4175
|
+
},
|
|
4176
|
+
retries: 3
|
|
4177
|
+
});
|
|
4178
|
+
}
|
|
4066
4179
|
async chatWithAI(content) {
|
|
4067
4180
|
return await this.aiClient.chat.completions.create({
|
|
4068
4181
|
model: this.apiConfig.ai.model,
|
|
@@ -4166,9 +4279,9 @@ var BiliAPI = class extends Service {
|
|
|
4166
4279
|
async getLoginInfoFromDB() {
|
|
4167
4280
|
const data = (await this.ctx.database.get("loginBili", 1))[0];
|
|
4168
4281
|
if (data === void 0) {
|
|
4169
|
-
this.
|
|
4170
|
-
|
|
4171
|
-
|
|
4282
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
4283
|
+
status: BiliLoginStatus.NOT_LOGIN,
|
|
4284
|
+
msg: "您尚未登录,请登录后使用插件"
|
|
4172
4285
|
});
|
|
4173
4286
|
return {
|
|
4174
4287
|
cookies: null,
|
|
@@ -4183,9 +4296,9 @@ var BiliAPI = class extends Service {
|
|
|
4183
4296
|
refresh_token: decryptedRefreshToken
|
|
4184
4297
|
};
|
|
4185
4298
|
} catch (_) {
|
|
4186
|
-
this.
|
|
4187
|
-
|
|
4188
|
-
|
|
4299
|
+
this.ctx.emit("bilibili-notify/login-status-report", {
|
|
4300
|
+
status: BiliLoginStatus.NOT_LOGIN,
|
|
4301
|
+
msg: "数据库被篡改,请重新登录"
|
|
4189
4302
|
});
|
|
4190
4303
|
await this.ctx.database.remove("loginBili", [1]);
|
|
4191
4304
|
return {
|
|
@@ -4259,16 +4372,13 @@ var BiliAPI = class extends Service {
|
|
|
4259
4372
|
if (!cookies || !refresh_token) return;
|
|
4260
4373
|
const csrf = cookies.find((cookie) => {
|
|
4261
4374
|
if (cookie.key === "bili_jct") return true;
|
|
4375
|
+
return false;
|
|
4262
4376
|
}).value;
|
|
4263
4377
|
this.checkIfTokenNeedRefresh(refresh_token, csrf);
|
|
4264
4378
|
}, 36e5);
|
|
4265
4379
|
}
|
|
4266
4380
|
async checkIfTokenNeedRefresh(refreshToken, csrf, times = 3) {
|
|
4267
4381
|
const notifyAndError = async (info) => {
|
|
4268
|
-
this.loginNotifier = this.ctx.notifier.create({
|
|
4269
|
-
type: "warning",
|
|
4270
|
-
content: info
|
|
4271
|
-
});
|
|
4272
4382
|
await this.createNewClient();
|
|
4273
4383
|
this.refreshCookieTimer();
|
|
4274
4384
|
throw new Error(info);
|
|
@@ -4323,6 +4433,7 @@ var BiliAPI = class extends Service {
|
|
|
4323
4433
|
}]);
|
|
4324
4434
|
const newCsrf = this.jar.serializeSync().cookies.find((cookie) => {
|
|
4325
4435
|
if (cookie.key === "bili_jct") return true;
|
|
4436
|
+
return false;
|
|
4326
4437
|
}).value;
|
|
4327
4438
|
const { data: aceeptData } = await this.client.post("https://passport.bilibili.com/x/passport-login/web/confirm/refresh", {
|
|
4328
4439
|
csrf: newCsrf,
|
|
@@ -4427,12 +4538,26 @@ var bili_live_default = BLive;
|
|
|
4427
4538
|
const inject = [
|
|
4428
4539
|
"puppeteer",
|
|
4429
4540
|
"database",
|
|
4430
|
-
"notifier"
|
|
4541
|
+
"notifier",
|
|
4542
|
+
"console"
|
|
4431
4543
|
];
|
|
4432
4544
|
const name = "bilibili-notify";
|
|
4433
4545
|
const usage = `
|
|
4434
|
-
|
|
4435
|
-
|
|
4546
|
+
<h1>Bilibili-Notify</h1>
|
|
4547
|
+
<p>使用问题请加群咨询 801338523</p>
|
|
4548
|
+
|
|
4549
|
+
---
|
|
4550
|
+
|
|
4551
|
+
使用说明:
|
|
4552
|
+
- 请仔细阅读subs的配置说明,并在订阅配置中填写正确的 UID 和订阅类型
|
|
4553
|
+
- 订阅类型包括:动态、直播等
|
|
4554
|
+
|
|
4555
|
+
注意事项:
|
|
4556
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4557
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4558
|
+
- 如果你使用的是 onebot 机器人,平台名请填写 onebot 而不是 qq
|
|
4559
|
+
|
|
4560
|
+
---
|
|
4436
4561
|
`;
|
|
4437
4562
|
let globalConfig;
|
|
4438
4563
|
var ServerManager = class extends Service {
|
|
@@ -4542,6 +4667,11 @@ function apply(ctx, config) {
|
|
|
4542
4667
|
globalConfig = config;
|
|
4543
4668
|
ctx.plugin(database_exports);
|
|
4544
4669
|
ctx.plugin(ServerManager);
|
|
4670
|
+
ctx.plugin(BilibiliNotifyDataServer);
|
|
4671
|
+
ctx.console.addEntry({
|
|
4672
|
+
dev: resolve(__dirname, "../client/index.ts"),
|
|
4673
|
+
prod: resolve(__dirname, "../dist")
|
|
4674
|
+
});
|
|
4545
4675
|
ctx.middleware((session, next) => {
|
|
4546
4676
|
if (session.content === "恶魔兔,启动!") return session.send("启动不了一点");
|
|
4547
4677
|
return next();
|
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": "3.
|
|
4
|
+
"version": "3.6.0-alpha.0",
|
|
5
5
|
"main": "./lib/index.cjs",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"tough-cookie": "^6.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
+
"@koishijs/client": "^5.30.11",
|
|
46
47
|
"@types/jsdom": "^27.0.0",
|
|
47
48
|
"@types/luxon": "^3.7.1",
|
|
48
49
|
"@types/md5": "^2.3.6",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"tsdown": "^0.16.6"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
56
|
+
"@koishijs/plugin-console": "^5.30.11",
|
|
55
57
|
"koishi": "^4.18.9"
|
|
56
58
|
},
|
|
57
59
|
"engines": {
|