koishi-plugin-bilibili-notify 3.2.0-alpha.6 → 3.2.1-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/biliAPI.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import { type Context, Schema, Service } from "koishi";
1
+ import { type Awaitable, type Context, Schema, Service } from "koishi";
2
+ import CacheableLookup from "cacheable-lookup";
3
+ import { type AxiosInstance } from "axios";
2
4
  import { CookieJar } from "tough-cookie";
3
5
  import type { Notifier } from "@koishijs/plugin-notifier";
4
6
  declare module "koishi" {
@@ -9,7 +11,8 @@ declare module "koishi" {
9
11
  declare class BiliAPI extends Service {
10
12
  static inject: string[];
11
13
  jar: CookieJar;
12
- client: any;
14
+ client: AxiosInstance;
15
+ cacheable: CacheableLookup;
13
16
  apiConfig: BiliAPI.Config;
14
17
  loginData: any;
15
18
  loginNotifier: Notifier;
@@ -17,6 +20,7 @@ declare class BiliAPI extends Service {
17
20
  loginInfoIsLoaded: boolean;
18
21
  constructor(ctx: Context, config: BiliAPI.Config);
19
22
  protected start(): void | Promise<void>;
23
+ protected stop(): Awaitable<void>;
20
24
  getMixinKey: (orig: string) => string;
21
25
  encWbi(params: {
22
26
  [key: string]: string | number | object;
package/lib/biliAPI.js CHANGED
@@ -12,6 +12,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const koishi_1 = require("koishi");
13
13
  const md5_1 = __importDefault(require("md5"));
14
14
  const node_crypto_1 = __importDefault(require("node:crypto"));
15
+ const node_http_1 = __importDefault(require("node:http"));
16
+ const node_https_1 = __importDefault(require("node:https"));
17
+ const cacheable_lookup_1 = __importDefault(require("cacheable-lookup"));
15
18
  const axios_1 = __importDefault(require("axios"));
16
19
  const tough_cookie_1 = require("tough-cookie");
17
20
  const axios_cookiejar_support_1 = require("axios-cookiejar-support");
@@ -52,8 +55,8 @@ const GET_LIVE_ROOMS_INFO = "https://api.live.bilibili.com/room/v1/Room/get_stat
52
55
  class BiliAPI extends koishi_1.Service {
53
56
  static inject = ["database", "notifier"];
54
57
  jar;
55
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
56
58
  client;
59
+ cacheable;
57
60
  apiConfig;
58
61
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
59
62
  loginData;
@@ -70,6 +73,11 @@ class BiliAPI extends koishi_1.Service {
70
73
  // 从数据库加载cookies
71
74
  this.loadCookiesFromDatabase();
72
75
  }
76
+ stop() {
77
+ // 将DNS缓存卸载
78
+ this.cacheable.uninstall(node_http_1.default.globalAgent);
79
+ this.cacheable.uninstall(node_https_1.default.globalAgent);
80
+ }
73
81
  // WBI签名
74
82
  // 对 imgKey 和 subKey 进行字符顺序打乱编码
75
83
  getMixinKey = (orig) => mixinKeyEncTab
@@ -287,7 +295,14 @@ class BiliAPI extends koishi_1.Service {
287
295
  return userAgents[index];
288
296
  }
289
297
  createNewClient() {
298
+ // 创建DNS缓存
299
+ this.cacheable = new cacheable_lookup_1.default();
300
+ // 安装到http和https
301
+ this.cacheable.install(node_http_1.default.globalAgent);
302
+ this.cacheable.install(node_https_1.default.globalAgent);
303
+ // 创建cookieJar
290
304
  this.jar = new tough_cookie_1.CookieJar();
305
+ // 包装cookieJar
291
306
  this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
292
307
  jar: this.jar,
293
308
  headers: {
package/lib/blive.js CHANGED
@@ -32,14 +32,11 @@ class BLive extends koishi_1.Service {
32
32
  uid: mySelfInfo.data.mid,
33
33
  },
34
34
  });
35
- // logger
36
- this.logger.info(`${roomId}直播间监听已开启`);
37
35
  }
38
36
  closeListener(roomId) {
39
37
  // 判断直播间监听器是否关闭
40
38
  if (!this.listenerRecord ||
41
- !this.listenerRecord[roomId] ||
42
- !this.listenerRecord[roomId].closed) {
39
+ !this.listenerRecord[roomId]?.closed) {
43
40
  // 输出logger
44
41
  this.logger.info(`${roomId}直播间弹幕监听器无需关闭`);
45
42
  }
@@ -23,7 +23,7 @@ declare class ComRegister {
23
23
  constructor(ctx: Context, config: ComRegister.Config);
24
24
  init(config: ComRegister.Config): Promise<void>;
25
25
  initManager(): void;
26
- getBot(pf: string): Bot<Context, any>;
26
+ getBot(pf: string, selfId?: string): Bot<Context, any>;
27
27
  sendPrivateMsg(content: string): Promise<void>;
28
28
  sendPrivateMsgAndRebootService(): Promise<void>;
29
29
  sendPrivateMsgAndStopService(): Promise<void>;
@@ -65,6 +65,7 @@ declare namespace ComRegister {
65
65
  live: boolean;
66
66
  liveGuardBuy: boolean;
67
67
  atAll: boolean;
68
+ bot: string;
68
69
  }>;
69
70
  platform: string;
70
71
  }>;
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
7
7
  // Koishi核心依赖
8
8
  const koishi_1 = require("koishi");
9
- // 外部依赖:qrcode
10
9
  const qrcode_1 = __importDefault(require("qrcode"));
11
10
  const cron_1 = require("cron");
12
11
  // Utils
@@ -380,8 +379,14 @@ class ComRegister {
380
379
  }
381
380
  }
382
381
  // biome-ignore lint/suspicious/noExplicitAny: <explanation>
383
- getBot(pf) {
384
- return this.ctx.bots.find((bot) => bot.platform === pf);
382
+ getBot(pf, selfId) {
383
+ // 判断是否存在selfId
384
+ if (!selfId || selfId === "") {
385
+ // 不存在则默认第一个bot
386
+ return this.ctx.bots.find((bot) => bot.platform === pf);
387
+ }
388
+ // 存在则返回对应bot
389
+ return this.ctx.bots.find((bot) => bot.platform === pf && bot.selfId === selfId);
385
390
  }
386
391
  async sendPrivateMsg(content) {
387
392
  if (this.config.master.enable) {
@@ -506,7 +511,16 @@ class ComRegister {
506
511
  // 获取目标
507
512
  const targetChannel = targets[0].channelArr[0];
508
513
  // 获取机器人实例
509
- const bot = this.getBot(targets[0].platform);
514
+ const bot = this.getBot(targets[0].platform, targetChannel.bot);
515
+ // 判断bot是否存在
516
+ if (!bot) {
517
+ // 发送私聊消息
518
+ this.sendPrivateMsg("未找到对应bot实例,本次消息推送取消!");
519
+ // logger
520
+ this.logger.warn("未找到对应bot实例,本次消息推送取消!");
521
+ // 直接返回
522
+ return;
523
+ }
510
524
  // 模式匹配
511
525
  const pushTypePatternMatching = {
512
526
  [type_1.PushType.Live]: async () => {
@@ -672,12 +686,17 @@ class ComRegister {
672
686
  await this.broadcastToTargets(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/jpeg"), dUrl] }), type_1.PushType.Dynamic);
673
687
  // 判断是否需要发送动态中的图片
674
688
  if (this.config.pushImgsInDynamic) {
675
- // 判断是否为图文动态,且存在draw
676
- if (item.type === "DYNAMIC_TYPE_DRAW" &&
677
- item.modules.module_dynamic.major?.draw) {
678
- for (const img of item.modules.module_dynamic.major.draw
679
- .items) {
680
- await this.broadcastToTargets(sub.target, (0, jsx_runtime_1.jsx)("img", { src: img.src, alt: "\u52A8\u6001\u56FE\u7247" }), type_1.PushType.Dynamic);
689
+ // 判断是否为图文动态
690
+ if (item.type === "DYNAMIC_TYPE_DRAW") {
691
+ // 获取pics
692
+ const pics = item.modules?.module_dynamic?.major?.opus?.pics;
693
+ // 判断pics是否存在
694
+ if (pics) {
695
+ for (const pic of pics) {
696
+ await this.broadcastToTargets(sub.target, (0, jsx_runtime_1.jsx)("img", { src: pic.url, alt: "\u52A8\u6001\u56FE\u7247" }), type_1.PushType.Dynamic);
697
+ // 随机睡眠1-3秒
698
+ await this.ctx.sleep(Math.floor(Math.random() * 2000) + 1000);
699
+ }
681
700
  }
682
701
  }
683
702
  }
@@ -858,12 +877,17 @@ class ComRegister {
858
877
  if (this.config.pushImgsInDynamic) {
859
878
  // logger
860
879
  this.logger.info("需要发送动态中的图片,开始发送...");
861
- // 判断是否为图文动态,且存在draw
862
- if (item.type === "DYNAMIC_TYPE_DRAW" &&
863
- item.modules.module_dynamic.major?.draw) {
864
- for (const img of item.modules.module_dynamic.major.draw
865
- .items) {
866
- await this.broadcastToTargets(sub.target, (0, jsx_runtime_1.jsx)("img", { src: img.src, alt: "\u52A8\u6001\u56FE\u7247" }), type_1.PushType.Dynamic);
880
+ // 判断是否为图文动态
881
+ if (item.type === "DYNAMIC_TYPE_DRAW") {
882
+ // 获取pics
883
+ const pics = item.modules?.module_dynamic?.major?.opus?.pics;
884
+ // 判断pics是否存在
885
+ if (pics) {
886
+ for (const pic of pics) {
887
+ await this.broadcastToTargets(sub.target, (0, jsx_runtime_1.jsx)("img", { src: pic.url, alt: "\u52A8\u6001\u56FE\u7247" }), type_1.PushType.Dynamic);
888
+ // 随机睡眠1-3秒
889
+ await this.ctx.sleep(Math.floor(Math.random() * 2000) + 1000);
890
+ }
867
891
  }
868
892
  }
869
893
  // logger
@@ -973,9 +997,12 @@ class ComRegister {
973
997
  let pushAtTimeTimer;
974
998
  // 定义弹幕存放数组
975
999
  const currentLiveDanmakuArr = [];
1000
+ // init flag
1001
+ let initFlag = false;
1002
+ // 连接中断flag
1003
+ let connFlag = false;
976
1004
  // 定义开播状态
977
1005
  let liveStatus = false;
978
- // 处理target
979
1006
  // 定义channelIdArr总长度
980
1007
  let channelArrLen = 0;
981
1008
  // 定义数据
@@ -1006,13 +1033,15 @@ class ComRegister {
1006
1033
  return await this.sendPrivateMsgAndStopService();
1007
1034
  }
1008
1035
  // 判断是否已经下播
1009
- if (liveRoomInfo.live_status === 0) {
1036
+ if (liveRoomInfo.live_status === 0 || liveRoomInfo.live_status === 2) {
1010
1037
  // 设置开播状态为false
1011
1038
  liveStatus = false;
1012
1039
  // 清除定时器
1013
1040
  pushAtTimeTimer?.();
1014
1041
  // 发送私聊消息
1015
- await this.sendPrivateMsg("直播间已下播,定时推送已停止!与直播间的连接可能已断开,请使用指令 sys restart 重启插件");
1042
+ await this.sendPrivateMsg("直播间已下播!与直播间的连接可能已断开,请使用指令 sys restart 重启插件");
1043
+ // 返回
1044
+ return;
1016
1045
  }
1017
1046
  // 设置开播时间
1018
1047
  liveTime = liveRoomInfo.live_time;
@@ -1064,6 +1093,31 @@ class ComRegister {
1064
1093
  };
1065
1094
  // 构建消息处理函数
1066
1095
  const handler = {
1096
+ onOpen: () => {
1097
+ if (!initFlag) {
1098
+ // init flag设置为true
1099
+ initFlag = true;
1100
+ // connFlag设置为false
1101
+ connFlag = false;
1102
+ // logger
1103
+ this.logger.info(`${roomId}直播间连接已建立!`);
1104
+ }
1105
+ },
1106
+ onClose: async () => {
1107
+ if (!connFlag) {
1108
+ // 更直播状态
1109
+ liveStatus = false;
1110
+ // 关闭定时推送
1111
+ pushAtTimeTimer?.();
1112
+ // 停止服务
1113
+ this.ctx.bl.closeListener(roomId);
1114
+ // 更改connFlag
1115
+ connFlag = true;
1116
+ // 发送消息
1117
+ await this.sendPrivateMsg(`${roomId}直播间连接已中断!`);
1118
+ this.logger.error(`${roomId}直播间连接已中断!`);
1119
+ }
1120
+ },
1067
1121
  onIncomeDanmu: ({ body }) => {
1068
1122
  // 保存消息到数组
1069
1123
  currentLiveDanmakuArr.push(body.content);
@@ -1793,6 +1847,7 @@ class ComRegister {
1793
1847
  live: koishi_1.Schema.boolean().description("该频道/群组是否推送直播通知"),
1794
1848
  liveGuardBuy: koishi_1.Schema.boolean().description("该频道/群组是否推送弹幕消息"),
1795
1849
  atAll: koishi_1.Schema.boolean().description("推送开播通知时是否艾特全体成员"),
1850
+ bot: koishi_1.Schema.string().description("若您有多个相同平台机器人,可在此填写当前群聊执行推送的机器人账号。不填则默认第一个"),
1796
1851
  })).description("频道/群组信息"),
1797
1852
  platform: koishi_1.Schema.string().description("推送平台"),
1798
1853
  })).description("订阅用户需要发送的频道/群组信息"),
package/lib/index.d.ts CHANGED
@@ -35,6 +35,7 @@ export interface Config {
35
35
  live: boolean;
36
36
  liveGuardBuy: boolean;
37
37
  atAll: boolean;
38
+ bot: string;
38
39
  }>;
39
40
  platform: string;
40
41
  }>;
package/lib/index.js CHANGED
@@ -193,15 +193,10 @@ function apply(ctx, config) {
193
193
  // 设置config
194
194
  globalConfig = config;
195
195
  // 设置提示
196
- ctx.notifier.create({
197
- type: "danger",
198
- content: "从3.1.0-alpha.0及以前版本升级到3.1.0-alpha.1及以后版本必定报错,请重新填写订阅配置中sub.target.channelArr的内容",
199
- });
200
196
  ctx.notifier.create({
201
197
  type: "warning",
202
198
  content: "请使用Auth插件创建超级管理员账号,没有权限将无法使用该插件提供的指令",
203
199
  });
204
- ctx.logger.warn("从3.1.0-alpha.0及以前版本升级到3.1.0-alpha.1版本必定报错,请重新填写订阅配置中sub.target.channelArr的内容");
205
200
  // load database
206
201
  ctx.plugin(Database);
207
202
  // Register ServerManager
@@ -280,6 +275,8 @@ exports.Config = koishi_1.Schema.object({
280
275
  atAll: koishi_1.Schema.boolean()
281
276
  .default(false)
282
277
  .description("推送开播通知时是否艾特全体成员"),
278
+ bot: koishi_1.Schema.string()
279
+ .description("若您有多个相同平台机器人,可在此填写当前群聊执行推送的机器人账号。不填则默认第一个")
283
280
  }))
284
281
  .role("table")
285
282
  .required()
@@ -11,6 +11,7 @@ export type Channel = {
11
11
  live: boolean;
12
12
  liveGuardBuy: boolean;
13
13
  atAll: boolean;
14
+ bot: string;
14
15
  };
15
16
  export type ChannelArr = Array<Channel>;
16
17
  export type TargetItem = {
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.2.0-alpha.6",
4
+ "version": "3.2.1-alpha.0",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
@@ -30,6 +30,7 @@
30
30
  "axios": "^1.7.9",
31
31
  "axios-cookiejar-support": "^5.0.5",
32
32
  "blive-message-listener": "^0.5.0",
33
+ "cacheable-lookup": "^7.0.0",
33
34
  "cron": "^4.3.0",
34
35
  "jsdom": "^24.1.3",
35
36
  "luxon": "^3.5.0",
package/readme.md CHANGED
@@ -255,6 +255,8 @@ uid为必填参数,为要推送的UP主的UID,index为可选参数,为要
255
255
  - ver 3.2.0-alpha.4 修复:直播卡片推送时间会是设置的 `pushTime` 的两倍;
256
256
  - ver 3.2.0-alpha.5 修复:直播检测 `WS` 模式下,直播中推送卡片 `累计观看人数` 位置错误显示为 `粉丝数变化` 、转发动态的留言文字不显示; 优化:直播检测 `API` 模式下,直播推送语 `-watched` 固定显示为 `API模式无法获取`;
257
257
  - ver 3.2.0-alpha.6 优化:调整配置项;
258
+ - ver 3.2.0-alpha.7 修复:自 `3.1.7` 版本 `pushImagesInDynamic` 功能失效;
259
+ - ver 3.2.1-alpha.0 新增:多个相同平台bot可以选择某个群聊/频道指定机器人发送; 优化:直播检测 `WS` 模式下播后仍推送; 修复:打开 `pushImagesInDynamic` 功能时,如果发送的动态里没有图片则会报错 `TypeError: Cannot read properties of null (reading 'opus')`
258
260
 
259
261
  ## 交流群
260
262