koishi-plugin-onebot-verifier 1.2.0 → 1.2.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.
Files changed (2) hide show
  1. package/lib/index.js +24 -36
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -101,8 +101,7 @@ function apply(ctx, config) {
101
101
  const activeTasks = /* @__PURE__ */ new Map();
102
102
  const activeCaptchas = /* @__PURE__ */ new Map();
103
103
  const inviterMap = /* @__PURE__ */ new Map();
104
- const requestMap = /* @__PURE__ */ new Map();
105
- const recentRemovals = /* @__PURE__ */ new Map();
104
+ const historyMap = /* @__PURE__ */ new Map();
106
105
  const getComment = /* @__PURE__ */ __name((comment) => {
107
106
  if (!comment) return "";
108
107
  const lines = comment.split(/[\r\n]+/).map((s) => s.trim());
@@ -212,7 +211,7 @@ function apply(ctx, config) {
212
211
  }
213
212
  const verifyText = getComment(eventData.comment);
214
213
  if (kind === "member") {
215
- const rules = config.verifyRules?.filter((r) => String(r.guildId) === String(session.guildId)) || [];
214
+ const rules = config.verifyRules?.filter((r) => r.guildId === session.guildId) || [];
216
215
  for (const rule of rules) {
217
216
  const stats = (rule.minLevel ?? 0) > 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
218
217
  const levelMatch = (stats?.qqLevel ?? 0) >= (rule.minLevel ?? 0);
@@ -222,12 +221,9 @@ function apply(ctx, config) {
222
221
  if (rule.keyword) logger.info(`[加群请求] ${session.userId} 内容 "${verifyText}" ${keywordMatch ? "=" : "≠"} "${rule.keyword}"`);
223
222
  }
224
223
  if (levelMatch && keywordMatch) {
225
- const historyKey = `${session.userId}:${session.guildId}`;
226
- const lastTime = requestMap.get(historyKey) || 0;
227
- const now = Date.now();
228
- const isFrequent = rule.frequency && now - lastTime < rule.frequency * 6e4;
224
+ const lastLeaveTime = historyMap.get(`${session.userId}:${session.guildId}`) || 0;
225
+ const isFrequent = rule.frequency && Date.now() - lastLeaveTime < rule.frequency * 6e4;
229
226
  if (isFrequent) {
230
- requestMap.set(historyKey, now);
231
227
  if (config.frequencyMode === "reject") {
232
228
  await executeAction(session, kind, false, "频繁申请,自动拒绝");
233
229
  await sendNotice(session, kind, "auto_reject");
@@ -238,7 +234,6 @@ function apply(ctx, config) {
238
234
  return await setupManual(session, kind, void 0, false, rule.action === "accept");
239
235
  }
240
236
  }
241
- requestMap.set(historyKey, now);
242
237
  if (rule.action) {
243
238
  await executeAction(session, kind, rule.action === "accept", rule.action === "accept" ? "" : "错误回答,自动拒绝");
244
239
  await sendNotice(session, kind, rule.action === "accept" ? "auto_pass" : "auto_reject");
@@ -246,7 +241,7 @@ function apply(ctx, config) {
246
241
  }
247
242
  }
248
243
  }
249
- const specialRule = config.specialRules?.find((r) => String(r.guildId) === String(session.guildId));
244
+ const specialRule = config.specialRules?.find((r) => r.guildId === session.guildId);
250
245
  if (specialRule) {
251
246
  if (specialRule.mode === "vote") return await setupManual(session, kind, "vote", config.voteInSitu);
252
247
  if (specialRule.mode === "captcha") {
@@ -337,9 +332,13 @@ function apply(ctx, config) {
337
332
  ctx.on("guild-request", hookEvent("guild"));
338
333
  ctx.on("guild-member-request", hookEvent("member"));
339
334
  ctx.on("guild-added", hookEvent("guild"));
335
+ ctx.on("guild-member-removed", async (session) => {
336
+ if (!session.guildId || !session.userId) return;
337
+ if (config.verifyRules?.some((r) => r.guildId === session.guildId)) historyMap.set(`${session.userId}:${session.guildId}`, Date.now());
338
+ });
340
339
  ctx.on("guild-member-added", async (session) => {
341
340
  if (!config.specialRules || !session.guildId || !session.userId) return;
342
- const rule = config.specialRules.find((r) => String(r.guildId) === String(session.guildId));
341
+ const rule = config.specialRules.find((r) => r.guildId === session.guildId);
343
342
  if (rule?.mode === "captcha") {
344
343
  let a, b, op = "+", answer;
345
344
  if (config.captchaDiff === "simple") {
@@ -364,24 +363,23 @@ function apply(ctx, config) {
364
363
  op = "×";
365
364
  answer = (a * b).toString();
366
365
  }
367
- const captchaKey = `${session.guildId}:${session.userId}`;
368
366
  await session.send(`<at id="${session.userId}"/> 请在 60 秒内回复计算结果,以进行验证:${a} ${op} ${b} =`);
369
367
  const timer = setTimeout(async () => {
370
- if (activeCaptchas.has(captchaKey)) {
371
- activeCaptchas.delete(captchaKey);
368
+ if (activeCaptchas.has(`${session.userId}:${session.guildId}`)) {
369
+ activeCaptchas.delete(`${session.userId}:${session.guildId}`);
372
370
  await session.send(`<at id="${session.userId}"/> 验证失败,将被移出本群。`);
373
371
  await session.onebot?.setGroupKick(session.guildId, session.userId, false);
374
372
  }
375
373
  }, 6e4);
376
- activeCaptchas.set(captchaKey, { guildId: session.guildId, userId: session.userId, answer, timer });
374
+ activeCaptchas.set(`${session.userId}:${session.guildId}`, { guildId: session.guildId, userId: session.userId, answer, timer });
377
375
  }
378
376
  });
379
377
  ctx.on("guild-removed", async (session) => {
380
378
  if (session.guildId) {
381
379
  const eventData = session.event?._data || {};
382
380
  const curTime = eventData.time || 0;
383
- if (Math.abs(curTime - (recentRemovals.get(session.guildId) || 0)) < 300) return;
384
- recentRemovals.set(session.guildId, curTime);
381
+ if (Math.abs(curTime - (historyMap.get(session.guildId) || 0)) < 300) return;
382
+ historyMap.set(session.guildId, curTime);
385
383
  if (config.debugMode) logger.info(`[事件] 退出: ${session.guildId} 数据: ${JSON.stringify(eventData)}`);
386
384
  if (eventData.sub_type === "kick_me") {
387
385
  const inviterId = inviterMap.get(session.guildId);
@@ -407,40 +405,30 @@ function apply(ctx, config) {
407
405
  ctx.middleware(async (session, next) => {
408
406
  if (typeof session.content !== "string") return next();
409
407
  if (session.guildId && session.userId) {
410
- const captchaKey = `${session.guildId}:${session.userId}`;
411
- const captcha = activeCaptchas.get(captchaKey);
412
- if (captcha) {
413
- const input2 = session.content.trim();
414
- if (input2 === captcha.answer) {
415
- clearTimeout(captcha.timer);
416
- activeCaptchas.delete(captchaKey);
417
- await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
418
- return;
419
- }
408
+ const captcha = activeCaptchas.get(`${session.userId}:${session.guildId}`);
409
+ if (captcha && session.content.trim() === captcha.answer) {
410
+ clearTimeout(captcha.timer);
411
+ activeCaptchas.delete(`${session.userId}:${session.guildId}`);
412
+ await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
413
+ return;
420
414
  }
421
415
  }
422
416
  if (!session.quote?.id) return next();
423
417
  const task = activeTasks.get(session.quote.id);
424
418
  if (!task) return next();
425
419
  const [ntType, ntId] = (config.notifyTarget || "").split(":");
426
- const isGlobalNotifyTarget = ntType === "private" ? session.userId === ntId : session.guildId === ntId;
427
- const isInSituGuild = task.inSitu && session.guildId && session.guildId === task.session.guildId;
428
- if (!isGlobalNotifyTarget && !isInSituGuild) return next();
420
+ if ((ntType === "private" ? session.userId !== ntId : session.guildId !== ntId) && !(task.inSitu && session.guildId === task.session.guildId)) return next();
429
421
  const input = session.content.replace(/<(quote|at)\s+[^>]*\/>/gi, "").trim();
430
422
  const cmdMatch = input.match(/^(y|n|通过|拒绝)(?:\s+(.*))?$/i);
431
423
  if (!cmdMatch) return next();
432
424
  const isApprove = ["y", "通过"].includes(cmdMatch[1].toLowerCase());
433
425
  const extraInfo = cmdMatch[2]?.trim() || "";
434
426
  if (config.debugMode) logger.info(`[操作] 收到指令: ${isApprove ? "同意" : "拒绝"}`);
435
- if (task.specialMode === "vote") {
436
- await handleSpecialVote(session, task, isApprove, extraInfo);
437
- return;
438
- }
427
+ if (task.specialMode === "vote") return await handleSpecialVote(session, task, isApprove, extraInfo);
439
428
  if (task.timer) clearTimeout(task.timer);
440
429
  task.messages.forEach((msg) => activeTasks.delete(msg));
441
430
  const isSuccess = await executeAction(task.session, task.kind, isApprove, isApprove ? "" : extraInfo, isApprove && task.kind === "friend" ? extraInfo : "");
442
- const replyText = isSuccess ? `已${isApprove ? "通过" : "拒绝"}该请求` : `处理请求失败`;
443
- await session.send(replyText).catch(() => {
431
+ await session.send(isSuccess ? `已${isApprove ? "通过" : "拒绝"}该请求` : `处理请求失败`).catch(() => {
444
432
  });
445
433
  });
446
434
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-onebot-verifier",
3
3
  "description": "[仅支持 Onebot 平台]支持好友申请/群组邀请/加群请求等的自动审核,可根据等级与正则进行筛选,并有入群验证码、投票表决、被踢清理等功能。",
4
- "version": "1.2.0",
4
+ "version": "1.2.1",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],