koishi-plugin-temporaryban 1.0.3 → 1.0.4-beta.2

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/README.md CHANGED
@@ -2,13 +2,126 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/koishi-plugin-temporaryban?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-temporaryban)
4
4
 
5
+ [English](#english) | [中文](#chinese)
6
+
7
+ <a name="english"></a>
8
+ ## English
9
+
10
+ A powerful Koishi forbidden words detection and temporary ban plugin. Supports database persistence for word lists, multiple detection mechanisms, automatic email reporting, and comprehensive group management commands.
11
+
12
+ ### ✨ Key Features
13
+
14
+ - **Multiple Detection Mechanisms**:
15
+ - 🏠 **Local Dictionary (Database)**: Supports dynamic addition/deletion via database, no restart required.
16
+ - ☁️ **Cloud API**: Integrated **Baidu AI**, **Aliyun Green**, and **Tencent Cloud TMS** for intelligent detection.
17
+ - 🌐 **Online API**: Supports generic online API detection.
18
+ - **Smart Punishment System**:
19
+ - 🚫 Automatically recalls violating messages.
20
+ - ⏱️ Triggers automatic mute after cumulative violations.
21
+ - 🛡️ **Dynamic Whitelist**: Automatically recognizes group owners and admins; supports manual user whitelist configuration.
22
+ - **Email Notification & Summary**:
23
+ - 📧 Supports immediate notification for each violation.
24
+ - 📊 **Daily/Periodic Summary**: Supports sending summary reports every N days to avoid spam.
25
+ - 🎨 Beautiful HTML email templates.
26
+ - **Convenient Management Commands**:
27
+ - New `temporaryban` command system for managing word lists, whitelists, and viewing statistics directly in groups.
28
+
29
+ ### 📦 Installation
30
+
31
+ This plugin depends on Koishi's **Database** service. Please ensure you have installed and configured a database plugin (e.g., MySQL, SQLite).
32
+
33
+ ```bash
34
+ # Install plugin
35
+ npm install koishi-plugin-temporaryban
36
+
37
+ # Install database plugin (e.g., mysql)
38
+ npm install @koishijs/plugin-database-mysql
39
+ ```
40
+
41
+ ### ⚙️ Configuration
42
+
43
+ #### 1. Basic Settings
44
+
45
+ - **`debug`**: Enable debug mode for detailed logs.
46
+ - **`adminList`**: Global admin list (User ID). Users in this list can use advanced management commands (e.g., manual report trigger).
47
+
48
+ #### 2. Cloud API Configuration
49
+
50
+ Supports **Baidu AI**, **Aliyun**, and **Tencent Cloud**. Configure the respective sections (`baidu`, `aliyun`, `tencent`) with your API keys if you wish to use them.
51
+
52
+ #### 3. Email Notification (SMTP)
53
+
54
+ | Option | Description | Example |
55
+ | --- | --- | --- |
56
+ | `host` | SMTP Server Address | `smtp.qq.com` |
57
+ | `port` | SMTP Port | `465` (SSL) |
58
+ | `user` | Sender Account | `123456@qq.com` |
59
+ | `pass` | **Authorization Code/Password** | Use Auth Code for QQ Mail |
60
+ | `receivers` | List of admin emails to receive notifications | `['admin@example.com']` |
61
+ | `summaryIntervalDays` | **Summary Interval (Days)** | `1` (Daily); `0` (Immediate) |
62
+
63
+ #### 4. Group Monitoring (Groups)
64
+
65
+ You can configure each group separately:
66
+
67
+ - **`groupId`**: Target Group ID.
68
+ - **`detectionMethod`**: Detection method (`local`, `api`, `baidu`, `aliyun`, `tencent`).
69
+ - **`triggerThreshold`**: Violations count to trigger mute (Default: 3).
70
+ - **`triggerWindowMinutes`**: Violation counting window (Default: 5 mins).
71
+ - **`muteMinutes`**: Mute duration (Default: 10 mins).
72
+
73
+ ### 💻 Commands
74
+
75
+ All commands start with `temporaryban`.
76
+
77
+ #### Global Commands
78
+ *Global Admins (`config.adminList`) only*
79
+
80
+ - **`temporaryban.report`**
81
+ - Manually trigger a violation summary report for the last 24 hours and send via email.
82
+
83
+ #### Group Management Commands
84
+ *Group Owner, Group Admin, or Global Admin only*
85
+
86
+ - **`temporaryban.add <word>`**
87
+ - Add a forbidden word to the current group dictionary.
88
+ - **`temporaryban.remove <word>`**
89
+ - Remove a forbidden word from the current group dictionary.
90
+ - **`temporaryban.list`**
91
+ - List all forbidden words in the current group.
92
+ - **`temporaryban.whitelist.add <user>`**
93
+ - Add a user to the current group whitelist.
94
+ - **`temporaryban.whitelist.remove <user>`**
95
+ - Remove a user from the current group whitelist.
96
+ - **`temporaryban.stats`**
97
+ - View violation statistics for the current period.
98
+ - **`temporaryban.clean <user>`**
99
+ - Clear violation records for a user (Manual pardon).
100
+ - **`temporaryban.check <text>`**
101
+ - Check if text contains forbidden words (Detection only, no punishment).
102
+
103
+ ### 🛠️ Development
104
+
105
+ This project follows a modular structure:
106
+
107
+ - **`src/commands/`**: Command implementations split by category.
108
+ - **`src/services/`**: Core logic (Detector, Mailer).
109
+ - **`src/utils/`**: Helper functions and types.
110
+ - **`src/locales/`**: Internationalization files.
111
+
112
+ ---
113
+
114
+ <a name="chinese"></a>
115
+ ## 中文
116
+
5
117
  一个功能强大的 Koishi 违禁词检测与自动禁言插件。支持数据库持久化词库、多重检测机制、自动邮件汇报以及完善的群组管理指令。
6
118
 
7
- ## ✨ 核心特性
119
+ ### ✨ 核心特性
8
120
 
9
121
  - **多重检测机制**:
10
122
  - 🏠 **本地词库 (Database)**:基于数据库存储,支持动态添加/删除,无需重启。
11
- - 🌐 **在线 API**:集成 ApiHz 敏感词检测接口,支持智能识别。
123
+ - ☁️ **云端检测**:集成 **百度 AI**、**阿里云内容安全**、**腾讯云 TMS**,支持智能识别。
124
+ - 🌐 **在线 API**:支持通用 API 敏感词检测接口。
12
125
  - **智能惩罚系统**:
13
126
  - 🚫 自动撤回违规消息。
14
127
  - ⏱️ 累计违规次数触发自动禁言。
@@ -20,7 +133,7 @@
20
133
  - **便捷的管理指令**:
21
134
  - 全新的 `temporaryban` 指令体系,支持在群内直接管理词库、白名单和查看统计。
22
135
 
23
- ## 📦 安装与依赖
136
+ ### 📦 安装与依赖
24
137
 
25
138
  本插件需要依赖 Koishi 的 **Database** 服务。请确保您已安装并配置了任意一款数据库插件(如 MySQL, SQLite 等)。
26
139
 
@@ -32,14 +145,18 @@ npm install koishi-plugin-temporaryban
32
145
  npm install @koishijs/plugin-database-mysql
33
146
  ```
34
147
 
35
- ## ⚙️ 配置说明
148
+ ### ⚙️ 配置说明
36
149
 
37
- ### 1. 基础设置
150
+ #### 1. 基础设置
38
151
 
39
152
  - **`debug`**: 开启调试模式,输出详细日志。
40
153
  - **`adminList`**: 全局管理员列表 (OneBot ID)。在此列表中的用户可以使用高级管理指令(如手动触发报告)。
41
154
 
42
- ### 2. 邮件通知 (SMTP)
155
+ #### 2. 云端检测配置
156
+
157
+ 支持 **百度 AI**、**阿里云**、**腾讯云**。请在配置项中分别填写对应的 API Key/Secret (`baidu`, `aliyun`, `tencent`) 以启用。
158
+
159
+ #### 3. 邮件通知 (SMTP)
43
160
 
44
161
  | 配置项 | 说明 | 示例 |
45
162
  | --- | --- | --- |
@@ -50,28 +167,27 @@ npm install @koishijs/plugin-database-mysql
50
167
  | `receivers` | 接收通知的管理员邮箱列表 | `['admin@example.com']` |
51
168
  | `summaryIntervalDays` | **汇总周期(天)** | `1` (每天发送一次汇总); `0` (立即发送) |
52
169
 
53
- ### 3. 群组监控 (Groups)
170
+ #### 4. 群组监控 (Groups)
54
171
 
55
172
  您可以为每个群组单独配置:
56
173
 
57
174
  - **`groupId`**: 目标群号。
58
- - **`detectionMethod`**: 检测方式 (`local` `api`)。
175
+ - **`detectionMethod`**: 检测方式 (`local`, `api`, `baidu`, `aliyun`, `tencent`)。
59
176
  - **`triggerThreshold`**: 触发禁言的累计违规次数(默认 3 次)。
60
177
  - **`triggerWindowMinutes`**: 违规计数窗口时间(默认 5 分钟)。
61
178
  - **`muteMinutes`**: 禁言时长(默认 10 分钟)。
62
- - **`localBadWordDict`**: **[已弃用/仅供迁移]** 首次启动时会自动将此处的词汇导入数据库。之后的增删操作请使用指令。
63
179
 
64
- ## 💻 指令使用
180
+ ### 💻 指令使用
65
181
 
66
182
  所有指令均以 `temporaryban` (或简写,需自行配置别名) 开头。
67
183
 
68
- ### 全局指令
184
+ #### 全局指令
69
185
  *仅限 `config.adminList` 中的全局管理员使用*
70
186
 
71
187
  - **`temporaryban.report`**
72
188
  - 手动触发最近 24 小时的违规汇总报告并发送邮件。
73
189
 
74
- ### 群组管理指令
190
+ #### 群组管理指令
75
191
  *仅限群主、群管理员或全局管理员使用*
76
192
 
77
193
  - **`temporaryban.add <word>`**
@@ -94,12 +210,14 @@ npm install @koishijs/plugin-database-mysql
94
210
  - 检测一段文本是否包含违禁词(仅检测,不触发惩罚)。
95
211
  - 示例:`temporaryban.check 这句话有问题吗`
96
212
 
97
- ## 🔄 迁移指南 (v1.3 -> v1.4)
213
+ ### 🛠️ 开发说明
214
+
215
+ 本项目采用模块化结构开发:
98
216
 
99
- v1.4 版本引入了数据库支持。更新插件后:
100
- 1. 插件会自动检测 `localBadWordDict` 中的配置。
101
- 2. 如果数据库中该群组的词库为空,插件会自动将配置文件中的词汇导入数据库。
102
- 3. 导入完成后,请使用指令管理词库。配置文件中的 `localBadWordDict` 将不再生效。
217
+ - **`src/commands/`**: 按类别拆分的命令实现。
218
+ - **`src/services/`**: 核心服务逻辑 (Detector, Mailer)。
219
+ - **`src/utils/`**: 工具函数和类型定义。
220
+ - **`src/locales/`**: 国际化语言文件。
103
221
 
104
222
  ## 📝 License
105
223
 
@@ -0,0 +1,4 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { MailerService } from '../services/mailer';
4
+ export declare function registerAdminCommands(ctx: Context, config: Config, mailer: MailerService): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerAdminCommands = registerAdminCommands;
4
+ function registerAdminCommands(ctx, config, mailer) {
5
+ const cmd = ctx.command('temporaryban');
6
+ cmd.subcommand('.report')
7
+ .action(async ({ session }) => {
8
+ if (!session?.userId || !config.adminList?.includes(session.userId)) {
9
+ return session?.text('commands.temporaryban.messages.global_admin_only');
10
+ }
11
+ const result = await mailer.sendSummaryReport(24);
12
+ if (result.success) {
13
+ if (result.count === 0)
14
+ return session?.text('commands.temporaryban.messages.no_violations');
15
+ return session?.text('commands.temporaryban.messages.report_sent', [result.receivers, result.count]);
16
+ }
17
+ else {
18
+ if (result.error === 'smtp_not_configured')
19
+ return session?.text('commands.temporaryban.messages.smtp_not_configured');
20
+ return session?.text('commands.temporaryban.messages.report_failed', [result.error]);
21
+ }
22
+ });
23
+ }
@@ -0,0 +1,4 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { DetectorService } from '../services/detector';
4
+ export declare function registerCheckCommands(ctx: Context, config: Config, detector: DetectorService): void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerCheckCommands = registerCheckCommands;
4
+ const permission_1 = require("../utils/permission");
5
+ function registerCheckCommands(ctx, config, detector) {
6
+ const cmd = ctx.command('temporaryban');
7
+ // 9. Check
8
+ cmd.subcommand('.check <text:text>')
9
+ .action(async ({ session }, text) => {
10
+ if (!session)
11
+ return;
12
+ if (!(0, permission_1.checkPermission)(session, config))
13
+ return session.text('commands.temporaryban.messages.permission_denied');
14
+ if (!session.guildId)
15
+ return session.text('commands.temporaryban.messages.group_only');
16
+ if (!text)
17
+ return session.text('commands.temporaryban.messages.specify_text');
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 res = await detector.check(text, session.guildId, groupConfig.detectionMethod);
22
+ if (res.detected) {
23
+ return session.text('commands.temporaryban.messages.detected', [res.detectedWords?.join(', ')]);
24
+ }
25
+ return session.text('commands.temporaryban.messages.safe');
26
+ });
27
+ }
@@ -0,0 +1,4 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { DetectorService } from '../services/detector';
4
+ export declare function registerDictionaryCommands(ctx: Context, config: Config, detector: DetectorService): void;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerDictionaryCommands = registerDictionaryCommands;
4
+ const permission_1 = require("../utils/permission");
5
+ function registerDictionaryCommands(ctx, config, detector) {
6
+ const cmd = ctx.command('temporaryban');
7
+ // 2. Add Word (Group Admin)
8
+ cmd.subcommand('.add <word:string>')
9
+ .action(async ({ session }, word) => {
10
+ if (!session)
11
+ return;
12
+ if (!(0, permission_1.checkPermission)(session, config))
13
+ return session.text('commands.temporaryban.messages.permission_denied');
14
+ if (!session.guildId)
15
+ return session.text('commands.temporaryban.messages.group_only');
16
+ if (!word)
17
+ return session.text('commands.temporaryban.messages.specify_word');
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 success = await detector.addWord(session.guildId, word);
22
+ if (!success)
23
+ return session.text('commands.temporaryban.messages.word_exists');
24
+ return session.text('commands.temporaryban.messages.word_added', [word]);
25
+ });
26
+ // 3. Remove Word
27
+ cmd.subcommand('.remove <word:string>')
28
+ .action(async ({ session }, word) => {
29
+ if (!session)
30
+ return;
31
+ if (!(0, permission_1.checkPermission)(session, config))
32
+ return session.text('commands.temporaryban.messages.permission_denied');
33
+ if (!session.guildId)
34
+ return session.text('commands.temporaryban.messages.group_only');
35
+ if (!word)
36
+ return session.text('commands.temporaryban.messages.specify_word');
37
+ const groupConfig = config.groups.find(g => g.groupId === session.guildId);
38
+ if (!groupConfig)
39
+ return session.text('commands.temporaryban.messages.group_not_configured');
40
+ const success = await detector.removeWord(session.guildId, word);
41
+ if (!success)
42
+ return session.text('commands.temporaryban.messages.word_not_found');
43
+ return session.text('commands.temporaryban.messages.word_removed', [word]);
44
+ });
45
+ // 4. List Words
46
+ cmd.subcommand('.list')
47
+ .action(async ({ session }) => {
48
+ if (!session)
49
+ return;
50
+ if (!(0, permission_1.checkPermission)(session, config))
51
+ return session.text('commands.temporaryban.messages.permission_denied');
52
+ if (!session.guildId)
53
+ return session.text('commands.temporaryban.messages.group_only');
54
+ const groupConfig = config.groups.find(g => g.groupId === session.guildId);
55
+ if (!groupConfig)
56
+ return session.text('commands.temporaryban.messages.group_not_configured');
57
+ const items = detector.getWords(session.guildId);
58
+ if (items.length === 0)
59
+ return session.text('commands.temporaryban.messages.no_forbidden_words');
60
+ return session.text('commands.temporaryban.messages.forbidden_words_list', [items.length, items.map(i => i.word).join(', ')]);
61
+ });
62
+ }
@@ -0,0 +1,6 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { DetectorService } from '../services/detector';
4
+ import { MailerService } from '../services/mailer';
5
+ import { UserRecord } from '../utils/types';
6
+ export declare function registerCommands(ctx: Context, config: Config, detector: DetectorService, mailer: MailerService, userRecords: Map<string, UserRecord>): void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerCommands = registerCommands;
4
+ const admin_1 = require("./admin");
5
+ const dictionary_1 = require("./dictionary");
6
+ const whitelist_1 = require("./whitelist");
7
+ const stats_1 = require("./stats");
8
+ const check_1 = require("./check");
9
+ function registerCommands(ctx, config, detector, mailer, userRecords) {
10
+ (0, admin_1.registerAdminCommands)(ctx, config, mailer);
11
+ (0, dictionary_1.registerDictionaryCommands)(ctx, config, detector);
12
+ (0, whitelist_1.registerWhitelistCommands)(ctx, config);
13
+ (0, stats_1.registerStatsCommands)(ctx, config, userRecords);
14
+ (0, check_1.registerCheckCommands)(ctx, config, detector);
15
+ }
@@ -0,0 +1,4 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { UserRecord } from '../utils/types';
4
+ export declare function registerStatsCommands(ctx: Context, config: Config, userRecords: Map<string, UserRecord>): void;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerStatsCommands = registerStatsCommands;
4
+ const permission_1 = require("../utils/permission");
5
+ function registerStatsCommands(ctx, config, userRecords) {
6
+ const cmd = ctx.command('temporaryban');
7
+ // 7. Stats
8
+ cmd.subcommand('.stats')
9
+ .action(async ({ session }) => {
10
+ if (!session)
11
+ return;
12
+ if (!(0, permission_1.checkPermission)(session, config))
13
+ return session.text('commands.temporaryban.messages.permission_denied');
14
+ if (!session.guildId)
15
+ return session.text('commands.temporaryban.messages.group_only');
16
+ const prefix = `${session.guildId}-`;
17
+ let count = 0;
18
+ let violators = 0;
19
+ for (const [key, val] of userRecords.entries()) {
20
+ if (key.startsWith(prefix)) {
21
+ violators++;
22
+ count += val.count;
23
+ }
24
+ }
25
+ return session.text('commands.temporaryban.messages.stats_header', [violators]);
26
+ });
27
+ // 8. Clean
28
+ cmd.subcommand('.clean <user:string>')
29
+ .action(async ({ session }, user) => {
30
+ if (!session)
31
+ return;
32
+ if (!(0, permission_1.checkPermission)(session, config))
33
+ return session.text('commands.temporaryban.messages.permission_denied');
34
+ if (!session.guildId)
35
+ return session.text('commands.temporaryban.messages.group_only');
36
+ if (!user)
37
+ return session.text('commands.temporaryban.messages.specify_user_id');
38
+ const key = `${session.guildId}-${user}`;
39
+ if (userRecords.delete(key)) {
40
+ return session.text('commands.temporaryban.messages.records_cleared', [user]);
41
+ }
42
+ return session.text('commands.temporaryban.messages.no_active_records', [user]);
43
+ });
44
+ }
@@ -0,0 +1,3 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ export declare function registerWhitelistCommands(ctx: Context, config: Config): void;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerWhitelistCommands = registerWhitelistCommands;
4
+ const permission_1 = require("../utils/permission");
5
+ function registerWhitelistCommands(ctx, config) {
6
+ const cmd = ctx.command('temporaryban');
7
+ // 5. Whitelist Add
8
+ cmd.subcommand('.whitelist.add <user:string>')
9
+ .action(async ({ session }, user) => {
10
+ if (!session)
11
+ return;
12
+ if (!(0, permission_1.checkPermission)(session, config))
13
+ return session.text('commands.temporaryban.messages.permission_denied');
14
+ if (!session.guildId)
15
+ return session.text('commands.temporaryban.messages.group_only');
16
+ if (!user)
17
+ return session.text('commands.temporaryban.messages.specify_user_id');
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
+ if (groupConfig.whitelist.some(u => u.userId === user))
22
+ return session.text('commands.temporaryban.messages.already_whitelisted');
23
+ groupConfig.whitelist.push({ userId: user });
24
+ try {
25
+ await ctx.scope.update(config);
26
+ }
27
+ catch (e) { }
28
+ return session.text('commands.temporaryban.messages.user_added_whitelist', [user]);
29
+ });
30
+ // 6. Whitelist Remove
31
+ cmd.subcommand('.whitelist.remove <user:string>')
32
+ .action(async ({ session }, user) => {
33
+ if (!session)
34
+ return;
35
+ if (!(0, permission_1.checkPermission)(session, config))
36
+ return session.text('commands.temporaryban.messages.permission_denied');
37
+ if (!session.guildId)
38
+ return session.text('commands.temporaryban.messages.group_only');
39
+ const groupConfig = config.groups.find(g => g.groupId === session.guildId);
40
+ if (!groupConfig)
41
+ return session.text('commands.temporaryban.messages.group_not_configured');
42
+ const idx = groupConfig.whitelist.findIndex(u => u.userId === user);
43
+ if (idx === -1)
44
+ return session.text('commands.temporaryban.messages.not_in_whitelist');
45
+ groupConfig.whitelist.splice(idx, 1);
46
+ try {
47
+ await ctx.scope.update(config);
48
+ }
49
+ catch (e) { }
50
+ return session.text('commands.temporaryban.messages.user_removed_whitelist', [user]);
51
+ });
52
+ }
package/lib/config.d.ts CHANGED
@@ -32,7 +32,7 @@ export interface GroupConfig {
32
32
  id: string;
33
33
  groupId: string;
34
34
  enable: boolean;
35
- detectionMethod: 'local' | 'api';
35
+ detectionMethod: 'local' | 'api' | 'baidu' | 'aliyun' | 'tencent';
36
36
  localBadWordDict: string;
37
37
  whitelist: WhitelistItem[];
38
38
  triggerThreshold: number;
@@ -40,11 +40,28 @@ export interface GroupConfig {
40
40
  muteMinutes: number;
41
41
  detailedLog: boolean;
42
42
  }
43
+ export interface BaiduConfig {
44
+ apiKey: string;
45
+ secretKey: string;
46
+ }
47
+ export interface AliyunConfig {
48
+ accessKeyId: string;
49
+ accessKeySecret: string;
50
+ endpoint: string;
51
+ }
52
+ export interface TencentConfig {
53
+ secretId: string;
54
+ secretKey: string;
55
+ region: string;
56
+ }
43
57
  export interface Config {
44
58
  debug: boolean;
45
59
  adminList: string[];
46
60
  smtp: SmtpConfig;
47
61
  api: ApiConfig;
62
+ baidu: BaiduConfig;
63
+ aliyun: AliyunConfig;
64
+ tencent: TencentConfig;
48
65
  groups: GroupConfig[];
49
66
  }
50
67
  export declare const Config: Schema<Config>;
package/lib/config.js CHANGED
@@ -21,6 +21,20 @@ exports.Config = koishi_1.Schema.object({
21
21
  apiId: koishi_1.Schema.string().description('ApiHz 开发者 ID (必填,否则无法使用 API 检测)').default(''),
22
22
  apiKey: koishi_1.Schema.string().role('secret').description('ApiHz 开发者 Key (必填)').default(''),
23
23
  }).description('在线检测设置 (ApiHz)'),
24
+ baidu: koishi_1.Schema.object({
25
+ apiKey: koishi_1.Schema.string().description('百度智能云 API Key').default(''),
26
+ secretKey: koishi_1.Schema.string().role('secret').description('百度智能云 Secret Key').default(''),
27
+ }).description('百度智能云设置'),
28
+ aliyun: koishi_1.Schema.object({
29
+ accessKeyId: koishi_1.Schema.string().description('阿里云 AccessKey ID').default(''),
30
+ accessKeySecret: koishi_1.Schema.string().role('secret').description('阿里云 AccessKey Secret').default(''),
31
+ endpoint: koishi_1.Schema.string().description('阿里云内容安全 Endpoint').default('green-cip.cn-shanghai.aliyuncs.com'),
32
+ }).description('阿里云内容安全设置'),
33
+ tencent: koishi_1.Schema.object({
34
+ secretId: koishi_1.Schema.string().description('腾讯云 SecretId').default(''),
35
+ secretKey: koishi_1.Schema.string().role('secret').description('腾讯云 SecretKey').default(''),
36
+ region: koishi_1.Schema.string().description('腾讯云地域 (例如 ap-shanghai)').default('ap-shanghai'),
37
+ }).description('腾讯云内容安全设置'),
24
38
  groups: koishi_1.Schema.array(koishi_1.Schema.object({
25
39
  id: koishi_1.Schema.string().hidden().default(''),
26
40
  groupId: koishi_1.Schema.string().description('群组 ID (群号)。机器人将监控此群内的消息。').required(),
@@ -28,7 +42,10 @@ exports.Config = koishi_1.Schema.object({
28
42
  detectionMethod: koishi_1.Schema.union([
29
43
  koishi_1.Schema.const('local').description('本地词库 (数据库)'),
30
44
  koishi_1.Schema.const('api').description('在线 API (ApiHz)'),
31
- ]).description('违禁词检测方式。推荐使用本地词库以获得更快的响应速度。').default('local'),
45
+ koishi_1.Schema.const('baidu').description('百度智能云'),
46
+ koishi_1.Schema.const('aliyun').description('阿里云 (内容安全增强版)'),
47
+ koishi_1.Schema.const('tencent').description('腾讯云 (TMS)'),
48
+ ]).description('违禁词检测方式。').default('local'),
32
49
  localBadWordDict: koishi_1.Schema.string()
33
50
  .description('【初始导入/Legacy】本地违禁词库配置。插件现已使用数据库存储词库。首次启动时,若数据库为空,将自动导入此处的词汇。之后的增删操作请使用指令 `temporaryban.add/remove`,此配置项将不再生效。')
34
51
  .default(''),