koishi-plugin-onebot-verifier 1.0.5 → 1.0.7

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
@@ -7,6 +7,7 @@ export declare const usage = "\n<div style=\"border-radius: 10px; border: 1px so
7
7
  export interface Config {
8
8
  notifyTarget?: string;
9
9
  debugMode?: boolean;
10
+ kickBan?: boolean;
10
11
  timeout?: number;
11
12
  timeoutAction?: 'accept' | 'reject';
12
13
  friendLevel?: number;
package/lib/index.js CHANGED
@@ -45,7 +45,8 @@ var usage = `
45
45
  var Config = import_koishi.Schema.intersect([
46
46
  import_koishi.Schema.object({
47
47
  notifyTarget: import_koishi.Schema.string().description("通知目标(guild/private:number)").required(),
48
- debugMode: import_koishi.Schema.boolean().description("输出调试日志").default(false)
48
+ debugMode: import_koishi.Schema.boolean().description("输出调试日志").default(false),
49
+ kickBan: import_koishi.Schema.boolean().description("被踢自动处理").default(false)
49
50
  }).description("基础配置"),
50
51
  import_koishi.Schema.object({
51
52
  timeout: import_koishi.Schema.number().description("请求超时时长").default(360).min(0),
@@ -78,10 +79,12 @@ var Config = import_koishi.Schema.intersect([
78
79
  function apply(ctx, config = {}) {
79
80
  const logger = new import_koishi.Logger("onebot-verifier");
80
81
  const activeTasks = /* @__PURE__ */ new Map();
82
+ const inviterMap = /* @__PURE__ */ new Map();
81
83
  const executeAction = /* @__PURE__ */ __name(async (session, kind, pass, reason = "", remark = "") => {
82
84
  try {
83
85
  const eventData = session.event?._data || {};
84
86
  if (config.debugMode) logger.info(`[执行操作] 类型:${kind} 结果:${pass ? "同意" : "拒绝"} 原因:${reason || "无"}`);
87
+ if (pass && kind === "guild" && session.guildId && session.userId) inviterMap.set(session.guildId, session.userId);
85
88
  if (!pass && kind === "guild" && session.guildId && (session.event?.type === "guild-added" || eventData.notice_type === "group_increase")) {
86
89
  if (reason) {
87
90
  try {
@@ -111,14 +114,26 @@ function apply(ctx, config = {}) {
111
114
  const eventData = session.event?._data || {};
112
115
  const userInfo = session.userId ? await session.bot.getUser?.(session.userId)?.catch(() => null) : null;
113
116
  const groupInfo = kind !== "friend" && session.guildId ? await session.bot.getGuild?.(session.guildId)?.catch(() => null) : null;
114
- const adminInfo = eventData.operator_id && session.userId && eventData.operator_id !== session.userId ? await session.bot.getUser?.(eventData.operator_id)?.catch(() => null) : null;
117
+ const adminId = eventData.operator_id || session.event.operator?.id;
118
+ const adminInfo = adminId && session.userId && adminId !== session.userId ? await session.bot.getUser?.(adminId)?.catch(() => null) : null;
115
119
  const infoLines = [];
116
120
  if (userInfo?.avatar) infoLines.push(`<image url="${userInfo.avatar}"/>`);
117
- const typeName = kind === "friend" ? "好友申请" : kind === "member" ? "加群请求" : "群组邀请";
118
- const statusText = status === "auto_pass" ? "[自动通过]" : status === "auto_reject" ? "[自动拒绝]" : "[等待处理]";
119
- infoLines.push(`类型:${typeName} ${statusText}`);
120
- if (kind !== "guild" || session.userId !== session.selfId) infoLines.push(`用户:${userInfo?.name || session.userId}${session.userId ? `(${session.userId})` : ""}`);
121
- if (adminInfo) infoLines.push(`管理:${adminInfo.name ? `${adminInfo.name}(${eventData.operator_id})` : eventData.operator_id}`);
121
+ let typeName = "";
122
+ if (kind === "friend") typeName = "好友申请";
123
+ else if (kind === "member") typeName = "加群请求";
124
+ else if (kind === "guild") typeName = "群组邀请";
125
+ else if (kind === "removed") typeName = eventData.sub_type === "kick_me" ? "机器人被踢" : "机器人退群";
126
+ let statusText = "";
127
+ if (kind === "removed") {
128
+ if (eventData.sub_type === "kick_me" && config.kickBan) statusText = " [自动清理]";
129
+ } else {
130
+ statusText = status === "auto_pass" ? " [自动通过]" : status === "auto_reject" ? " [自动拒绝]" : " [等待处理]";
131
+ }
132
+ infoLines.push(`类型:${typeName}${statusText}`);
133
+ if (kind !== "guild" && kind !== "removed" || session.userId !== session.selfId) {
134
+ infoLines.push(`用户:${userInfo?.name || session.userId}${session.userId ? `(${session.userId})` : ""}`);
135
+ }
136
+ if (adminInfo) infoLines.push(`管理:${adminInfo.name ? `${adminInfo.name}(${adminId})` : adminId}`);
122
137
  if (groupInfo) infoLines.push(`群组:${groupInfo.name ? `${groupInfo.name}(${session.guildId})` : session.guildId}`);
123
138
  if (eventData.comment) infoLines.push(`验证信息:${eventData.comment}`);
124
139
  const content = infoLines.join("\n");
@@ -130,7 +145,7 @@ function apply(ctx, config = {}) {
130
145
  }, "sendNotice");
131
146
  const checkCriteria = /* @__PURE__ */ __name(async (session, kind) => {
132
147
  const rawText = session.event?._data?.comment || "";
133
- const cleanLines = rawText.split(/[\r\n]+/).map((s) => s.trim()).filter((s) => /^(回答)[::]/i.test(s)).map((s) => s.replace(/^(回答)[::]\s*/i, ""));
148
+ const cleanLines = rawText.split(/[\r\n]+/).map((s) => s.trim()).filter((s) => /^(回答|答案)[::]/i.test(s)).map((s) => s.replace(/^(回答|答案)[::]\s*/i, ""));
134
149
  const verifyText = cleanLines.length > 0 ? cleanLines.join("\n") : rawText;
135
150
  if (kind === "friend") {
136
151
  try {
@@ -155,7 +170,7 @@ function apply(ctx, config = {}) {
155
170
  try {
156
171
  const userData = session.userId ? await ctx.database.getUser(session.platform, session.userId) : null;
157
172
  if (userData && userData.authority > 1) {
158
- if (config.debugMode) logger.info(`[规则匹配] : ${userData.authority}`);
173
+ if (config.debugMode) logger.info(`[规则匹配] 白名单: ${userData.authority}`);
159
174
  return true;
160
175
  }
161
176
  } catch {
@@ -205,13 +220,15 @@ function apply(ctx, config = {}) {
205
220
  }, "setupManual");
206
221
  const handleEvent = /* @__PURE__ */ __name(async (session, kind) => {
207
222
  try {
208
- if (config.debugMode) logger.info(`[收到请求] 类型:${kind} 数据:${JSON.stringify(session.event?._data || {})}`);
223
+ if (config.debugMode) logger.info(`[收到请求] 类型: ${kind} 数据:${JSON.stringify(session.event?._data || {})}`);
209
224
  if (kind === "member") {
210
- const rule = config.verifyRules?.find((r) => r.guildId === session.guildId);
225
+ const rule = config.verifyRules?.find((r) => String(r.guildId) === String(session.guildId));
211
226
  if (rule) {
212
227
  const rawText = session.event?._data?.comment || "";
228
+ const cleanLines = rawText.split(/[\r\n]+/).map((s) => s.trim()).filter((s) => /^(回答|答案)[::]/i.test(s)).map((s) => s.replace(/^(回答|答案)[::]\s*/i, ""));
229
+ const verifyText = cleanLines.length > 0 ? cleanLines.join("\n") : rawText;
213
230
  const stats = (rule.minLevel ?? -1) >= 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
214
- const keywordMatch = !rule.keyword || new RegExp(rule.keyword, "i").test(rawText);
231
+ const keywordMatch = !rule.keyword || new RegExp(rule.keyword, "i").test(verifyText);
215
232
  const levelMatch = !stats || (stats.qqLevel ?? 0) >= rule.minLevel;
216
233
  const isMatch = keywordMatch && levelMatch;
217
234
  if (config.debugMode) logger.info(`[规则判定] ${rule.guildId}: 关键词=${keywordMatch}, 等级=${levelMatch}, 结果=${isMatch}`);
@@ -248,6 +265,19 @@ function apply(ctx, config = {}) {
248
265
  ctx.on("guild-request", hookEvent("guild"));
249
266
  ctx.on("guild-member-request", hookEvent("member"));
250
267
  ctx.on("guild-added", hookEvent("guild"));
268
+ ctx.on("guild-removed", async (session) => {
269
+ const subType = session.event?._data?.sub_type;
270
+ if (subType === "kick_me") {
271
+ const inviterId = inviterMap.get(session.guildId);
272
+ if (inviterId) {
273
+ await session.onebot?.deleteFriend(inviterId);
274
+ inviterMap.delete(session.guildId);
275
+ }
276
+ await session.execute(`analyse.clear -g ${session.guildId}`).catch(() => {
277
+ });
278
+ }
279
+ await sendNotice(session, "removed");
280
+ });
251
281
  ctx.middleware(async (session, next) => {
252
282
  if (typeof session.content !== "string" || !session.quote?.id) return next();
253
283
  const activeTask = activeTasks.get(session.quote.id);
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.5",
4
+ "version": "1.0.7",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],