koishi-plugin-onebot-verifier 1.2.8 → 1.2.10

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 +40 -27
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -160,7 +160,9 @@ function apply(ctx, config) {
160
160
  if (kind !== "guild" && kind !== "removed" || session.userId && session.userId !== session.selfId) infoLines.push(`用户:${userInfo?.name || session.userId}${session.userId ? `(${session.userId})` : ""}`);
161
161
  if (adminId) infoLines.push(`管理:${adminInfo?.name ? `${adminInfo.name}(${adminId})` : adminId}`);
162
162
  if (session.guildId) infoLines.push(`群组:${groupInfo?.name ? `${groupInfo.name}(${session.guildId})` : session.guildId}`);
163
+ if (eventData.invitor_id && String(eventData.invitor_id) !== "0") infoLines.push(`邀请者:${eventData.invitor_id}`);
163
164
  if (eventData.comment) infoLines.push(`验证信息:${eventData.comment}`);
165
+ if (eventData.via) infoLines.push(`来源:${eventData.via}`);
164
166
  if (status === "waiting" && kind !== "removed") {
165
167
  if (specialMode === "vote") infoLines.push(`[投票模式]需${config.voteRatio.split(":")[0]}人同意或${config.voteRatio.split(":")[1]}人拒绝`);
166
168
  infoLines.push(`使用"y/n"回复本消息以处理该请求`);
@@ -209,29 +211,40 @@ function apply(ctx, config) {
209
211
  const eventData = session.event?._data || {};
210
212
  if (eventData.user_id) session.userId = String(eventData.user_id);
211
213
  if (eventData.group_id) session.guildId = String(eventData.group_id);
214
+ const isApply = kind === "guild" && eventData.post_type === "request" && !!eventData.invited_id && String(eventData.invited_id) !== String(eventData.self_id);
215
+ if (isApply) session.userId = String(eventData.invited_id);
212
216
  if (session.guildId && config.blacklist?.includes(session.guildId)) return;
213
217
  try {
214
- if (config.debugMode) logger.info(`[请求] 类型: ${kind} 数据: ${JSON.stringify(eventData)}`);
218
+ if (config.debugMode) logger.info(`[请求] 类型: ${isApply ? "member" : kind} 数据: ${JSON.stringify(eventData)}`);
219
+ const verifyText = getComment(eventData.comment);
215
220
  if (kind === "friend") {
216
- const flag = eventData.flag || `${session.userId}:${eventData.time}`;
217
- const now = Date.now();
218
- const flagKey = `flag:${flag}`;
219
- if (historyMap.has(flagKey) && now - historyMap.get(flagKey) < 3e4) return;
220
- historyMap.set(flagKey, now);
221
- let updatedPending = false;
222
- for (const task of new Set(activeTasks.values())) {
223
- if (task.kind === "friend" && task.session.userId === session.userId) {
224
- task.session = session;
225
- updatedPending = true;
221
+ const existingTask = [...activeTasks.values()].find((t) => t.kind === "friend" && t.session.userId === session.userId);
222
+ if (existingTask) {
223
+ if (existingTask.timer) clearTimeout(existingTask.timer);
224
+ const oldVerifyText = getComment(existingTask.session.event?._data?.comment);
225
+ if (oldVerifyText === verifyText) {
226
+ existingTask.session = session;
227
+ const timeoutCfg = config.friendTimeout;
228
+ if (typeof timeoutCfg === "number") {
229
+ const isPass = timeoutCfg > 0;
230
+ existingTask.timer = setTimeout(async () => {
231
+ if (!activeTasks.has(existingTask.messages[0])) return;
232
+ existingTask.messages.forEach((id) => activeTasks.delete(id));
233
+ await executeAction(session, "friend", isPass, isPass ? "" : "等待超时,自动拒绝");
234
+ const [targetType, targetId] = (config.notifyTarget || "").split(":");
235
+ if (targetId && session.bot) {
236
+ const statusText = `已自动${isPass ? "通过" : "拒绝"}该请求`;
237
+ await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, statusText) : session.bot.sendMessage(targetId, statusText)).catch(() => {
238
+ });
239
+ }
240
+ }, Math.abs(timeoutCfg) * 6e4);
241
+ }
242
+ return;
226
243
  }
244
+ existingTask.messages.forEach((id) => activeTasks.delete(id));
227
245
  }
228
- if (updatedPending) return;
229
- const userKey = `friend:${session.userId}`;
230
- if (historyMap.has(userKey) && now - historyMap.get(userKey) < 3e4) return;
231
- historyMap.set(userKey, now);
232
246
  }
233
- const verifyText = getComment(eventData.comment);
234
- if (kind === "member") {
247
+ if (isApply || kind === "member") {
235
248
  const rules = config.verifyRules?.filter((r) => r.guildId === session.guildId) || [];
236
249
  for (const rule of rules) {
237
250
  const stats = (rule.minLevel ?? 0) > 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
@@ -246,32 +259,32 @@ function apply(ctx, config) {
246
259
  const isFrequent = rule.frequency && Date.now() - lastLeaveTime < rule.frequency * 6e4;
247
260
  if (isFrequent) {
248
261
  if (config.frequencyMode === "reject") {
249
- await executeAction(session, kind, false, "频繁申请,自动拒绝");
250
- await sendNotice(session, kind, "auto_reject");
262
+ await executeAction(session, isApply ? "member" : kind, false, "频繁申请,自动拒绝");
263
+ await sendNotice(session, isApply ? "member" : kind, "auto_reject");
251
264
  return;
252
265
  } else if (config.frequencyMode === "ignore") {
253
- return await setupManual(session, kind);
266
+ return await setupManual(session, isApply ? "member" : kind);
254
267
  } else if (config.frequencyMode === "delay") {
255
- return await setupManual(session, kind, void 0, false, rule.action === "accept");
268
+ return await setupManual(session, isApply ? "member" : kind, void 0, false, rule.action === "accept");
256
269
  }
257
270
  }
258
271
  if (rule.action) {
259
- await executeAction(session, kind, rule.action === "accept", rule.action === "accept" ? "" : "错误回答,自动拒绝");
260
- await sendNotice(session, kind, rule.action === "accept" ? "auto_pass" : "auto_reject");
272
+ await executeAction(session, isApply ? "member" : kind, rule.action === "accept", rule.action === "accept" ? "" : "错误回答,自动拒绝");
273
+ await sendNotice(session, isApply ? "member" : kind, rule.action === "accept" ? "auto_pass" : "auto_reject");
261
274
  return;
262
275
  }
263
276
  }
264
277
  }
265
278
  const specialRule = config.specialRules?.find((r) => r.guildId === session.guildId);
266
279
  if (specialRule) {
267
- if (specialRule.mode === "vote") return await setupManual(session, kind, "vote", config.voteInSitu);
280
+ if (specialRule.mode === "vote") return await setupManual(session, isApply ? "member" : kind, "vote", config.voteInSitu);
268
281
  if (specialRule.mode === "captcha") {
269
- await executeAction(session, kind, true, "验证码验证,自动通过");
270
- await sendNotice(session, kind, "auto_pass");
282
+ await executeAction(session, isApply ? "member" : kind, true, "验证码验证,自动通过");
283
+ await sendNotice(session, isApply ? "member" : kind, "auto_pass");
271
284
  return;
272
285
  }
273
286
  }
274
- return await setupManual(session, kind);
287
+ return await setupManual(session, isApply ? "member" : kind);
275
288
  }
276
289
  let verdict = false;
277
290
  if (kind === "friend") {
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.8",
4
+ "version": "1.2.10",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],