@joliegg/moderation 0.3.0 → 0.3.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 +2 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +16 -7
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/index.ts +20 -7
- package/src/types/index.ts +1 -0
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@ const client = new ModerationClient({
|
|
|
32
32
|
apiKey: GOOGLE_API_KEY
|
|
33
33
|
},
|
|
34
34
|
banlist: ['some word'],
|
|
35
|
+
urlBlackList: ['someurl.example'],
|
|
35
36
|
});
|
|
36
37
|
```
|
|
37
38
|
|
|
@@ -54,7 +55,7 @@ Currently only OGG files are supported
|
|
|
54
55
|
|
|
55
56
|
```js
|
|
56
57
|
|
|
57
|
-
const audioModeration = await client.moderateAudio('https://example.example/image.ogg');
|
|
58
|
+
const audioModeration = await client.moderateAudio('https://example.example/image.ogg', 'en-US');
|
|
58
59
|
```
|
|
59
60
|
|
|
60
61
|
### Moderating Links
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { ModerationConfiguration, ModerationResult } from './types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Moderation Client
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
5
|
+
* @class ModerationClient
|
|
6
6
|
*/
|
|
7
7
|
declare class ModerationClient {
|
|
8
8
|
private rekognitionClient?;
|
|
@@ -10,6 +10,7 @@ declare class ModerationClient {
|
|
|
10
10
|
private googleSpeechClient?;
|
|
11
11
|
private googleAPIKey?;
|
|
12
12
|
private banList?;
|
|
13
|
+
private urlBlackList?;
|
|
13
14
|
/**
|
|
14
15
|
*
|
|
15
16
|
* @param {ModerationConfiguration} configuration
|
|
@@ -35,6 +36,6 @@ declare class ModerationClient {
|
|
|
35
36
|
*/
|
|
36
37
|
moderateImage(url: string, minimumConfidence?: number): Promise<ModerationResult>;
|
|
37
38
|
moderateLink(url: string): Promise<ModerationResult>;
|
|
38
|
-
moderateAudio(url: string, minimumConfidence?: number): Promise<ModerationResult>;
|
|
39
|
+
moderateAudio(url: string, language?: string, minimumConfidence?: number): Promise<ModerationResult>;
|
|
39
40
|
}
|
|
40
41
|
export default ModerationClient;
|
package/dist/index.js
CHANGED
|
@@ -12,14 +12,15 @@ const url_blacklist_json_1 = __importDefault(require("./url-blacklist.json"));
|
|
|
12
12
|
/**
|
|
13
13
|
* Moderation Client
|
|
14
14
|
*
|
|
15
|
-
* @
|
|
15
|
+
* @class ModerationClient
|
|
16
16
|
*/
|
|
17
17
|
class ModerationClient {
|
|
18
18
|
rekognitionClient;
|
|
19
19
|
googleLanguageClient;
|
|
20
20
|
googleSpeechClient;
|
|
21
21
|
googleAPIKey;
|
|
22
|
-
banList;
|
|
22
|
+
banList = [];
|
|
23
|
+
urlBlackList = [];
|
|
23
24
|
/**
|
|
24
25
|
*
|
|
25
26
|
* @param {ModerationConfiguration} configuration
|
|
@@ -38,6 +39,9 @@ class ModerationClient {
|
|
|
38
39
|
if (Array.isArray(configuration.banList)) {
|
|
39
40
|
this.banList = configuration.banList;
|
|
40
41
|
}
|
|
42
|
+
if (Array.isArray(configuration.urlBlackList)) {
|
|
43
|
+
this.urlBlackList = configuration.urlBlackList;
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
/**
|
|
43
47
|
* Returns a list of moderation categories detected on a text
|
|
@@ -53,9 +57,10 @@ class ModerationClient {
|
|
|
53
57
|
const normalizedText = text.toLowerCase();
|
|
54
58
|
const matches = this.banList.filter(w => normalizedText.indexOf(w) > -1);
|
|
55
59
|
if (matches.length > 0) {
|
|
60
|
+
const words = normalizedText.split(' ');
|
|
56
61
|
categories.push({
|
|
57
|
-
category: '
|
|
58
|
-
confidence: matches.length,
|
|
62
|
+
category: 'BAN_LIST',
|
|
63
|
+
confidence: (matches.length / words.length) * 100,
|
|
59
64
|
});
|
|
60
65
|
}
|
|
61
66
|
}
|
|
@@ -121,8 +126,12 @@ class ModerationClient {
|
|
|
121
126
|
return { source: url, moderation: [] };
|
|
122
127
|
}
|
|
123
128
|
async moderateLink(url) {
|
|
124
|
-
const blacklisted =
|
|
129
|
+
const blacklisted = this.urlBlackList?.some(b => url.indexOf(b) > -1);
|
|
125
130
|
if (blacklisted) {
|
|
131
|
+
return { source: url, moderation: [{ category: 'CUSTOM_BLACK_LIST', confidence: 100 }] };
|
|
132
|
+
}
|
|
133
|
+
const globallyBlacklisted = url_blacklist_json_1.default.some(b => url.indexOf(b) > -1);
|
|
134
|
+
if (globallyBlacklisted) {
|
|
126
135
|
return { source: url, moderation: [{ category: 'BLACK_LIST', confidence: 100 }] };
|
|
127
136
|
}
|
|
128
137
|
if (typeof this.googleAPIKey !== 'string') {
|
|
@@ -147,7 +156,7 @@ class ModerationClient {
|
|
|
147
156
|
}
|
|
148
157
|
return { source: url, moderation: [] };
|
|
149
158
|
}
|
|
150
|
-
async moderateAudio(url, minimumConfidence = 50) {
|
|
159
|
+
async moderateAudio(url, language = 'en-US', minimumConfidence = 50) {
|
|
151
160
|
if (typeof this.googleSpeechClient === 'undefined') {
|
|
152
161
|
return { source: url, moderation: [] };
|
|
153
162
|
}
|
|
@@ -155,7 +164,7 @@ class ModerationClient {
|
|
|
155
164
|
const options = {
|
|
156
165
|
encoding: 'OGG_OPUS',
|
|
157
166
|
sampleRateHertz: 48000,
|
|
158
|
-
languageCode:
|
|
167
|
+
languageCode: language,
|
|
159
168
|
};
|
|
160
169
|
const [response] = await this.googleSpeechClient.recognize({
|
|
161
170
|
audio: { content: Buffer.from(data, 'binary').toString('base64') },
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joliegg/moderation",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A set of tools for chat moderation",
|
|
5
5
|
"author": "Diana Islas Ocampo",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"test": "node test/index.js"
|
|
13
13
|
},
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": "20.x"
|
|
15
|
+
"node": ">=20.x"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@babel/eslint-parser": "^7.24.8",
|
package/src/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ type ISpeechRecognitionResult = protos.google.cloud.speech.v1.ISpeechRecognition
|
|
|
19
19
|
/**
|
|
20
20
|
* Moderation Client
|
|
21
21
|
*
|
|
22
|
-
* @
|
|
22
|
+
* @class ModerationClient
|
|
23
23
|
*/
|
|
24
24
|
class ModerationClient {
|
|
25
25
|
|
|
@@ -27,7 +27,8 @@ class ModerationClient {
|
|
|
27
27
|
private googleLanguageClient?: LanguageServiceClient;
|
|
28
28
|
private googleSpeechClient?: SpeechClient;
|
|
29
29
|
private googleAPIKey?: string;
|
|
30
|
-
private banList?: string[];
|
|
30
|
+
private banList?: string[] = [];
|
|
31
|
+
private urlBlackList?: string[] = [];
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
*
|
|
@@ -50,6 +51,10 @@ class ModerationClient {
|
|
|
50
51
|
if (Array.isArray(configuration.banList)) {
|
|
51
52
|
this.banList = configuration.banList;
|
|
52
53
|
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(configuration.urlBlackList)) {
|
|
56
|
+
this.urlBlackList = configuration.urlBlackList;
|
|
57
|
+
}
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
/**
|
|
@@ -68,9 +73,11 @@ class ModerationClient {
|
|
|
68
73
|
const matches = this.banList.filter(w => normalizedText.indexOf(w) > -1);
|
|
69
74
|
|
|
70
75
|
if (matches.length > 0) {
|
|
76
|
+
const words = normalizedText.split(' ');
|
|
77
|
+
|
|
71
78
|
categories.push({
|
|
72
|
-
category: '
|
|
73
|
-
confidence: matches.length,
|
|
79
|
+
category: 'BAN_LIST',
|
|
80
|
+
confidence: (matches.length / words.length) * 100,
|
|
74
81
|
});
|
|
75
82
|
}
|
|
76
83
|
}
|
|
@@ -148,9 +155,15 @@ class ModerationClient {
|
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
async moderateLink (url: string): Promise<ModerationResult> {
|
|
151
|
-
const blacklisted =
|
|
158
|
+
const blacklisted = this.urlBlackList?.some(b => url.indexOf(b) > -1);
|
|
152
159
|
|
|
153
160
|
if (blacklisted) {
|
|
161
|
+
return { source: url, moderation: [{ category: 'CUSTOM_BLACK_LIST', confidence: 100 }] };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const globallyBlacklisted = URLBlackList.some(b => url.indexOf(b) > -1);
|
|
165
|
+
|
|
166
|
+
if (globallyBlacklisted) {
|
|
154
167
|
return { source: url, moderation: [{ category: 'BLACK_LIST', confidence: 100 }] };
|
|
155
168
|
}
|
|
156
169
|
|
|
@@ -185,7 +198,7 @@ class ModerationClient {
|
|
|
185
198
|
return { source: url, moderation: [] };
|
|
186
199
|
}
|
|
187
200
|
|
|
188
|
-
async moderateAudio (url: string, minimumConfidence: number = 50): Promise<ModerationResult> {
|
|
201
|
+
async moderateAudio (url: string, language: string = 'en-US', minimumConfidence: number = 50): Promise<ModerationResult> {
|
|
189
202
|
if (typeof this.googleSpeechClient === 'undefined') {
|
|
190
203
|
return { source: url, moderation: [] };
|
|
191
204
|
}
|
|
@@ -196,7 +209,7 @@ class ModerationClient {
|
|
|
196
209
|
const options: IRecognitionConfig = {
|
|
197
210
|
encoding: 'OGG_OPUS',
|
|
198
211
|
sampleRateHertz: 48000,
|
|
199
|
-
languageCode:
|
|
212
|
+
languageCode: language,
|
|
200
213
|
};
|
|
201
214
|
|
|
202
215
|
const [ response ] = await this.googleSpeechClient.recognize ({
|