koishi-plugin-onebot-verifier 1.0.10 → 1.1.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/index.d.ts CHANGED
@@ -21,12 +21,13 @@ export interface Config {
21
21
  minLevel?: number;
22
22
  action?: 'accept' | 'reject';
23
23
  }[];
24
- voteRatio?: string;
25
24
  syncNotify?: boolean;
26
25
  specialRules?: {
27
26
  guildId: string;
28
- mode: 'vote';
27
+ enabled: boolean;
28
+ mode: 'vote' | 'captcha';
29
29
  }[];
30
+ voteRatio?: string;
30
31
  }
31
32
  export declare const Config: Schema<Config>;
32
33
  export declare function apply(ctx: Context, config?: Config): void;
package/lib/index.js CHANGED
@@ -73,22 +73,25 @@ var Config = import_koishi.Schema.intersect([
73
73
  import_koishi.Schema.const("accept").description("同意"),
74
74
  import_koishi.Schema.const("reject").description("拒绝")
75
75
  ]).description("操作")
76
- })).description("加群验证配置").role("table")
76
+ })).description("普通验证配置").role("table")
77
77
  }).description("加群请求配置"),
78
78
  import_koishi.Schema.object({
79
79
  syncNotify: import_koishi.Schema.boolean().description("同步通知目标").default(true),
80
80
  specialRules: import_koishi.Schema.array(import_koishi.Schema.object({
81
81
  guildId: import_koishi.Schema.string().description("群号").required(),
82
82
  mode: import_koishi.Schema.union([
83
- import_koishi.Schema.const("vote").description("投票")
84
- ]).description("模式").default("vote")
85
- })).description("群组特殊配置").role("table"),
83
+ import_koishi.Schema.const("vote").description("投票"),
84
+ import_koishi.Schema.const("captcha").description("验证码")
85
+ ]).description("模式").default("vote"),
86
+ enabled: import_koishi.Schema.boolean().description("前置规则").default(true)
87
+ })).description("配置列表").role("table"),
86
88
  voteRatio: import_koishi.Schema.string().description("投票比例").default("3:2")
87
89
  }).description("特殊验证配置")
88
90
  ]);
89
91
  function apply(ctx, config = {}) {
90
92
  const logger = new import_koishi.Logger("onebot-verifier");
91
93
  const activeTasks = /* @__PURE__ */ new Map();
94
+ const activeCaptchas = /* @__PURE__ */ new Map();
92
95
  const inviterMap = /* @__PURE__ */ new Map();
93
96
  const getComment = /* @__PURE__ */ __name((comment) => {
94
97
  if (!comment) return "";
@@ -149,24 +152,6 @@ function apply(ctx, config = {}) {
149
152
  return [];
150
153
  }
151
154
  }, "sendNotice");
152
- const handleSpecialRule = /* @__PURE__ */ __name(async (session, kind) => {
153
- if (kind !== "member" || !config.specialRules || config.specialRules.length === 0) return false;
154
- const rule = config.specialRules.find((r) => String(r.guildId) === String(session.guildId));
155
- if (!rule) return false;
156
- if (rule.mode === "vote") {
157
- const [yesStr, noStr] = config.voteRatio.split(":");
158
- const targetYes = parseInt(yesStr) || 0;
159
- const targetNo = parseInt(noStr) || 0;
160
- let msgIds = [];
161
- if (config.syncNotify !== false) msgIds = await sendNotice(session, kind, "waiting");
162
- if (msgIds.length > 0) {
163
- const task = { session, kind, messages: msgIds, specialMode: "vote", voteTarget: { yes: targetYes, no: targetNo }, votes: { yes: /* @__PURE__ */ new Set(), no: /* @__PURE__ */ new Set() } };
164
- msgIds.forEach((id) => activeTasks.set(id, task));
165
- }
166
- return true;
167
- }
168
- return false;
169
- }, "handleSpecialRule");
170
155
  const setupManual = /* @__PURE__ */ __name(async (session, kind) => {
171
156
  const waitMinutes = config.timeout ?? 0;
172
157
  const action = kind === "member" ? config.verifyMode : config.timeoutAction;
@@ -206,7 +191,6 @@ function apply(ctx, config = {}) {
206
191
  if (config.debugMode) logger.info(`[收到请求] 类型: ${kind} 数据: ${JSON.stringify(session.event?._data || {})}`);
207
192
  const verifyText = getComment(session.event?._data?.comment);
208
193
  if (kind === "member") {
209
- if (await handleSpecialRule(session, kind)) return;
210
194
  const rules = config.verifyRules?.filter((r) => String(r.guildId) === String(session.guildId)) || [];
211
195
  for (const rule of rules) {
212
196
  const minL = rule.minLevel ?? 0;
@@ -224,9 +208,29 @@ function apply(ctx, config = {}) {
224
208
  return;
225
209
  }
226
210
  }
211
+ const specialRule = config.specialRules?.find((r) => String(r.guildId) === String(session.guildId) && r.enabled);
212
+ if (specialRule) {
213
+ if (specialRule.mode === "vote") {
214
+ const [yesStr, noStr] = config.voteRatio.split(":");
215
+ const targetYes = parseInt(yesStr) || 0;
216
+ const targetNo = parseInt(noStr) || 0;
217
+ let msgIds = [];
218
+ if (config.syncNotify !== false) msgIds = await sendNotice(session, kind, "waiting");
219
+ if (msgIds.length > 0) {
220
+ const task = { session, kind, messages: msgIds, specialMode: "vote", voteTarget: { yes: targetYes, no: targetNo }, votes: { yes: /* @__PURE__ */ new Set(), no: /* @__PURE__ */ new Set() } };
221
+ msgIds.forEach((id) => activeTasks.set(id, task));
222
+ }
223
+ return;
224
+ }
225
+ if (specialRule.mode === "captcha") {
226
+ await executeAction(session, kind, true, "验证码验证,自动通过");
227
+ if (config.syncNotify !== false) await sendNotice(session, kind, "auto_pass");
228
+ return;
229
+ }
230
+ }
227
231
  if (config.verifyMode && config.verifyMode !== "manual") {
228
232
  const isApprove = config.verifyMode === "accept";
229
- await executeAction(session, kind, isApprove, "等待超时,自动处理");
233
+ await executeAction(session, kind, isApprove, "默认规则,自动处理");
230
234
  await sendNotice(session, kind, isApprove ? "auto_pass" : "auto_reject");
231
235
  return;
232
236
  }
@@ -317,6 +321,25 @@ function apply(ctx, config = {}) {
317
321
  ctx.on("guild-request", hookEvent("guild"));
318
322
  ctx.on("guild-member-request", hookEvent("member"));
319
323
  ctx.on("guild-added", hookEvent("guild"));
324
+ ctx.on("guild-member-added", async (session) => {
325
+ if (!config.specialRules || !session.guildId || !session.userId) return;
326
+ const rule = config.specialRules.find((r) => String(r.guildId) === String(session.guildId) && r.enabled);
327
+ if (rule?.mode === "captcha") {
328
+ const a = Math.floor(Math.random() * 20) + 1;
329
+ const b = Math.floor(Math.random() * 20) + 1;
330
+ const answer = (a + b).toString();
331
+ const captchaKey = `${session.guildId}:${session.userId}`;
332
+ await session.send(`<at id="${session.userId}"/> 请在 60 秒内回复计算结果,以进行验证:${a} + ${b} =`);
333
+ const timer = setTimeout(async () => {
334
+ if (activeCaptchas.has(captchaKey)) {
335
+ activeCaptchas.delete(captchaKey);
336
+ await session.send(`<at id="${session.userId}"/> 验证失败,将被移出本群。`);
337
+ await session.onebot?.setGroupKick(session.guildId, session.userId, false);
338
+ }
339
+ }, 6e4);
340
+ activeCaptchas.set(captchaKey, { guildId: session.guildId, userId: session.userId, answer, timer });
341
+ }
342
+ });
320
343
  ctx.on("guild-removed", async (session) => {
321
344
  if (session.event?._data?.sub_type === "kick_me") {
322
345
  const gid = session.guildId;
@@ -335,7 +358,21 @@ function apply(ctx, config = {}) {
335
358
  await sendNotice(session, "removed");
336
359
  });
337
360
  ctx.middleware(async (session, next) => {
338
- if (typeof session.content !== "string" || !session.quote?.id) return next();
361
+ if (typeof session.content !== "string") return next();
362
+ if (session.guildId && session.userId) {
363
+ const captchaKey = `${session.guildId}:${session.userId}`;
364
+ const captcha = activeCaptchas.get(captchaKey);
365
+ if (captcha) {
366
+ const input2 = session.content.trim();
367
+ if (input2 === captcha.answer) {
368
+ clearTimeout(captcha.timer);
369
+ activeCaptchas.delete(captchaKey);
370
+ await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
371
+ return;
372
+ }
373
+ }
374
+ }
375
+ if (!session.quote?.id) return next();
339
376
  const task = activeTasks.get(session.quote.id);
340
377
  if (!task) return next();
341
378
  const [targetType, targetId] = (config.notifyTarget || "").split(":");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-onebot-verifier",
3
3
  "description": "适用于 Onebot 的审核插件,支持自动审核好友/加群/邀请请求",
4
- "version": "1.0.10",
4
+ "version": "1.1.0",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],