@amatiscorp/disguard 1.4.0 → 1.6.0
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 +309 -14
- package/dist/AntiSpam.d.ts +9 -1
- package/dist/AntiSpam.d.ts.map +1 -1
- package/dist/AntiSpam.js +155 -2
- package/dist/AntiSpam.js.map +1 -1
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +95 -1
- package/dist/defaults.js.map +1 -1
- package/dist/detectors/blank.d.ts +3 -0
- package/dist/detectors/blank.d.ts.map +1 -0
- package/dist/detectors/blank.js +25 -0
- package/dist/detectors/blank.js.map +1 -0
- package/dist/detectors/embed.d.ts +3 -0
- package/dist/detectors/embed.d.ts.map +1 -0
- package/dist/detectors/embed.js +25 -0
- package/dist/detectors/embed.js.map +1 -0
- package/dist/detectors/emojis.d.ts.map +1 -1
- package/dist/detectors/emojis.js +19 -1
- package/dist/detectors/emojis.js.map +1 -1
- package/dist/detectors/files.d.ts.map +1 -1
- package/dist/detectors/files.js +29 -1
- package/dist/detectors/files.js.map +1 -1
- package/dist/detectors/forward.d.ts +3 -0
- package/dist/detectors/forward.d.ts.map +1 -0
- package/dist/detectors/forward.js +35 -0
- package/dist/detectors/forward.js.map +1 -0
- package/dist/detectors/ghost.d.ts.map +1 -1
- package/dist/detectors/ghost.js +7 -0
- package/dist/detectors/ghost.js.map +1 -1
- package/dist/detectors/impersonate.d.ts +3 -0
- package/dist/detectors/impersonate.d.ts.map +1 -0
- package/dist/detectors/impersonate.js +86 -0
- package/dist/detectors/impersonate.js.map +1 -0
- package/dist/detectors/joins.d.ts +4 -0
- package/dist/detectors/joins.d.ts.map +1 -0
- package/dist/detectors/joins.js +30 -0
- package/dist/detectors/joins.js.map +1 -0
- package/dist/detectors/polls.d.ts +3 -0
- package/dist/detectors/polls.d.ts.map +1 -0
- package/dist/detectors/polls.js +35 -0
- package/dist/detectors/polls.js.map +1 -0
- package/dist/detectors/raid.d.ts +3 -0
- package/dist/detectors/raid.d.ts.map +1 -0
- package/dist/detectors/raid.js +23 -0
- package/dist/detectors/raid.js.map +1 -0
- package/dist/detectors/replies.d.ts +3 -0
- package/dist/detectors/replies.d.ts.map +1 -0
- package/dist/detectors/replies.js +32 -0
- package/dist/detectors/replies.js.map +1 -0
- package/dist/detectors/stickers.d.ts +3 -0
- package/dist/detectors/stickers.d.ts.map +1 -0
- package/dist/detectors/stickers.js +60 -0
- package/dist/detectors/stickers.js.map +1 -0
- package/dist/detectors/voice.d.ts +3 -0
- package/dist/detectors/voice.d.ts.map +1 -0
- package/dist/detectors/voice.js +35 -0
- package/dist/detectors/voice.js.map +1 -0
- package/dist/detectors/words.d.ts.map +1 -1
- package/dist/detectors/words.js +27 -3
- package/dist/detectors/words.js.map +1 -1
- package/dist/enforcement.d.ts +2 -1
- package/dist/enforcement.d.ts.map +1 -1
- package/dist/enforcement.js +100 -5
- package/dist/enforcement.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/store/MemoryStore.d.ts +6 -0
- package/dist/store/MemoryStore.d.ts.map +1 -1
- package/dist/store/MemoryStore.js +44 -0
- package/dist/store/MemoryStore.js.map +1 -1
- package/dist/types.d.ts +131 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/flags.d.ts +5 -0
- package/dist/utils/flags.d.ts.map +1 -0
- package/dist/utils/flags.js +41 -0
- package/dist/utils/flags.js.map +1 -0
- package/dist/utils/normalize.d.ts +2 -0
- package/dist/utils/normalize.d.ts.map +1 -1
- package/dist/utils/normalize.js +46 -0
- package/dist/utils/normalize.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Configurable antispam for discord.js v14**
|
|
6
6
|
|
|
7
|
-
Flood · phishing ·
|
|
7
|
+
Flood · phishing · forwards · impersonation · join raids · leaked secrets · TypeScript
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@amatiscorp/disguard)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -22,7 +22,7 @@ Configurable antispam for [discord.js](https://discord.js.org) v14 bots.
|
|
|
22
22
|
|
|
23
23
|
It is **not** a bot. You plug it into your existing `Client` and decide every threshold, allowlist, and punishment.
|
|
24
24
|
|
|
25
|
-
Detects flood, leaked tokens/webhooks, channel hopping, blocked words, phishing, duplicate images, mention spam, ghost pings, and more.
|
|
25
|
+
Detects flood, leaked tokens/webhooks, channel hopping, blocked words, phishing, duplicate images, mention spam, ghost pings, forwarded-message dumps, bot impersonation, join raids, and more.
|
|
26
26
|
|
|
27
27
|
**Languages**
|
|
28
28
|
|
|
@@ -33,6 +33,86 @@ Detects flood, leaked tokens/webhooks, channel hopping, blocked words, phishing,
|
|
|
33
33
|
|
|
34
34
|
# English
|
|
35
35
|
|
|
36
|
+
## What's new in 1.6.0
|
|
37
|
+
|
|
38
|
+
Forward dumps, sticker floods, bot/staff impersonation, join raids, voice-note spam, poll spam, and harder-to-dodge word/file filters. Kick/ban stay **off**. `joins` is **off** in `balanced` so a busy invite night does not false-positive.
|
|
39
|
+
|
|
40
|
+
| Option | Default | What it does |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `forwards` | **on**, 4 / 10s | Too many Discord **forwarded** messages (HasSnapshot) in a short window. |
|
|
43
|
+
| `stickers` | **on**, 3 per message, 8 / 10s | Sticker dumps. `blockOnly` (off) flags sticker-only messages. |
|
|
44
|
+
| `impersonate` | **on**, match bot at 0.84 | Nick / username / display name too close to the **bot** (or `names`). |
|
|
45
|
+
| `joins` | **off** (`strict`: on, 6 / 8s) | Too many **distinct accounts joining** the guild at once. Needs `guildMemberAdd`. |
|
|
46
|
+
| `voice` | **on**, 3 / 15s | Too many **voice messages** in a window. |
|
|
47
|
+
| `polls` | **on**, 2 / 20s | Too many **polls** in a window. |
|
|
48
|
+
| `files.blockDoubleExtensions` | `true` | Flags `virus.exe.png` (blocked ext hidden behind a safe one). |
|
|
49
|
+
| `words.scanEmbeds` | `true` | Word list also reads embed text. |
|
|
50
|
+
| `words.normalizeHomoglyphs` | `true` | Folds Cyrillic / Greek / fullwidth lookalikes (`rаid` → `raid`). |
|
|
51
|
+
| `ignoreBoosters` | `false` | Skip server boosters. |
|
|
52
|
+
| `punishment.slowmodeSeconds` | `0` | On `raid` / `join` hits, set channel slowmode (needs **Manage Channels**). Sticky until a mod changes it. |
|
|
53
|
+
| `getRecentIncidents()` | — | Last 50 live hits (not `analyze()`). |
|
|
54
|
+
| `setDetectorEnabled(type, bool)` | — | Toggle one detector without rewriting `disabledDetectors`. |
|
|
55
|
+
| `onJoin` | — | Callback for join-raid incidents (no message). |
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const antispam = new AntiSpam(client, {
|
|
59
|
+
preset: "balanced",
|
|
60
|
+
forwards: { maxForwards: 3, windowMs: 8_000 },
|
|
61
|
+
stickers: { maxStickers: 2, maxInWindow: 6 },
|
|
62
|
+
impersonate: { names: ["Admin", "Moderador", "Staff"] },
|
|
63
|
+
joins: { enabled: true, maxJoins: 8, windowMs: 10_000 },
|
|
64
|
+
voice: { maxVoice: 3 },
|
|
65
|
+
polls: { maxPolls: 2 },
|
|
66
|
+
ignoreBoosters: true,
|
|
67
|
+
words: { enabled: true, list: ["raid-now"], normalizeHomoglyphs: true },
|
|
68
|
+
punishment: { slowmodeSeconds: 10 },
|
|
69
|
+
onJoin(incident) {
|
|
70
|
+
console.log("join raid", incident.details);
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
antispam.setDetectorEnabled("poll", false);
|
|
75
|
+
console.log(antispam.getRecentIncidents(10));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Turn `joins` on only if you want a burst of accounts joining at once to timeout the newest member. Pair it with `accounts.minAgeDays` if the raid is all-new alts. `impersonate.names` is for **staff/brand** clones; `matchBot` already covers the bot's own name.
|
|
79
|
+
|
|
80
|
+
`graceMessages` now also runs **impersonate** and **forward** during the hello window (still skips flood).
|
|
81
|
+
|
|
82
|
+
## What's new in 1.5.0
|
|
83
|
+
|
|
84
|
+
Channel raids, reply spam, empty messages, embed walls, file allowlists, and per-user overlays. Kick/ban stay **off**. `raid` is **off** in `balanced` so busy servers do not false-positive.
|
|
85
|
+
|
|
86
|
+
| Option | Default | What it does |
|
|
87
|
+
| --- | --- | --- |
|
|
88
|
+
| `replies` | **on**, 6 / 8s | Too many Discord **replies** in a short window (reply ping / bump spam). |
|
|
89
|
+
| `blank` | **on** | Empty or whitespace-only messages (no files/stickers/embeds). |
|
|
90
|
+
| `embeds` | **on**, 6 | Too many embeds in one message. |
|
|
91
|
+
| `raid` | **off** (`strict`: on, 6 users / 5s) | Too many **distinct users** posting in the **same channel** at once. |
|
|
92
|
+
| `files.allowedExtensions` | `[]` | If set, only those extensions are allowed (after the blocklist). |
|
|
93
|
+
| `emojis.maxInWindow` | `0` (off) | Cap emojis+stickers across several messages. |
|
|
94
|
+
| `ignoreNsfw` | `false` | Skip NSFW channels. |
|
|
95
|
+
| `graceMessages` | `0` | First N messages from a user only run file/secret/link/word (say hi without flood). |
|
|
96
|
+
| `userOverrides` / `setUserConfig` | `{}` | Per-user config overlay (after roles, before channel). |
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
const antispam = new AntiSpam(client, {
|
|
100
|
+
preset: "balanced",
|
|
101
|
+
replies: { maxReplies: 5, windowMs: 8_000 },
|
|
102
|
+
blank: { enabled: true },
|
|
103
|
+
embeds: { maxEmbeds: 6 },
|
|
104
|
+
raid: { enabled: true, maxUsers: 8, windowMs: 6_000 },
|
|
105
|
+
files: { allowedExtensions: ["png", "jpg", "webp", "gif"] },
|
|
106
|
+
graceMessages: 2,
|
|
107
|
+
ignoreNsfw: true,
|
|
108
|
+
emojis: { maxInWindow: 30, windowMs: 10_000 },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
antispam.setUserConfig("KNOWN_SPAMMER_ID", { flood: { maxMessages: 2 } });
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Turn `raid` on only if you want a busy general chat to trip when many people post at once (join raids). For a meme channel, leave it off or raise `maxUsers`.
|
|
115
|
+
|
|
36
116
|
## What's new in 1.4.0
|
|
37
117
|
|
|
38
118
|
Secret scanning, cross-channel copy-paste, invisible unicode, attachment floods, and cleaner logs. Kick/ban stay **off**.
|
|
@@ -208,6 +288,8 @@ console.log(antispam.getStats());
|
|
|
208
288
|
|
|
209
289
|
## Table of contents
|
|
210
290
|
|
|
291
|
+
- [What's new in 1.6.0](#whats-new-in-160)
|
|
292
|
+
- [What's new in 1.5.0](#whats-new-in-150)
|
|
211
293
|
- [What's new in 1.4.0](#whats-new-in-140)
|
|
212
294
|
- [What's new in 1.3.0](#whats-new-in-130)
|
|
213
295
|
- [What's new in 1.2.0](#whats-new-in-120)
|
|
@@ -254,6 +336,16 @@ console.log(antispam.getStats());
|
|
|
254
336
|
| **echo** | Same text pasted in several channels |
|
|
255
337
|
| **invisible** | Zero-width / bidi obfuscation |
|
|
256
338
|
| **attach** | Attachment floods over a sliding window |
|
|
339
|
+
| **reply** | Too many replies in a short window |
|
|
340
|
+
| **blank** | Empty / whitespace-only messages |
|
|
341
|
+
| **embed** | Too many embeds in one message |
|
|
342
|
+
| **raid** | Many distinct users posting in one channel (off by default) |
|
|
343
|
+
| **forward** | Too many Discord forwarded messages in a window |
|
|
344
|
+
| **sticker** | Sticker dumps / optional sticker-only messages |
|
|
345
|
+
| **impersonate** | Nick/username too close to the bot or protected names |
|
|
346
|
+
| **join** | Mass joins in a short window (off by default) |
|
|
347
|
+
| **voice** | Too many voice messages in a window |
|
|
348
|
+
| **poll** | Too many polls in a window |
|
|
257
349
|
|
|
258
350
|
Also included:
|
|
259
351
|
|
|
@@ -261,7 +353,7 @@ Also included:
|
|
|
261
353
|
- Ignore lists for users, roles, channels, categories, guilds, and command prefixes
|
|
262
354
|
- Per-guild, per-channel, and per-role overlays
|
|
263
355
|
- Strike system with decay
|
|
264
|
-
- Optional delete / warn / timeout / kick / ban / addRole / removeRole (kick and ban are **off** by default)
|
|
356
|
+
- Optional delete / warn / timeout / kick / ban / addRole / removeRole / slowmode (kick and ban are **off** by default)
|
|
265
357
|
- `dryRun` to tune rules without punishing anyone
|
|
266
358
|
- Edit scanning (links, mentions, and words)
|
|
267
359
|
- Zero extra runtime dependencies (peer: `discord.js`)
|
|
@@ -379,6 +471,8 @@ npm run dev
|
|
|
379
471
|
| Log embeds | **Embed Links** |
|
|
380
472
|
| Kick / ban (opt-in) | **Kick Members** / **Ban Members** |
|
|
381
473
|
| Mute / add / remove roles (opt-in) | **Manage Roles** |
|
|
474
|
+
| Slowmode on raid/join (opt-in) | **Manage Channels** |
|
|
475
|
+
| Join-raid detector | **Server Members Intent** (`guildMemberAdd`) |
|
|
382
476
|
|
|
383
477
|
The bot will not sanction the guild owner or anyone above it in the role hierarchy. Those actions are skipped and reported in `onAction`.
|
|
384
478
|
|
|
@@ -388,10 +482,11 @@ Enable **Message Content Intent** in the [Discord Developer Portal](https://disc
|
|
|
388
482
|
|
|
389
483
|
1. Ignores bots, webhooks, system messages, the owner, administrators, command prefixes, and anything in your ignore lists.
|
|
390
484
|
2. Keeps a short **in-memory** history per user and guild (no database).
|
|
391
|
-
3. Runs detectors in this order: files → secrets → words → flood → hop → echo → duplicates → attachments → links → images → mentions → zalgo → newlines → punctuation → spoilers → invisible → accounts → length → caps → emojis. The first match wins.
|
|
485
|
+
3. Runs detectors in this order: files → secrets → words → impersonate → flood → hop → echo → duplicates → attachments → raid → replies → blank → embeds → forwards → voice → polls → stickers → links → images → mentions → zalgo → newlines → punctuation → spoilers → invisible → accounts → length → caps → emojis. The first match wins.
|
|
392
486
|
4. Adds one strike (with optional decay) and applies the configured punishment.
|
|
393
487
|
5. Message edits re-check **links**, **mentions**, **words**, **secrets**, and **invisible**.
|
|
394
488
|
6. Deletes can trigger **ghost** pings if `ghostPing.enabled` is true.
|
|
489
|
+
7. Joins can trigger **join** raids if `joins.enabled` is true (`guildMemberAdd`).
|
|
395
490
|
|
|
396
491
|
Call `antispam.stop()` on shutdown, hot reload, or plugin unload.
|
|
397
492
|
|
|
@@ -423,6 +518,7 @@ new AntiSpam(client, {
|
|
|
423
518
|
| Block shorteners | no | yes | yes |
|
|
424
519
|
| Channel hop | off | 5 / 8s | 3 / 6s |
|
|
425
520
|
| Ghost pings | off | off | on |
|
|
521
|
+
| Join raids | off | off | on |
|
|
426
522
|
| Auto timeout | off | 60s from 2 strikes | 5 min from 1 strike |
|
|
427
523
|
|
|
428
524
|
## Full configuration
|
|
@@ -441,8 +537,10 @@ Every option is optional. Missing fields fall back to the preset (or `balanced`
|
|
|
441
537
|
| `ignoreAdministrators` | `boolean` | `true` | Skip members with Administrator. |
|
|
442
538
|
| `checkEdits` | `boolean` | `true` | Re-scan edits for links, mentions, and words. |
|
|
443
539
|
| `checkDeletes` | `boolean` | `true` | Listen for `messageDelete` (ghost pings). |
|
|
540
|
+
| `checkJoins` | `boolean` | `true` | Listen for `guildMemberAdd` (join raids). |
|
|
444
541
|
| `ignoreThreads` | `boolean` | `false` | Skip messages in threads. |
|
|
445
542
|
| `ignoreSystem` | `boolean` | `true` | Skip Discord system messages. |
|
|
543
|
+
| `ignoreBoosters` | `boolean` | `false` | Skip server boosters. |
|
|
446
544
|
| `cleanupIntervalMs` | `number` | `60000` | How often the memory store is pruned. |
|
|
447
545
|
| `locale` | `"en"` \| `"es"` | `"en"` | Language for warnings and log embeds. |
|
|
448
546
|
| `ignorePermissions` | `string[]` | `[]` | Permission names that bypass checks. |
|
|
@@ -620,6 +718,7 @@ files: {
|
|
|
620
718
|
enabled: true,
|
|
621
719
|
blockedExtensions: ["exe", "bat", "cmd", "com", "scr", "dll", "msi", "vbs", "ps1", "jar", "apk"],
|
|
622
720
|
maxBytes: 0, // 0 = unlimited
|
|
721
|
+
blockDoubleExtensions: true, // virus.exe.png
|
|
623
722
|
severity: "critical",
|
|
624
723
|
}
|
|
625
724
|
|
|
@@ -645,6 +744,8 @@ words: {
|
|
|
645
744
|
regex: ["n[i1]tro\\s+free"],
|
|
646
745
|
ignoreCase: true,
|
|
647
746
|
matchWholeWord: true,
|
|
747
|
+
scanEmbeds: true,
|
|
748
|
+
normalizeHomoglyphs: true, // rаid-now (Cyrillic a) still matches
|
|
648
749
|
severity: "high",
|
|
649
750
|
}
|
|
650
751
|
|
|
@@ -687,6 +788,83 @@ checkDeletes: true
|
|
|
687
788
|
|
|
688
789
|
Disable with `ghostPing: { enabled: false }` or `disabledDetectors: ["ghost"]`.
|
|
689
790
|
|
|
791
|
+
### Forwards, stickers, voice, polls
|
|
792
|
+
|
|
793
|
+
```js
|
|
794
|
+
forwards: {
|
|
795
|
+
enabled: true,
|
|
796
|
+
maxForwards: 4, // 4th forward in the window triggers
|
|
797
|
+
windowMs: 10_000,
|
|
798
|
+
severity: "medium",
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
stickers: {
|
|
802
|
+
enabled: true,
|
|
803
|
+
maxStickers: 3, // per message
|
|
804
|
+
maxInWindow: 8, // 0 = off
|
|
805
|
+
windowMs: 10_000,
|
|
806
|
+
blockOnly: false, // true = sticker-only messages (no text)
|
|
807
|
+
severity: "low",
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
voice: {
|
|
811
|
+
enabled: true,
|
|
812
|
+
maxVoice: 3,
|
|
813
|
+
windowMs: 15_000,
|
|
814
|
+
severity: "medium",
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
polls: {
|
|
818
|
+
enabled: true,
|
|
819
|
+
maxPolls: 2,
|
|
820
|
+
windowMs: 20_000,
|
|
821
|
+
severity: "medium",
|
|
822
|
+
}
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
`lenient` turns forwards, voice, and polls off. `strict` tightens the windows and sets `stickers.blockOnly: true`.
|
|
826
|
+
|
|
827
|
+
### Impersonation
|
|
828
|
+
|
|
829
|
+
Compares nick / username / display name to the bot (`matchBot`) and any extra `names`. Text is folded (homoglyphs stripped, alphanumeric only) before similarity.
|
|
830
|
+
|
|
831
|
+
```js
|
|
832
|
+
impersonate: {
|
|
833
|
+
enabled: true,
|
|
834
|
+
matchBot: true,
|
|
835
|
+
names: ["Admin", "Moderador", "Staff"],
|
|
836
|
+
minSimilarity: 0.84,
|
|
837
|
+
checkNickname: true,
|
|
838
|
+
checkUsername: true,
|
|
839
|
+
checkDisplayName: true,
|
|
840
|
+
severity: "high",
|
|
841
|
+
}
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
Skip the bot itself. Short names under 3 letters after folding are ignored.
|
|
845
|
+
|
|
846
|
+
### Join raids
|
|
847
|
+
|
|
848
|
+
Off in `balanced` / `lenient`. On in `strict`. Needs `checkJoins: true` (default) and **Server Members Intent**. There is no message to delete: Disguard timeouts/kicks the newest joiner if those punishments are enabled.
|
|
849
|
+
|
|
850
|
+
```js
|
|
851
|
+
joins: {
|
|
852
|
+
enabled: false,
|
|
853
|
+
maxJoins: 8, // 8th distinct join in the window triggers
|
|
854
|
+
windowMs: 10_000,
|
|
855
|
+
minAccountAgeDays: 0, // e.g. 1 = only count accounts younger than 1 day
|
|
856
|
+
severity: "critical",
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
checkJoins: true
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
```js
|
|
863
|
+
onJoin(incident) {
|
|
864
|
+
// no Message — use incident.userId / guildId
|
|
865
|
+
}
|
|
866
|
+
```
|
|
867
|
+
|
|
690
868
|
### Punishment
|
|
691
869
|
|
|
692
870
|
Kick and ban stay **disabled** on purpose. Turn them on only if you really want that.
|
|
@@ -709,6 +887,7 @@ punishment: {
|
|
|
709
887
|
addRoleIds: [], // e.g. ["MUTE_ROLE_ID"] — needs Manage Roles
|
|
710
888
|
removeRoleIds: [],
|
|
711
889
|
minStrikesForRoles: 1,
|
|
890
|
+
slowmodeSeconds: 0, // e.g. 10 — on raid/join, needs Manage Channels
|
|
712
891
|
}
|
|
713
892
|
|
|
714
893
|
// timeout.scale: "none" | "linear" (base * strikes) | "exponential" (base * 2^n)
|
|
@@ -718,7 +897,7 @@ punishment: {
|
|
|
718
897
|
|
|
719
898
|
`warnMessage` placeholders: `{user}` `{reason}` `{type}` `{strikes}`.
|
|
720
899
|
|
|
721
|
-
With `escalate: true`, Disguard applies **one** hard action (timeout, or kick, or ban — whichever threshold you hit). Delete and warn can still run together. `addRole` / `removeRole` run if those ID lists are non-empty and strikes ≥ `minStrikesForRoles`.
|
|
900
|
+
With `escalate: true`, Disguard applies **one** hard action (timeout, or kick, or ban — whichever threshold you hit). Delete and warn can still run together. `addRole` / `removeRole` run if those ID lists are non-empty and strikes ≥ `minStrikesForRoles`. `slowmodeSeconds` only runs on **raid** and **join** hits; it stays until a moderator changes it.
|
|
722
901
|
|
|
723
902
|
If the bot lacks a permission, or the target is higher in the hierarchy, that action is skipped and listed in `result.skipped`.
|
|
724
903
|
|
|
@@ -739,6 +918,9 @@ new AntiSpam(client, {
|
|
|
739
918
|
onCooldown(message) {
|
|
740
919
|
// Extra spam during punishment.cooldownMs (already deleted if deleteDuringCooldown).
|
|
741
920
|
},
|
|
921
|
+
onJoin(incident) {
|
|
922
|
+
// Join raid. No message object.
|
|
923
|
+
},
|
|
742
924
|
});
|
|
743
925
|
```
|
|
744
926
|
|
|
@@ -749,7 +931,8 @@ new AntiSpam(client, {
|
|
|
749
931
|
type: "flood" | "duplicate" | "link" | "image" | "mention" | "caps" | "emoji"
|
|
750
932
|
| "file" | "zalgo" | "newline" | "account" | "length"
|
|
751
933
|
| "word" | "hop" | "punctuation" | "spoiler" | "ghost"
|
|
752
|
-
| "secret" | "echo" | "invisible" | "attach"
|
|
934
|
+
| "secret" | "echo" | "invisible" | "attach" | "reply" | "blank" | "embed" | "raid"
|
|
935
|
+
| "forward" | "sticker" | "impersonate" | "join" | "voice" | "poll",
|
|
753
936
|
severity: "low" | "medium" | "high" | "critical",
|
|
754
937
|
userId: string,
|
|
755
938
|
guildId: string,
|
|
@@ -757,7 +940,7 @@ new AntiSpam(client, {
|
|
|
757
940
|
messageId: string,
|
|
758
941
|
reason: string,
|
|
759
942
|
details: Record<string, unknown>,
|
|
760
|
-
recommendedActions: Array<"delete" | "warn" | "timeout" | "kick" | "ban" | "addRole" | "removeRole" | "purge">,
|
|
943
|
+
recommendedActions: Array<"delete" | "warn" | "timeout" | "kick" | "ban" | "addRole" | "removeRole" | "purge" | "slowmode">,
|
|
761
944
|
timestamp: number,
|
|
762
945
|
}
|
|
763
946
|
```
|
|
@@ -804,11 +987,15 @@ antispam.setChannelConfig(guildId, channelId, { images: { maxRepeats: 8 } });
|
|
|
804
987
|
antispam.getChannelConfig(guildId, channelId);
|
|
805
988
|
antispam.clearChannelConfig(guildId, channelId);
|
|
806
989
|
antispam.setRoleConfig(roleId, { flood: { maxMessages: 12 } });
|
|
990
|
+
antispam.setUserConfig(userId, { flood: { maxMessages: 2 } });
|
|
991
|
+
antispam.clearUserConfig(userId);
|
|
807
992
|
antispam.clearRoleConfig(roleId);
|
|
808
993
|
|
|
809
994
|
antispam.use(customDetector);
|
|
810
995
|
antispam.getStats();
|
|
811
996
|
antispam.resetStats();
|
|
997
|
+
antispam.getRecentIncidents(20);
|
|
998
|
+
antispam.setDetectorEnabled("poll", false);
|
|
812
999
|
|
|
813
1000
|
// Analyze only — no punishment, no callbacks
|
|
814
1001
|
const incident = await antispam.analyze(message);
|
|
@@ -823,7 +1010,9 @@ Helpers you can import for your own tools:
|
|
|
823
1010
|
import {
|
|
824
1011
|
extractUrls,
|
|
825
1012
|
normalizeText,
|
|
1013
|
+
foldHomoglyphs,
|
|
826
1014
|
similarity,
|
|
1015
|
+
isForwardedMessage,
|
|
827
1016
|
DEFAULT_PHISHING_KEYWORDS,
|
|
828
1017
|
DEFAULT_SHORTENERS,
|
|
829
1018
|
OFFICIAL_BRANDS,
|
|
@@ -964,9 +1153,21 @@ Wait a few seconds between categories so flood does not eat the next test.
|
|
|
964
1153
|
| Echo | Same long sentence in 3 channels within 12s |
|
|
965
1154
|
| Invisible | A message padded with many zero-width spaces |
|
|
966
1155
|
| Attachments | 8+ files in 10 seconds |
|
|
1156
|
+
| Replies | Reply to someone 6 times in 8s |
|
|
1157
|
+
| Blank | A message with only spaces |
|
|
1158
|
+
| Embeds | A webhook-style dump with 7+ embeds |
|
|
1159
|
+
| Raid | Enable `raid` and have 8 people post in the same channel in 6s |
|
|
1160
|
+
| Forwards | Forward the same / any messages 4 times in 10s |
|
|
1161
|
+
| Stickers | Send 4 stickers in one message |
|
|
1162
|
+
| Impersonate | Set your nick to the bot's username (or a name in `impersonate.names`) |
|
|
1163
|
+
| Voice | Send 3 voice messages in 15s |
|
|
1164
|
+
| Polls | Post 2 polls in 20s |
|
|
1165
|
+
| Double ext | Upload `foto.exe.png` |
|
|
1166
|
+
| Homoglyph word | Enable `words` with `raid-now`, send `rаid-now` (Cyrillic **а**) |
|
|
1167
|
+
| Joins | Enable `joins` and have 8 accounts join within 10s |
|
|
967
1168
|
| Edit | Send `hello`, then edit it to `Free Nitro https://bit.ly/test` |
|
|
968
1169
|
|
|
969
|
-
Watch the terminal: `[detect] flood|duplicate|link|image|mention|caps|emoji|file|zalgo|newline|word|hop|punctuation|spoiler|ghost|secret|echo|invisible|attach`.
|
|
1170
|
+
Watch the terminal: `[detect] flood|duplicate|link|image|mention|caps|emoji|file|zalgo|newline|word|hop|punctuation|spoiler|ghost|secret|echo|invisible|attach|forward|sticker|impersonate|voice|poll|join`.
|
|
970
1171
|
|
|
971
1172
|
The second strike applies a 1 minute timeout with the default example config. Strikes decay after 15 minutes, or call `resetUser`.
|
|
972
1173
|
|
|
@@ -1007,6 +1208,70 @@ MIT
|
|
|
1007
1208
|
|
|
1008
1209
|
# Español
|
|
1009
1210
|
|
|
1211
|
+
## Novedades de 1.6.0
|
|
1212
|
+
|
|
1213
|
+
Reenvíos, dumps de stickers, impersonación del bot/staff, raids de joins, mensajes de voz, encuestas y filtros de palabras/archivos más difíciles de esquivar. Kick/ban siguen **apagados**. `joins` va **apagado** en `balanced`.
|
|
1214
|
+
|
|
1215
|
+
| Opción | Default | Qué hace |
|
|
1216
|
+
| --- | --- | --- |
|
|
1217
|
+
| `forwards` | **on**, 4 / 10s | Demasiados mensajes **reenviados** de Discord. |
|
|
1218
|
+
| `stickers` | **on**, 3 por mensaje, 8 / 10s | Dump de stickers. `blockOnly` (off) caza mensajes solo-sticker. |
|
|
1219
|
+
| `impersonate` | **on**, bot a 0.84 | Nick / username / display name demasiado parecido al **bot** (o a `names`). |
|
|
1220
|
+
| `joins` | **off** (`strict`: on, 6 / 8s) | Demasiadas **cuentas distintas entrando** al servidor. Hace falta `guildMemberAdd`. |
|
|
1221
|
+
| `voice` | **on**, 3 / 15s | Demasiados **mensajes de voz**. |
|
|
1222
|
+
| `polls` | **on**, 2 / 20s | Demasiadas **encuestas**. |
|
|
1223
|
+
| `files.blockDoubleExtensions` | `true` | Caza `virus.exe.png`. |
|
|
1224
|
+
| `words.scanEmbeds` | `true` | La lista de palabras también lee embeds. |
|
|
1225
|
+
| `words.normalizeHomoglyphs` | `true` | Pliega lookalikes cirílicos / griegos / fullwidth. |
|
|
1226
|
+
| `ignoreBoosters` | `false` | Ignora boosters. |
|
|
1227
|
+
| `punishment.slowmodeSeconds` | `0` | En hits `raid` / `join`, pone slowmode (hace falta **Manage Channels**). |
|
|
1228
|
+
| `getRecentIncidents()` | — | Últimos 50 hits en vivo (no `analyze()`). |
|
|
1229
|
+
| `setDetectorEnabled(type, bool)` | — | Enciende/apaga un detector. |
|
|
1230
|
+
| `onJoin` | — | Callback de raid de joins (sin mensaje). |
|
|
1231
|
+
|
|
1232
|
+
```js
|
|
1233
|
+
new AntiSpam(client, {
|
|
1234
|
+
forwards: { maxForwards: 3 },
|
|
1235
|
+
impersonate: { names: ["Admin", "Moderador"] },
|
|
1236
|
+
joins: { enabled: true, maxJoins: 8 },
|
|
1237
|
+
ignoreBoosters: true,
|
|
1238
|
+
words: { enabled: true, list: ["raid-now"], normalizeHomoglyphs: true },
|
|
1239
|
+
punishment: { slowmodeSeconds: 10 },
|
|
1240
|
+
onJoin(incident) {
|
|
1241
|
+
console.log("join raid", incident.details);
|
|
1242
|
+
},
|
|
1243
|
+
});
|
|
1244
|
+
antispam.setDetectorEnabled("poll", false);
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
Activa `joins` solo si quieres que un burst de cuentas nuevas dispare timeout al último en entrar.
|
|
1248
|
+
|
|
1249
|
+
## Novedades de 1.5.0
|
|
1250
|
+
|
|
1251
|
+
Raids de canal, spam de replies, mensajes vacíos, paredes de embeds, allowlist de archivos y config por usuario. Kick/ban siguen **apagados**. `raid` va **apagado** en `balanced`.
|
|
1252
|
+
|
|
1253
|
+
| Opción | Default | Qué hace |
|
|
1254
|
+
| --- | --- | --- |
|
|
1255
|
+
| `replies` | **on**, 6 / 8s | Demasiadas **respuestas** seguidas. |
|
|
1256
|
+
| `blank` | **on** | Mensajes vacíos o solo espacios. |
|
|
1257
|
+
| `embeds` | **on**, 6 | Demasiados embeds en un mensaje. |
|
|
1258
|
+
| `raid` | **off** (`strict`: on) | Demasiados **usuarios distintos** escribiendo en el **mismo canal**. |
|
|
1259
|
+
| `files.allowedExtensions` | `[]` | Si lo rellenas, solo esas extensiones pasan. |
|
|
1260
|
+
| `emojis.maxInWindow` | `0` (off) | Tope de emojis+stickers entre varios mensajes. |
|
|
1261
|
+
| `ignoreNsfw` | `false` | Ignora canales NSFW. |
|
|
1262
|
+
| `graceMessages` | `0` | Los primeros N mensajes solo miran file/secret/link/word. |
|
|
1263
|
+
| `setUserConfig` | — | Overlay por usuario. |
|
|
1264
|
+
|
|
1265
|
+
```js
|
|
1266
|
+
new AntiSpam(client, {
|
|
1267
|
+
raid: { enabled: true, maxUsers: 8 },
|
|
1268
|
+
files: { allowedExtensions: ["png", "jpg", "webp"] },
|
|
1269
|
+
graceMessages: 2,
|
|
1270
|
+
ignoreNsfw: true,
|
|
1271
|
+
});
|
|
1272
|
+
antispam.setUserConfig("ID_USER", { flood: { maxMessages: 2 } });
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1010
1275
|
## Novedades de 1.4.0
|
|
1011
1276
|
|
|
1012
1277
|
Escaneo de secretos, copypasta entre canales, unicode invisible, flood de adjuntos y logs por webhook. Kick/ban siguen **apagados**.
|
|
@@ -1124,6 +1389,8 @@ new AntiSpam(client, {
|
|
|
1124
1389
|
|
|
1125
1390
|
## Tabla de contenidos
|
|
1126
1391
|
|
|
1392
|
+
- [Novedades de 1.6.0](#novedades-de-160)
|
|
1393
|
+
- [Novedades de 1.5.0](#novedades-de-150)
|
|
1127
1394
|
- [Novedades de 1.4.0](#novedades-de-140)
|
|
1128
1395
|
- [Novedades de 1.3.0](#novedades-de-130)
|
|
1129
1396
|
- [Novedades de 1.2.0](#novedades-de-120)
|
|
@@ -1149,7 +1416,7 @@ new AntiSpam(client, {
|
|
|
1149
1416
|
|
|
1150
1417
|
**Disguard** es una librería antispam para bots de discord.js v14. No es un bot: la enchufas a tu `Client` y tú decides umbrales, listas y castigos.
|
|
1151
1418
|
|
|
1152
|
-
Detecta flood, salto de canales, palabras bloqueadas, phishing / enlaces no deseados (también en embeds), imágenes repetidas, spam de menciones, ghost pings, mayúsculas, emojis, archivos peligrosos, zalgo y paredes de líneas.
|
|
1419
|
+
Detecta flood, salto de canales, palabras bloqueadas, phishing / enlaces no deseados (también en embeds), imágenes repetidas, spam de menciones, ghost pings, reenvíos, impersonación, raids de joins, mayúsculas, emojis, archivos peligrosos, zalgo y paredes de líneas.
|
|
1153
1420
|
|
|
1154
1421
|
## Requisitos
|
|
1155
1422
|
|
|
@@ -1236,6 +1503,8 @@ npm run dev
|
|
|
1236
1503
|
| Embed de logs | **Embed Links** |
|
|
1237
1504
|
| Kick / ban (opt-in) | **Kick Members** / **Ban Members** |
|
|
1238
1505
|
| Mute / add / remove roles (opt-in) | **Manage Roles** |
|
|
1506
|
+
| Slowmode en raid/join (opt-in) | **Manage Channels** |
|
|
1507
|
+
| Raid de joins | **Server Members Intent** (`guildMemberAdd`) |
|
|
1239
1508
|
|
|
1240
1509
|
No puede sancionar al dueño del servidor ni a quien esté por encima del bot en la jerarquía.
|
|
1241
1510
|
|
|
@@ -1245,10 +1514,11 @@ Activa **Message Content Intent** en el [Portal de Discord](https://discord.com/
|
|
|
1245
1514
|
|
|
1246
1515
|
1. Ignora bots, webhooks, mensajes de sistema, el dueño, administradores, prefijos de comando y tus listas de ignore.
|
|
1247
1516
|
2. Guarda en **memoria** un historial corto por usuario y servidor. Sin base de datos.
|
|
1248
|
-
3. Pasa el mensaje por: archivos → secretos → palabras → flood → hop → echo → duplicados → adjuntos → enlaces → imágenes → menciones → zalgo → líneas → puntuación → spoilers → invisibles → cuentas → longitud → caps → emojis. El primero que dispare gana.
|
|
1517
|
+
3. Pasa el mensaje por: archivos → secretos → palabras → impersonate → flood → hop → echo → duplicados → adjuntos → raid → replies → vacíos → embeds → reenvíos → voz → encuestas → stickers → enlaces → imágenes → menciones → zalgo → líneas → puntuación → spoilers → invisibles → cuentas → longitud → caps → emojis. El primero que dispare gana.
|
|
1249
1518
|
4. Suma un strike (con caducidad) y aplica el castigo configurado.
|
|
1250
1519
|
5. Las ediciones revisan **enlaces**, **menciones** y **palabras**.
|
|
1251
1520
|
6. Los borrados pueden disparar **ghost** ping si `ghostPing.enabled` es true.
|
|
1521
|
+
7. Los joins pueden disparar **join** si `joins.enabled` es true.
|
|
1252
1522
|
|
|
1253
1523
|
Llama `antispam.stop()` al apagar el proceso.
|
|
1254
1524
|
|
|
@@ -1283,8 +1553,10 @@ Todo es opcional. Lo que no pongas usa el preset.
|
|
|
1283
1553
|
| `ignoreAdministrators` | `boolean` | `true` | Ignora quien tenga Administrator. |
|
|
1284
1554
|
| `checkEdits` | `boolean` | `true` | Revisa ediciones (enlaces, menciones y palabras). |
|
|
1285
1555
|
| `checkDeletes` | `boolean` | `true` | Escucha `messageDelete` (ghost pings). |
|
|
1556
|
+
| `checkJoins` | `boolean` | `true` | Escucha `guildMemberAdd` (raids de joins). |
|
|
1286
1557
|
| `ignoreThreads` | `boolean` | `false` | Ignora hilos. |
|
|
1287
1558
|
| `ignoreSystem` | `boolean` | `true` | Ignora mensajes de sistema. |
|
|
1559
|
+
| `ignoreBoosters` | `boolean` | `false` | Ignora boosters. |
|
|
1288
1560
|
| `cleanupIntervalMs` | `number` | `60000` | Limpieza de memoria. |
|
|
1289
1561
|
| `roleOverrides` | `object` | `{}` | Parches por rol. |
|
|
1290
1562
|
|
|
@@ -1383,7 +1655,7 @@ emojis: { enabled: true, maxEmojis: 12, maxStickers: 3, severity: "low" },
|
|
|
1383
1655
|
### Archivos, zalgo, saltos de línea
|
|
1384
1656
|
|
|
1385
1657
|
```js
|
|
1386
|
-
files: { enabled: true, blockedExtensions: ["exe", "bat", "cmd", "dll", "msi"], maxBytes: 0, severity: "critical" },
|
|
1658
|
+
files: { enabled: true, blockedExtensions: ["exe", "bat", "cmd", "dll", "msi"], maxBytes: 0, blockDoubleExtensions: true, severity: "critical" },
|
|
1387
1659
|
zalgo: { enabled: true, maxCombining: 20, severity: "medium" },
|
|
1388
1660
|
newlines: { enabled: true, maxNewlines: 15, severity: "low" },
|
|
1389
1661
|
```
|
|
@@ -1391,14 +1663,20 @@ newlines: { enabled: true, maxNewlines: 15, severity: "low" },
|
|
|
1391
1663
|
### Palabras, hop, puntuación, spoilers, ghost ping
|
|
1392
1664
|
|
|
1393
1665
|
```js
|
|
1394
|
-
words: { enabled: false, list: ["raid-now"], regex: [], ignoreCase: true, matchWholeWord: true, severity: "high" },
|
|
1666
|
+
words: { enabled: false, list: ["raid-now"], regex: [], ignoreCase: true, matchWholeWord: true, scanEmbeds: true, normalizeHomoglyphs: true, severity: "high" },
|
|
1395
1667
|
hop: { enabled: true, maxChannels: 5, windowMs: 8_000, severity: "high" },
|
|
1396
1668
|
punctuation: { enabled: true, maxRepeated: 10, severity: "low" },
|
|
1397
1669
|
spoilers: { enabled: true, maxSpoilers: 8, severity: "low" },
|
|
1398
1670
|
ghostPing: { enabled: false, minMentions: 1, maxAgeMs: 15_000, severity: "high" },
|
|
1671
|
+
forwards: { enabled: true, maxForwards: 4, windowMs: 10_000, severity: "medium" },
|
|
1672
|
+
stickers: { enabled: true, maxStickers: 3, maxInWindow: 8, blockOnly: false, severity: "low" },
|
|
1673
|
+
impersonate: { enabled: true, matchBot: true, names: ["Admin", "Moderador"], minSimilarity: 0.84, severity: "high" },
|
|
1674
|
+
joins: { enabled: false, maxJoins: 8, windowMs: 10_000, severity: "critical" },
|
|
1675
|
+
voice: { enabled: true, maxVoice: 3, windowMs: 15_000, severity: "medium" },
|
|
1676
|
+
polls: { enabled: true, maxPolls: 2, windowMs: 20_000, severity: "medium" },
|
|
1399
1677
|
```
|
|
1400
1678
|
|
|
1401
|
-
`lenient` apaga hop y
|
|
1679
|
+
`lenient` apaga hop, puntuación, reenvíos, voz y encuestas. `strict` enciende ghost ping, joins y aprieta umbrales.
|
|
1402
1680
|
|
|
1403
1681
|
### Castigos
|
|
1404
1682
|
|
|
@@ -1421,6 +1699,7 @@ punishment: {
|
|
|
1421
1699
|
addRoleIds: [],
|
|
1422
1700
|
removeRoleIds: [],
|
|
1423
1701
|
minStrikesForRoles: 1,
|
|
1702
|
+
slowmodeSeconds: 0,
|
|
1424
1703
|
}
|
|
1425
1704
|
```
|
|
1426
1705
|
|
|
@@ -1439,6 +1718,7 @@ new AntiSpam(client, {
|
|
|
1439
1718
|
console.error(context, error);
|
|
1440
1719
|
},
|
|
1441
1720
|
onCooldown(message) {},
|
|
1721
|
+
onJoin(incident) {},
|
|
1442
1722
|
});
|
|
1443
1723
|
```
|
|
1444
1724
|
|
|
@@ -1461,7 +1741,10 @@ antispam.resetUser(guildId, userId);
|
|
|
1461
1741
|
antispam.setGuildConfig(guildId, { flood: { maxMessages: 3 } });
|
|
1462
1742
|
antispam.setChannelConfig(guildId, channelId, { flood: { maxMessages: 12 } });
|
|
1463
1743
|
antispam.setRoleConfig(roleId, { emojis: { maxEmojis: 40 } });
|
|
1744
|
+
antispam.setUserConfig(userId, { flood: { maxMessages: 2 } });
|
|
1464
1745
|
antispam.getStats();
|
|
1746
|
+
antispam.getRecentIncidents(10);
|
|
1747
|
+
antispam.setDetectorEnabled("poll", false);
|
|
1465
1748
|
|
|
1466
1749
|
const incident = await antispam.analyze(message);
|
|
1467
1750
|
const editado = await antispam.analyze(message, { isEdit: true });
|
|
@@ -1540,9 +1823,21 @@ Espera unos segundos entre categorías.
|
|
|
1540
1823
|
| Echo | La misma frase larga en 3 canales en 12s |
|
|
1541
1824
|
| Invisible | Un mensaje con muchos espacios de ancho cero |
|
|
1542
1825
|
| Adjuntos | 8+ archivos en 10 segundos |
|
|
1826
|
+
| Replies | Responder 6 veces en 8s |
|
|
1827
|
+
| Vacío | Un mensaje solo con espacios |
|
|
1828
|
+
| Embeds | 7+ embeds en un mensaje |
|
|
1829
|
+
| Raid | Activa `raid` y que 8 personas escriban en el mismo canal |
|
|
1830
|
+
| Reenvíos | Reenvía 4 mensajes en 10s |
|
|
1831
|
+
| Stickers | 4 stickers en un mensaje |
|
|
1832
|
+
| Impersonar | Pon tu nick igual al del bot (o un nombre de `impersonate.names`) |
|
|
1833
|
+
| Voz | 3 mensajes de voz en 15s |
|
|
1834
|
+
| Encuestas | 2 polls en 20s |
|
|
1835
|
+
| Doble ext | Sube `foto.exe.png` |
|
|
1836
|
+
| Homoglyph | Activa `words` con `raid-now` y manda `rаid-now` (а cirílica) |
|
|
1837
|
+
| Joins | Activa `joins` y que 8 cuentas entren en 10s |
|
|
1543
1838
|
| Edición | Manda `hola` y edítalo a `Free Nitro https://bit.ly/test` |
|
|
1544
1839
|
|
|
1545
|
-
En la terminal: `[detect] flood|duplicate|link|image|mention|caps|emoji|file|zalgo|newline|word|hop|punctuation|spoiler|ghost|secret|echo|invisible|attach`.
|
|
1840
|
+
En la terminal: `[detect] flood|duplicate|link|image|mention|caps|emoji|file|zalgo|newline|word|hop|punctuation|spoiler|ghost|secret|echo|invisible|attach|forward|sticker|impersonate|voice|poll|join`.
|
|
1546
1841
|
|
|
1547
1842
|
Al segundo strike el ejemplo mete timeout de 1 minuto. Los strikes caducan a los 15 minutos, o usa `resetUser`.
|
|
1548
1843
|
|
package/dist/AntiSpam.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Client, type Message } from "discord.js";
|
|
2
2
|
import { MemoryStore } from "./store/MemoryStore";
|
|
3
|
-
import type { AntiSpamOptions, AntiSpamStats, DeepPartial, Detector, Incident, ResolvedConfig } from "./types";
|
|
3
|
+
import type { AntiSpamOptions, AntiSpamStats, DeepPartial, Detector, DetectorType, Incident, ResolvedConfig } from "./types";
|
|
4
4
|
export declare class AntiSpam {
|
|
5
5
|
readonly client: Client;
|
|
6
6
|
readonly store: MemoryStore;
|
|
@@ -10,12 +10,14 @@ export declare class AntiSpam {
|
|
|
10
10
|
private readonly guildConfigs;
|
|
11
11
|
private readonly channelConfigs;
|
|
12
12
|
private stats;
|
|
13
|
+
private readonly recentIncidents;
|
|
13
14
|
private started;
|
|
14
15
|
private paused;
|
|
15
16
|
private cleanupTimer;
|
|
16
17
|
private readonly onMessage;
|
|
17
18
|
private readonly onEdit;
|
|
18
19
|
private readonly onDelete;
|
|
20
|
+
private readonly onJoin;
|
|
19
21
|
constructor(client: Client, options?: AntiSpamOptions);
|
|
20
22
|
/** Starts listening to `messageCreate` (and `messageUpdate` / `messageDelete` if enabled). */
|
|
21
23
|
start(): this;
|
|
@@ -40,10 +42,14 @@ export declare class AntiSpam {
|
|
|
40
42
|
clearChannelConfig(guildId: string, channelId: string): void;
|
|
41
43
|
setRoleConfig(roleId: string, patch: DeepPartial<ResolvedConfig>): void;
|
|
42
44
|
clearRoleConfig(roleId: string): void;
|
|
45
|
+
setUserConfig(userId: string, patch: DeepPartial<ResolvedConfig>): void;
|
|
46
|
+
clearUserConfig(userId: string): void;
|
|
43
47
|
getStrikes(guildId: string, userId: string): number;
|
|
44
48
|
isCoolingDown(guildId: string, userId: string): boolean;
|
|
45
49
|
resetUser(guildId: string, userId: string): void;
|
|
46
50
|
getStats(): AntiSpamStats;
|
|
51
|
+
getRecentIncidents(limit?: number): Incident[];
|
|
52
|
+
setDetectorEnabled(type: DetectorType, enabled: boolean): this;
|
|
47
53
|
resetStats(): void;
|
|
48
54
|
/**
|
|
49
55
|
* Analyzes a message without punishing.
|
|
@@ -54,10 +60,12 @@ export declare class AntiSpam {
|
|
|
54
60
|
}): Promise<Incident | null>;
|
|
55
61
|
private handle;
|
|
56
62
|
private handleDelete;
|
|
63
|
+
private handleJoin;
|
|
57
64
|
shouldIgnore(message: Message): boolean;
|
|
58
65
|
private configFor;
|
|
59
66
|
private orderedDetectors;
|
|
60
67
|
private toSnapshot;
|
|
68
|
+
private pushRecent;
|
|
61
69
|
private maxRetentionMs;
|
|
62
70
|
}
|
|
63
71
|
export declare function createAntiSpam(client: Client, options?: AntiSpamOptions): AntiSpam;
|
package/dist/AntiSpam.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AntiSpam.d.ts","sourceRoot":"","sources":["../src/AntiSpam.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"AntiSpam.d.ts","sourceRoot":"","sources":["../src/AntiSpam.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAEX,KAAK,OAAO,EAEb,MAAM,YAAY,CAAC;AAkCpB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAEV,eAAe,EACf,aAAa,EACb,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,QAAQ,EAER,cAAc,EACf,MAAM,SAAS,CAAC;AA8DjB,qBAAa,QAAQ;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,cAAqB;IAEnC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkD;IAC/E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkD;IACjF,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA+B;IAEnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAExB;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGrB;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAEvB;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAErB;gBAEU,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;IA8CzD,8FAA8F;IAC9F,KAAK,IAAI,IAAI;IAoBb,8CAA8C;IAC9C,IAAI,IAAI,IAAI;IAcZ,mEAAmE;IACnE,KAAK,IAAI,IAAI;IAKb,MAAM,IAAI,IAAI;IAKd,QAAQ,IAAI,OAAO;IAInB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,SAAS,IAAI,OAAO;IAIpB,+DAA+D;IAC/D,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAK7B,SAAS,IAAI,cAAc;IAI3B,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,cAAc;IAK7D,gDAAgD;IAChD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc;IAI/C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,cAAc;IAMnF,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIvC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc;IAIpE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,cAAc;IAOxG,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5D,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,IAAI;IAMvE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,IAAI;IAMvE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IASnD,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAKvD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAIhD,QAAQ,IAAI,aAAa;IAIzB,kBAAkB,CAAC,KAAK,SAAK,GAAG,QAAQ,EAAE;IAI1C,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAQ9D,UAAU,IAAI,IAAI;IAKlB;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YAiE/E,MAAM;YAqDN,YAAY;YAmCZ,UAAU;IA4CxB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAqDvC,OAAO,CAAC,SAAS;IA2BjB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,cAAc;CAsBvB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAElF"}
|