koishi-plugin-group-verification 1.0.13 → 1.0.14
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 +1 -0
- package/lib/index.js +76 -29
- package/package.json +1 -1
- package/readme.md +132 -99
- package/src/index.ts +99 -38
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -46,6 +46,7 @@ function apply(ctx, config) {
|
|
|
46
46
|
keywords: "list",
|
|
47
47
|
reviewMethod: "integer",
|
|
48
48
|
reviewParameters: "json",
|
|
49
|
+
reminderEnabled: "boolean",
|
|
49
50
|
reminderMessage: "string",
|
|
50
51
|
createdBy: "string",
|
|
51
52
|
updatedBy: "string",
|
|
@@ -134,6 +135,10 @@ function apply(ctx, config) {
|
|
|
134
135
|
requestMessage: message,
|
|
135
136
|
applyTime: /* @__PURE__ */ new Date()
|
|
136
137
|
});
|
|
138
|
+
if (!config2.reminderEnabled || !config2.reminderMessage || config2.reminderMessage === "") {
|
|
139
|
+
logger.info(`群 ${guildId} 的提醒消息已被禁用,跳过发送`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
137
142
|
let reminderMsg = config2.reminderMessage;
|
|
138
143
|
reminderMsg = reminderMsg.replace(/{user}/g, username).replace(/{id}/g, userId).replace(/{group}/g, guildId).replace(/{gname}/g, groupName).replace(/{question}/g, message).replace(/{answer}/g, matchedCount.toString()).replace(/{threshold}/g, requiredThreshold);
|
|
139
144
|
await ctx2.broadcast([guildId], reminderMsg);
|
|
@@ -259,7 +264,7 @@ ${debugInfo}`];
|
|
|
259
264
|
"gverify.配置",
|
|
260
265
|
"group-verify.配置",
|
|
261
266
|
"gvc"
|
|
262
|
-
).option("groupId", "-i <groupId> 指定群号").option("method", "-m <method> 审核方式 (0-3)").option("threshold", "-t <threshold> 阈值参数").option("message", "-msg
|
|
267
|
+
).option("groupId", "-i <groupId> 指定群号").option("method", "-m <method> 审核方式 (0-3)").option("threshold", "-t <threshold> 阈值参数").option("message", "-msg [message] 自定义提醒消息").option("disableMessage", "-nomsg 禁用提醒消息").option("query", "-? 查询当前配置").option("remove", "-r 删除配置").action(async ({ session, options }, keywords) => {
|
|
263
268
|
const targetGroupId = options.groupId || session.guildId;
|
|
264
269
|
const [hasPermission, errorMsg] = await checkPermission(session, targetGroupId);
|
|
265
270
|
if (!hasPermission) {
|
|
@@ -308,11 +313,13 @@ ${debugInfo}`];
|
|
|
308
313
|
}
|
|
309
314
|
const createTime = new Date(config2.createdAt).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
|
|
310
315
|
const updateTime = new Date(config2.updatedAt).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
|
|
316
|
+
const reminderStatus = config2.reminderEnabled ? "启用" : "禁用";
|
|
311
317
|
return `群 ${targetGroupId} 配置:
|
|
312
318
|
关键词: ${config2.keywords.join(", ")}
|
|
313
319
|
审核方式: ${methodDesc}
|
|
314
320
|
阈值: ${thresholdInfo}
|
|
315
|
-
提醒消息: ${
|
|
321
|
+
提醒消息: ${reminderStatus}
|
|
322
|
+
自定义消息: ${config2.reminderMessage || "无"}
|
|
316
323
|
创建时间: ${createTime}
|
|
317
324
|
更新时间: ${updateTime}
|
|
318
325
|
创建者: ${config2.createdBy}
|
|
@@ -323,9 +330,15 @@ ${debugInfo}`];
|
|
|
323
330
|
}
|
|
324
331
|
let keywordList = keywords ? keywords.split(",").map((k) => k.trim()).filter((k) => k) : [];
|
|
325
332
|
if (!keywords && !options.query && !options.remove) {
|
|
326
|
-
const hasConfigParams = options.method !== void 0 || options.threshold !== void 0 || options.message !== void 0;
|
|
333
|
+
const hasConfigParams = options.method !== void 0 || options.threshold !== void 0 || options.message !== void 0 || options.disableMessage !== void 0;
|
|
327
334
|
if (!hasConfigParams) {
|
|
328
|
-
return
|
|
335
|
+
return `用法:
|
|
336
|
+
gvc 关键词1,关键词2 -m 1 -t 2 # 创建配置
|
|
337
|
+
gvc -m 1 -t 2 # 修改审核参数
|
|
338
|
+
gvc -msg "消息内容" # 修改提醒消息
|
|
339
|
+
gvc -nomsg # 禁用提醒消息
|
|
340
|
+
gvc -? # 查询配置
|
|
341
|
+
gvc -r # 删除配置`;
|
|
329
342
|
}
|
|
330
343
|
const existingConfig2 = await ctx.database.get("group_verification_config", { groupId: targetGroupId });
|
|
331
344
|
if (existingConfig2.length === 0) {
|
|
@@ -333,43 +346,71 @@ ${debugInfo}`];
|
|
|
333
346
|
}
|
|
334
347
|
keywordList = existingConfig2[0].keywords;
|
|
335
348
|
}
|
|
349
|
+
let reminderEnabled = true;
|
|
350
|
+
let reminderMessage = config.defaultReminderMessage || `用户 {user}({id}) 申请加入群 {gname}({group})
|
|
351
|
+
申请理由:{question}
|
|
352
|
+
答对情况:{answer}
|
|
353
|
+
阈值要求:{threshold}
|
|
354
|
+
请管理员使用 #同意 或 #拒绝 来处理此申请`;
|
|
355
|
+
if (options.disableMessage) {
|
|
356
|
+
reminderEnabled = false;
|
|
357
|
+
reminderMessage = "";
|
|
358
|
+
} else if (options.message !== void 0) {
|
|
359
|
+
reminderEnabled = true;
|
|
360
|
+
reminderMessage = options.message || config.defaultReminderMessage || `用户 {user}({id}) 申请加入群 {gname}({group})
|
|
361
|
+
申请理由:{question}
|
|
362
|
+
答对情况:{answer}
|
|
363
|
+
阈值要求:{threshold}
|
|
364
|
+
请管理员使用 #同意 或 #拒绝 来处理此申请`;
|
|
365
|
+
}
|
|
366
|
+
if (reminderEnabled && reminderMessage) {
|
|
367
|
+
reminderMessage = reminderMessage.replace(/\\n/g, "\n");
|
|
368
|
+
}
|
|
336
369
|
let reviewMethod = 0;
|
|
337
370
|
let reviewParameters = {};
|
|
371
|
+
if (!keywords && !options.query && !options.remove) {
|
|
372
|
+
const existingConfig2 = await ctx.database.get("group_verification_config", { groupId: targetGroupId });
|
|
373
|
+
if (existingConfig2.length > 0) {
|
|
374
|
+
reviewMethod = existingConfig2[0].reviewMethod;
|
|
375
|
+
if (existingConfig2[0].reviewParameters?.threshold) {
|
|
376
|
+
reviewParameters.threshold = existingConfig2[0].reviewParameters.threshold;
|
|
377
|
+
}
|
|
378
|
+
if (options.disableMessage === void 0 && options.message === void 0) {
|
|
379
|
+
reminderEnabled = existingConfig2[0].reminderEnabled;
|
|
380
|
+
reminderMessage = existingConfig2[0].reminderMessage;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
338
384
|
if (options.method !== void 0) {
|
|
339
385
|
const methodNum = parseInt(options.method);
|
|
340
386
|
if (isNaN(methodNum) || methodNum < 0 || methodNum > 3) {
|
|
341
387
|
return "审核方式参数错误:0-全部同意, 1-按数量同意, 2-按比例同意, 3-全部拒绝";
|
|
342
388
|
}
|
|
343
389
|
reviewMethod = methodNum;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
390
|
+
}
|
|
391
|
+
if ((reviewMethod === 1 || reviewMethod === 2) && options.threshold !== void 0) {
|
|
392
|
+
const thresholdNum = parseInt(options.threshold);
|
|
393
|
+
if (isNaN(thresholdNum)) {
|
|
394
|
+
return "阈值参数必须为数字";
|
|
395
|
+
}
|
|
396
|
+
if (reviewMethod === 1) {
|
|
397
|
+
if (thresholdNum <= 0 || thresholdNum > keywordList.length) {
|
|
398
|
+
return `数量阈值必须在1-${keywordList.length}之间`;
|
|
348
399
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
reviewParameters.threshold = thresholdNum;
|
|
354
|
-
} else if (reviewMethod === 2) {
|
|
355
|
-
if (thresholdNum <= 0 || thresholdNum > 100) {
|
|
356
|
-
return "比例阈值必须在1-100之间";
|
|
357
|
-
}
|
|
358
|
-
reviewParameters.threshold = thresholdNum;
|
|
400
|
+
reviewParameters.threshold = thresholdNum;
|
|
401
|
+
} else if (reviewMethod === 2) {
|
|
402
|
+
if (thresholdNum <= 0 || thresholdNum > 100) {
|
|
403
|
+
return "比例阈值必须在1-100之间";
|
|
359
404
|
}
|
|
405
|
+
reviewParameters.threshold = thresholdNum;
|
|
360
406
|
}
|
|
361
407
|
}
|
|
362
|
-
let reminderMessage = options.message || config.defaultReminderMessage || `用户 {user}({id}) 申请加入群 {gname}({group})
|
|
363
|
-
申请理由:{question}
|
|
364
|
-
答对情况:{answer}
|
|
365
|
-
阈值要求:{threshold}
|
|
366
|
-
请管理员使用 #同意 或 #拒绝 来处理此申请`;
|
|
367
|
-
reminderMessage = reminderMessage.replace(/\\n/g, "\n");
|
|
368
408
|
const existingConfig = await ctx.database.get("group_verification_config", { groupId: targetGroupId });
|
|
369
409
|
const configData = {
|
|
370
410
|
keywords: keywordList,
|
|
371
411
|
reviewMethod,
|
|
372
412
|
reviewParameters,
|
|
413
|
+
reminderEnabled,
|
|
373
414
|
reminderMessage,
|
|
374
415
|
updatedBy: session.username || session.userId,
|
|
375
416
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -589,16 +630,18 @@ ${debugInfo}`];
|
|
|
589
630
|
配置命令 (.config/.cfg):
|
|
590
631
|
用法:
|
|
591
632
|
1. 创建新配置:gv.cfg 关键词1,关键词2 -m 1 -t 2
|
|
592
|
-
2. 修改现有配置:gv.cfg -m
|
|
593
|
-
3.
|
|
594
|
-
4.
|
|
595
|
-
5.
|
|
633
|
+
2. 修改现有配置:gv.cfg -m 1 -t 2 (不提供关键词)
|
|
634
|
+
3. 启用提醒消息:gv.cfg -msg "消息内容"
|
|
635
|
+
4. 禁用提醒消息:gv.cfg -nomsg
|
|
636
|
+
5. 查询配置:gv.cfg -?
|
|
637
|
+
6. 删除配置:gv.cfg -r
|
|
596
638
|
|
|
597
639
|
参数说明:
|
|
598
640
|
-i <群号> 指定群号(私聊时必需)
|
|
599
641
|
-m <方式> 审核方式 (0=全部同意, 1=按数量, 2=按比例, 3=全部拒绝)
|
|
600
642
|
-t <阈值> 阈值参数(方式1或2时必需)
|
|
601
|
-
-msg
|
|
643
|
+
-msg [消息] 自定义提醒消息(不带参数显示帮助)
|
|
644
|
+
-nomsg 禁用提醒消息
|
|
602
645
|
-? 查询当前配置
|
|
603
646
|
-r 删除配置
|
|
604
647
|
|
|
@@ -610,7 +653,11 @@ ${debugInfo}`];
|
|
|
610
653
|
{question} - 申请理由
|
|
611
654
|
{answer} - 答对数量/比例
|
|
612
655
|
{threshold} - 阈值要求
|
|
656
|
+
|
|
657
|
+
消息格式化:
|
|
613
658
|
\\n - 换行符
|
|
659
|
+
可以组合使用变量和换行符创建格式化的消息
|
|
660
|
+
示例:gv.cfg -msg "用户 {user}\\n申请理由:{question}\\n匹配:{answer}/{threshold}"
|
|
614
661
|
|
|
615
662
|
快捷命令:
|
|
616
663
|
gvc - 配置命令快捷方式
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,151 +1,184 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Koishi 群组验证插件
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个功能完整的 Koishi 群组加群验证插件,支持多关键词匹配审核、多种审核方式和详细统计功能。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 🌟 主要特性
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **多关键词匹配**:支持多个关键词的灵活配置
|
|
8
|
+
- **四种审核方式**:全部同意、按数量同意、按比例同意、全部拒绝
|
|
9
|
+
- **完善的权限控制**:群主/管理员权限或 Koishi 三级以上权限
|
|
10
|
+
- **详细的统计功能**:自动记录审核统计和手动入群统计
|
|
11
|
+
- **灵活的消息配置**:支持自定义提醒消息和禁用功能
|
|
12
|
+
- **友好的命令系统**:丰富的别名和快捷命令
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
- ✅ 验证失败时通知管理员审核
|
|
11
|
-
- ✅ 每个群组独立配置
|
|
12
|
-
- ✅ 详细的统计信息(自动通过/手动通过/拒绝)
|
|
13
|
-
- ✅ 管理员指令控制
|
|
14
|
+
## 🚀 安装使用
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
```bash
|
|
17
|
+
# 在 Koishi 控制台中搜索并安装
|
|
18
|
+
koishi-plugin-group-verification
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 📋 命令说明
|
|
16
22
|
|
|
17
|
-
###
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
- `
|
|
21
|
-
- `parameters`: 验证参数
|
|
22
|
-
- `reminderMessage`: 提醒消息模板
|
|
23
|
+
### 主指令别名
|
|
24
|
+
- `group-verify` (完整名称)
|
|
25
|
+
- `gv` (快捷别名)
|
|
26
|
+
- `gverify` (中等长度别名)
|
|
23
27
|
|
|
24
|
-
###
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
- `rejected`: 拒绝数量
|
|
28
|
+
### 配置命令
|
|
29
|
+
```
|
|
30
|
+
# 创建新配置
|
|
31
|
+
gvc 关键词1,关键词2,关键词3 -m 1 -t 2
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
- `userId`: 用户ID
|
|
33
|
-
- `userName`: 用户名
|
|
34
|
-
- `requestMessage`: 申请理由
|
|
35
|
-
- `applyTime`: 申请时间
|
|
33
|
+
# 修改审核参数
|
|
34
|
+
gvc -m 2 -t 60
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
# 启用自定义提醒消息
|
|
37
|
+
gvc -msg "用户 {user} 申请入群,匹配 {answer} 个关键词"
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
# 禁用提醒消息
|
|
40
|
+
gvc -nomsg
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
# 查询当前配置
|
|
43
|
+
gvc -?
|
|
42
44
|
|
|
45
|
+
# 删除配置
|
|
46
|
+
gvc -r
|
|
43
47
|
```
|
|
44
|
-
|
|
48
|
+
|
|
49
|
+
### 审核命令
|
|
45
50
|
```
|
|
51
|
+
# 同意申请(处理最近一个)
|
|
52
|
+
gva
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- `-m <方式>` 审核方式 (0=全部同意, 1=按数量, 2=按比例, 3=全部拒绝)
|
|
50
|
-
- `-t <阈值>` 阈值参数(方式1或2时必需)
|
|
51
|
-
- `-?` 查询当前配置
|
|
52
|
-
- `-r` 删除配置
|
|
54
|
+
# 同意指定用户
|
|
55
|
+
gva 123456789
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **阈值**:当审核方式为1或2时需要指定
|
|
57
|
-
- 方式1(按数量):阈值范围1-关键词总数
|
|
58
|
-
- 方式2(按比例):阈值范围1-100(百分比)
|
|
57
|
+
# 同意所有申请
|
|
58
|
+
gva all
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
# 拒绝申请
|
|
61
|
+
gvr 123456789
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
# 拒绝所有申请
|
|
64
|
+
gvr all
|
|
63
65
|
```
|
|
64
|
-
# 基本配置(全部同意模式)
|
|
65
|
-
group-verify.config 学生,校友,老师
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
### 查询命令
|
|
68
|
+
```
|
|
69
|
+
# 查看待审核列表
|
|
70
|
+
gvp
|
|
69
71
|
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
+
# 查看统计信息
|
|
73
|
+
gvs
|
|
72
74
|
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
+
# 查看指定群统计
|
|
76
|
+
gvs 123456789
|
|
75
77
|
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
+
# 查看总计统计(需要权限)
|
|
79
|
+
gvs total
|
|
80
|
+
```
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
group-verify.config -i 123456789 -?
|
|
82
|
+
## ⚙️ 参数说明
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
### 审核方式 (-m)
|
|
85
|
+
- `0` - 全部同意(默认)
|
|
86
|
+
- `1` - 按数量同意(需配合 -t 使用)
|
|
87
|
+
- `2` - 按比例同意(需配合 -t 使用)
|
|
88
|
+
- `3` - 全部拒绝
|
|
85
89
|
|
|
86
|
-
###
|
|
90
|
+
### 阈值参数 (-t)
|
|
91
|
+
- 方式1(按数量):需要匹配的关键词数量(1-N)
|
|
92
|
+
- 方式2(按比例):需要达到的百分比(1-100)
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
### 提醒消息配置
|
|
95
|
+
- `-msg "消息内容"` - 设置自定义提醒消息
|
|
96
|
+
- `-nomsg` - 禁用提醒消息功能
|
|
97
|
+
- 不带参数的 `-msg` 会显示帮助信息
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
### 提醒消息变量
|
|
91
100
|
```
|
|
92
|
-
|
|
101
|
+
{user} - 用户名
|
|
102
|
+
{id} - 用户ID
|
|
103
|
+
{group} - 群号
|
|
104
|
+
{gname} - 群名称
|
|
105
|
+
{question} - 申请理由
|
|
106
|
+
{answer} - 答对数量/比例
|
|
107
|
+
{threshold} - 阈值要求
|
|
108
|
+
\n - 换行符
|
|
93
109
|
```
|
|
94
110
|
|
|
95
|
-
|
|
111
|
+
## 🔐 权限说明
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
### 配置和审核命令
|
|
114
|
+
需要以下任一权限:
|
|
115
|
+
- 群主权限
|
|
116
|
+
- 管理员权限
|
|
117
|
+
- Koishi 三级以上权限
|
|
101
118
|
|
|
102
|
-
|
|
119
|
+
### 统计命令
|
|
120
|
+
- 普通统计:任意用户可查看
|
|
121
|
+
- 总计统计:需要 Koishi 三级以上权限
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
## 📊 统计功能
|
|
124
|
+
|
|
125
|
+
插件会自动记录以下统计信息:
|
|
126
|
+
- **自动批准**:通过关键词验证自动入群的用户数
|
|
127
|
+
- **手动批准**:管理员手动同意的用户数
|
|
128
|
+
- **拒绝**:被拒绝的申请数
|
|
129
|
+
- **手动入群**:管理员直接邀请入群的用户数
|
|
130
|
+
|
|
131
|
+
## 🛠️ 开发配置
|
|
108
132
|
|
|
109
|
-
|
|
133
|
+
### 全局配置
|
|
134
|
+
在 Koishi 控制台插件配置页面可以设置:
|
|
135
|
+
- 默认提醒消息模板
|
|
136
|
+
- 日志级别
|
|
110
137
|
|
|
111
|
-
###
|
|
138
|
+
### 数据库结构
|
|
139
|
+
插件使用以下数据表:
|
|
140
|
+
- `group_verification_config` - 群组配置表
|
|
141
|
+
- `group_verification_stats` - 统计信息表
|
|
142
|
+
- `group_verification_pending` - 待审核申请表
|
|
112
143
|
|
|
113
|
-
|
|
144
|
+
## 📝 使用示例
|
|
114
145
|
|
|
146
|
+
### 场景1:学生群验证
|
|
115
147
|
```
|
|
116
|
-
|
|
148
|
+
# 设置学生群验证规则
|
|
149
|
+
gvc 学生,校友,老师 -m 1 -t 2 -msg "欢迎 {user} 加入学习群!"
|
|
117
150
|
```
|
|
118
151
|
|
|
119
|
-
|
|
152
|
+
### 场景2:企业内部群
|
|
153
|
+
```
|
|
154
|
+
# 设置严格的验证规则
|
|
155
|
+
gvc 员工,实习生,部门 -m 2 -t 100 -nomsg
|
|
156
|
+
```
|
|
120
157
|
|
|
121
|
-
|
|
158
|
+
### 场景3:兴趣爱好群
|
|
122
159
|
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
group-verify.stats all # 查看总体统计
|
|
160
|
+
# 设置宽松的验证规则
|
|
161
|
+
gvc 兴趣,爱好,交流 -m 0 -msg "欢迎 {user} 加入我们的大家庭!"
|
|
126
162
|
```
|
|
127
163
|
|
|
128
|
-
|
|
164
|
+
## 🐛 常见问题
|
|
129
165
|
|
|
130
|
-
|
|
166
|
+
### Q: 如何禁用提醒消息?
|
|
167
|
+
A: 使用 `gvc -nomsg` 命令禁用提醒功能
|
|
131
168
|
|
|
132
|
-
|
|
133
|
-
group
|
|
134
|
-
|
|
169
|
+
### Q: 提醒消息支持哪些变量?
|
|
170
|
+
A: 支持 {user}, {id}, {group}, {gname}, {question}, {answer}, {threshold} 等变量
|
|
171
|
+
|
|
172
|
+
### Q: 如何查看统计信息?
|
|
173
|
+
A: 使用 `gvs` 查看当前群统计,`gvs total` 查看总计统计
|
|
135
174
|
|
|
136
|
-
|
|
175
|
+
### Q: 权限不够怎么办?
|
|
176
|
+
A: 需要群主/管理员权限或 Koishi 三级以上权限
|
|
137
177
|
|
|
138
|
-
##
|
|
178
|
+
## 📄 许可证
|
|
139
179
|
|
|
140
|
-
|
|
141
|
-
2. 系统检查该群是否配置了验证规则
|
|
142
|
-
3. 如果未配置或验证通过 → 自动同意入群
|
|
143
|
-
4. 如果验证失败 → 将申请加入待审核列表,并在群内发送提醒
|
|
144
|
-
5. 管理员使用指令处理待审核申请
|
|
145
|
-
6. 系统自动更新相关统计信息
|
|
180
|
+
MIT License
|
|
146
181
|
|
|
147
|
-
##
|
|
182
|
+
## 🤝 贡献
|
|
148
183
|
|
|
149
|
-
|
|
150
|
-
- 关键词匹配不区分大小写
|
|
151
|
-
- 统计信息会自动累计,包括每个群和总体数据
|
|
184
|
+
欢迎提交 Issue 和 Pull Request!
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface GroupVerificationConfig {
|
|
|
20
20
|
reviewParameters: {
|
|
21
21
|
threshold?: number // 数量阈值或比例阈值
|
|
22
22
|
}
|
|
23
|
+
reminderEnabled: boolean // 是否启用提醒消息
|
|
23
24
|
reminderMessage: string
|
|
24
25
|
createdBy: string
|
|
25
26
|
updatedBy: string
|
|
@@ -77,6 +78,7 @@ export function apply(ctx: Context, config: Config) {
|
|
|
77
78
|
keywords: 'list',
|
|
78
79
|
reviewMethod: 'integer',
|
|
79
80
|
reviewParameters: 'json',
|
|
81
|
+
reminderEnabled: 'boolean',
|
|
80
82
|
reminderMessage: 'string',
|
|
81
83
|
createdBy: 'string',
|
|
82
84
|
updatedBy: 'string',
|
|
@@ -209,6 +211,12 @@ export function apply(ctx: Context, config: Config) {
|
|
|
209
211
|
applyTime: new Date()
|
|
210
212
|
})
|
|
211
213
|
|
|
214
|
+
// 如果提醒消息被禁用,直接返回
|
|
215
|
+
if (!config.reminderEnabled || !config.reminderMessage || config.reminderMessage === '') {
|
|
216
|
+
logger.info(`群 ${guildId} 的提醒消息已被禁用,跳过发送`)
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
212
220
|
// 替换提醒消息中的变量
|
|
213
221
|
let reminderMsg = config.reminderMessage
|
|
214
222
|
reminderMsg = reminderMsg
|
|
@@ -379,7 +387,8 @@ export function apply(ctx: Context, config: Config) {
|
|
|
379
387
|
.option('groupId', '-i <groupId> 指定群号')
|
|
380
388
|
.option('method', '-m <method> 审核方式 (0-3)')
|
|
381
389
|
.option('threshold', '-t <threshold> 阈值参数')
|
|
382
|
-
.option('message', '-msg
|
|
390
|
+
.option('message', '-msg [message] 自定义提醒消息')
|
|
391
|
+
.option('disableMessage', '-nomsg 禁用提醒消息')
|
|
383
392
|
.option('query', '-? 查询当前配置')
|
|
384
393
|
.option('remove', '-r 删除配置')
|
|
385
394
|
.action(async ({ session, options }, keywords) => {
|
|
@@ -441,12 +450,14 @@ export function apply(ctx: Context, config: Config) {
|
|
|
441
450
|
|
|
442
451
|
const createTime = new Date(config.createdAt).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
443
452
|
const updateTime = new Date(config.updatedAt).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
|
|
453
|
+
const reminderStatus = config.reminderEnabled ? '启用' : '禁用'
|
|
444
454
|
|
|
445
455
|
return `群 ${targetGroupId} 配置:
|
|
446
456
|
关键词: ${config.keywords.join(', ')}
|
|
447
457
|
审核方式: ${methodDesc}
|
|
448
458
|
阈值: ${thresholdInfo}
|
|
449
|
-
提醒消息: ${
|
|
459
|
+
提醒消息: ${reminderStatus}
|
|
460
|
+
自定义消息: ${config.reminderMessage || '无'}
|
|
450
461
|
创建时间: ${createTime}
|
|
451
462
|
更新时间: ${updateTime}
|
|
452
463
|
创建者: ${config.createdBy}
|
|
@@ -460,15 +471,21 @@ export function apply(ctx: Context, config: Config) {
|
|
|
460
471
|
let keywordList = keywords ? keywords.split(',').map(k => k.trim()).filter(k => k) : []
|
|
461
472
|
|
|
462
473
|
// 如果没有提供关键词且不是查询/删除操作,则报错
|
|
463
|
-
// 但允许只提供参数来修改现有配置
|
|
464
474
|
if (!keywords && !options.query && !options.remove) {
|
|
465
475
|
// 检查是否提供了其他配置参数
|
|
466
476
|
const hasConfigParams = options.method !== undefined ||
|
|
467
477
|
options.threshold !== undefined ||
|
|
468
|
-
options.message !== undefined
|
|
478
|
+
options.message !== undefined ||
|
|
479
|
+
options.disableMessage !== undefined
|
|
469
480
|
|
|
470
481
|
if (!hasConfigParams) {
|
|
471
|
-
return
|
|
482
|
+
return `用法:
|
|
483
|
+
gvc 关键词1,关键词2 -m 1 -t 2 # 创建配置
|
|
484
|
+
gvc -m 1 -t 2 # 修改审核参数
|
|
485
|
+
gvc -msg "消息内容" # 修改提醒消息
|
|
486
|
+
gvc -nomsg # 禁用提醒消息
|
|
487
|
+
gvc -? # 查询配置
|
|
488
|
+
gvc -r # 删除配置`
|
|
472
489
|
}
|
|
473
490
|
|
|
474
491
|
// 如果只提供了参数,检查是否存在现有配置
|
|
@@ -481,50 +498,87 @@ export function apply(ctx: Context, config: Config) {
|
|
|
481
498
|
keywordList = existingConfig[0].keywords
|
|
482
499
|
}
|
|
483
500
|
|
|
501
|
+
// 处理提醒消息配置
|
|
502
|
+
let reminderEnabled = true
|
|
503
|
+
let reminderMessage = config.defaultReminderMessage ||
|
|
504
|
+
`用户 {user}({id}) 申请加入群 {gname}({group})
|
|
505
|
+
申请理由:{question}
|
|
506
|
+
答对情况:{answer}
|
|
507
|
+
阈值要求:{threshold}
|
|
508
|
+
请管理员使用 #同意 或 #拒绝 来处理此申请`
|
|
509
|
+
|
|
510
|
+
// 处理 -nomsg 选项
|
|
511
|
+
if (options.disableMessage) {
|
|
512
|
+
reminderEnabled = false
|
|
513
|
+
reminderMessage = ''
|
|
514
|
+
}
|
|
515
|
+
// 处理 -msg 选项
|
|
516
|
+
else if (options.message !== undefined) {
|
|
517
|
+
reminderEnabled = true
|
|
518
|
+
reminderMessage = options.message || config.defaultReminderMessage ||
|
|
519
|
+
`用户 {user}({id}) 申请加入群 {gname}({group})
|
|
520
|
+
申请理由:{question}
|
|
521
|
+
答对情况:{answer}
|
|
522
|
+
阈值要求:{threshold}
|
|
523
|
+
请管理员使用 #同意 或 #拒绝 来处理此申请`
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// 替换换行符
|
|
527
|
+
if (reminderEnabled && reminderMessage) {
|
|
528
|
+
reminderMessage = reminderMessage.replace(/\\n/g, '\n')
|
|
529
|
+
}
|
|
530
|
+
|
|
484
531
|
// 解析审核方式和阈值
|
|
485
532
|
let reviewMethod: 0 | 1 | 2 | 3 = 0 // 默认全部同意
|
|
486
533
|
let reviewParameters: { threshold?: number } = {}
|
|
487
534
|
|
|
535
|
+
// 如果是修改现有配置,先获取现有参数
|
|
536
|
+
if (!keywords && !options.query && !options.remove) {
|
|
537
|
+
const existingConfig = await ctx.database.get('group_verification_config', { groupId: targetGroupId })
|
|
538
|
+
if (existingConfig.length > 0) {
|
|
539
|
+
// 使用现有配置的参数作为默认值
|
|
540
|
+
reviewMethod = existingConfig[0].reviewMethod
|
|
541
|
+
if (existingConfig[0].reviewParameters?.threshold) {
|
|
542
|
+
reviewParameters.threshold = existingConfig[0].reviewParameters.threshold
|
|
543
|
+
}
|
|
544
|
+
// 如果没有明确设置提醒相关选项,使用现有配置
|
|
545
|
+
if (options.disableMessage === undefined && options.message === undefined) {
|
|
546
|
+
reminderEnabled = existingConfig[0].reminderEnabled
|
|
547
|
+
reminderMessage = existingConfig[0].reminderMessage
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// 解析审核方式和阈值
|
|
553
|
+
|
|
488
554
|
if (options.method !== undefined) {
|
|
489
555
|
const methodNum = parseInt(options.method)
|
|
490
556
|
if (isNaN(methodNum) || methodNum < 0 || methodNum > 3) {
|
|
491
557
|
return '审核方式参数错误:0-全部同意, 1-按数量同意, 2-按比例同意, 3-全部拒绝'
|
|
492
558
|
}
|
|
493
559
|
reviewMethod = methodNum as 0 | 1 | 2 | 3
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// 只有当审核方式需要阈值时才处理阈值参数
|
|
563
|
+
if ((reviewMethod === 1 || reviewMethod === 2) && options.threshold !== undefined) {
|
|
564
|
+
const thresholdNum = parseInt(options.threshold)
|
|
565
|
+
if (isNaN(thresholdNum)) {
|
|
566
|
+
return '阈值参数必须为数字'
|
|
567
|
+
}
|
|
494
568
|
|
|
495
|
-
//
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (isNaN(thresholdNum)) {
|
|
499
|
-
return '阈值参数必须为数字'
|
|
569
|
+
if (reviewMethod === 1) { // 按数量同意
|
|
570
|
+
if (thresholdNum <= 0 || thresholdNum > keywordList.length) {
|
|
571
|
+
return `数量阈值必须在1-${keywordList.length}之间`
|
|
500
572
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
reviewParameters.threshold = thresholdNum
|
|
507
|
-
} else if (reviewMethod === 2) { // 按比例同意
|
|
508
|
-
if (thresholdNum <= 0 || thresholdNum > 100) {
|
|
509
|
-
return '比例阈值必须在1-100之间'
|
|
510
|
-
}
|
|
511
|
-
reviewParameters.threshold = thresholdNum
|
|
573
|
+
reviewParameters.threshold = thresholdNum
|
|
574
|
+
} else if (reviewMethod === 2) { // 按比例同意
|
|
575
|
+
if (thresholdNum <= 0 || thresholdNum > 100) {
|
|
576
|
+
return '比例阈值必须在1-100之间'
|
|
512
577
|
}
|
|
578
|
+
reviewParameters.threshold = thresholdNum
|
|
513
579
|
}
|
|
514
580
|
}
|
|
515
581
|
|
|
516
|
-
// 处理提醒消息
|
|
517
|
-
let reminderMessage = options.message ||
|
|
518
|
-
config.defaultReminderMessage ||
|
|
519
|
-
`用户 {user}({id}) 申请加入群 {gname}({group})
|
|
520
|
-
申请理由:{question}
|
|
521
|
-
答对情况:{answer}
|
|
522
|
-
阈值要求:{threshold}
|
|
523
|
-
请管理员使用 #同意 或 #拒绝 来处理此申请`
|
|
524
|
-
|
|
525
|
-
// 替换换行符
|
|
526
|
-
reminderMessage = reminderMessage.replace(/\\n/g, '\n')
|
|
527
|
-
|
|
528
582
|
// Check if configuration already exists
|
|
529
583
|
const existingConfig = await ctx.database.get('group_verification_config', { groupId: targetGroupId })
|
|
530
584
|
|
|
@@ -532,6 +586,7 @@ export function apply(ctx: Context, config: Config) {
|
|
|
532
586
|
keywords: keywordList,
|
|
533
587
|
reviewMethod: reviewMethod,
|
|
534
588
|
reviewParameters: reviewParameters,
|
|
589
|
+
reminderEnabled: reminderEnabled,
|
|
535
590
|
reminderMessage: reminderMessage,
|
|
536
591
|
updatedBy: session.username || session.userId,
|
|
537
592
|
updatedAt: new Date()
|
|
@@ -819,16 +874,18 @@ export function apply(ctx: Context, config: Config) {
|
|
|
819
874
|
配置命令 (.config/.cfg):
|
|
820
875
|
用法:
|
|
821
876
|
1. 创建新配置:gv.cfg 关键词1,关键词2 -m 1 -t 2
|
|
822
|
-
2. 修改现有配置:gv.cfg -m
|
|
823
|
-
3.
|
|
824
|
-
4.
|
|
825
|
-
5.
|
|
877
|
+
2. 修改现有配置:gv.cfg -m 1 -t 2 (不提供关键词)
|
|
878
|
+
3. 启用提醒消息:gv.cfg -msg "消息内容"
|
|
879
|
+
4. 禁用提醒消息:gv.cfg -nomsg
|
|
880
|
+
5. 查询配置:gv.cfg -?
|
|
881
|
+
6. 删除配置:gv.cfg -r
|
|
826
882
|
|
|
827
883
|
参数说明:
|
|
828
884
|
-i <群号> 指定群号(私聊时必需)
|
|
829
885
|
-m <方式> 审核方式 (0=全部同意, 1=按数量, 2=按比例, 3=全部拒绝)
|
|
830
886
|
-t <阈值> 阈值参数(方式1或2时必需)
|
|
831
|
-
-msg
|
|
887
|
+
-msg [消息] 自定义提醒消息(不带参数显示帮助)
|
|
888
|
+
-nomsg 禁用提醒消息
|
|
832
889
|
-? 查询当前配置
|
|
833
890
|
-r 删除配置
|
|
834
891
|
|
|
@@ -840,7 +897,11 @@ export function apply(ctx: Context, config: Config) {
|
|
|
840
897
|
{question} - 申请理由
|
|
841
898
|
{answer} - 答对数量/比例
|
|
842
899
|
{threshold} - 阈值要求
|
|
900
|
+
|
|
901
|
+
消息格式化:
|
|
843
902
|
\\n - 换行符
|
|
903
|
+
可以组合使用变量和换行符创建格式化的消息
|
|
904
|
+
示例:gv.cfg -msg "用户 {user}\\n申请理由:{question}\\n匹配:{answer}/{threshold}"
|
|
844
905
|
|
|
845
906
|
快捷命令:
|
|
846
907
|
gvc - 配置命令快捷方式
|