koishi-plugin-onebot-verifier 1.0.7 → 1.0.9
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.js +142 -143
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -54,10 +54,10 @@ var Config = import_koishi.Schema.intersect([
|
|
|
54
54
|
import_koishi.Schema.const("accept").description("同意"),
|
|
55
55
|
import_koishi.Schema.const("reject").description("拒绝")
|
|
56
56
|
]).description("默认超时操作").default("accept"),
|
|
57
|
-
friendLevel: import_koishi.Schema.number().description("最低好友等级").default(
|
|
57
|
+
friendLevel: import_koishi.Schema.number().description("最低好友等级").default(0).min(0).max(256),
|
|
58
58
|
friendRegex: import_koishi.Schema.string().description("好友验证正则"),
|
|
59
|
-
minMembers: import_koishi.Schema.number().description("最低群成员数").default(
|
|
60
|
-
maxCapacity: import_koishi.Schema.number().description("最低受邀容量").default(
|
|
59
|
+
minMembers: import_koishi.Schema.number().description("最低群成员数").default(0).min(0).max(3e3),
|
|
60
|
+
maxCapacity: import_koishi.Schema.number().description("最低受邀容量").default(0).min(0).max(3e3)
|
|
61
61
|
}).description("好友邀群配置"),
|
|
62
62
|
import_koishi.Schema.object({
|
|
63
63
|
verifyMode: import_koishi.Schema.union([
|
|
@@ -68,7 +68,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
68
68
|
verifyRules: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
69
69
|
guildId: import_koishi.Schema.string().description("群号").required(),
|
|
70
70
|
keyword: import_koishi.Schema.string().description("正则"),
|
|
71
|
-
minLevel: import_koishi.Schema.number().description("等级").default(
|
|
71
|
+
minLevel: import_koishi.Schema.number().description("等级").default(0),
|
|
72
72
|
action: import_koishi.Schema.union([
|
|
73
73
|
import_koishi.Schema.const("accept").description("同意"),
|
|
74
74
|
import_koishi.Schema.const("reject").description("拒绝")
|
|
@@ -80,25 +80,31 @@ function apply(ctx, config = {}) {
|
|
|
80
80
|
const logger = new import_koishi.Logger("onebot-verifier");
|
|
81
81
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
82
82
|
const inviterMap = /* @__PURE__ */ new Map();
|
|
83
|
+
const getComment = /* @__PURE__ */ __name((comment) => {
|
|
84
|
+
if (!comment) return "";
|
|
85
|
+
const lines = comment.split(/[\r\n]+/).map((s) => s.trim());
|
|
86
|
+
const answers = lines.filter((s) => /^(回答|答案)[::]/i.test(s)).map((s) => s.replace(/^(回答|答案)[::]\s*/i, ""));
|
|
87
|
+
return answers.length > 0 ? answers.join("\n") : comment;
|
|
88
|
+
}, "getComment");
|
|
83
89
|
const executeAction = /* @__PURE__ */ __name(async (session, kind, pass, reason = "", remark = "") => {
|
|
84
90
|
try {
|
|
85
91
|
const eventData = session.event?._data || {};
|
|
86
|
-
if (config.debugMode) logger.info(`[
|
|
92
|
+
if (config.debugMode) logger.info(`[操作] 类型:${kind} 结果:${pass ? "同意" : "拒绝"} 原因:${reason || "无"}`);
|
|
87
93
|
if (pass && kind === "guild" && session.guildId && session.userId) inviterMap.set(session.guildId, session.userId);
|
|
88
94
|
if (!pass && kind === "guild" && session.guildId && (session.event?.type === "guild-added" || eventData.notice_type === "group_increase")) {
|
|
89
|
-
if (reason) {
|
|
90
|
-
|
|
91
|
-
await session.bot.sendMessage(session.guildId, `${reason},将退出该群`);
|
|
92
|
-
} catch (error) {
|
|
93
|
-
logger.warn(`发送退群通知失败: ${error}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
95
|
+
if (reason) await session.bot?.sendMessage(session.guildId, `${reason},将退出该群`).catch(() => {
|
|
96
|
+
});
|
|
96
97
|
await session.onebot?.setGroupLeave(session.guildId, false);
|
|
98
|
+
if (config.debugMode) logger.info(`[操作] 退出群组: ${session.guildId}`);
|
|
97
99
|
return true;
|
|
98
100
|
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
101
|
+
const flag = eventData.flag;
|
|
102
|
+
if (!flag || !session.onebot) return false;
|
|
103
|
+
if (kind === "friend") {
|
|
104
|
+
await session.onebot.setFriendAddRequest(flag, pass, remark);
|
|
105
|
+
} else {
|
|
106
|
+
await session.onebot.setGroupAddRequest(flag, eventData.sub_type ?? "add", pass, pass ? "" : reason);
|
|
107
|
+
}
|
|
102
108
|
return true;
|
|
103
109
|
} catch (error) {
|
|
104
110
|
logger.error(`操作失败: ${error}`);
|
|
@@ -107,141 +113,135 @@ function apply(ctx, config = {}) {
|
|
|
107
113
|
}, "executeAction");
|
|
108
114
|
const sendNotice = /* @__PURE__ */ __name(async (session, kind, status = "waiting") => {
|
|
109
115
|
const notifyConfig = config.notifyTarget || "";
|
|
110
|
-
if (!notifyConfig) return [];
|
|
111
116
|
const [targetType, targetId] = notifyConfig.split(":");
|
|
112
|
-
if (!targetId ||
|
|
117
|
+
if (!targetId || !session.bot) return [];
|
|
113
118
|
try {
|
|
114
119
|
const eventData = session.event?._data || {};
|
|
115
|
-
const userInfo = session.userId ? await session.bot.getUser?.(session.userId)
|
|
116
|
-
const groupInfo = kind !== "friend" && session.guildId ? await session.bot.getGuild?.(session.guildId)
|
|
117
|
-
const adminId = eventData.operator_id || session.event
|
|
118
|
-
const adminInfo = adminId &&
|
|
120
|
+
const userInfo = session.userId ? await session.bot.getUser?.(session.userId).catch(() => null) : null;
|
|
121
|
+
const groupInfo = kind !== "friend" && session.guildId ? await session.bot.getGuild?.(session.guildId).catch(() => null) : null;
|
|
122
|
+
const adminId = String(eventData.operator_id || session.event?.operator?.id || "");
|
|
123
|
+
const adminInfo = adminId && adminId !== session.userId ? await session.bot.getUser?.(adminId).catch(() => null) : null;
|
|
124
|
+
const typeMap = { friend: "好友申请", member: "加群请求", guild: "群组邀请", removed: eventData.sub_type === "kick_me" ? "移出群组" : "退出群组" };
|
|
125
|
+
const statusMap = { auto_pass: " [自动通过]", auto_reject: " [自动拒绝]", waiting: " [等待处理]" };
|
|
119
126
|
const infoLines = [];
|
|
120
127
|
if (userInfo?.avatar) infoLines.push(`<image url="${userInfo.avatar}"/>`);
|
|
121
|
-
|
|
122
|
-
if (kind
|
|
123
|
-
|
|
124
|
-
|
|
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}`);
|
|
137
|
-
if (groupInfo) infoLines.push(`群组:${groupInfo.name ? `${groupInfo.name}(${session.guildId})` : session.guildId}`);
|
|
128
|
+
infoLines.push(`类型:${typeMap[kind] || "未知"}${kind === "removed" ? eventData.sub_type === "kick_me" && config.kickBan ? " [自动清理]" : "" : statusMap[status]}`);
|
|
129
|
+
if (kind !== "guild" && kind !== "removed" || session.userId && session.userId !== session.selfId) infoLines.push(`用户:${userInfo?.name || session.userId}${session.userId ? `(${session.userId})` : ""}`);
|
|
130
|
+
if (adminId) infoLines.push(`管理:${adminInfo?.name ? `${adminInfo.name}(${adminId})` : adminId}`);
|
|
131
|
+
if (session.guildId) infoLines.push(`群组:${groupInfo?.name ? `${groupInfo.name}(${session.guildId})` : session.guildId}`);
|
|
138
132
|
if (eventData.comment) infoLines.push(`验证信息:${eventData.comment}`);
|
|
139
133
|
const content = infoLines.join("\n");
|
|
140
|
-
|
|
134
|
+
const msgIds = await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, content) : session.bot.sendMessage(targetId, content)) || [];
|
|
135
|
+
return msgIds;
|
|
141
136
|
} catch (error) {
|
|
142
137
|
logger.error(`通知失败: ${error}`);
|
|
143
138
|
return [];
|
|
144
139
|
}
|
|
145
140
|
}, "sendNotice");
|
|
146
|
-
const checkCriteria = /* @__PURE__ */ __name(async (session, kind) => {
|
|
147
|
-
const rawText = session.event?._data?.comment || "";
|
|
148
|
-
const cleanLines = rawText.split(/[\r\n]+/).map((s) => s.trim()).filter((s) => /^(回答|答案)[::]/i.test(s)).map((s) => s.replace(/^(回答|答案)[::]\s*/i, ""));
|
|
149
|
-
const verifyText = cleanLines.length > 0 ? cleanLines.join("\n") : rawText;
|
|
150
|
-
if (kind === "friend") {
|
|
151
|
-
try {
|
|
152
|
-
if (config.friendRegex && new RegExp(config.friendRegex, "i").test(verifyText)) {
|
|
153
|
-
if (config.debugMode) logger.info(`[规则匹配] 好友检查: ${config.friendRegex}`);
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
const limitLevel = config.friendLevel ?? -1;
|
|
157
|
-
if (limitLevel >= 0 && session.onebot && session.userId) {
|
|
158
|
-
const stats = await session.onebot.getStrangerInfo(session.userId, true);
|
|
159
|
-
const isPassed = (stats.qqLevel ?? 0) >= limitLevel;
|
|
160
|
-
if (config.debugMode) logger.info(`[规则判定] 等级检查: ${stats.qqLevel} > ${limitLevel} = ${isPassed}`);
|
|
161
|
-
if (!isPassed) return `QQ 等级低于 ${limitLevel} 级`;
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
} catch {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
if (kind === "guild") {
|
|
170
|
-
try {
|
|
171
|
-
const userData = session.userId ? await ctx.database.getUser(session.platform, session.userId) : null;
|
|
172
|
-
if (userData && userData.authority > 1) {
|
|
173
|
-
if (config.debugMode) logger.info(`[规则匹配] 白名单: ${userData.authority}`);
|
|
174
|
-
return true;
|
|
175
|
-
}
|
|
176
|
-
} catch {
|
|
177
|
-
}
|
|
178
|
-
if (session.onebot && session.guildId && ((config.minMembers ?? -1) >= 0 || (config.maxCapacity ?? -1) >= 0)) {
|
|
179
|
-
try {
|
|
180
|
-
const stats = await session.onebot.getGroupInfo(session.guildId, true);
|
|
181
|
-
if ((config.minMembers ?? -1) >= 0 && stats.member_count < (config.minMembers ?? 0)) {
|
|
182
|
-
if (config.debugMode) logger.info(`[规则判定] 成员检查: ${stats.member_count} < ${config.minMembers}`);
|
|
183
|
-
return `群成员不足 ${config.minMembers} 人`;
|
|
184
|
-
}
|
|
185
|
-
if ((config.maxCapacity ?? -1) >= 0 && stats.max_member_count < (config.maxCapacity ?? 0)) {
|
|
186
|
-
if (config.debugMode) logger.info(`[规则判定] 容量检查: ${stats.max_member_count} < ${config.maxCapacity}`);
|
|
187
|
-
return `群容量不足 ${config.maxCapacity} 人`;
|
|
188
|
-
}
|
|
189
|
-
return true;
|
|
190
|
-
} catch {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
return false;
|
|
197
|
-
}, "checkCriteria");
|
|
198
141
|
const setupManual = /* @__PURE__ */ __name(async (session, kind) => {
|
|
199
|
-
const msgIds = await sendNotice(session, kind, "waiting");
|
|
200
|
-
if (!msgIds?.length) return;
|
|
201
|
-
const task = { session, kind, messages: msgIds };
|
|
202
|
-
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
203
142
|
const waitMinutes = config.timeout ?? 0;
|
|
143
|
+
const action = kind === "member" ? config.verifyMode : config.timeoutAction;
|
|
204
144
|
if (waitMinutes > 0) {
|
|
145
|
+
const msgIds = await sendNotice(session, kind, "waiting");
|
|
146
|
+
if (!msgIds?.length) return;
|
|
147
|
+
const task = { session, kind, messages: msgIds };
|
|
148
|
+
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
205
149
|
task.timer = setTimeout(async () => {
|
|
206
150
|
if (!activeTasks.has(msgIds[0])) return;
|
|
207
151
|
msgIds.forEach((id) => activeTasks.delete(id));
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
210
|
-
const isPass =
|
|
211
|
-
await executeAction(session, kind, isPass, isPass ? "" : "
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
if (targetId) {
|
|
152
|
+
const finalAction = kind === "member" ? config.verifyMode ?? "manual" : config.timeoutAction ?? "accept";
|
|
153
|
+
if (finalAction === "manual") return;
|
|
154
|
+
const isPass = finalAction === "accept";
|
|
155
|
+
await executeAction(session, kind, isPass, isPass ? "" : "等待超时,自动拒绝");
|
|
156
|
+
const [targetType, targetId] = (config.notifyTarget || "").split(":");
|
|
157
|
+
if (targetId && session.bot) {
|
|
215
158
|
const statusText = `已自动${isPass ? "通过" : "拒绝"}该请求`;
|
|
216
|
-
await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, statusText) : session.bot.sendMessage(targetId, statusText))
|
|
159
|
+
await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, statusText) : session.bot.sendMessage(targetId, statusText)).catch(() => {
|
|
160
|
+
});
|
|
217
161
|
}
|
|
162
|
+
if (config.debugMode) logger.info(`[操作] 等待超时,默认${isPass ? "通过" : "拒绝"}`);
|
|
218
163
|
}, waitMinutes * 6e4);
|
|
164
|
+
} else {
|
|
165
|
+
if (action === "manual" || !action) return await sendNotice(session, kind, "waiting");
|
|
166
|
+
const isPass = action === "accept";
|
|
167
|
+
await executeAction(session, kind, isPass, "等待超时,自动处理");
|
|
168
|
+
await sendNotice(session, kind, isPass ? "auto_pass" : "auto_reject");
|
|
169
|
+
if (config.debugMode) logger.info(`[操作] 无需等待,默认${isPass ? "通过" : "拒绝"}`);
|
|
219
170
|
}
|
|
220
171
|
}, "setupManual");
|
|
221
|
-
const
|
|
172
|
+
const hookEvent = /* @__PURE__ */ __name((kind) => async (session) => {
|
|
173
|
+
const eventData = session.event?._data || {};
|
|
174
|
+
if (eventData.user_id) session.userId = String(eventData.user_id);
|
|
175
|
+
if (eventData.group_id) session.guildId = String(eventData.group_id);
|
|
222
176
|
try {
|
|
223
|
-
if (config.debugMode) logger.info(`[收到请求] 类型: ${kind}
|
|
177
|
+
if (config.debugMode) logger.info(`[收到请求] 类型: ${kind} 数据: ${JSON.stringify(session.event?._data || {})}`);
|
|
178
|
+
const verifyText = getComment(session.event?._data?.comment);
|
|
224
179
|
if (kind === "member") {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
const
|
|
229
|
-
const verifyText = cleanLines.length > 0 ? cleanLines.join("\n") : rawText;
|
|
230
|
-
const stats = (rule.minLevel ?? -1) >= 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
|
|
180
|
+
const rules = config.verifyRules?.filter((r) => String(r.guildId) === String(session.guildId)) || [];
|
|
181
|
+
for (const rule of rules) {
|
|
182
|
+
const minL = rule.minLevel ?? 0;
|
|
183
|
+
const stats = minL > 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
|
|
231
184
|
const keywordMatch = !rule.keyword || new RegExp(rule.keyword, "i").test(verifyText);
|
|
232
|
-
const levelMatch = !stats || (stats.qqLevel ?? 0) >=
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
185
|
+
const levelMatch = !stats || (stats.qqLevel ?? 0) >= minL;
|
|
186
|
+
if (config.debugMode) {
|
|
187
|
+
if (rule.keyword) logger.info(`[加群验证] 内容 "${verifyText}" ${keywordMatch ? "匹配" : "不匹配"}正则 "${rule.keyword}"`);
|
|
188
|
+
if (stats) logger.info(`[加群验证] 用户 ${session.userId} 等级 ${stats.qqLevel ?? 0}${levelMatch ? ">" : "<"}${minL}`);
|
|
189
|
+
}
|
|
190
|
+
if (keywordMatch && levelMatch && rule.action) {
|
|
236
191
|
const isApprove = rule.action === "accept";
|
|
237
|
-
await executeAction(session, kind, isApprove, isApprove ? "" : "
|
|
192
|
+
await executeAction(session, kind, isApprove, isApprove ? "" : "命中规则,自动拒绝");
|
|
238
193
|
await sendNotice(session, kind, isApprove ? "auto_pass" : "auto_reject");
|
|
239
194
|
return;
|
|
240
195
|
}
|
|
241
196
|
}
|
|
197
|
+
if (config.verifyMode && config.verifyMode !== "manual") {
|
|
198
|
+
const isApprove = config.verifyMode === "accept";
|
|
199
|
+
await executeAction(session, kind, isApprove, "等待超时,自动处理");
|
|
200
|
+
await sendNotice(session, kind, isApprove ? "auto_pass" : "auto_reject");
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
242
203
|
return await setupManual(session, kind);
|
|
243
204
|
}
|
|
244
|
-
|
|
205
|
+
let verdict = false;
|
|
206
|
+
if (kind === "friend") {
|
|
207
|
+
if (config.friendRegex) {
|
|
208
|
+
const isRegexMatched = new RegExp(config.friendRegex, "i").test(verifyText);
|
|
209
|
+
if (config.debugMode) logger.info(`[好友验证] 内容 "${verifyText}" ${isRegexMatched ? "匹配" : "不匹配"}正则 "${config.friendRegex}" `);
|
|
210
|
+
if (isRegexMatched) verdict = true;
|
|
211
|
+
}
|
|
212
|
+
if (verdict !== true) {
|
|
213
|
+
const fLevel = config.friendLevel ?? 0;
|
|
214
|
+
if (fLevel > 0 && session.onebot && session.userId) {
|
|
215
|
+
const stats = await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({}));
|
|
216
|
+
const isLevelMatched = (stats.qqLevel ?? 0) >= fLevel;
|
|
217
|
+
if (config.debugMode) logger.info(`[好友验证] 用户 ${session.userId} 等级 ${stats.qqLevel ?? 0}${isLevelMatched ? ">" : "<"}${fLevel}`);
|
|
218
|
+
if (isLevelMatched) verdict = true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} else if (kind === "guild") {
|
|
222
|
+
if (ctx.database && session.userId) {
|
|
223
|
+
const userData = await ctx.database.getUser(session.platform, session.userId, ["authority"]).catch(() => null);
|
|
224
|
+
if (userData && userData.authority > 3) {
|
|
225
|
+
if (config.debugMode) logger.info(`[群组邀请] 用户 ${session.userId} 权限 ${userData.authority}>3`);
|
|
226
|
+
verdict = true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (verdict !== true && session.onebot && session.guildId) {
|
|
230
|
+
const stats = await session.onebot.getGroupInfo(session.guildId, true).catch(() => ({}));
|
|
231
|
+
const minM = config.minMembers ?? 0;
|
|
232
|
+
const maxC = config.maxCapacity ?? 0;
|
|
233
|
+
if (minM > 0 && (stats.member_count ?? 0) < minM) {
|
|
234
|
+
verdict = `群成员不足 ${minM} 人`;
|
|
235
|
+
if (config.debugMode) logger.info(`[群组邀请] 群组 ${session.guildId} 成员数 ${stats.member_count ?? 0}<${minM}`);
|
|
236
|
+
} else if (maxC > 0 && (stats.max_member_count ?? 0) < maxC) {
|
|
237
|
+
verdict = `群容量不足 ${maxC} 人`;
|
|
238
|
+
if (config.debugMode) logger.info(`[群组邀请] 群组 ${session.guildId} 受邀容量 ${stats.max_member_count ?? 0}<${maxC}`);
|
|
239
|
+
} else {
|
|
240
|
+
verdict = minM > 0 || maxC > 0;
|
|
241
|
+
if (config.debugMode && verdict) logger.info(`[群组邀请] 群组 ${session.guildId} 成员数 ${stats.member_count ?? 0}>${minM},受邀容量 ${stats.max_member_count ?? 0}>${maxC}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
245
|
if (verdict === true) {
|
|
246
246
|
await executeAction(session, kind, true);
|
|
247
247
|
await sendNotice(session, kind, "auto_pass");
|
|
@@ -254,48 +254,47 @@ function apply(ctx, config = {}) {
|
|
|
254
254
|
} catch (error) {
|
|
255
255
|
logger.error(`处理失败: ${error}`);
|
|
256
256
|
}
|
|
257
|
-
}, "handleEvent");
|
|
258
|
-
const hookEvent = /* @__PURE__ */ __name((kind) => async (session) => {
|
|
259
|
-
const eventData = session.event?._data || {};
|
|
260
|
-
session.userId = eventData.user_id;
|
|
261
|
-
if (kind !== "friend") session.guildId = eventData.group_id;
|
|
262
|
-
await handleEvent(session, kind);
|
|
263
257
|
}, "hookEvent");
|
|
264
258
|
ctx.on("friend-request", hookEvent("friend"));
|
|
265
259
|
ctx.on("guild-request", hookEvent("guild"));
|
|
266
260
|
ctx.on("guild-member-request", hookEvent("member"));
|
|
267
261
|
ctx.on("guild-added", hookEvent("guild"));
|
|
268
262
|
ctx.on("guild-removed", async (session) => {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
263
|
+
if (session.event?._data?.sub_type === "kick_me") {
|
|
264
|
+
const gid = session.guildId;
|
|
265
|
+
if (gid) {
|
|
266
|
+
const inviterId = inviterMap.get(gid);
|
|
267
|
+
if (inviterId) {
|
|
268
|
+
await session.onebot?.deleteFriend(inviterId).catch(() => {
|
|
269
|
+
});
|
|
270
|
+
inviterMap.delete(gid);
|
|
271
|
+
if (config.debugMode) logger.info(`[操作] 删除好友: ${inviterId}`);
|
|
272
|
+
}
|
|
273
|
+
await session.execute(`analyse.clear -g ${gid}`).catch(() => {
|
|
274
|
+
});
|
|
275
275
|
}
|
|
276
|
-
await session.execute(`analyse.clear -g ${session.guildId}`).catch(() => {
|
|
277
|
-
});
|
|
278
276
|
}
|
|
279
277
|
await sendNotice(session, "removed");
|
|
280
278
|
});
|
|
281
279
|
ctx.middleware(async (session, next) => {
|
|
282
280
|
if (typeof session.content !== "string" || !session.quote?.id) return next();
|
|
283
|
-
const
|
|
284
|
-
if (!
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
if (
|
|
281
|
+
const task = activeTasks.get(session.quote.id);
|
|
282
|
+
if (!task) return next();
|
|
283
|
+
const [targetType, targetId] = (config.notifyTarget || "").split(":");
|
|
284
|
+
const isMatched = targetType === "private" ? session.userId === targetId : session.guildId === targetId;
|
|
285
|
+
if (!isMatched) return next();
|
|
288
286
|
const input = session.content.replace(/<(quote|at)\s+[^>]*\/>/gi, "").trim();
|
|
289
|
-
const cmdMatch = input.match(/^(y|n|通过|拒绝)(?:\s+(.*))?$/);
|
|
287
|
+
const cmdMatch = input.match(/^(y|n|通过|拒绝)(?:\s+(.*))?$/i);
|
|
290
288
|
if (!cmdMatch) return next();
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
const isApprove =
|
|
289
|
+
if (task.timer) clearTimeout(task.timer);
|
|
290
|
+
task.messages.forEach((msg) => activeTasks.delete(msg));
|
|
291
|
+
const isApprove = ["y", "通过"].includes(cmdMatch[1].toLowerCase());
|
|
294
292
|
const extraInfo = cmdMatch[2]?.trim() || "";
|
|
295
|
-
if (config.debugMode) logger.info(`[
|
|
296
|
-
const isSuccess = await executeAction(
|
|
293
|
+
if (config.debugMode) logger.info(`[操作] 收到指令: ${isApprove ? "同意" : "拒绝"}`);
|
|
294
|
+
const isSuccess = await executeAction(task.session, task.kind, isApprove, isApprove ? "" : extraInfo, isApprove && task.kind === "friend" ? extraInfo : "");
|
|
297
295
|
const replyText = isSuccess ? `已${isApprove ? "通过" : "拒绝"}该请求` : `处理请求失败`;
|
|
298
|
-
await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, replyText) : session.bot.sendMessage(targetId, replyText))
|
|
296
|
+
if (session.bot) await (targetType === "private" ? session.bot.sendPrivateMessage(targetId, replyText) : session.bot.sendMessage(targetId, replyText)).catch(() => {
|
|
297
|
+
});
|
|
299
298
|
});
|
|
300
299
|
}
|
|
301
300
|
__name(apply, "apply");
|