koishi-plugin-echo-cave 1.24.19 → 1.25.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.
@@ -12,5 +12,7 @@ export interface Config {
12
12
  useBase64ForMedia?: boolean;
13
13
  sendAllAsForwardMsg?: boolean;
14
14
  rankingTopCount?: number;
15
+ forwardSelectTimeout?: number;
16
+ enableForwardUserSelection?: boolean;
15
17
  }
16
18
  export declare const Config: Schema<Config>;
package/lib/index.cjs CHANGED
@@ -92,6 +92,51 @@ function parseUserIds(userIds) {
92
92
  };
93
93
  }
94
94
 
95
+ // src/utils/msg/message-listener.ts
96
+ async function listenForUserMessage(options) {
97
+ const { ctx, session, prompt, timeout, onTimeout, onMessage } = options;
98
+ const userId = session.userId;
99
+ const channelId = session.channelId;
100
+ const promptMessage = await session.send(prompt);
101
+ let promptMessageId = "";
102
+ try {
103
+ const msgObj = promptMessage;
104
+ if (msgObj && typeof msgObj === "object" && msgObj.messageId) {
105
+ promptMessageId = String(msgObj.messageId);
106
+ }
107
+ } catch (error) {
108
+ }
109
+ let timeoutId;
110
+ const listener = async (msgSession) => {
111
+ if (msgSession.userId === userId && msgSession.channelId === channelId) {
112
+ clearTimeout(timeoutId);
113
+ const shouldContinue = await onMessage(msgSession.content);
114
+ if (!shouldContinue) {
115
+ ctx.off("message", listener);
116
+ if (promptMessageId) {
117
+ try {
118
+ await session.onebot.deleteMsg(promptMessageId);
119
+ } catch (error) {
120
+ }
121
+ }
122
+ }
123
+ }
124
+ };
125
+ ctx.on("message", listener);
126
+ timeoutId = setTimeout(async () => {
127
+ ctx.off("message", listener);
128
+ if (onTimeout) {
129
+ await onTimeout();
130
+ }
131
+ if (promptMessageId) {
132
+ try {
133
+ await session.onebot.deleteMsg(promptMessageId);
134
+ } catch (error) {
135
+ }
136
+ }
137
+ }, timeout);
138
+ }
139
+
95
140
  // src/utils/media/media-helper.ts
96
141
  var import_axios = __toESM(require("axios"), 1);
97
142
  var import_node_fs = require("node:fs");
@@ -377,6 +422,7 @@ async function addCave(ctx, session, cfg, userIds) {
377
422
  }
378
423
  let content;
379
424
  let type;
425
+ let forwardUsers = [];
380
426
  if (quote.elements[0].type === "forward") {
381
427
  type = "forward";
382
428
  const message = await reconstructForwardMsg(
@@ -386,6 +432,20 @@ async function addCave(ctx, session, cfg, userIds) {
386
432
  cfg
387
433
  );
388
434
  content = JSON.stringify(message);
435
+ const userMap = /* @__PURE__ */ new Map();
436
+ for (const node of message) {
437
+ if (node.type === "node" && node.data) {
438
+ const userId2 = String(node.data.user_id);
439
+ const nickname = node.data.nickname;
440
+ if (userId2 && nickname && !userMap.has(userId2)) {
441
+ userMap.set(userId2, nickname);
442
+ }
443
+ }
444
+ }
445
+ forwardUsers = Array.from(userMap.entries()).map(([userId2, nickname]) => ({
446
+ userId: userId2,
447
+ nickname
448
+ }));
389
449
  } else {
390
450
  type = "msg";
391
451
  const message = (await session.onebot.getMsg(messageId)).message;
@@ -401,6 +461,50 @@ async function addCave(ctx, session, cfg, userIds) {
401
461
  }
402
462
  content = JSON.stringify(await processMessageContent(ctx, msgJson, cfg));
403
463
  }
464
+ if (type === "forward" && forwardUsers.length > 0 && parsedUserIds.length === 0 && cfg.enableForwardUserSelection) {
465
+ const userSelectionPromise = new Promise((resolve) => {
466
+ let prompt = session.text(".selectRelatedUsers");
467
+ forwardUsers.forEach((user, index) => {
468
+ prompt += `
469
+ ${index + 1}: ${user.nickname}`;
470
+ });
471
+ prompt += `
472
+ ${session.text(".selectInstruction")}`;
473
+ listenForUserMessage({
474
+ ctx,
475
+ session,
476
+ prompt,
477
+ timeout: (cfg.forwardSelectTimeout || 20) * 1e3,
478
+ // Convert seconds to milliseconds
479
+ onTimeout: async () => {
480
+ resolve([]);
481
+ },
482
+ onMessage: async (message) => {
483
+ const trimmedMessage = message.trim();
484
+ let selectedUsers = [];
485
+ if (trimmedMessage.toLowerCase() === "all") {
486
+ selectedUsers = forwardUsers.map((user) => user.userId);
487
+ } else if (trimmedMessage.toLowerCase() === "skip") {
488
+ selectedUsers = [];
489
+ } else {
490
+ const indices = trimmedMessage.split(/\s+/).map((index) => parseInt(index.trim()) - 1);
491
+ const validIndices = indices.filter(
492
+ (index) => index >= 0 && index < forwardUsers.length
493
+ );
494
+ if (validIndices.length > 0) {
495
+ selectedUsers = validIndices.map((index) => forwardUsers[index].userId);
496
+ } else {
497
+ await session.send(session.text(".invalidSelection"));
498
+ return true;
499
+ }
500
+ }
501
+ resolve(selectedUsers);
502
+ return false;
503
+ }
504
+ });
505
+ });
506
+ parsedUserIds = await userSelectionPromise;
507
+ }
404
508
  try {
405
509
  const result = await ctx.database.create("echo_cave_v2", {
406
510
  channelId,
@@ -966,7 +1070,10 @@ var zh_CN_default = {
966
1070
  messages: {
967
1071
  noMsgQuoted: "\u{1F4A1} \u8BF7\u5F15\u7528\u4E00\u6761\u6D88\u606F\u540E\u518D\u4F7F\u7528\u6B64\u547D\u4EE4\uFF01",
968
1072
  msgSaved: "\u2705 \u56DE\u58F0\u6D1E\u6D88\u606F\u5DF2\u6210\u529F\u5B58\u5165\uFF0C\u6D88\u606F ID\uFF1A{0}",
969
- msgFailedToSave: "\u274C \u56DE\u58F0\u6D1E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF01"
1073
+ msgFailedToSave: "\u274C \u56DE\u58F0\u6D1E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF01",
1074
+ selectRelatedUsers: "\u8BF7\u9009\u62E9\u8981\u5173\u8054\u7684\u7528\u6237\uFF08\u4EE5\u7A7A\u683C\u5206\u9694\u5E8F\u53F7\uFF0C\u8F93\u5165'all'\u9009\u62E9\u5168\u90E8\uFF09\uFF1A",
1075
+ selectInstruction: "\u8F93\u5165\u793A\u4F8B\uFF1A1 3 \u6216 all",
1076
+ invalidSelection: "\u274C \u65E0\u6548\u7684\u9009\u62E9\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\uFF01"
970
1077
  }
971
1078
  },
972
1079
  "cave.drop": {
@@ -1056,7 +1163,9 @@ var zh_CN_default2 = {
1056
1163
  maxRecordSize: "\u6700\u5927\u5F55\u97F3\u5927\u5C0F (MB)",
1057
1164
  useBase64ForMedia: "\u662F\u5426\u4F7F\u7528 Base64 \u7F16\u7801\u53D1\u9001\u5A92\u4F53\u6587\u4EF6\uFF0C\u5F00\u542F\u540E\u5C06\u8BFB\u53D6 base64 \u7F16\u7801\u53D1\u9001\u800C\u4E0D\u662F\u4F7F\u7528 file uri",
1058
1165
  sendAllAsForwardMsg: "\u662F\u5426\u5C06\u6240\u6709\u6D88\u606F\u4EE5\u8F6C\u53D1\u6D88\u606F\u5F62\u5F0F\u53D1\u9001\uFF0C\u5F00\u542F\u540E\u666E\u901A\u6D88\u606F\u4E5F\u4F1A\u8F6C\u6362\u4E3A\u8F6C\u53D1\u6D88\u606F\u683C\u5F0F",
1059
- rankingTopCount: "\u6392\u884C\u699C\u663E\u793A\u7684\u7528\u6237\u6570\u91CF"
1166
+ rankingTopCount: "\u6392\u884C\u699C\u663E\u793A\u7684\u7528\u6237\u6570\u91CF",
1167
+ forwardSelectTimeout: "\u5408\u5E76\u8F6C\u53D1\u6D88\u606F\u9009\u62E9\u5173\u8054\u7528\u6237\u7684\u8D85\u65F6\u65F6\u95F4 (\u79D2)",
1168
+ enableForwardUserSelection: "\u662F\u5426\u542F\u7528\u5408\u5E76\u8F6C\u53D1\u6D88\u606F\u7684\u5173\u8054\u7528\u6237\u9009\u62E9\u529F\u80FD"
1060
1169
  };
1061
1170
 
1062
1171
  // src/config/config.ts
@@ -1073,7 +1182,9 @@ var Config = import_koishi2.Schema.object({
1073
1182
  maxRecordSize: import_koishi2.Schema.number().default(512),
1074
1183
  useBase64ForMedia: import_koishi2.Schema.boolean().default(false),
1075
1184
  sendAllAsForwardMsg: import_koishi2.Schema.boolean().default(false),
1076
- rankingTopCount: import_koishi2.Schema.number().default(10)
1185
+ rankingTopCount: import_koishi2.Schema.number().default(10),
1186
+ forwardSelectTimeout: import_koishi2.Schema.number().default(20),
1187
+ enableForwardUserSelection: import_koishi2.Schema.boolean().default(true)
1077
1188
  }).i18n({
1078
1189
  "zh-CN": zh_CN_default2
1079
1190
  });
@@ -0,0 +1,10 @@
1
+ import { Context, Session } from 'koishi';
2
+ export interface MessageListenerOptions {
3
+ ctx: Context;
4
+ session: Session;
5
+ prompt: string;
6
+ timeout: number;
7
+ onTimeout?: () => Promise<void>;
8
+ onMessage: (message: string) => Promise<boolean>;
9
+ }
10
+ export declare function listenForUserMessage(options: MessageListenerOptions): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-echo-cave",
3
3
  "description": "Group echo cave",
4
- "version": "1.24.19",
4
+ "version": "1.25.0",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",