koishi-plugin-group-control 0.2.2 → 0.2.4

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
@@ -49,6 +49,7 @@ export interface GroupConfig {
49
49
  export interface GroupInviteConfig {
50
50
  enabled: boolean;
51
51
  adminQQs: string[];
52
+ notificationGroupId: string;
52
53
  inviteWaitMessage: string;
53
54
  inviteRequestMessage: string;
54
55
  autoApprove: boolean;
package/lib/index.js CHANGED
@@ -54,9 +54,10 @@ var Config = import_koishi.Schema.intersect([
54
54
  import_koishi.Schema.object({
55
55
  invite: import_koishi.Schema.object({
56
56
  enabled: import_koishi.Schema.boolean().default(false).description("启用群聊邀请审核功能"),
57
- adminQQs: import_koishi.Schema.array(String).default([]).description("管理员QQ号列表,用于接收邀请审核请求"),
57
+ adminQQs: import_koishi.Schema.array(String).default([]).description("管理员QQ号列表(用于权限验证)"),
58
+ notificationGroupId: import_koishi.Schema.string().description("通知群号(可选:若填写,邀请请求将发送到此群;若不填,则发送私聊给管理员)"),
58
59
  inviteWaitMessage: import_koishi.Schema.string().default("已收到您的群聊邀请,正在等待管理员审核,请耐心等待。").description("发送给邀请者的等待审核提示消息"),
59
- inviteRequestMessage: import_koishi.Schema.string().default('收到新的群聊邀请请求:\n群名称:{groupName}\n群号:{groupId}\n邀请者:{userName} (QQ: {userId})\n\n请引用此消息回复"同意"或"拒绝"进行审核。').description("发送给管理员的邀请请求消息模板,支持变量{groupName}, {groupId}, {userName}, {userId}"),
60
+ inviteRequestMessage: import_koishi.Schema.string().default('收到新的群聊邀请请求:\n群名称:{groupName}\n群号:{groupId}\n邀请者:{userName} (QQ: {userId})\n\n请管理员引用此消息回复"同意"或"拒绝"').description("发送给管理员的邀请请求消息模板,支持变量{groupName}, {groupId}, {userName}, {userId}"),
60
61
  autoApprove: import_koishi.Schema.boolean().default(false).description("是否自动同意邀请(仅在没有指定管理员时)"),
61
62
  showDetailedLog: import_koishi.Schema.boolean().default(false).description("是否显示详细日志")
62
63
  }).description("群聊邀请审核")
@@ -162,7 +163,7 @@ function apply(ctx, config) {
162
163
  }
163
164
  try {
164
165
  const waitMessage = config.invite.inviteWaitMessage.replace("{groupName}", groupName).replace("{groupId}", guildId).replace("{userName}", userName).replace("{userId}", userId);
165
- await session.bot.sendMessage(userId, waitMessage, platform);
166
+ await session.bot.sendPrivateMessage(userId, waitMessage);
166
167
  } catch (error) {
167
168
  console.error("发送等待审核提示失败:", error);
168
169
  }
@@ -195,25 +196,47 @@ function apply(ctx, config) {
195
196
  userName,
196
197
  time: Date.now(),
197
198
  flag
198
- // 保存flag用于后续处理请求
199
199
  });
200
200
  const requestMessage = config.invite.inviteRequestMessage.replace("{groupName}", groupName).replace("{groupId}", guildId).replace("{userName}", userName).replace("{userId}", userId);
201
- for (const adminQQ of config.invite.adminQQs) {
201
+ let requestSent = false;
202
+ if (config.invite.notificationGroupId) {
202
203
  try {
203
- const messageId = await session.bot.sendMessage(adminQQ, requestMessage, platform);
204
+ await session.bot.sendMessage(config.invite.notificationGroupId, requestMessage);
205
+ requestSent = true;
204
206
  if (config.invite.showDetailedLog) {
205
- console.log(`发送群聊邀请请求给管理员 ${adminQQ}: 群号 ${guildId}, 邀请者 ${userId}`);
207
+ console.log(`发送群聊邀请请求到通知群 ${config.invite.notificationGroupId}`);
206
208
  }
207
209
  } catch (error) {
208
- console.error(`发送邀请请求给管理员 ${adminQQ} 失败:`, error);
210
+ console.error(`发送邀请请求到通知群 ${config.invite.notificationGroupId} 失败:`, error);
209
211
  }
210
212
  }
213
+ if (!config.invite.notificationGroupId) {
214
+ for (const adminQQ of config.invite.adminQQs) {
215
+ try {
216
+ await session.bot.sendPrivateMessage(adminQQ, requestMessage);
217
+ requestSent = true;
218
+ if (config.invite.showDetailedLog) {
219
+ console.log(`发送群聊邀请请求给管理员 ${adminQQ}: 群号 ${guildId}, 邀请者 ${userId}`);
220
+ }
221
+ } catch (error) {
222
+ console.error(`发送邀请请求给管理员 ${adminQQ} 失败:`, error);
223
+ }
224
+ }
225
+ }
226
+ if (!requestSent && config.invite.showDetailedLog) {
227
+ console.warn("群邀请请求未发送给任何目标(未配置通知群且私聊发送失败或未配置管理员)");
228
+ }
211
229
  });
212
230
  ctx.on("message", async (session) => {
213
- const { userId, content, platform } = session;
231
+ const { userId, content, platform, guildId } = session;
214
232
  if (!config.invite.adminQQs.includes(userId)) {
215
233
  return;
216
234
  }
235
+ const isNotificationGroup = config.invite.notificationGroupId && guildId === config.invite.notificationGroupId;
236
+ const isPrivate = !guildId;
237
+ if (!isNotificationGroup && !isPrivate && config.invite.notificationGroupId) {
238
+ return;
239
+ }
217
240
  const hasQuote = session.elements.some((element) => element.type === "quote");
218
241
  if (!hasQuote) {
219
242
  return;
@@ -253,15 +276,15 @@ function apply(ctx, config) {
253
276
  if (config.invite.showDetailedLog) {
254
277
  console.log(`管理员 ${userId} 同意群聊邀请: 群号 ${inviteData.groupId}, 邀请者 ${inviteData.userId}`);
255
278
  }
256
- await session.bot.sendMessage(userId, `已同意加入群 ${inviteData.groupId}`, platform);
279
+ await session.send(`已同意加入群 ${inviteData.groupId}`);
257
280
  try {
258
- await session.bot.sendMessage(inviteData.userId, `您的群聊邀请已通过管理员审核,机器人已加入群聊。`, platform);
281
+ await session.bot.sendPrivateMessage(inviteData.userId, `您的群聊邀请已通过管理员审核,机器人已加入群聊。`);
259
282
  } catch (error) {
260
283
  console.error("通知邀请者审核结果失败:", error);
261
284
  }
262
285
  } catch (error) {
263
286
  console.error("处理同意邀请失败:", error);
264
- await session.bot.sendMessage(userId, `处理同意邀请失败: ${error.message}`, platform);
287
+ await session.send(`处理同意邀请失败: ${error.message}`);
265
288
  }
266
289
  } else if (trimmedContent === "拒绝" || trimmedContent === "reject") {
267
290
  try {
@@ -274,15 +297,15 @@ function apply(ctx, config) {
274
297
  if (config.invite.showDetailedLog) {
275
298
  console.log(`管理员 ${userId} 拒绝群聊邀请: 群号 ${inviteData.groupId}, 邀请者 ${inviteData.userId}`);
276
299
  }
277
- await session.bot.sendMessage(userId, `已拒绝加入群 ${inviteData.groupId}`, platform);
300
+ await session.send(`已拒绝加入群 ${inviteData.groupId}`);
278
301
  try {
279
- await session.bot.sendMessage(inviteData.userId, `您的群聊邀请未通过管理员审核,机器人将不会加入该群聊。`, platform);
302
+ await session.bot.sendPrivateMessage(inviteData.userId, `您的群聊邀请未通过管理员审核,机器人将不会加入该群聊。`);
280
303
  } catch (error) {
281
304
  console.error("通知邀请者审核结果失败:", error);
282
305
  }
283
306
  } catch (error) {
284
307
  console.error("处理拒绝邀请失败:", error);
285
- await session.bot.sendMessage(userId, `处理拒绝邀请失败: ${error.message}`, platform);
308
+ await session.send(`处理拒绝邀请失败: ${error.message}`);
286
309
  }
287
310
  }
288
311
  pendingInvites.delete(targetInviteId);
@@ -345,54 +368,24 @@ function apply(ctx, config) {
345
368
  if (config.frequency.enabled) {
346
369
  ctx.on("command/before-execute", async (argv) => {
347
370
  const session = argv.session;
348
- if (!session.guildId || !config.frequency.enabled) {
349
- return;
350
- }
371
+ if (!session.guildId || !config.frequency.enabled) return;
351
372
  const { guildId, platform } = session;
352
- if (config.frequency.whitelist && config.frequency.whitelist.includes(guildId)) {
353
- return;
354
- }
373
+ if (config.frequency.whitelist && config.frequency.whitelist.includes(guildId)) return;
355
374
  let record = await getCommandFrequencyRecord(ctx, platform, guildId);
356
375
  function handleExpiredWindow(currentRecord, platform2, guildId2, now2, windowStart2, warnDelay) {
357
376
  if (currentRecord && currentRecord.lastCommandTime < windowStart2) {
358
377
  if (currentRecord.warningSent && currentRecord.firstWarningTime > 0) {
359
378
  if (now2 - currentRecord.firstWarningTime > warnDelay) {
360
- return {
361
- platform: platform2,
362
- guildId: guildId2,
363
- commandCount: 1,
364
- lastCommandTime: now2,
365
- warningSent: false,
366
- // 重置警告状态
367
- blockExpiryTime: 0,
368
- firstWarningTime: 0
369
- // 重置警告时间
370
- };
379
+ return { platform: platform2, guildId: guildId2, commandCount: 1, lastCommandTime: now2, warningSent: false, blockExpiryTime: 0, firstWarningTime: 0 };
371
380
  } else {
372
381
  currentRecord.commandCount = 1;
373
382
  currentRecord.lastCommandTime = now2;
374
383
  return currentRecord;
375
384
  }
376
385
  } else if (isCurrentlyBlocked(currentRecord) && Date.now() >= currentRecord.blockExpiryTime * 1e3) {
377
- return {
378
- platform: platform2,
379
- guildId: guildId2,
380
- commandCount: 1,
381
- lastCommandTime: now2,
382
- warningSent: false,
383
- blockExpiryTime: 0,
384
- firstWarningTime: 0
385
- };
386
+ return { platform: platform2, guildId: guildId2, commandCount: 1, lastCommandTime: now2, warningSent: false, blockExpiryTime: 0, firstWarningTime: 0 };
386
387
  } else {
387
- return {
388
- platform: platform2,
389
- guildId: guildId2,
390
- commandCount: 1,
391
- lastCommandTime: now2,
392
- warningSent: false,
393
- blockExpiryTime: 0,
394
- firstWarningTime: 0
395
- };
388
+ return { platform: platform2, guildId: guildId2, commandCount: 1, lastCommandTime: now2, warningSent: false, blockExpiryTime: 0, firstWarningTime: 0 };
396
389
  }
397
390
  } else {
398
391
  if (currentRecord) {
@@ -400,15 +393,7 @@ function apply(ctx, config) {
400
393
  currentRecord.lastCommandTime = now2;
401
394
  return currentRecord;
402
395
  } else {
403
- return {
404
- platform: platform2,
405
- guildId: guildId2,
406
- commandCount: 1,
407
- lastCommandTime: now2,
408
- warningSent: false,
409
- blockExpiryTime: 0,
410
- firstWarningTime: 0
411
- };
396
+ return { platform: platform2, guildId: guildId2, commandCount: 1, lastCommandTime: now2, warningSent: false, blockExpiryTime: 0, firstWarningTime: 0 };
412
397
  }
413
398
  }
414
399
  }
@@ -485,13 +470,7 @@ function apply(ctx, config) {
485
470
  } catch (leaveError) {
486
471
  quittingGuilds.delete(`${platform}:${guildId}`);
487
472
  console.error("退出群聊失败:", leaveError);
488
- const failMessage = `退出失败: ${leaveError.message || "OneBot API 调用失败"}`;
489
- try {
490
- await session.bot.sendMessage(session.guildId, failMessage, platform);
491
- } catch (reSendError) {
492
- console.error("发送退出失败提示也失败:", reSendError);
493
- }
494
- return failMessage;
473
+ return `退出失败: ${leaveError.message || "OneBot API 调用失败"}`;
495
474
  }
496
475
  return "";
497
476
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-group-control",
3
3
  "description": "Koishi群聊自管理插件,支持自定义机器人进群消息、被踢出自动拉黑、刷屏自动屏蔽功能和主动退群指令等。(仅支持OneBot适配器)",
4
- "version": "0.2.2",
4
+ "version": "0.2.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [