koishi-plugin-echo-cave 1.24.18 → 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.
- package/lib/config/config.d.ts +2 -0
- package/lib/index.cjs +116 -5
- package/lib/utils/msg/message-listener.d.ts +10 -0
- package/package.json +1 -1
package/lib/config/config.d.ts
CHANGED
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");
|
|
@@ -126,7 +171,7 @@ async function saveMedia(ctx, mediaElement, type, cfg) {
|
|
|
126
171
|
ctx.logger.warn(`Invalid image content-type: ${contentType}`);
|
|
127
172
|
return mediaUrl;
|
|
128
173
|
}
|
|
129
|
-
if (type === "video" && !contentType.startsWith("video/")) {
|
|
174
|
+
if (type === "video" && !contentType.startsWith("video/") && contentType !== "application/octet-stream") {
|
|
130
175
|
ctx.logger.warn(`Invalid video content-type: ${contentType}`);
|
|
131
176
|
return mediaUrl;
|
|
132
177
|
}
|
|
@@ -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,
|
|
@@ -914,7 +1018,7 @@ async function searchCave(ctx, session, userIds) {
|
|
|
914
1018
|
channelId
|
|
915
1019
|
});
|
|
916
1020
|
const matchingCaves = caves.filter(
|
|
917
|
-
(cave) => cave.originUserId === targetUserId
|
|
1021
|
+
(cave) => cave.relatedUsers.length === 0 ? cave.originUserId === targetUserId : cave.relatedUsers.includes(targetUserId)
|
|
918
1022
|
);
|
|
919
1023
|
if (matchingCaves.length === 0) {
|
|
920
1024
|
return session.text(".noMatchingCaves", [targetUserId]);
|
|
@@ -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>;
|