koishi-plugin-group-verification 1.0.10 → 1.0.12
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 +192 -63
- package/package.json +1 -1
- package/src/index.ts +226 -90
package/lib/index.js
CHANGED
|
@@ -251,7 +251,15 @@ ${debugInfo}`];
|
|
|
251
251
|
}
|
|
252
252
|
__name(checkPermission, "checkPermission");
|
|
253
253
|
const groupVerify = ctx.command("group-verify", "群组验证管理命令").alias("gv", "gverify");
|
|
254
|
-
groupVerify.subcommand(".config [keywords:text]", "配置群组验证规则").alias(
|
|
254
|
+
groupVerify.subcommand(".config [keywords:text]", "配置群组验证规则").alias(
|
|
255
|
+
"gv.cfg",
|
|
256
|
+
"gverify.cfg",
|
|
257
|
+
"group-verify.cfg",
|
|
258
|
+
"gv.配置",
|
|
259
|
+
"gverify.配置",
|
|
260
|
+
"group-verify.配置",
|
|
261
|
+
"gvc"
|
|
262
|
+
).option("groupId", "-i <groupId> 指定群号").option("method", "-m <method> 审核方式 (0-3)").option("threshold", "-t <threshold> 阈值参数").option("message", "-msg <message> 自定义提醒消息").option("query", "-? 查询当前配置").option("remove", "-r 删除配置").action(async ({ session, options }, keywords) => {
|
|
255
263
|
const targetGroupId = options.groupId || session.guildId;
|
|
256
264
|
const [hasPermission, errorMsg] = await checkPermission(session, targetGroupId);
|
|
257
265
|
if (!hasPermission) {
|
|
@@ -373,91 +381,180 @@ ${debugInfo}`];
|
|
|
373
381
|
return `已为群 ${targetGroupId} 创建验证配置`;
|
|
374
382
|
}
|
|
375
383
|
});
|
|
376
|
-
groupVerify.subcommand(".approve
|
|
377
|
-
|
|
378
|
-
|
|
384
|
+
groupVerify.subcommand(".approve [userId]", "同意加群申请").alias(
|
|
385
|
+
"gv.accept",
|
|
386
|
+
"gverify.accept",
|
|
387
|
+
"group-verify.accept",
|
|
388
|
+
"gv.同意",
|
|
389
|
+
"gverify.同意",
|
|
390
|
+
"group-verify.同意",
|
|
391
|
+
"gva"
|
|
392
|
+
).action(async ({ session }, userId) => {
|
|
393
|
+
const [hasPermission, errorMsg] = await checkPermission(session);
|
|
394
|
+
if (!hasPermission) {
|
|
395
|
+
return errorMsg || "权限不足";
|
|
379
396
|
}
|
|
380
|
-
|
|
397
|
+
const groupId = session.guildId;
|
|
398
|
+
if (!groupId) {
|
|
381
399
|
return "请在群聊中使用此命令";
|
|
382
400
|
}
|
|
383
|
-
if (!userId) {
|
|
384
|
-
|
|
401
|
+
if (!userId || userId.toLowerCase() === "all") {
|
|
402
|
+
if (userId?.toLowerCase() === "all") {
|
|
403
|
+
const pendingRequests2 = await ctx.database.get("group_verification_pending", { groupId });
|
|
404
|
+
if (pendingRequests2.length === 0) {
|
|
405
|
+
return "当前无待审核的加群申请";
|
|
406
|
+
}
|
|
407
|
+
let approvedCount = 0;
|
|
408
|
+
for (const request2 of pendingRequests2) {
|
|
409
|
+
try {
|
|
410
|
+
await ctx.database.remove("group_verification_pending", { id: request2.id });
|
|
411
|
+
await updateStats(groupId, "manuallyApproved");
|
|
412
|
+
approvedCount++;
|
|
413
|
+
} catch (error) {
|
|
414
|
+
logger.warn(`处理申请 ${request2.id} 时出错:`, error);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return `已处理 ${approvedCount} 个加群申请`;
|
|
418
|
+
} else {
|
|
419
|
+
const recentRequest = await ctx.database.get("group_verification_pending", { groupId }, ["id", "userId", "userName"]);
|
|
420
|
+
if (recentRequest.length === 0) {
|
|
421
|
+
return "当前无待审核的加群申请";
|
|
422
|
+
}
|
|
423
|
+
const request2 = recentRequest[0];
|
|
424
|
+
try {
|
|
425
|
+
await session.bot.handleGuildMemberRequest(request2.userId, true);
|
|
426
|
+
await ctx.database.remove("group_verification_pending", { id: request2.id });
|
|
427
|
+
await updateStats(groupId, "manuallyApproved");
|
|
428
|
+
return `已同意用户 ${request2.userName}(${request2.userId}) 的加群申请`;
|
|
429
|
+
} catch (error) {
|
|
430
|
+
return `处理申请时出错: ${error.message}`;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
385
433
|
}
|
|
386
|
-
const
|
|
387
|
-
groupId
|
|
434
|
+
const pendingRequests = await ctx.database.get("group_verification_pending", {
|
|
435
|
+
groupId,
|
|
388
436
|
userId
|
|
389
437
|
});
|
|
390
|
-
if (
|
|
438
|
+
if (pendingRequests.length === 0) {
|
|
391
439
|
return `未找到用户 ${userId} 的待审核申请`;
|
|
392
440
|
}
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
441
|
+
const request = pendingRequests[0];
|
|
442
|
+
try {
|
|
443
|
+
await session.bot.handleGuildMemberRequest(request.userId, true);
|
|
444
|
+
await ctx.database.remove("group_verification_pending", { id: request.id });
|
|
445
|
+
await updateStats(groupId, "manuallyApproved");
|
|
446
|
+
return `已同意用户 ${request.userName}(${userId}) 的加群申请`;
|
|
447
|
+
} catch (error) {
|
|
448
|
+
return `处理申请时出错: ${error.message}`;
|
|
449
|
+
}
|
|
397
450
|
});
|
|
398
|
-
groupVerify.subcommand(".reject
|
|
399
|
-
|
|
400
|
-
|
|
451
|
+
groupVerify.subcommand(".reject [userId]", "拒绝加群申请").alias(
|
|
452
|
+
"gv.拒绝",
|
|
453
|
+
"gverify.拒绝",
|
|
454
|
+
"group-verify.拒绝",
|
|
455
|
+
"gv.rej",
|
|
456
|
+
"gverify.rej",
|
|
457
|
+
"group-verify.rej",
|
|
458
|
+
"gvr"
|
|
459
|
+
).action(async ({ session }, userId) => {
|
|
460
|
+
const [hasPermission, errorMsg] = await checkPermission(session);
|
|
461
|
+
if (!hasPermission) {
|
|
462
|
+
return errorMsg || "权限不足";
|
|
401
463
|
}
|
|
402
|
-
|
|
464
|
+
const groupId = session.guildId;
|
|
465
|
+
if (!groupId) {
|
|
403
466
|
return "请在群聊中使用此命令";
|
|
404
467
|
}
|
|
405
|
-
if (!userId) {
|
|
406
|
-
|
|
468
|
+
if (!userId || userId.toLowerCase() === "all") {
|
|
469
|
+
if (userId?.toLowerCase() === "all") {
|
|
470
|
+
const pendingRequests2 = await ctx.database.get("group_verification_pending", { groupId });
|
|
471
|
+
if (pendingRequests2.length === 0) {
|
|
472
|
+
return "当前无待审核的加群申请";
|
|
473
|
+
}
|
|
474
|
+
let rejectedCount = 0;
|
|
475
|
+
for (const request2 of pendingRequests2) {
|
|
476
|
+
try {
|
|
477
|
+
await ctx.database.remove("group_verification_pending", { id: request2.id });
|
|
478
|
+
await updateStats(groupId, "rejected");
|
|
479
|
+
rejectedCount++;
|
|
480
|
+
} catch (error) {
|
|
481
|
+
logger.warn(`处理申请 ${request2.id} 时出错:`, error);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return `已拒绝 ${rejectedCount} 个加群申请`;
|
|
485
|
+
} else {
|
|
486
|
+
const recentRequest = await ctx.database.get("group_verification_pending", { groupId }, ["id", "userId", "userName"]);
|
|
487
|
+
if (recentRequest.length === 0) {
|
|
488
|
+
return "当前无待审核的加群申请";
|
|
489
|
+
}
|
|
490
|
+
const request2 = recentRequest[0];
|
|
491
|
+
try {
|
|
492
|
+
await ctx.database.remove("group_verification_pending", { id: request2.id });
|
|
493
|
+
await updateStats(groupId, "rejected");
|
|
494
|
+
return `已拒绝用户 ${request2.userName}(${request2.userId}) 的加群申请`;
|
|
495
|
+
} catch (error) {
|
|
496
|
+
return `处理申请时出错: ${error.message}`;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
407
499
|
}
|
|
408
|
-
const
|
|
409
|
-
groupId
|
|
500
|
+
const pendingRequests = await ctx.database.get("group_verification_pending", {
|
|
501
|
+
groupId,
|
|
410
502
|
userId
|
|
411
503
|
});
|
|
412
|
-
if (
|
|
504
|
+
if (pendingRequests.length === 0) {
|
|
413
505
|
return `未找到用户 ${userId} 的待审核申请`;
|
|
414
506
|
}
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
507
|
+
const request = pendingRequests[0];
|
|
508
|
+
try {
|
|
509
|
+
await ctx.database.remove("group_verification_pending", { id: request.id });
|
|
510
|
+
await updateStats(groupId, "rejected");
|
|
511
|
+
return `已拒绝用户 ${request.userName}(${userId}) 的加群申请`;
|
|
512
|
+
} catch (error) {
|
|
513
|
+
return `处理申请时出错: ${error.message}`;
|
|
514
|
+
}
|
|
419
515
|
});
|
|
420
|
-
groupVerify.subcommand(".stats [
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
516
|
+
groupVerify.subcommand(".stats [target]", "查看群组验证统计信息").alias(
|
|
517
|
+
"gv.统计",
|
|
518
|
+
"gverify.统计",
|
|
519
|
+
"group-verify.统计",
|
|
520
|
+
"gvs"
|
|
521
|
+
).action(async ({ session }, target) => {
|
|
522
|
+
const validTargets = ["all", "total"];
|
|
523
|
+
const isGroupId = target && /^\d+$/.test(target);
|
|
524
|
+
const isSpecialTarget = target && validTargets.includes(target.toLowerCase());
|
|
525
|
+
if (target && !isGroupId && !isSpecialTarget) {
|
|
526
|
+
return "参数错误:只能指定群号、all、total或留空";
|
|
527
|
+
}
|
|
528
|
+
if (target?.toLowerCase() === "total" || target?.toLowerCase() === "all") {
|
|
529
|
+
const koishiAuthority = session.author?.authority || session.user?.authority;
|
|
530
|
+
if (!(koishiAuthority && koishiAuthority >= 3)) {
|
|
531
|
+
return "查看总计统计需要koishi 3级以上权限";
|
|
434
532
|
}
|
|
435
|
-
} else {
|
|
436
|
-
const groupStats = await ctx.database.get("group_verification_stats", { groupId: targetGroupId });
|
|
437
|
-
statsList = groupStats;
|
|
438
533
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
return `群 ${targetGroupId} 暂无验证统计信息`;
|
|
534
|
+
const groupId = session.guildId;
|
|
535
|
+
if (!target) {
|
|
536
|
+
if (!groupId) {
|
|
537
|
+
return "请在群聊中使用此命令或指定群号";
|
|
444
538
|
}
|
|
539
|
+
return await getGroupStats(groupId);
|
|
445
540
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
自动批准: ${stats.autoApproved}
|
|
452
|
-
手动批准: ${stats.manuallyApproved}
|
|
453
|
-
拒绝: ${stats.rejected}
|
|
454
|
-
最后更新: ${lastUpdated}
|
|
455
|
-
|
|
456
|
-
`;
|
|
541
|
+
if (target.toLowerCase() === "all" || target.toLowerCase() === "total") {
|
|
542
|
+
return await getTotalStats();
|
|
543
|
+
}
|
|
544
|
+
if (isGroupId) {
|
|
545
|
+
return await getGroupStats(target);
|
|
457
546
|
}
|
|
458
|
-
return
|
|
547
|
+
return "参数错误";
|
|
459
548
|
});
|
|
460
|
-
groupVerify.subcommand(".pending", "查看待审核加群申请").alias(
|
|
549
|
+
groupVerify.subcommand(".pending", "查看待审核加群申请").alias(
|
|
550
|
+
"gv.list",
|
|
551
|
+
"gverify.list",
|
|
552
|
+
"group-verify.list",
|
|
553
|
+
"gv.待处理",
|
|
554
|
+
"gverify.待处理",
|
|
555
|
+
"group-verify.待处理",
|
|
556
|
+
"gvp"
|
|
557
|
+
).action(async ({ session }) => {
|
|
461
558
|
if (!session.guildId) {
|
|
462
559
|
return "请在群聊中使用此命令";
|
|
463
560
|
}
|
|
@@ -477,7 +574,11 @@ ${debugInfo}`];
|
|
|
477
574
|
});
|
|
478
575
|
return result;
|
|
479
576
|
});
|
|
480
|
-
groupVerify.subcommand(".help", "显示帮助信息").alias(
|
|
577
|
+
groupVerify.subcommand(".help", "显示帮助信息").alias(
|
|
578
|
+
"gv.帮助",
|
|
579
|
+
"gverify.帮助",
|
|
580
|
+
"group-verify.帮助"
|
|
581
|
+
).action(() => {
|
|
481
582
|
return `群组验证命令帮助:
|
|
482
583
|
主指令别名:gv, gverify
|
|
483
584
|
|
|
@@ -532,6 +633,34 @@ ${debugInfo}`];
|
|
|
532
633
|
}
|
|
533
634
|
await syncTotalStats(ctx);
|
|
534
635
|
});
|
|
636
|
+
async function getGroupStats(groupId) {
|
|
637
|
+
const stats = await ctx.database.get("group_verification_stats", { groupId });
|
|
638
|
+
if (stats.length === 0) {
|
|
639
|
+
return `群 ${groupId} 暂无验证统计信息`;
|
|
640
|
+
}
|
|
641
|
+
const stat = stats[0];
|
|
642
|
+
const lastUpdated = new Date(stat.lastUpdated).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
|
|
643
|
+
return `群 ${groupId} 验证统计:
|
|
644
|
+
自动批准: ${stat.autoApproved}
|
|
645
|
+
手动批准: ${stat.manuallyApproved}
|
|
646
|
+
拒绝: ${stat.rejected}
|
|
647
|
+
最后更新: ${lastUpdated}`;
|
|
648
|
+
}
|
|
649
|
+
__name(getGroupStats, "getGroupStats");
|
|
650
|
+
async function getTotalStats() {
|
|
651
|
+
const stats = await ctx.database.get("group_verification_stats", { groupId: "TOTAL" });
|
|
652
|
+
if (stats.length === 0) {
|
|
653
|
+
return "暂无统计信息";
|
|
654
|
+
}
|
|
655
|
+
const stat = stats[0];
|
|
656
|
+
const lastUpdated = new Date(stat.lastUpdated).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
|
|
657
|
+
return `总计验证统计:
|
|
658
|
+
自动批准: ${stat.autoApproved}
|
|
659
|
+
手动批准: ${stat.manuallyApproved}
|
|
660
|
+
拒绝: ${stat.rejected}
|
|
661
|
+
最后更新: ${lastUpdated}`;
|
|
662
|
+
}
|
|
663
|
+
__name(getTotalStats, "getTotalStats");
|
|
535
664
|
async function syncTotalStats(ctx2) {
|
|
536
665
|
try {
|
|
537
666
|
const allStats = await ctx2.database.get("group_verification_stats", {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -371,7 +371,11 @@ export function apply(ctx: Context, config: Config) {
|
|
|
371
371
|
// Subcommand: configure group verification
|
|
372
372
|
groupVerify
|
|
373
373
|
.subcommand('.config [keywords:text]', '配置群组验证规则')
|
|
374
|
-
.alias(
|
|
374
|
+
.alias(
|
|
375
|
+
'gv.cfg', 'gverify.cfg', 'group-verify.cfg',
|
|
376
|
+
'gv.配置', 'gverify.配置', 'group-verify.配置',
|
|
377
|
+
'gvc'
|
|
378
|
+
)
|
|
375
379
|
.option('groupId', '-i <groupId> 指定群号')
|
|
376
380
|
.option('method', '-m <method> 审核方式 (0-3)')
|
|
377
381
|
.option('threshold', '-t <threshold> 阈值参数')
|
|
@@ -536,138 +540,232 @@ export function apply(ctx: Context, config: Config) {
|
|
|
536
540
|
|
|
537
541
|
// Subcommand: approve join request
|
|
538
542
|
groupVerify
|
|
539
|
-
.subcommand('.approve
|
|
540
|
-
.alias(
|
|
543
|
+
.subcommand('.approve [userId]', '同意加群申请')
|
|
544
|
+
.alias(
|
|
545
|
+
'gv.accept', 'gverify.accept', 'group-verify.accept',
|
|
546
|
+
'gv.同意', 'gverify.同意', 'group-verify.同意',
|
|
547
|
+
'gva'
|
|
548
|
+
)
|
|
541
549
|
.action(async ({ session }, userId) => {
|
|
542
550
|
// 权限检查
|
|
543
|
-
|
|
544
|
-
|
|
551
|
+
const [hasPermission, errorMsg] = await checkPermission(session)
|
|
552
|
+
if (!hasPermission) {
|
|
553
|
+
return errorMsg || '权限不足'
|
|
545
554
|
}
|
|
546
555
|
|
|
547
|
-
|
|
556
|
+
const groupId = session.guildId
|
|
557
|
+
if (!groupId) {
|
|
548
558
|
return '请在群聊中使用此命令'
|
|
549
559
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
560
|
+
|
|
561
|
+
// 处理默认情况和all情况
|
|
562
|
+
if (!userId || userId.toLowerCase() === 'all') {
|
|
563
|
+
if (userId?.toLowerCase() === 'all') {
|
|
564
|
+
// 处理所有待审核申请
|
|
565
|
+
const pendingRequests = await ctx.database.get('group_verification_pending', { groupId })
|
|
566
|
+
if (pendingRequests.length === 0) {
|
|
567
|
+
return '当前无待审核的加群申请'
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
let approvedCount = 0
|
|
571
|
+
for (const request of pendingRequests) {
|
|
572
|
+
try {
|
|
573
|
+
// TODO: 需要获取实际的requestId来进行审批
|
|
574
|
+
// await session.bot.handleGuildMemberRequest(request.requestId, true)
|
|
575
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
576
|
+
await updateStats(groupId, 'manuallyApproved')
|
|
577
|
+
approvedCount++
|
|
578
|
+
} catch (error) {
|
|
579
|
+
logger.warn(`处理申请 ${request.id} 时出错:`, error)
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return `已处理 ${approvedCount} 个加群申请`
|
|
584
|
+
} else {
|
|
585
|
+
// 处理最近的一个申请
|
|
586
|
+
const recentRequest = await ctx.database.get('group_verification_pending', { groupId }, ['id', 'userId', 'userName'])
|
|
587
|
+
if (recentRequest.length === 0) {
|
|
588
|
+
return '当前无待审核的加群申请'
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const request = recentRequest[0]
|
|
592
|
+
try {
|
|
593
|
+
// 这里需要获取实际的requestId,暂时用userId作为示例
|
|
594
|
+
await session.bot.handleGuildMemberRequest(request.userId, true)
|
|
595
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
596
|
+
await updateStats(groupId, 'manuallyApproved')
|
|
597
|
+
return `已同意用户 ${request.userName}(${request.userId}) 的加群申请`
|
|
598
|
+
} catch (error) {
|
|
599
|
+
return `处理申请时出错: ${error.message}`
|
|
600
|
+
}
|
|
601
|
+
}
|
|
553
602
|
}
|
|
554
|
-
|
|
555
|
-
//
|
|
556
|
-
const
|
|
557
|
-
groupId
|
|
558
|
-
userId: userId
|
|
603
|
+
|
|
604
|
+
// 处理指定用户ID的情况
|
|
605
|
+
const pendingRequests = await ctx.database.get('group_verification_pending', {
|
|
606
|
+
groupId,
|
|
607
|
+
userId: userId
|
|
559
608
|
})
|
|
560
|
-
|
|
561
|
-
if (
|
|
609
|
+
|
|
610
|
+
if (pendingRequests.length === 0) {
|
|
562
611
|
return `未找到用户 ${userId} 的待审核申请`
|
|
563
612
|
}
|
|
564
|
-
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
613
|
+
|
|
614
|
+
const request = pendingRequests[0]
|
|
615
|
+
try {
|
|
616
|
+
// 这里需要获取实际的requestId来进行审批
|
|
617
|
+
await session.bot.handleGuildMemberRequest(request.userId, true)
|
|
618
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
619
|
+
await updateStats(groupId, 'manuallyApproved')
|
|
620
|
+
return `已同意用户 ${request.userName}(${userId}) 的加群申请`
|
|
621
|
+
} catch (error) {
|
|
622
|
+
return `处理申请时出错: ${error.message}`
|
|
623
|
+
}
|
|
572
624
|
})
|
|
573
625
|
|
|
574
626
|
// Subcommand: reject join request
|
|
575
627
|
groupVerify
|
|
576
|
-
.subcommand('.reject
|
|
577
|
-
.alias(
|
|
628
|
+
.subcommand('.reject [userId]', '拒绝加群申请')
|
|
629
|
+
.alias(
|
|
630
|
+
'gv.拒绝', 'gverify.拒绝', 'group-verify.拒绝',
|
|
631
|
+
'gv.rej', 'gverify.rej', 'group-verify.rej',
|
|
632
|
+
'gvr'
|
|
633
|
+
)
|
|
578
634
|
.action(async ({ session }, userId) => {
|
|
579
635
|
// 权限检查
|
|
580
|
-
|
|
581
|
-
|
|
636
|
+
const [hasPermission, errorMsg] = await checkPermission(session)
|
|
637
|
+
if (!hasPermission) {
|
|
638
|
+
return errorMsg || '权限不足'
|
|
582
639
|
}
|
|
583
640
|
|
|
584
|
-
|
|
641
|
+
const groupId = session.guildId
|
|
642
|
+
if (!groupId) {
|
|
585
643
|
return '请在群聊中使用此命令'
|
|
586
644
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
645
|
+
|
|
646
|
+
// 处理默认情况和all情况
|
|
647
|
+
if (!userId || userId.toLowerCase() === 'all') {
|
|
648
|
+
if (userId?.toLowerCase() === 'all') {
|
|
649
|
+
// 拒绝所有待审核申请
|
|
650
|
+
const pendingRequests = await ctx.database.get('group_verification_pending', { groupId })
|
|
651
|
+
if (pendingRequests.length === 0) {
|
|
652
|
+
return '当前无待审核的加群申请'
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
let rejectedCount = 0
|
|
656
|
+
for (const request of pendingRequests) {
|
|
657
|
+
try {
|
|
658
|
+
// TODO: 需要获取实际的requestId来进行拒绝
|
|
659
|
+
// await session.bot.handleGuildMemberRequest(request.requestId, false)
|
|
660
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
661
|
+
await updateStats(groupId, 'rejected')
|
|
662
|
+
rejectedCount++
|
|
663
|
+
} catch (error) {
|
|
664
|
+
logger.warn(`处理申请 ${request.id} 时出错:`, error)
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return `已拒绝 ${rejectedCount} 个加群申请`
|
|
669
|
+
} else {
|
|
670
|
+
// 拒绝最近的一个申请
|
|
671
|
+
const recentRequest = await ctx.database.get('group_verification_pending', { groupId }, ['id', 'userId', 'userName'])
|
|
672
|
+
if (recentRequest.length === 0) {
|
|
673
|
+
return '当前无待审核的加群申请'
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const request = recentRequest[0]
|
|
677
|
+
try {
|
|
678
|
+
// TODO: 需要获取实际的requestId来进行拒绝
|
|
679
|
+
// await session.bot.handleGuildMemberRequest(request.requestId, false)
|
|
680
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
681
|
+
await updateStats(groupId, 'rejected')
|
|
682
|
+
return `已拒绝用户 ${request.userName}(${request.userId}) 的加群申请`
|
|
683
|
+
} catch (error) {
|
|
684
|
+
return `处理申请时出错: ${error.message}`
|
|
685
|
+
}
|
|
686
|
+
}
|
|
590
687
|
}
|
|
591
|
-
|
|
592
|
-
//
|
|
593
|
-
const
|
|
594
|
-
groupId
|
|
595
|
-
userId: userId
|
|
688
|
+
|
|
689
|
+
// 处理指定用户ID的情况
|
|
690
|
+
const pendingRequests = await ctx.database.get('group_verification_pending', {
|
|
691
|
+
groupId,
|
|
692
|
+
userId: userId
|
|
596
693
|
})
|
|
597
|
-
|
|
598
|
-
if (
|
|
694
|
+
|
|
695
|
+
if (pendingRequests.length === 0) {
|
|
599
696
|
return `未找到用户 ${userId} 的待审核申请`
|
|
600
697
|
}
|
|
601
|
-
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
698
|
+
|
|
699
|
+
const request = pendingRequests[0]
|
|
700
|
+
try {
|
|
701
|
+
// TODO: 需要获取实际的requestId来进行拒绝
|
|
702
|
+
// await session.bot.handleGuildMemberRequest(request.requestId, false)
|
|
703
|
+
await ctx.database.remove('group_verification_pending', { id: request.id })
|
|
704
|
+
await updateStats(groupId, 'rejected')
|
|
705
|
+
return `已拒绝用户 ${request.userName}(${userId}) 的加群申请`
|
|
706
|
+
} catch (error) {
|
|
707
|
+
return `处理申请时出错: ${error.message}`
|
|
708
|
+
}
|
|
609
709
|
})
|
|
610
710
|
|
|
611
711
|
// Subcommand: view statistics
|
|
612
712
|
groupVerify
|
|
613
|
-
.subcommand('.stats [
|
|
614
|
-
.alias(
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
713
|
+
.subcommand('.stats [target]', '查看群组验证统计信息')
|
|
714
|
+
.alias(
|
|
715
|
+
'gv.统计', 'gverify.统计', 'group-verify.统计',
|
|
716
|
+
'gvs'
|
|
717
|
+
)
|
|
718
|
+
.action(async ({ session }, target) => {
|
|
719
|
+
// 参数验证:只能是群号、all、total或空
|
|
720
|
+
const validTargets = ['all', 'total']
|
|
721
|
+
const isGroupId = target && /^\d+$/.test(target)
|
|
722
|
+
const isSpecialTarget = target && validTargets.includes(target.toLowerCase())
|
|
723
|
+
|
|
724
|
+
if (target && !isGroupId && !isSpecialTarget) {
|
|
725
|
+
return '参数错误:只能指定群号、all、total或留空'
|
|
726
|
+
}
|
|
619
727
|
|
|
620
|
-
|
|
621
|
-
|
|
728
|
+
// 权限检查:总计统计需要3级以上权限
|
|
729
|
+
if (target?.toLowerCase() === 'total' || target?.toLowerCase() === 'all') {
|
|
730
|
+
// 检查是否为koishi 3级以上权限
|
|
731
|
+
const koishiAuthority = (session as any).author?.authority || (session as any).user?.authority
|
|
732
|
+
if (!(koishiAuthority && koishiAuthority >= 3)) {
|
|
733
|
+
return '查看总计统计需要koishi 3级以上权限'
|
|
734
|
+
}
|
|
622
735
|
}
|
|
623
736
|
|
|
624
|
-
|
|
737
|
+
const groupId = session.guildId
|
|
625
738
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (
|
|
630
|
-
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// 如果同时指定了具体群号,也显示该群统计
|
|
634
|
-
if (targetGroupId && targetGroupId !== 'TOTAL') {
|
|
635
|
-
const groupStats = await ctx.database.get('group_verification_stats', { groupId: targetGroupId })
|
|
636
|
-
statsList = statsList.concat(groupStats)
|
|
739
|
+
// 处理不同参数情况
|
|
740
|
+
if (!target) {
|
|
741
|
+
// 无参数:显示当前群统计
|
|
742
|
+
if (!groupId) {
|
|
743
|
+
return '请在群聊中使用此命令或指定群号'
|
|
637
744
|
}
|
|
638
|
-
|
|
639
|
-
// 显示指定群统计
|
|
640
|
-
const groupStats = await ctx.database.get('group_verification_stats', { groupId: targetGroupId })
|
|
641
|
-
statsList = groupStats
|
|
745
|
+
return await getGroupStats(groupId)
|
|
642
746
|
}
|
|
643
747
|
|
|
644
|
-
if (
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
} else {
|
|
648
|
-
return `群 ${targetGroupId} 暂无验证统计信息`
|
|
649
|
-
}
|
|
748
|
+
if (target.toLowerCase() === 'all' || target.toLowerCase() === 'total') {
|
|
749
|
+
// 显示总计统计
|
|
750
|
+
return await getTotalStats()
|
|
650
751
|
}
|
|
651
752
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
const lastUpdated = new Date(stats.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
656
|
-
|
|
657
|
-
result += `${groupName} 验证统计:
|
|
658
|
-
自动批准: ${stats.autoApproved}
|
|
659
|
-
手动批准: ${stats.manuallyApproved}
|
|
660
|
-
拒绝: ${stats.rejected}
|
|
661
|
-
最后更新: ${lastUpdated}\n\n`
|
|
753
|
+
if (isGroupId) {
|
|
754
|
+
// 显示指定群统计
|
|
755
|
+
return await getGroupStats(target)
|
|
662
756
|
}
|
|
663
757
|
|
|
664
|
-
return
|
|
758
|
+
return '参数错误'
|
|
665
759
|
})
|
|
666
760
|
|
|
667
761
|
// Subcommand: view pending requests
|
|
668
762
|
groupVerify
|
|
669
763
|
.subcommand('.pending', '查看待审核加群申请')
|
|
670
|
-
.alias(
|
|
764
|
+
.alias(
|
|
765
|
+
'gv.list', 'gverify.list', 'group-verify.list',
|
|
766
|
+
'gv.待处理', 'gverify.待处理', 'group-verify.待处理',
|
|
767
|
+
'gvp'
|
|
768
|
+
)
|
|
671
769
|
.action(async ({ session }) => {
|
|
672
770
|
if (!session.guildId) {
|
|
673
771
|
return '请在群聊中使用此命令'
|
|
@@ -696,7 +794,9 @@ export function apply(ctx: Context, config: Config) {
|
|
|
696
794
|
// Subcommand: help information
|
|
697
795
|
groupVerify
|
|
698
796
|
.subcommand('.help', '显示帮助信息')
|
|
699
|
-
.alias(
|
|
797
|
+
.alias(
|
|
798
|
+
'gv.帮助', 'gverify.帮助', 'group-verify.帮助'
|
|
799
|
+
)
|
|
700
800
|
.action(() => {
|
|
701
801
|
return `群组验证命令帮助:
|
|
702
802
|
主指令别名:gv, gverify
|
|
@@ -760,6 +860,42 @@ export function apply(ctx: Context, config: Config) {
|
|
|
760
860
|
await syncTotalStats(ctx)
|
|
761
861
|
})
|
|
762
862
|
|
|
863
|
+
// 辅助函数:获取群组统计
|
|
864
|
+
async function getGroupStats(groupId: string): Promise<string> {
|
|
865
|
+
const stats = await ctx.database.get('group_verification_stats', { groupId })
|
|
866
|
+
|
|
867
|
+
if (stats.length === 0) {
|
|
868
|
+
return `群 ${groupId} 暂无验证统计信息`
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
const stat = stats[0]
|
|
872
|
+
const lastUpdated = new Date(stat.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
873
|
+
|
|
874
|
+
return `群 ${groupId} 验证统计:
|
|
875
|
+
自动批准: ${stat.autoApproved}
|
|
876
|
+
手动批准: ${stat.manuallyApproved}
|
|
877
|
+
拒绝: ${stat.rejected}
|
|
878
|
+
最后更新: ${lastUpdated}`
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// 辅助函数:获取总计统计
|
|
882
|
+
async function getTotalStats(): Promise<string> {
|
|
883
|
+
const stats = await ctx.database.get('group_verification_stats', { groupId: 'TOTAL' })
|
|
884
|
+
|
|
885
|
+
if (stats.length === 0) {
|
|
886
|
+
return '暂无统计信息'
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const stat = stats[0]
|
|
890
|
+
const lastUpdated = new Date(stat.lastUpdated).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
891
|
+
|
|
892
|
+
return `总计验证统计:
|
|
893
|
+
自动批准: ${stat.autoApproved}
|
|
894
|
+
手动批准: ${stat.manuallyApproved}
|
|
895
|
+
拒绝: ${stat.rejected}
|
|
896
|
+
最后更新: ${lastUpdated}`
|
|
897
|
+
}
|
|
898
|
+
|
|
763
899
|
// 同步统计数据到总计行的函数
|
|
764
900
|
async function syncTotalStats(ctx: Context) {
|
|
765
901
|
try {
|