koishi-plugin-bilirice 0.0.4 → 0.0.6

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.d.ts CHANGED
@@ -1,39 +1,9 @@
1
1
  import { Context, Schema } from 'koishi';
2
- export declare const name = "bilirice";
3
- interface BiliriceConfig {
4
- anchors: [string, string][];
5
- pollInterval?: number;
6
- templates?: {
7
- liveStart?: string;
8
- liveEnd?: string;
9
- };
10
- timeout?: number;
11
- bilibiliCookie?: string;
2
+ export declare const name = "koishi-plugin-bilirice";
3
+ export interface Config {
4
+ roomId: number;
5
+ channelId: string;
6
+ pollInterval: number;
12
7
  }
13
- export declare const Config: Schema<Schemastery.ObjectS<{
14
- anchors: Schema<[string?, string?, ...any[]][], [string?, string?, ...any[]][]>;
15
- pollInterval: Schema<number, number>;
16
- timeout: Schema<number, number>;
17
- bilibiliCookie: Schema<string, string>;
18
- templates: Schema<Schemastery.ObjectS<{
19
- liveStart: Schema<string, string>;
20
- liveEnd: Schema<string, string>;
21
- }>, Schemastery.ObjectT<{
22
- liveStart: Schema<string, string>;
23
- liveEnd: Schema<string, string>;
24
- }>>;
25
- }>, Schemastery.ObjectT<{
26
- anchors: Schema<[string?, string?, ...any[]][], [string?, string?, ...any[]][]>;
27
- pollInterval: Schema<number, number>;
28
- timeout: Schema<number, number>;
29
- bilibiliCookie: Schema<string, string>;
30
- templates: Schema<Schemastery.ObjectS<{
31
- liveStart: Schema<string, string>;
32
- liveEnd: Schema<string, string>;
33
- }>, Schemastery.ObjectT<{
34
- liveStart: Schema<string, string>;
35
- liveEnd: Schema<string, string>;
36
- }>>;
37
- }>>;
38
- export declare function apply(ctx: Context, config: BiliriceConfig): void;
39
- export {};
8
+ export declare const Config: Schema<Config>;
9
+ export declare function apply(ctx: Context, config: Config): void;
package/lib/index.js CHANGED
@@ -36,267 +36,181 @@ __export(src_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(src_exports);
38
38
  var import_koishi = require("koishi");
39
- var import_axios = __toESM(require("axios"));
40
- var import_https = __toESM(require("https"));
41
- var name = "bilirice";
42
- var Config = import_koishi.Schema.object({
43
- anchors: import_koishi.Schema.array(import_koishi.Schema.tuple([
44
- import_koishi.Schema.string().description("B站主播UID(数字,如老番茄14663353)"),
45
- import_koishi.Schema.string().description("通知群号(OneBot格式加group_前缀,如group_123456789)")
46
- ])).required().description("监听的主播列表 → 点击「添加项」可配置多个主播").role("table"),
47
- pollInterval: import_koishi.Schema.number().default(10).description("轮询间隔(秒),建议≥5秒(避免触发B站API风控)").role("slider", { min: 5, max: 30, step: 1 }),
48
- // 控制台显示滑块,更易用
49
- timeout: import_koishi.Schema.number().default(1e4).description("API请求超时时间(毫秒),建议5000-15000").role("number", { min: 5e3, max: 3e4 }),
50
- // 核心:Cookie字段适配控制台(密码类型,输入隐藏 + 详细说明)
51
- bilibiliCookie: import_koishi.Schema.string().description(`【必填】B站登录Cookie(解决-352错误)
52
- 获取方式:
53
- 1. 登录B站直播页 https://live.bilibili.com/
54
- 2. F12 → 网络 → 搜索 getInfoByRoom
55
- 3. 复制请求头中的「Cookie」完整值
56
- (包含SESSDATA/bili_jct/DedeUserID等核心字段)`).required().role("password"),
57
- // 控制台显示为密码输入框,输入内容隐藏
58
- // 通知模板:控制台支持多行文本编辑
59
- templates: import_koishi.Schema.object({
60
- liveStart: import_koishi.Schema.string().default("【{uname} 开播啦】\n标题:{title}\n分区:{area}\n链接:{url}\n开播时间:{startTime}\n封面:{cover}").description("开播通知模板,支持占位符:{uname}/{title}/{area}/{url}/{startTime}/{cover}").role("textarea"),
61
- // 控制台显示多行文本框
62
- liveEnd: import_koishi.Schema.string().default("【{uname} 下播啦】\n直播时长:{liveTime}\n最高在线:{peakOnline}\n观看人数:{watchCount}\n弹幕数:{dmCount}\n人均弹幕:{avgDmPerUser}\n下播时间:{endTime}").description("下播通知模板,额外支持:{liveTime}/{peakOnline}/{watchCount}/{dmCount}/{avgDmPerUser}/{endTime}").role("textarea")
63
- }).description("自定义通知模板(保留占位符即可自动替换数据)")
64
- });
65
- function apply(ctx, config) {
66
- const finalConfig = {
67
- pollInterval: config.pollInterval || 10,
68
- timeout: config.timeout || 1e4,
69
- templates: {
70
- liveStart: config.templates?.liveStart || "【{uname} 开播啦】\n标题:{title}\n分区:{area}\n链接:{url}\n开播时间:{startTime}\n封面:{cover}",
71
- liveEnd: config.templates?.liveEnd || "【{uname} 下播啦】\n直播时长:{liveTime}\n最高在线:{peakOnline}\n观看人数:{watchCount}\n弹幕数:{dmCount}\n人均弹幕:{avgDmPerUser}\n下播时间:{endTime}"
72
- },
73
- anchors: config.anchors || [],
74
- bilibiliCookie: config.bilibiliCookie || ""
75
- };
76
- const anchorStateCache = /* @__PURE__ */ new Map();
77
- const api = import_axios.default.create({
78
- baseURL: "https://api.live.bilibili.com",
79
- timeout: finalConfig.timeout,
80
- httpsAgent: new import_https.default.Agent({ rejectUnauthorized: false }),
81
- headers: {
82
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
83
- "Referer": "https://live.bilibili.com/",
84
- "Origin": "https://live.bilibili.com",
85
- "Accept": "application/json, text/plain, */*",
86
- "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7",
87
- "Cache-Control": "no-cache",
88
- "Pragma": "no-cache",
89
- "Sec-Fetch-Dest": "empty",
90
- "Sec-Fetch-Mode": "cors",
91
- "Sec-Fetch-Site": "same-site",
92
- "Cookie": finalConfig.bilibiliCookie
93
- // 读取控制台配置的Cookie
94
- },
95
- transformResponse: [(data) => data]
96
- });
97
- api.interceptors.response.use(
98
- (response) => {
99
- try {
100
- response.data = JSON.parse(response.data);
101
- return response;
102
- } catch (err) {
103
- throw new Error(`API响应解析失败: ${err.message}`);
104
- }
105
- },
106
- (error) => {
107
- throw new Error(`API请求失败: ${error.message || error.code}`);
108
- }
109
- );
110
- async function getRoomIdByMid(mid) {
111
- const res = await api.get("/room/v1/Room/getRoomInfoOld", {
112
- params: { mid: Number(mid) }
113
- });
114
- if (res.data.code !== 0) throw new Error(`获取直播间ID失败: ${res.data.code} ${res.data.message || ""}`);
115
- return res.data.data.roomid.toString();
39
+
40
+ // src/session.ts
41
+ var LiveSession = class {
42
+ static {
43
+ __name(this, "LiveSession");
116
44
  }
117
- __name(getRoomIdByMid, "getRoomIdByMid");
118
- async function getRoomBaseInfo(roomId) {
119
- const res = await api.get("/room/v1/Room/get_info", {
120
- params: { room_id: Number(roomId) }
121
- });
122
- if (res.data.code !== 0) throw new Error(`获取直播间基础信息失败: ${res.data.code} ${res.data.message || ""}`);
123
- return res.data.data;
45
+ startTime = 0;
46
+ danmuCount = 0;
47
+ maxOnline = 0;
48
+ guardNew = 0;
49
+ guardRenew = 0;
50
+ start() {
51
+ this.startTime = Date.now();
124
52
  }
125
- __name(getRoomBaseInfo, "getRoomBaseInfo");
126
- async function getRoomStat(roomId) {
127
- const res = await api.get("/xlive/web-room/v1/index/getInfoByRoom", {
128
- params: {
129
- room_id: Number(roomId),
130
- platform: "web",
131
- version: "1.0.0",
132
- ts: Date.now()
133
- }
134
- });
135
- if (res.data.code !== 0) throw new Error(`获取直播间统计失败: ${res.data.code} ${res.data.message || ""}`);
136
- const data = res.data.data;
137
- if (!data || !data.room_info) throw new Error("获取直播间统计失败: 返回数据结构异常");
53
+ end() {
138
54
  return {
139
- online: data.room_info.online || 0,
140
- watch_num: data.room_info.watch_num || 0,
141
- interact_num: data.room_info.interact_num || 0,
142
- dm_count: data.room_info.dm_count || 0,
143
- medal_count: data.room_info.medal_count || 0,
144
- fans_count: data.anchor_info?.base_info?.fans_count || 0,
145
- live_time: data.room_info.live_time || 0
55
+ durationMs: Date.now() - this.startTime,
56
+ danmuCount: this.danmuCount,
57
+ maxOnline: this.maxOnline,
58
+ guardNew: this.guardNew,
59
+ guardRenew: this.guardRenew
146
60
  };
147
61
  }
148
- __name(getRoomStat, "getRoomStat");
149
- async function getAnchorInfo(roomId) {
150
- const res = await api.get("/live_user/v1/UserInfo/get_anchor_in_room", {
151
- params: { roomid: Number(roomId) }
152
- });
153
- if (res.data.code !== 0) throw new Error(`获取主播信息失败: ${res.data.code} ${res.data.message || ""}`);
154
- return res.data.data;
62
+ onDanmu() {
63
+ this.danmuCount++;
155
64
  }
156
- __name(getAnchorInfo, "getAnchorInfo");
157
- function formatTime(timestamp) {
158
- return new Date(timestamp * 1e3).toLocaleString("zh-CN", {
159
- year: "numeric",
160
- month: "2-digit",
161
- day: "2-digit",
162
- hour: "2-digit",
163
- minute: "2-digit",
164
- second: "2-digit"
165
- });
65
+ onOnline(count) {
66
+ this.maxOnline = Math.max(this.maxOnline, count);
166
67
  }
167
- __name(formatTime, "formatTime");
168
- function formatSeconds(seconds) {
169
- const h = Math.floor(seconds / 3600);
170
- const m = Math.floor(seconds % 3600 / 60);
171
- const s = seconds % 60;
172
- return [h, m, s].map((v) => v.toString().padStart(2, "0")).join(":");
68
+ onGuard(num) {
69
+ num > 1 ? this.guardRenew++ : this.guardNew++;
173
70
  }
174
- __name(formatSeconds, "formatSeconds");
175
- function calcLiveStat(startTime, endTime, lastStat, currentStat) {
176
- let fansChange = 0;
177
- if (lastStat && currentStat) fansChange = currentStat.fans_count - lastStat.fans_count;
178
- return {
179
- liveTime: endTime - startTime,
180
- peakOnline: currentStat.online,
181
- watchCount: currentStat.watch_num,
182
- interactCount: currentStat.interact_num,
183
- dmCount: currentStat.dm_count,
184
- avgDmPerUser: Number((currentStat.dm_count / Math.max(currentStat.watch_num, 1)).toFixed(2)),
185
- medalCount: currentStat.medal_count,
186
- fansChange,
187
- endTime
188
- };
71
+ get avgDanmu() {
72
+ return this.maxOnline ? (this.danmuCount / this.maxOnline).toFixed(2) : "0";
73
+ }
74
+ formatDuration(ms) {
75
+ const h2 = Math.floor(ms / 36e5);
76
+ const m = Math.floor(ms % 36e5 / 6e4);
77
+ return `${h2}小时${m}分钟`;
78
+ }
79
+ };
80
+
81
+ // src/index.ts
82
+ var import_ws = __toESM(require("ws"));
83
+ var name = "koishi-plugin-bilirice";
84
+ var logger = new import_koishi.Logger("bilirice");
85
+ var Config = import_koishi.Schema.object({
86
+ roomId: import_koishi.Schema.number().description("Bilibili 直播间 room_id").required(),
87
+ channelId: import_koishi.Schema.string().description("推送到的群 / 频道 ID").required(),
88
+ pollInterval: import_koishi.Schema.number().default(30).description("轮询间隔(秒)")
89
+ });
90
+ function apply(ctx, config) {
91
+ const session = new LiveSession();
92
+ let isLiving = false;
93
+ let ws = null;
94
+ let liveStartTime = 0;
95
+ async function fetchJSON(url) {
96
+ const res = await ctx.http.get(url);
97
+ if (res?.code !== 0) throw new Error(res?.message || "API Error");
98
+ return res.data;
189
99
  }
190
- __name(calcLiveStat, "calcLiveStat");
191
- function renderTemplate(template, data) {
192
- return template.replace(/\{(\w+)\}/g, (_, key) => data[key] ?? `{${key}}`);
100
+ __name(fetchJSON, "fetchJSON");
101
+ async function send(text, image) {
102
+ const content = image ? import_koishi.h.image(image) + "\n" + text : text;
103
+ await ctx.broadcast([config.channelId], content);
193
104
  }
194
- __name(renderTemplate, "renderTemplate");
195
- async function sendGroupMessage(groupId, message) {
196
- const bot = ctx.bots.values().next().value;
197
- if (!bot) throw new Error("未找到可用的Bot实例");
198
- await bot.sendMessage(groupId, message);
105
+ __name(send, "send");
106
+ function formatTime(ts = Date.now()) {
107
+ return new Date(ts).toLocaleString();
199
108
  }
200
- __name(sendGroupMessage, "sendGroupMessage");
201
- async function initAnchorState(mid) {
202
- if (anchorStateCache.has(mid)) return;
203
- const roomId = await getRoomIdByMid(mid);
204
- const roomInfo = await getRoomBaseInfo(roomId);
205
- const isOnline = roomInfo.live_status === 1;
206
- const lastStat = isOnline ? await getRoomStat(roomId) : null;
207
- anchorStateCache.set(mid, {
208
- mid,
209
- roomId,
210
- isOnline,
211
- liveStartTime: isOnline ? roomInfo.live_time : 0,
212
- lastStat
109
+ __name(formatTime, "formatTime");
110
+ const getRoomInfo = /* @__PURE__ */ __name(() => fetchJSON(`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${config.roomId}`), "getRoomInfo");
111
+ const getAnchorInfo = /* @__PURE__ */ __name(() => fetchJSON(`https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room?roomid=${config.roomId}`), "getAnchorInfo");
112
+ async function onLiveStart(room, anchor) {
113
+ session.start();
114
+ liveStartTime = Date.now();
115
+ const text = `【开播提醒】${anchor.info.uname} 开始直播啦!
116
+
117
+ 📝 直播间标题:${room.title}
118
+ 📂 直播分区:${room.parent_area_name} / ${room.area_name}
119
+ 🏷️ 标签:${room.tags || "无"}
120
+ 开播时间:${formatTime(room.live_time * 1e3)}
121
+
122
+ 快来直播间一起玩吧~
123
+ 👉 https://live.bilibili.com/${config.roomId}`;
124
+ await send(text, room.user_cover);
125
+ connectWS();
126
+ }
127
+ __name(onLiveStart, "onLiveStart");
128
+ async function onLiveEnd(anchor) {
129
+ disconnectWS();
130
+ const result = session.end();
131
+ const text = `【下播提醒】${anchor.info.uname} 结束直播啦!
132
+
133
+ 📊 直播时长:${session.formatDuration(Date.now() - liveStartTime)}
134
+ 👥 最高在线:${result.maxOnline}
135
+ 💬 弹幕统计:${result.danmuCount}
136
+ 📈 人均弹幕:${session.avgDanmu}
137
+ ⚓ 舰队统计:新增 ${result.guardNew} 人,续费 ${result.guardRenew} 人
138
+ ⏰ 下播时间:${formatTime()}
139
+
140
+ 感谢大家的陪伴 💖`;
141
+ await send(text);
142
+ }
143
+ __name(onLiveEnd, "onLiveEnd");
144
+ function connectWS() {
145
+ if (ws) return;
146
+ ws = new import_ws.default("wss://broadcastlv.chat.bilibili.com/sub");
147
+ ws.on("open", () => {
148
+ logger.info("WebSocket connected");
149
+ });
150
+ ws.on("message", (data) => {
151
+ try {
152
+ const text = data.toString();
153
+ if (!text.includes("{")) return;
154
+ const msg = JSON.parse(text);
155
+ handleWSMessage(msg);
156
+ } catch {
157
+ }
158
+ });
159
+ ws.on("close", () => {
160
+ ws = null;
161
+ logger.warn("WebSocket closed");
213
162
  });
214
163
  }
215
- __name(initAnchorState, "initAnchorState");
216
- async function checkAnchorState(mid, groupIds) {
217
- const state = anchorStateCache.get(mid);
218
- if (!state) {
219
- await initAnchorState(mid);
220
- return;
221
- }
222
- const roomInfo = await getRoomBaseInfo(state.roomId);
223
- const currentOnline = roomInfo.live_status === 1;
224
- const anchorInfo = await getAnchorInfo(state.roomId);
225
- const now = Math.floor(Date.now() / 1e3);
226
- if (!state.isOnline && currentOnline) {
227
- const currentStat = await getRoomStat(state.roomId);
228
- state.isOnline = true;
229
- state.liveStartTime = roomInfo.live_time || now;
230
- state.lastStat = currentStat;
231
- const templateData = {
232
- uname: anchorInfo.info.uname,
233
- title: roomInfo.title,
234
- area: `${roomInfo.parent_area_name || ""} - ${roomInfo.area_name || ""}`,
235
- url: `https://live.bilibili.com/${state.roomId}`,
236
- startTime: formatTime(state.liveStartTime),
237
- cover: import_koishi.segment.image(roomInfo.user_cover || "")
238
- };
239
- const message = renderTemplate(finalConfig.templates.liveStart, templateData);
240
- for (const gid of groupIds) await sendGroupMessage(gid, message);
241
- ctx.logger.info(`主播${mid}开播,已发送通知到指定群聊`);
242
- } else if (state.isOnline && !currentOnline && state.liveStartTime > 0) {
243
- const currentStat = await getRoomStat(state.roomId);
244
- const liveStat = calcLiveStat(state.liveStartTime, now, state.lastStat, currentStat);
245
- state.isOnline = false;
246
- state.liveStartTime = 0;
247
- const templateData = {
248
- uname: anchorInfo.info.uname,
249
- liveTime: formatSeconds(liveStat.liveTime),
250
- peakOnline: liveStat.peakOnline.toLocaleString(),
251
- watchCount: liveStat.watchCount.toLocaleString(),
252
- dmCount: liveStat.dmCount.toLocaleString(),
253
- avgDmPerUser: liveStat.avgDmPerUser,
254
- medalCount: liveStat.medalCount.toLocaleString(),
255
- fansChange: liveStat.fansChange > 0 ? `+${liveStat.fansChange}` : liveStat.fansChange.toString(),
256
- endTime: formatTime(liveStat.endTime),
257
- url: `https://live.bilibili.com/${state.roomId}`
258
- };
259
- const message = renderTemplate(finalConfig.templates.liveEnd, templateData);
260
- for (const gid of groupIds) await sendGroupMessage(gid, message);
261
- ctx.logger.info(`主播${mid}下播,已发送统计通知到指定群聊`);
262
- } else if (state.isOnline && currentOnline) {
263
- const currentStat = await getRoomStat(state.roomId);
264
- state.lastStat = currentStat;
265
- }
164
+ __name(connectWS, "connectWS");
165
+ function disconnectWS() {
166
+ ws?.close();
167
+ ws = null;
266
168
  }
267
- __name(checkAnchorState, "checkAnchorState");
268
- ctx.on("ready", async () => {
269
- if (!finalConfig.anchors || finalConfig.anchors.length === 0) {
270
- ctx.logger.error("bilirice插件未配置任何主播,无法启动!");
271
- return;
169
+ __name(disconnectWS, "disconnectWS");
170
+ function handleWSMessage(msg) {
171
+ const cmd = msg?.cmd;
172
+ if (cmd === "DANMU_MSG") {
173
+ session.onDanmu();
272
174
  }
273
- if (!finalConfig.bilibiliCookie) {
274
- ctx.logger.error("bilirice插件未配置B站Cookie,无法解决-352错误,请补充配置!");
275
- return;
175
+ if (cmd === "SUPER_CHAT_MESSAGE") {
176
+ const sc = msg.data;
177
+ const price = sc.price * 10;
178
+ const text = `【醒目留言 ${price}电池】
179
+ ${sc.user_info.uname}(${sc.uid}):
180
+ ${sc.message}`;
181
+ send(text);
276
182
  }
277
- for (const [mid, _] of finalConfig.anchors) {
278
- await initAnchorState(mid).catch((err) => ctx.logger.error(`初始化主播${mid}失败:`, err.message));
183
+ if (cmd === "GUARD_BUY") {
184
+ const g = msg.data;
185
+ session.onGuard(g.num);
186
+ const price = g.price * g.num * 10;
187
+ const text = `【舰队事件】
188
+ ${g.username}(${g.uid})
189
+ 开通 ${g.gift_name}(${price}电池)`;
190
+ send(text);
279
191
  }
280
- ctx.setInterval(async () => {
281
- for (const [mid, groupStr] of finalConfig.anchors) {
282
- const groupIds = groupStr.split(",").filter((g) => g.trim());
283
- await checkAnchorState(mid, groupIds).catch((err) => ctx.logger.error(`检查主播${mid}失败:`, err.message));
284
- }
285
- }, finalConfig.pollInterval * 1e3);
286
- ctx.logger.info(`bilirice插件已启动,监听主播数:${finalConfig.anchors.length},轮询间隔:${finalConfig.pollInterval}秒`);
287
- });
288
- ctx.command("bilirice <mid>", "手动检查指定主播的直播间状态").action(async ({ session }, mid) => {
289
- if (!mid) return "请输入主播UID";
290
- if (!finalConfig.bilibiliCookie) return "插件未配置B站Cookie,无法执行操作!";
192
+ if (cmd === "ROOM_REAL_TIME_MESSAGE_UPDATE") {
193
+ session.onOnline(msg.data.online);
194
+ }
195
+ }
196
+ __name(handleWSMessage, "handleWSMessage");
197
+ ctx.setInterval(async () => {
291
198
  try {
292
- const groupIds = session.guildId ? [session.guildId] : [];
293
- await initAnchorState(mid);
294
- await checkAnchorState(mid, groupIds);
295
- return `已检查主播${mid}的直播间状态(含完整统计数据)`;
296
- } catch (err) {
297
- return `检查失败:${err.message}`;
199
+ const room = await getRoomInfo();
200
+ const anchor = await getAnchorInfo();
201
+ const living = room.live_status === 1;
202
+ if (living && !isLiving) {
203
+ isLiving = true;
204
+ await onLiveStart(room, anchor);
205
+ }
206
+ if (!living && isLiving) {
207
+ isLiving = false;
208
+ await onLiveEnd(anchor);
209
+ }
210
+ } catch (e) {
211
+ logger.warn(String(e));
298
212
  }
299
- });
213
+ }, config.pollInterval * 1e3);
300
214
  }
301
215
  __name(apply, "apply");
302
216
  // Annotate the CommonJS export names for ESM import in node:
@@ -0,0 +1,20 @@
1
+ export declare class LiveSession {
2
+ private startTime;
3
+ danmuCount: number;
4
+ maxOnline: number;
5
+ guardNew: number;
6
+ guardRenew: number;
7
+ start(): void;
8
+ end(): {
9
+ durationMs: number;
10
+ danmuCount: number;
11
+ maxOnline: number;
12
+ guardNew: number;
13
+ guardRenew: number;
14
+ };
15
+ onDanmu(): void;
16
+ onOnline(count: number): void;
17
+ onGuard(num: number): void;
18
+ get avgDanmu(): string;
19
+ formatDuration(ms: number): string;
20
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-bilirice",
3
3
  "description": "这是一个bilibili直播间事件监控插件",
4
- "version": "0.0.4",
4
+ "version": "0.0.6",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -19,6 +19,10 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "axios": "^1.13.4",
22
- "koishi-plugin-adapter-onebot": "^6.8.0"
22
+ "koishi-plugin-adapter-onebot": "^6.8.0",
23
+ "ws": "^8.19.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/ws": "^8"
23
27
  }
24
28
  }