mioki 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_package = require('./package-xEK88jTG.cjs');
2
+ const require_package = require('./package-DrAKGYns.cjs');
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_package.__toESM(node_fs);
5
5
  let node_path = require("node:path");
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "./package-DFYh9fsp.mjs";
2
+ import { t as version } from "./package-75_Caljc.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import mri from "mri";
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_package = require('./package-xEK88jTG.cjs');
1
+ const require_package = require('./package-DrAKGYns.cjs');
2
2
  let node_fs = require("node:fs");
3
3
  node_fs = require_package.__toESM(node_fs);
4
4
  let node_util = require("node:util");
@@ -1224,36 +1224,100 @@ function bindBot(bot, func) {
1224
1224
  return (...args) => func(bot, ...args);
1225
1225
  }
1226
1226
  /**
1227
- * 消息去重器
1228
- * 处理多个 bot 在同一个群时,同一消息只处理一次
1227
+ * 去重器
1228
+ * 处理多个 bot 在相同场景下,同一事件只处理一次
1229
1229
  */
1230
- var MessageDeduplicator = class {
1231
- processedMessages = /* @__PURE__ */ new Set();
1230
+ var Deduplicator = class {
1231
+ processedEvents = /* @__PURE__ */ new Set();
1232
1232
  maxSize = 1e3;
1233
1233
  /**
1234
- * 生成消息唯一键
1235
- * 对于群消息:使用 group_id:user_id:time
1236
- * 对于私聊消息:使用 private:user_id:time
1234
+ * 获取事件类型键
1237
1235
  */
1238
- getKey(event) {
1239
- if (event.message_type === "group") return `group:${event.group_id}:${event.user_id}:${event.time}`;
1240
- else return `private:${event.user_id}:${event.time}`;
1236
+ getEventTypeKey(e) {
1237
+ const { post_type } = e;
1238
+ if (post_type === "message") return `msg:${e.message_type}`;
1239
+ if (post_type === "request") {
1240
+ if (e.request_type === "friend") return "req:friend";
1241
+ return `req:group:${e.sub_type ?? "unknown"}`;
1242
+ }
1243
+ if (post_type === "notice") {
1244
+ if (e.notice_type === "group") return `notice:group:${e.sub_type}`;
1245
+ return `notice:${e.notice_type}:${e.sub_type}`;
1246
+ }
1247
+ return "unknown";
1241
1248
  }
1242
- isProcessed(event) {
1243
- return this.processedMessages.has(this.getKey(event));
1249
+ getGroupMessageKey(e) {
1250
+ const groupId = e.group_id ?? "_";
1251
+ const userId = e.user_id ?? "_";
1252
+ const time = e.time ?? "_";
1253
+ const raw = e.raw_message ?? "_";
1254
+ return `msg:group:${groupId}:${userId}:${time}:${node_crypto.default.createHash("md5").update(raw).digest("hex")}`;
1244
1255
  }
1245
- markProcessed(event) {
1246
- if (this.processedMessages.size >= this.maxSize) {
1247
- const first = this.processedMessages.values().next();
1248
- if (!first.done) this.processedMessages.delete(first.value);
1256
+ getPrivateMessageKey(e) {
1257
+ const userId = e.user_id ?? "_";
1258
+ const targetId = e.target_id ?? "_";
1259
+ const time = e.time ?? "_";
1260
+ const raw = e.raw_message ?? "_";
1261
+ return `msg:private:${userId}:${targetId}:${time}:${node_crypto.default.createHash("md5").update(raw).digest("hex")}`;
1262
+ }
1263
+ getNoticeGroupKey(e) {
1264
+ return `${this.getEventTypeKey(e)}:${e.group_id ?? "_"}:${e.user_id ?? "_"}:${"operator_id" in e ? e.operator_id ?? "_" : "_"}:${"target_id" in e ? e.target_id ?? "_" : "_"}:${e.sub_type ?? "_"}:${"action_type" in e ? e.action_type ?? "_" : "_"}:${"duration" in e ? e.duration ?? "_" : "_"}:${e.time ?? "_"}`;
1265
+ }
1266
+ getRequestKey(e) {
1267
+ const typeKey = this.getEventTypeKey(e);
1268
+ const userId = e.user_id ?? "_";
1269
+ const groupId = "group_id" in e ? e.group_id ?? "_" : "_";
1270
+ const time = e.time ?? "_";
1271
+ const comment = e.comment ?? "_";
1272
+ return `${typeKey}:${userId}:${groupId}:${time}:${comment ? node_crypto.default.createHash("md5").update(comment).digest("hex") : "_"}`;
1273
+ }
1274
+ /**
1275
+ * 生成事件唯一键
1276
+ */
1277
+ getKey(e) {
1278
+ const typeKey = this.getEventTypeKey(e);
1279
+ if (typeKey === "msg:group") return this.getGroupMessageKey(e);
1280
+ if (typeKey === "msg:private") return this.getPrivateMessageKey(e);
1281
+ if (typeKey.startsWith("notice:group:")) return this.getNoticeGroupKey(e);
1282
+ if (typeKey.startsWith("req:")) return this.getRequestKey(e);
1283
+ return "";
1284
+ }
1285
+ /**
1286
+ * 检查事件是否已处理过
1287
+ * @param event
1288
+ * @param scope
1289
+ */
1290
+ isProcessed(event, scope) {
1291
+ const key = scope ? `${this.getKey(event)}:${scope}` : this.getKey(event);
1292
+ return this.processedEvents.has(key);
1293
+ }
1294
+ /**
1295
+ * 标记事件为已处理
1296
+ * @param event
1297
+ * @param scope 需与 isProcessed 一致
1298
+ */
1299
+ markProcessed(event, scope) {
1300
+ const key = scope ? `${this.getKey(event)}:${scope}` : this.getKey(event);
1301
+ if (this.processedEvents.size >= this.maxSize) {
1302
+ const first = this.processedEvents.values().next();
1303
+ if (!first.done) this.processedEvents.delete(first.value);
1249
1304
  }
1250
- this.processedMessages.add(this.getKey(event));
1305
+ this.processedEvents.add(key);
1251
1306
  }
1252
- clear() {
1253
- this.processedMessages.clear();
1307
+ };
1308
+ /**
1309
+ * 消息去重器
1310
+ * @deprecated 请使用 Deduplicator,它支持更多事件类型
1311
+ */
1312
+ var MessageDeduplicator = class extends Deduplicator {
1313
+ isProcessed(event) {
1314
+ return super.isProcessed(event);
1315
+ }
1316
+ markProcessed(event) {
1317
+ super.markProcessed(event);
1254
1318
  }
1255
1319
  };
1256
- const deduplicator = new MessageDeduplicator();
1320
+ const deduplicator = new Deduplicator();
1257
1321
  const runtimePlugins = /* @__PURE__ */ new Map();
1258
1322
  const buildRemovedActions = (bot) => Object.fromEntries(Object.entries(actions_exports).map(([k, v]) => [k, bindBot(bot, v)]));
1259
1323
  /**
@@ -1275,6 +1339,24 @@ function isMessageEvent(event) {
1275
1339
  return isGroupMessageEvent(event) || isPrivateMessageEvent(event);
1276
1340
  }
1277
1341
  /**
1342
+ * 检查事件是否是请求事件
1343
+ */
1344
+ function isRequestEvent(event) {
1345
+ return event?.post_type === "request";
1346
+ }
1347
+ /**
1348
+ * 检查事件是否是群通知事件
1349
+ */
1350
+ function isGroupNoticeEvent(event) {
1351
+ return event?.post_type === "notice" && event?.notice_type === "group";
1352
+ }
1353
+ /**
1354
+ * 检查事件是否需要去重
1355
+ */
1356
+ function isDeduplicableEvent(event) {
1357
+ return isMessageEvent(event) || isRequestEvent(event) || isGroupNoticeEvent(event);
1358
+ }
1359
+ /**
1278
1360
  * 定义一个 Mioki 插件
1279
1361
  * @param plugin Mioki 插件对象
1280
1362
  * @returns Mioki 插件对象
@@ -1325,22 +1407,26 @@ async function enablePlugin(bots, plugin, type = "external") {
1325
1407
  clears.add(remove);
1326
1408
  return remove;
1327
1409
  },
1328
- handle: (eventName, handler) => {
1410
+ handle: (eventName, handler, options = {}) => {
1329
1411
  logger$1.debug(`Registering event handler for event: ${String(eventName)}`);
1412
+ const { deduplicate = true } = options;
1413
+ const dedupeScope = `${name}:${String(eventName)}:${node_crypto.default.randomUUID()}`;
1330
1414
  const unsubscribes = [];
1331
1415
  for (const bot$1 of bots) {
1332
- const wrappedHandler = (event) => {
1333
- if (isMessageEvent(event)) {
1334
- const messageEvent = event;
1335
- if (isPrivateMessageEvent(messageEvent)) {
1336
- if (messageEvent.self_id !== bot$1.bot_id) return;
1337
- }
1338
- if (isGroupMessageEvent(messageEvent)) {
1339
- if (deduplicator.isProcessed(messageEvent)) return;
1340
- deduplicator.markProcessed(messageEvent);
1341
- }
1416
+ const wrappedHandler = (e) => {
1417
+ if (isPrivateMessageEvent(e)) {
1418
+ if (e.self_id !== bot$1.bot_id) return;
1419
+ }
1420
+ const senderUserId = e.user_id;
1421
+ const senderOperatorId = e.operator_id;
1422
+ const isFromConnectedBot = senderUserId && bots.some((b) => b.bot_id === senderUserId);
1423
+ const isFromConnectedBotOperator = senderOperatorId && bots.some((b) => b.bot_id === senderOperatorId);
1424
+ if (isFromConnectedBot || isFromConnectedBotOperator) return;
1425
+ if (deduplicate && isDeduplicableEvent(e)) {
1426
+ if (deduplicator.isProcessed(e, dedupeScope)) return;
1427
+ deduplicator.markProcessed(e, dedupeScope);
1342
1428
  }
1343
- handler(event);
1429
+ handler(e);
1344
1430
  };
1345
1431
  bot$1.on(eventName, wrappedHandler);
1346
1432
  const unsubscribe = () => {
@@ -2061,6 +2147,7 @@ exports.BOT_CWD = BOT_CWD;
2061
2147
  exports.BUILTIN_PLUGINS = BUILTIN_PLUGINS;
2062
2148
  exports.CORE_PLUGINS = CORE_PLUGINS;
2063
2149
  exports.ChromeUA = ChromeUA;
2150
+ exports.Deduplicator = Deduplicator;
2064
2151
  exports.MessageDeduplicator = MessageDeduplicator;
2065
2152
  exports.START_TIME = START_TIME;
2066
2153
  exports.SystemMap = SystemMap;