koishi-plugin-temporaryban 1.0.7 → 1.1.1
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/commands/index.js +1 -1
- package/lib/commands/info.js +1 -1
- package/lib/commands/stats.js +15 -2
- package/lib/commands/whitelist.d.ts +2 -1
- package/lib/commands/whitelist.js +126 -7
- package/lib/config.d.ts +15 -6
- package/lib/config.js +142 -71
- package/lib/index.d.ts +19 -0
- package/lib/index.js +101 -20
- package/lib/locales/en-US.d.ts +26 -0
- package/lib/locales/en-US.js +27 -1
- package/lib/locales/zh-CN.d.ts +26 -0
- package/lib/locales/zh-CN.js +27 -1
- package/lib/services/detector.d.ts +5 -0
- package/lib/services/detector.js +71 -8
- package/lib/services/mailer.d.ts +1 -4
- package/lib/services/mailer.js +49 -60
- package/lib/services/whitelist.d.ts +2 -1
- package/lib/services/whitelist.js +31 -11
- package/package.json +8 -5
package/lib/commands/index.js
CHANGED
|
@@ -11,7 +11,7 @@ const info_1 = require("./info");
|
|
|
11
11
|
function registerCommands(ctx, config, detector, mailer, userRecords, history, whitelistService) {
|
|
12
12
|
(0, admin_1.registerAdminCommands)(ctx, config, mailer);
|
|
13
13
|
(0, dictionary_1.registerDictionaryCommands)(ctx, config, detector);
|
|
14
|
-
(0, whitelist_1.registerWhitelistCommands)(ctx, config, whitelistService);
|
|
14
|
+
(0, whitelist_1.registerWhitelistCommands)(ctx, config, whitelistService, detector);
|
|
15
15
|
(0, stats_1.registerStatsCommands)(ctx, config, userRecords);
|
|
16
16
|
(0, check_1.registerCheckCommands)(ctx, config, detector);
|
|
17
17
|
(0, history_1.registerHistoryCommands)(ctx, config, history);
|
package/lib/commands/info.js
CHANGED
|
@@ -16,7 +16,7 @@ function registerInfoCommands(ctx, config, whitelistService) {
|
|
|
16
16
|
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
17
17
|
if (!groupConfig)
|
|
18
18
|
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
19
|
-
const whitelistCount = whitelistService.
|
|
19
|
+
const whitelistCount = whitelistService.getWhitelist(session.guildId).length;
|
|
20
20
|
const methods = groupConfig.detectionMethods.join(', ') || 'None';
|
|
21
21
|
const smartVer = groupConfig.smartVerification ? 'ON' : 'OFF';
|
|
22
22
|
return session.text('commands.temporaryban.messages.group_info', [
|
package/lib/commands/stats.js
CHANGED
|
@@ -25,14 +25,27 @@ function registerStatsCommands(ctx, config, userRecords) {
|
|
|
25
25
|
return session.text('commands.temporaryban.messages.stats_header', [violators]);
|
|
26
26
|
});
|
|
27
27
|
// 8. Clean
|
|
28
|
-
cmd.subcommand('.clean
|
|
29
|
-
.
|
|
28
|
+
cmd.subcommand('.clean [user:string]')
|
|
29
|
+
.option('all', '-a 清除本群所有违规记录')
|
|
30
|
+
.action(async ({ session, options }, user) => {
|
|
30
31
|
if (!session)
|
|
31
32
|
return;
|
|
32
33
|
if (!(0, permission_1.checkPermission)(session, config))
|
|
33
34
|
return session.text('commands.temporaryban.messages.permission_denied');
|
|
34
35
|
if (!session.guildId)
|
|
35
36
|
return session.text('commands.temporaryban.messages.group_only');
|
|
37
|
+
// Bulk Clean
|
|
38
|
+
if (options?.all) {
|
|
39
|
+
const prefix = `${session.guildId}-`;
|
|
40
|
+
let removedCount = 0;
|
|
41
|
+
for (const key of userRecords.keys()) {
|
|
42
|
+
if (key.startsWith(prefix)) {
|
|
43
|
+
userRecords.delete(key);
|
|
44
|
+
removedCount++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return session.text('commands.temporaryban.messages.all_records_cleared', [removedCount]);
|
|
48
|
+
}
|
|
36
49
|
if (!user)
|
|
37
50
|
return session.text('commands.temporaryban.messages.specify_user_id');
|
|
38
51
|
const key = `${session.guildId}-${user}`;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
2
|
import { Config } from '../config';
|
|
3
3
|
import { WhitelistService } from '../services/whitelist';
|
|
4
|
-
|
|
4
|
+
import { DetectorService } from '../services/detector';
|
|
5
|
+
export declare function registerWhitelistCommands(ctx: Context, config: Config, whitelistService: WhitelistService, detector: DetectorService): void;
|
|
@@ -2,10 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerWhitelistCommands = registerWhitelistCommands;
|
|
4
4
|
const permission_1 = require("../utils/permission");
|
|
5
|
-
function registerWhitelistCommands(ctx, config, whitelistService) {
|
|
5
|
+
function registerWhitelistCommands(ctx, config, whitelistService, detector) {
|
|
6
6
|
const cmd = ctx.command('temporaryban');
|
|
7
|
-
//
|
|
8
|
-
cmd.subcommand('.whitelist
|
|
7
|
+
// --- Whitelist User Management ---
|
|
8
|
+
const whitelistCmd = cmd.subcommand('.whitelist');
|
|
9
|
+
// 10. Whitelist User List
|
|
10
|
+
whitelistCmd.subcommand('.list')
|
|
11
|
+
.action(async ({ session }) => {
|
|
12
|
+
if (!session)
|
|
13
|
+
return;
|
|
14
|
+
if (!(0, permission_1.checkPermission)(session, config))
|
|
15
|
+
return session.text('commands.temporaryban.messages.permission_denied');
|
|
16
|
+
if (!session.guildId)
|
|
17
|
+
return session.text('commands.temporaryban.messages.group_only');
|
|
18
|
+
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
19
|
+
if (!groupConfig)
|
|
20
|
+
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
21
|
+
const items = whitelistService.getWhitelist(session.guildId);
|
|
22
|
+
if (items.length === 0)
|
|
23
|
+
return session.text('commands.temporaryban.messages.no_whitelist_users');
|
|
24
|
+
return session.text('commands.temporaryban.messages.whitelist_users_list', [items.length, items.join(', ')]);
|
|
25
|
+
});
|
|
26
|
+
// 5. Whitelist Add User
|
|
27
|
+
whitelistCmd.subcommand('.add <user:string>')
|
|
9
28
|
.action(async ({ session }, user) => {
|
|
10
29
|
if (!session)
|
|
11
30
|
return;
|
|
@@ -13,18 +32,28 @@ function registerWhitelistCommands(ctx, config, whitelistService) {
|
|
|
13
32
|
return session.text('commands.temporaryban.messages.permission_denied');
|
|
14
33
|
if (!session.guildId)
|
|
15
34
|
return session.text('commands.temporaryban.messages.group_only');
|
|
16
|
-
if (!user)
|
|
17
|
-
|
|
35
|
+
if (!user) {
|
|
36
|
+
await session.send(session.text('commands.temporaryban.messages.specify_user_id'));
|
|
37
|
+
user = await session.prompt();
|
|
38
|
+
if (!user)
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
18
41
|
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
19
42
|
if (!groupConfig)
|
|
20
43
|
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
44
|
+
// Support At-element (e.g. <at id="123"/>)
|
|
45
|
+
if (user.includes('<at')) {
|
|
46
|
+
const match = user.match(/id="([^"]+)"/);
|
|
47
|
+
if (match)
|
|
48
|
+
user = match[1];
|
|
49
|
+
}
|
|
21
50
|
const success = await whitelistService.add(session.guildId, user);
|
|
22
51
|
if (!success)
|
|
23
52
|
return session.text('commands.temporaryban.messages.already_whitelisted');
|
|
24
53
|
return session.text('commands.temporaryban.messages.user_added_whitelist', [user]);
|
|
25
54
|
});
|
|
26
|
-
// 6. Whitelist Remove
|
|
27
|
-
|
|
55
|
+
// 6. Whitelist Remove User
|
|
56
|
+
whitelistCmd.subcommand('.remove <user:string>')
|
|
28
57
|
.action(async ({ session }, user) => {
|
|
29
58
|
if (!session)
|
|
30
59
|
return;
|
|
@@ -32,6 +61,18 @@ function registerWhitelistCommands(ctx, config, whitelistService) {
|
|
|
32
61
|
return session.text('commands.temporaryban.messages.permission_denied');
|
|
33
62
|
if (!session.guildId)
|
|
34
63
|
return session.text('commands.temporaryban.messages.group_only');
|
|
64
|
+
if (!user) {
|
|
65
|
+
await session.send(session.text('commands.temporaryban.messages.specify_user_id'));
|
|
66
|
+
user = await session.prompt();
|
|
67
|
+
if (!user)
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Support At-element
|
|
71
|
+
if (user.includes('<at')) {
|
|
72
|
+
const match = user.match(/id="([^"]+)"/);
|
|
73
|
+
if (match)
|
|
74
|
+
user = match[1];
|
|
75
|
+
}
|
|
35
76
|
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
36
77
|
if (!groupConfig)
|
|
37
78
|
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
@@ -40,4 +81,82 @@ function registerWhitelistCommands(ctx, config, whitelistService) {
|
|
|
40
81
|
return session.text('commands.temporaryban.messages.not_in_whitelist');
|
|
41
82
|
return session.text('commands.temporaryban.messages.user_removed_whitelist', [user]);
|
|
42
83
|
});
|
|
84
|
+
// --- Whitelist Word Management ---
|
|
85
|
+
const wordCmd = whitelistCmd.subcommand('.word');
|
|
86
|
+
// 7. Whitelist Word Add
|
|
87
|
+
wordCmd.subcommand('.add <text:text>')
|
|
88
|
+
.action(async ({ session }, text) => {
|
|
89
|
+
if (!session)
|
|
90
|
+
return;
|
|
91
|
+
if (!(0, permission_1.checkPermission)(session, config))
|
|
92
|
+
return session.text('commands.temporaryban.messages.permission_denied');
|
|
93
|
+
if (!session.guildId)
|
|
94
|
+
return session.text('commands.temporaryban.messages.group_only');
|
|
95
|
+
if (!text) {
|
|
96
|
+
await session.send(session.text('commands.temporaryban.messages.specify_word'));
|
|
97
|
+
text = await session.prompt();
|
|
98
|
+
if (!text)
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
102
|
+
if (!groupConfig)
|
|
103
|
+
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
104
|
+
// Support batch add (comma or newline separated)
|
|
105
|
+
const words = text.split(/[,,\n]/).map(w => w.trim()).filter(w => w);
|
|
106
|
+
const added = [];
|
|
107
|
+
for (const w of words) {
|
|
108
|
+
const success = await detector.addIgnoredWord(session.guildId, w);
|
|
109
|
+
if (success)
|
|
110
|
+
added.push(w);
|
|
111
|
+
}
|
|
112
|
+
if (added.length === 0)
|
|
113
|
+
return session.text('commands.temporaryban.messages.word_exists');
|
|
114
|
+
return session.text('commands.temporaryban.messages.ignored_word_added', [added.join(', ')]);
|
|
115
|
+
});
|
|
116
|
+
// 8. Whitelist Word Remove
|
|
117
|
+
wordCmd.subcommand('.remove <text:text>')
|
|
118
|
+
.action(async ({ session }, text) => {
|
|
119
|
+
if (!session)
|
|
120
|
+
return;
|
|
121
|
+
if (!(0, permission_1.checkPermission)(session, config))
|
|
122
|
+
return session.text('commands.temporaryban.messages.permission_denied');
|
|
123
|
+
if (!session.guildId)
|
|
124
|
+
return session.text('commands.temporaryban.messages.group_only');
|
|
125
|
+
if (!text) {
|
|
126
|
+
await session.send(session.text('commands.temporaryban.messages.specify_word'));
|
|
127
|
+
text = await session.prompt();
|
|
128
|
+
if (!text)
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
132
|
+
if (!groupConfig)
|
|
133
|
+
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
134
|
+
const words = text.split(/[,,\n]/).map(w => w.trim()).filter(w => w);
|
|
135
|
+
const removed = [];
|
|
136
|
+
for (const w of words) {
|
|
137
|
+
const success = await detector.removeIgnoredWord(session.guildId, w);
|
|
138
|
+
if (success)
|
|
139
|
+
removed.push(w);
|
|
140
|
+
}
|
|
141
|
+
if (removed.length === 0)
|
|
142
|
+
return session.text('commands.temporaryban.messages.word_not_found');
|
|
143
|
+
return session.text('commands.temporaryban.messages.ignored_word_removed', [removed.join(', ')]);
|
|
144
|
+
});
|
|
145
|
+
// 9. Whitelist Word List
|
|
146
|
+
wordCmd.subcommand('.list')
|
|
147
|
+
.action(async ({ session }) => {
|
|
148
|
+
if (!session)
|
|
149
|
+
return;
|
|
150
|
+
if (!(0, permission_1.checkPermission)(session, config))
|
|
151
|
+
return session.text('commands.temporaryban.messages.permission_denied');
|
|
152
|
+
if (!session.guildId)
|
|
153
|
+
return session.text('commands.temporaryban.messages.group_only');
|
|
154
|
+
const groupConfig = config.groups.find(g => g.groupId === session.guildId);
|
|
155
|
+
if (!groupConfig)
|
|
156
|
+
return session.text('commands.temporaryban.messages.group_not_configured');
|
|
157
|
+
const items = detector.getIgnoredWords(session.guildId);
|
|
158
|
+
if (items.length === 0)
|
|
159
|
+
return session.text('commands.temporaryban.messages.no_ignored_words');
|
|
160
|
+
return session.text('commands.temporaryban.messages.ignored_words_list', [items.length, items.join(', ')]);
|
|
161
|
+
});
|
|
43
162
|
}
|
package/lib/config.d.ts
CHANGED
|
@@ -36,12 +36,14 @@ export interface GroupConfig {
|
|
|
36
36
|
smartVerification: boolean;
|
|
37
37
|
contextMsgCount: number;
|
|
38
38
|
aiThreshold?: number;
|
|
39
|
+
showCensoredWord?: boolean;
|
|
39
40
|
localBadWordDict: string;
|
|
40
41
|
whitelist: WhitelistItem[];
|
|
41
42
|
triggerThreshold?: number;
|
|
42
43
|
triggerWindowMinutes?: number;
|
|
43
44
|
muteMinutes?: number;
|
|
44
45
|
checkProbability?: number;
|
|
46
|
+
warningTemplate?: string;
|
|
45
47
|
detailedLog: boolean;
|
|
46
48
|
}
|
|
47
49
|
export interface BaiduConfig {
|
|
@@ -66,17 +68,24 @@ export interface OpenAIConfig {
|
|
|
66
68
|
export interface Config {
|
|
67
69
|
debug: boolean;
|
|
68
70
|
adminList: string[];
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
useApi: boolean;
|
|
72
|
+
useBaidu: boolean;
|
|
73
|
+
useAliyun: boolean;
|
|
74
|
+
useTencent: boolean;
|
|
75
|
+
useOpenAI: boolean;
|
|
76
|
+
useEmail: boolean;
|
|
77
|
+
smtp?: SmtpConfig;
|
|
78
|
+
api?: ApiConfig;
|
|
79
|
+
baidu?: BaiduConfig;
|
|
80
|
+
aliyun?: AliyunConfig;
|
|
81
|
+
tencent?: TencentConfig;
|
|
82
|
+
openai?: OpenAIConfig;
|
|
75
83
|
defaultMuteMinutes: number;
|
|
76
84
|
defaultTriggerThreshold: number;
|
|
77
85
|
defaultAiThreshold: number;
|
|
78
86
|
defaultCheckProbability: number;
|
|
79
87
|
checkAdmin: boolean;
|
|
88
|
+
defaultShowCensoredWord: boolean;
|
|
80
89
|
groups: GroupConfig[];
|
|
81
90
|
}
|
|
82
91
|
export declare const Config: Schema<Config>;
|
package/lib/config.js
CHANGED
|
@@ -2,74 +2,145 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Config = void 0;
|
|
4
4
|
const koishi_1 = require("koishi");
|
|
5
|
-
exports.Config = koishi_1.Schema.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
koishi_1.Schema.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
5
|
+
exports.Config = koishi_1.Schema.intersect([
|
|
6
|
+
koishi_1.Schema.object({
|
|
7
|
+
debug: koishi_1.Schema.boolean().description('开启全局调试日志。').default(false),
|
|
8
|
+
adminList: koishi_1.Schema.array(String).description('全局管理员列表 (OneBot 用户ID)。').role('table'),
|
|
9
|
+
checkAdmin: koishi_1.Schema.boolean().description('是否检查机器人在群内的管理权限。').default(true),
|
|
10
|
+
defaultMuteMinutes: koishi_1.Schema.number().description('全局默认禁言时长 (分钟)。').default(10).min(0.1),
|
|
11
|
+
defaultTriggerThreshold: koishi_1.Schema.number().description('全局默认触发阈值 (次数)。').default(3).min(1),
|
|
12
|
+
defaultAiThreshold: koishi_1.Schema.number().description('全局默认 AI 判定阈值 (0.0 - 1.0)。').default(0.6).min(0).max(1).step(0.1),
|
|
13
|
+
defaultCheckProbability: koishi_1.Schema.number().description('全局默认检查概率 (0.0 - 1.0)。').default(1.0).min(0).max(1).step(0.1),
|
|
14
|
+
defaultShowCensoredWord: koishi_1.Schema.boolean().description('全局默认是否在警告中显示触发的违禁词。').default(true),
|
|
15
|
+
}).description('基础设置'),
|
|
16
|
+
koishi_1.Schema.intersect([
|
|
17
|
+
koishi_1.Schema.object({
|
|
18
|
+
useEmail: koishi_1.Schema.boolean().description('启用邮件通知系统').default(false),
|
|
19
|
+
}).description('邮件通知开关'),
|
|
20
|
+
koishi_1.Schema.union([
|
|
21
|
+
koishi_1.Schema.object({
|
|
22
|
+
useEmail: koishi_1.Schema.const(true).required(),
|
|
23
|
+
smtp: koishi_1.Schema.object({
|
|
24
|
+
host: koishi_1.Schema.string().description('SMTP 服务器地址').default('smtp.example.com'),
|
|
25
|
+
port: koishi_1.Schema.number().description('SMTP 端口').default(465),
|
|
26
|
+
secure: koishi_1.Schema.boolean().description('启用 SSL/TLS 加密链接').default(true),
|
|
27
|
+
user: koishi_1.Schema.string().description('SMTP 用户名').default('user@example.com'),
|
|
28
|
+
pass: koishi_1.Schema.string().role('secret').description('SMTP 密码或授权码').default('password'),
|
|
29
|
+
senderName: koishi_1.Schema.string().description('邮件发件人显示名称').default('Koishi Bot'),
|
|
30
|
+
senderEmail: koishi_1.Schema.string().description('邮件发件人地址').default('bot@example.com'),
|
|
31
|
+
receivers: koishi_1.Schema.array(String).description('接收违规通知的管理员邮箱列表').role('table'),
|
|
32
|
+
summaryIntervalDays: koishi_1.Schema.number().description('邮件汇总周期 (天)').default(1).min(0),
|
|
33
|
+
}).description('邮件通知设置 (SMTP)'),
|
|
34
|
+
}),
|
|
35
|
+
koishi_1.Schema.object({}),
|
|
36
|
+
]),
|
|
37
|
+
]),
|
|
38
|
+
koishi_1.Schema.intersect([
|
|
39
|
+
koishi_1.Schema.object({
|
|
40
|
+
useApi: koishi_1.Schema.boolean().description('启用在线 API 检测 (ApiHz)').default(false),
|
|
41
|
+
}).description('在线 API 开关'),
|
|
42
|
+
koishi_1.Schema.union([
|
|
43
|
+
koishi_1.Schema.object({
|
|
44
|
+
useApi: koishi_1.Schema.const(true).required(),
|
|
45
|
+
api: koishi_1.Schema.object({
|
|
46
|
+
apiUrl: koishi_1.Schema.string().description('在线检测 API 地址').default('https://cn.apihz.cn/api/zici/mgc.php'),
|
|
47
|
+
apiId: koishi_1.Schema.string().description('ApiHz 开发者 ID').default(''),
|
|
48
|
+
apiKey: koishi_1.Schema.string().role('secret').description('ApiHz 开发者 Key').default(''),
|
|
49
|
+
}).description('在线检测设置 (ApiHz)'),
|
|
50
|
+
}),
|
|
51
|
+
koishi_1.Schema.object({}),
|
|
52
|
+
]),
|
|
53
|
+
]),
|
|
54
|
+
koishi_1.Schema.intersect([
|
|
55
|
+
koishi_1.Schema.object({
|
|
56
|
+
useOpenAI: koishi_1.Schema.boolean().description('启用 AI 模型检测 (OpenAI/SiliconFlow)').default(false),
|
|
57
|
+
}).description('AI 检测开关'),
|
|
58
|
+
koishi_1.Schema.union([
|
|
59
|
+
koishi_1.Schema.object({
|
|
60
|
+
useOpenAI: koishi_1.Schema.const(true).required(),
|
|
61
|
+
openai: koishi_1.Schema.object({
|
|
62
|
+
apiKey: koishi_1.Schema.string().role('secret').description('API Key').default(''),
|
|
63
|
+
baseUrl: koishi_1.Schema.string().description('API Base URL').default('https://api.siliconflow.cn/v1'),
|
|
64
|
+
model: koishi_1.Schema.string().description('模型 ID').default('deepseek-ai/DeepSeek-V2.5'),
|
|
65
|
+
}).description('AI 检测设置'),
|
|
66
|
+
}),
|
|
67
|
+
koishi_1.Schema.object({}),
|
|
68
|
+
]),
|
|
69
|
+
]),
|
|
70
|
+
koishi_1.Schema.intersect([
|
|
71
|
+
koishi_1.Schema.object({
|
|
72
|
+
useBaidu: koishi_1.Schema.boolean().description('启用百度智能云检测').default(false),
|
|
73
|
+
}).description('百度智能云开关'),
|
|
74
|
+
koishi_1.Schema.union([
|
|
75
|
+
koishi_1.Schema.object({
|
|
76
|
+
useBaidu: koishi_1.Schema.const(true).required(),
|
|
77
|
+
baidu: koishi_1.Schema.object({
|
|
78
|
+
apiKey: koishi_1.Schema.string().description('API Key').default(''),
|
|
79
|
+
secretKey: koishi_1.Schema.string().role('secret').description('Secret Key').default(''),
|
|
80
|
+
}).description('百度智能云设置'),
|
|
81
|
+
}),
|
|
82
|
+
koishi_1.Schema.object({}),
|
|
83
|
+
]),
|
|
84
|
+
]),
|
|
85
|
+
koishi_1.Schema.intersect([
|
|
86
|
+
koishi_1.Schema.object({
|
|
87
|
+
useAliyun: koishi_1.Schema.boolean().description('启用阿里云内容安全检测').default(false),
|
|
88
|
+
}).description('阿里云开关'),
|
|
89
|
+
koishi_1.Schema.union([
|
|
90
|
+
koishi_1.Schema.object({
|
|
91
|
+
useAliyun: koishi_1.Schema.const(true).required(),
|
|
92
|
+
aliyun: koishi_1.Schema.object({
|
|
93
|
+
accessKeyId: koishi_1.Schema.string().description('AccessKey ID').default(''),
|
|
94
|
+
accessKeySecret: koishi_1.Schema.string().role('secret').description('AccessKey Secret').default(''),
|
|
95
|
+
endpoint: koishi_1.Schema.string().description('Endpoint').default('green-cip.cn-shanghai.aliyuncs.com'),
|
|
96
|
+
}).description('阿里云设置'),
|
|
97
|
+
}),
|
|
98
|
+
koishi_1.Schema.object({}),
|
|
99
|
+
]),
|
|
100
|
+
]),
|
|
101
|
+
koishi_1.Schema.intersect([
|
|
102
|
+
koishi_1.Schema.object({
|
|
103
|
+
useTencent: koishi_1.Schema.boolean().description('启用腾讯云检测').default(false),
|
|
104
|
+
}).description('腾讯云开关'),
|
|
105
|
+
koishi_1.Schema.union([
|
|
106
|
+
koishi_1.Schema.object({
|
|
107
|
+
useTencent: koishi_1.Schema.const(true).required(),
|
|
108
|
+
tencent: koishi_1.Schema.object({
|
|
109
|
+
secretId: koishi_1.Schema.string().description('SecretId').default(''),
|
|
110
|
+
secretKey: koishi_1.Schema.string().role('secret').description('SecretKey').default(''),
|
|
111
|
+
region: koishi_1.Schema.string().description('Region').default('ap-shanghai'),
|
|
112
|
+
}).description('腾讯云设置'),
|
|
113
|
+
}),
|
|
114
|
+
koishi_1.Schema.object({}),
|
|
115
|
+
]),
|
|
116
|
+
]),
|
|
117
|
+
koishi_1.Schema.object({
|
|
118
|
+
groups: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
119
|
+
id: koishi_1.Schema.string().hidden().default(''),
|
|
120
|
+
groupId: koishi_1.Schema.string().description('群组 ID (群号)').required(),
|
|
121
|
+
enable: koishi_1.Schema.boolean().description('是否启用监控').default(true),
|
|
122
|
+
detectionMethods: koishi_1.Schema.array(koishi_1.Schema.union([
|
|
123
|
+
koishi_1.Schema.const('local').description('本地词库 (数据库)'),
|
|
124
|
+
koishi_1.Schema.const('ai').description('AI 模型检测'),
|
|
125
|
+
koishi_1.Schema.const('api').description('在线 API'),
|
|
126
|
+
koishi_1.Schema.const('baidu').description('百度智能云'),
|
|
127
|
+
koishi_1.Schema.const('aliyun').description('阿里云'),
|
|
128
|
+
koishi_1.Schema.const('tencent').description('腾讯云'),
|
|
129
|
+
])).role('checkbox').description('启用的检测方式').default(['local']),
|
|
130
|
+
smartVerification: koishi_1.Schema.boolean().description('开启智能验证').default(false),
|
|
131
|
+
contextMsgCount: koishi_1.Schema.number().description('智能验证上下文数量').default(3).min(1).max(10),
|
|
132
|
+
aiThreshold: koishi_1.Schema.number().description('AI 判定阈值 (留空用默认)').min(0).max(1).step(0.1),
|
|
133
|
+
checkProbability: koishi_1.Schema.number().description('检查概率 (留空用默认)').min(0).max(1).step(0.1),
|
|
134
|
+
showCensoredWord: koishi_1.Schema.boolean().description('是否显示触发的违禁词 (留空用默认)'),
|
|
135
|
+
localBadWordDict: koishi_1.Schema.string().description('【Legacy】本地违禁词库 (初始导入)').default(''),
|
|
136
|
+
whitelist: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
137
|
+
userId: koishi_1.Schema.string().required().description('白名单用户 ID'),
|
|
138
|
+
})).description('白名单用户').role('table'),
|
|
139
|
+
warningTemplate: koishi_1.Schema.string().role('textarea').description('自定义警告语模板。支持变量: {at} (At用户), {userId}, {nick}, {words} (触发词), {count} (当前次数), {maxCount} (阈值), {muteMinutes} (禁言时长)'),
|
|
140
|
+
triggerThreshold: koishi_1.Schema.number().description('触发阈值 (次数)。覆盖全局设置。').min(1),
|
|
141
|
+
triggerWindowMinutes: koishi_1.Schema.number().description('触发窗口期 (分钟)。').default(5).min(1),
|
|
142
|
+
muteMinutes: koishi_1.Schema.number().description('禁言时长 (分钟, 留空用默认)').min(0.1),
|
|
143
|
+
detailedLog: koishi_1.Schema.boolean().description('开启详细日志').default(false),
|
|
144
|
+
}).description('群组配置')).description('监控群组列表').role('list').default([])
|
|
145
|
+
}).description('群组监控设置')
|
|
146
|
+
]);
|
package/lib/index.d.ts
CHANGED
|
@@ -4,11 +4,30 @@ import { WhitelistTable } from './services/whitelist';
|
|
|
4
4
|
export * from './config';
|
|
5
5
|
export declare const name = "koishi-plugin-temporaryban";
|
|
6
6
|
export declare const inject: string[];
|
|
7
|
+
export interface IgnoredWordTable {
|
|
8
|
+
id: number;
|
|
9
|
+
groupId: string;
|
|
10
|
+
word: string;
|
|
11
|
+
createdAt: Date;
|
|
12
|
+
}
|
|
13
|
+
export interface ViolationTable {
|
|
14
|
+
id: number;
|
|
15
|
+
userId: string;
|
|
16
|
+
groupId: string;
|
|
17
|
+
words: string[];
|
|
18
|
+
content: string;
|
|
19
|
+
timestamp: Date;
|
|
20
|
+
}
|
|
7
21
|
declare module 'koishi' {
|
|
8
22
|
interface Tables {
|
|
9
23
|
temporaryban_badwords: BadWordTable;
|
|
10
24
|
temporaryban_message_history: MessageHistoryTable;
|
|
11
25
|
temporaryban_whitelist: WhitelistTable;
|
|
26
|
+
temporaryban_ignored_words: IgnoredWordTable;
|
|
27
|
+
temporaryban_violations: ViolationTable;
|
|
28
|
+
}
|
|
29
|
+
interface Context {
|
|
30
|
+
console: any;
|
|
12
31
|
}
|
|
13
32
|
}
|
|
14
33
|
export interface MessageHistoryTable {
|