koishi-plugin-onebot-verifier 1.1.3 → 1.1.5
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 +10 -4
- package/lib/index.js +46 -33
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -8,13 +8,18 @@ export interface Config {
|
|
|
8
8
|
notifyTarget?: string;
|
|
9
9
|
debugMode?: boolean;
|
|
10
10
|
kickBan?: boolean;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
friendTimeout: 'manual' | {
|
|
12
|
+
action: 'accept' | 'reject';
|
|
13
|
+
timeout: number;
|
|
14
|
+
};
|
|
13
15
|
friendLevel?: number;
|
|
14
16
|
friendRegex?: string;
|
|
15
17
|
minMembers?: number;
|
|
16
18
|
maxCapacity?: number;
|
|
17
|
-
|
|
19
|
+
memberTimeout: 'manual' | {
|
|
20
|
+
action: 'accept' | 'reject';
|
|
21
|
+
timeout: number;
|
|
22
|
+
};
|
|
18
23
|
verifyRules?: {
|
|
19
24
|
guildId: string;
|
|
20
25
|
keyword?: string;
|
|
@@ -28,6 +33,7 @@ export interface Config {
|
|
|
28
33
|
}[];
|
|
29
34
|
captchaDiff?: 'simple' | 'medium' | 'hard';
|
|
30
35
|
voteRatio?: string;
|
|
36
|
+
voteInSitu?: boolean;
|
|
31
37
|
}
|
|
32
38
|
export declare const Config: Schema<Config>;
|
|
33
|
-
export declare function apply(ctx: Context, config
|
|
39
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -49,22 +49,32 @@ var Config = import_koishi.Schema.intersect([
|
|
|
49
49
|
kickBan: import_koishi.Schema.boolean().description("被踢自动处理").default(false)
|
|
50
50
|
}).description("基础配置"),
|
|
51
51
|
import_koishi.Schema.object({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import_koishi.Schema.
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
friendTimeout: import_koishi.Schema.union([
|
|
53
|
+
import_koishi.Schema.const("manual").description("手动"),
|
|
54
|
+
import_koishi.Schema.object({
|
|
55
|
+
action: import_koishi.Schema.union([
|
|
56
|
+
import_koishi.Schema.const("accept").description("同意"),
|
|
57
|
+
import_koishi.Schema.const("reject").description("拒绝")
|
|
58
|
+
]).description("操作").required(),
|
|
59
|
+
timeout: import_koishi.Schema.number().description("时长").default(360).min(1)
|
|
60
|
+
}).description("自动")
|
|
61
|
+
]).description("模式").default("manual"),
|
|
57
62
|
friendLevel: import_koishi.Schema.number().description("最低好友等级").default(0).min(0).max(256),
|
|
58
63
|
friendRegex: import_koishi.Schema.string().description("好友验证正则"),
|
|
59
64
|
minMembers: import_koishi.Schema.number().description("最低群成员数").default(0).min(0).max(3e3),
|
|
60
65
|
maxCapacity: import_koishi.Schema.number().description("最低受邀容量").default(0).min(0).max(3e3)
|
|
61
66
|
}).description("好友邀群配置"),
|
|
62
67
|
import_koishi.Schema.object({
|
|
63
|
-
|
|
64
|
-
import_koishi.Schema.const("
|
|
65
|
-
import_koishi.Schema.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
memberTimeout: import_koishi.Schema.union([
|
|
69
|
+
import_koishi.Schema.const("manual").description("手动"),
|
|
70
|
+
import_koishi.Schema.object({
|
|
71
|
+
action: import_koishi.Schema.union([
|
|
72
|
+
import_koishi.Schema.const("accept").description("同意"),
|
|
73
|
+
import_koishi.Schema.const("reject").description("拒绝")
|
|
74
|
+
]).description("操作").required(),
|
|
75
|
+
timeout: import_koishi.Schema.number().description("超时").default(360).min(1)
|
|
76
|
+
}).description("自动")
|
|
77
|
+
]).description("模式").default("manual"),
|
|
68
78
|
verifyRules: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
69
79
|
guildId: import_koishi.Schema.string().description("群号").required(),
|
|
70
80
|
keyword: import_koishi.Schema.string().description("正则"),
|
|
@@ -84,15 +94,16 @@ var Config = import_koishi.Schema.intersect([
|
|
|
84
94
|
]).description("模式").default("vote"),
|
|
85
95
|
enabled: import_koishi.Schema.boolean().description("前置规则").default(true)
|
|
86
96
|
})).description("配置列表").role("table"),
|
|
87
|
-
voteRatio: import_koishi.Schema.string().description("[投票]
|
|
97
|
+
voteRatio: import_koishi.Schema.string().description("[投票]支持/反对人数").default("3:2"),
|
|
98
|
+
voteInSitu: import_koishi.Schema.boolean().description("[投票]对应群中发起").default(true),
|
|
88
99
|
captchaDiff: import_koishi.Schema.union([
|
|
89
100
|
import_koishi.Schema.const("simple").description("简单"),
|
|
90
101
|
import_koishi.Schema.const("medium").description("中等"),
|
|
91
102
|
import_koishi.Schema.const("hard").description("困难")
|
|
92
|
-
]).description("[
|
|
103
|
+
]).description("[验证]难度").default("simple")
|
|
93
104
|
}).description("特殊验证配置")
|
|
94
105
|
]);
|
|
95
|
-
function apply(ctx, config
|
|
106
|
+
function apply(ctx, config) {
|
|
96
107
|
const logger = new import_koishi.Logger("onebot-verifier");
|
|
97
108
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
98
109
|
const activeCaptchas = /* @__PURE__ */ new Map();
|
|
@@ -128,8 +139,8 @@ function apply(ctx, config = {}) {
|
|
|
128
139
|
return false;
|
|
129
140
|
}
|
|
130
141
|
}, "executeAction");
|
|
131
|
-
const sendNotice = /* @__PURE__ */ __name(async (session, kind, status = "waiting") => {
|
|
132
|
-
const notifyConfig = config.notifyTarget || "";
|
|
142
|
+
const sendNotice = /* @__PURE__ */ __name(async (session, kind, status = "waiting", overrideTarget) => {
|
|
143
|
+
const notifyConfig = overrideTarget || config.notifyTarget || "";
|
|
133
144
|
const [targetType, targetId] = notifyConfig.split(":");
|
|
134
145
|
if (!targetId || !session.bot) return [];
|
|
135
146
|
try {
|
|
@@ -156,35 +167,36 @@ function apply(ctx, config = {}) {
|
|
|
156
167
|
return [];
|
|
157
168
|
}
|
|
158
169
|
}, "sendNotice");
|
|
159
|
-
const setupManual = /* @__PURE__ */ __name(async (session, kind, specialMode) => {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
const setupManual = /* @__PURE__ */ __name(async (session, kind, specialMode, useInSitu) => {
|
|
171
|
+
const mode = kind === "member" ? config.memberTimeout : config.friendTimeout;
|
|
172
|
+
let targetStr = config.notifyTarget || "";
|
|
173
|
+
if (useInSitu && kind === "member" && session.guildId) targetStr = `guild:${session.guildId}`;
|
|
174
|
+
const msgIds = await sendNotice(session, kind, "waiting", targetStr);
|
|
163
175
|
if (!msgIds?.length) return;
|
|
164
|
-
const task = { session, kind, messages: msgIds, specialMode };
|
|
176
|
+
const task = { session, kind, messages: msgIds, specialMode, inSitu: useInSitu };
|
|
165
177
|
if (specialMode === "vote") {
|
|
166
178
|
const [yesStr, noStr] = config.voteRatio.split(":");
|
|
167
179
|
task.voteTarget = { yes: parseInt(yesStr) || 0, no: parseInt(noStr) || 0 };
|
|
168
180
|
task.votes = { yes: /* @__PURE__ */ new Set(), no: /* @__PURE__ */ new Set() };
|
|
169
181
|
}
|
|
170
182
|
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
171
|
-
if (
|
|
183
|
+
if (mode !== "manual" && typeof mode === "object") {
|
|
184
|
+
const { action, timeout } = mode;
|
|
172
185
|
task.timer = setTimeout(async () => {
|
|
173
186
|
if (!activeTasks.has(msgIds[0])) return;
|
|
174
187
|
msgIds.forEach((id) => activeTasks.delete(id));
|
|
175
188
|
let finalAction = action;
|
|
176
|
-
if (specialMode === "vote"
|
|
177
|
-
if (finalAction === "manual") return;
|
|
189
|
+
if (specialMode === "vote") finalAction = "reject";
|
|
178
190
|
const isPass = finalAction === "accept";
|
|
179
191
|
await executeAction(session, kind, isPass, isPass ? "" : "等待超时,自动拒绝");
|
|
180
|
-
const [targetType, targetId] =
|
|
192
|
+
const [targetType, targetId] = targetStr.split(":");
|
|
181
193
|
if (targetId && session.bot) {
|
|
182
194
|
const statusText = `已自动${isPass ? "通过" : "拒绝"}该请求`;
|
|
183
195
|
await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, statusText) : session.bot.sendMessage(targetId, statusText)).catch(() => {
|
|
184
196
|
});
|
|
185
197
|
}
|
|
186
198
|
if (config.debugMode) logger.info(`[操作] 等待超时,默认${isPass ? "通过" : "拒绝"}`);
|
|
187
|
-
},
|
|
199
|
+
}, timeout * 6e4);
|
|
188
200
|
}
|
|
189
201
|
}, "setupManual");
|
|
190
202
|
const hookEvent = /* @__PURE__ */ __name((kind) => async (session) => {
|
|
@@ -214,7 +226,7 @@ function apply(ctx, config = {}) {
|
|
|
214
226
|
}
|
|
215
227
|
const specialRule = config.specialRules?.find((r) => String(r.guildId) === String(session.guildId) && r.enabled);
|
|
216
228
|
if (specialRule) {
|
|
217
|
-
if (specialRule.mode === "vote") return await setupManual(session, kind, "vote");
|
|
229
|
+
if (specialRule.mode === "vote") return await setupManual(session, kind, "vote", config.voteInSitu);
|
|
218
230
|
if (specialRule.mode === "captcha") {
|
|
219
231
|
await executeAction(session, kind, true, "验证码验证,自动通过");
|
|
220
232
|
await sendNotice(session, kind, "auto_pass");
|
|
@@ -270,7 +282,7 @@ function apply(ctx, config = {}) {
|
|
|
270
282
|
logger.error(`处理失败: ${error}`);
|
|
271
283
|
}
|
|
272
284
|
}, "hookEvent");
|
|
273
|
-
const handleSpecialVote = /* @__PURE__ */ __name(async (session, task, isApprove, extraInfo
|
|
285
|
+
const handleSpecialVote = /* @__PURE__ */ __name(async (session, task, isApprove, extraInfo) => {
|
|
274
286
|
if (!task.voteTarget || !task.votes) return;
|
|
275
287
|
const voterId = session.userId;
|
|
276
288
|
if (!voterId) return;
|
|
@@ -296,7 +308,7 @@ function apply(ctx, config = {}) {
|
|
|
296
308
|
task.messages.forEach((msg) => activeTasks.delete(msg));
|
|
297
309
|
const isSuccess = await executeAction(task.session, task.kind, finalVerdict, finalVerdict ? "" : extraInfo);
|
|
298
310
|
const replyText = isSuccess ? `已${finalVerdict ? "通过" : "拒绝"}该投票` : `处理投票失败`;
|
|
299
|
-
|
|
311
|
+
await session.send(replyText).catch(() => {
|
|
300
312
|
});
|
|
301
313
|
}, "handleSpecialVote");
|
|
302
314
|
ctx.on("friend-request", hookEvent("friend"));
|
|
@@ -377,9 +389,10 @@ function apply(ctx, config = {}) {
|
|
|
377
389
|
if (!session.quote?.id) return next();
|
|
378
390
|
const task = activeTasks.get(session.quote.id);
|
|
379
391
|
if (!task) return next();
|
|
380
|
-
const [
|
|
381
|
-
const
|
|
382
|
-
|
|
392
|
+
const [ntType, ntId] = (config.notifyTarget || "").split(":");
|
|
393
|
+
const isGlobalNotifyTarget = ntType === "private" ? session.userId === ntId : session.guildId === ntId;
|
|
394
|
+
const isInSituGuild = task.inSitu && session.guildId && session.guildId === task.session.guildId;
|
|
395
|
+
if (!isGlobalNotifyTarget && !isInSituGuild) return next();
|
|
383
396
|
const input = session.content.replace(/<(quote|at)\s+[^>]*\/>/gi, "").trim();
|
|
384
397
|
const cmdMatch = input.match(/^(y|n|通过|拒绝)(?:\s+(.*))?$/i);
|
|
385
398
|
if (!cmdMatch) return next();
|
|
@@ -387,14 +400,14 @@ function apply(ctx, config = {}) {
|
|
|
387
400
|
const extraInfo = cmdMatch[2]?.trim() || "";
|
|
388
401
|
if (config.debugMode) logger.info(`[操作] 收到指令: ${isApprove ? "同意" : "拒绝"}`);
|
|
389
402
|
if (task.specialMode === "vote") {
|
|
390
|
-
await handleSpecialVote(session, task, isApprove, extraInfo
|
|
403
|
+
await handleSpecialVote(session, task, isApprove, extraInfo);
|
|
391
404
|
return;
|
|
392
405
|
}
|
|
393
406
|
if (task.timer) clearTimeout(task.timer);
|
|
394
407
|
task.messages.forEach((msg) => activeTasks.delete(msg));
|
|
395
408
|
const isSuccess = await executeAction(task.session, task.kind, isApprove, isApprove ? "" : extraInfo, isApprove && task.kind === "friend" ? extraInfo : "");
|
|
396
409
|
const replyText = isSuccess ? `已${isApprove ? "通过" : "拒绝"}该请求` : `处理请求失败`;
|
|
397
|
-
|
|
410
|
+
await session.send(replyText).catch(() => {
|
|
398
411
|
});
|
|
399
412
|
});
|
|
400
413
|
}
|