Word Filter
Block slurs, harassment, and custom banned words. Pick from curated preset packages, add your own words, and optionally choose a different action per package.
Open AutoMod →Word Filter is the richest AutoMod trigger. Turn on curated preset packages (hate speech, harassment, NSFW, profanity), add your own words, and route each package to a different action — ban for slurs, delete for mild swears.
What is this?
A rule that watches every message for words from a list you control. The list is the union of curated preset packages (hate speech, harassment, NSFW terms, profanity) plus any custom words you add. Matches are whole-word and case-insensitive by default.
Why you might want it
If you're tired of mods watching for the same five slurs day in day out, this is the rule that hands that work to the bot. Most servers turn on the hate speech and harassment packages, add a handful of community-specific words, and let it run. AutoMod is free up to three rules, so a word filter alone is comfortably inside the free tier.
Why use this rule?
- Stops slurs, hate speech, and targeted harassment the moment they are posted.
- Blocks names, phrases, or keywords specific to your community — scam URLs, banned terms, inside-drama topics.
- Lets you escalate severity by package: a ban for hate speech, a delete for mild swears, all in one rule.
- Saves moderator time — most word-filter hits never need a human.
What it detects
Messages containing any word from the resolved word list: the union of every word in the enabled preset packages plus the rule's custom_words. Matching is case-insensitive by default and uses word boundaries, so ass does not match assassin.
hate_speech. Action: ban (package override).What it does NOT detect
- Words inside embeds, attachment filenames, sticker names, or reactions — only message content is scanned.
- Leetspeak or character-substitution obfuscation (
n1gger,f u c k). - Unicode variants — stylised fonts like
ⓕⓤⓒⓚor fullwidth text are not normalised before matching.
Configuration
| Field | Type | Default | What it means |
|---|---|---|---|
| preset_packages | list of IDs | see below | Which preset word packages to enable. The seed defaults to five packages (see the Preset packages table). |
| allow_swearing | boolean | false | When on, the two profanity packages are skipped even if enabled. Useful for more relaxed servers. |
| nsfw_server | boolean | false | When on, the NSFW-terms package is skipped even if enabled. |
| custom_words | list of strings | [] | Extra words added on top of the preset packages. Tagged as custom. |
| package_actions | object | {} | Optional per-package action overrides. Lets you ban for hate speech while merely deleting for mild swears. |
Preset packages
Six curated packages ship with Arkanis. Each package is tagged so per-package action overrides can target it.
| Package | Approx. words | Severity | Enabled by default |
|---|---|---|---|
| hate_speech | ~33 | Major | Yes |
| harassment_threats | ~18 | Major | Yes |
| sexual_explicit | ~180 | Major | Yes |
| nsfw_terms | ~75 | Minor | Yes |
| profanity_harsh | ~29 | Minor | Yes |
| profanity_mild | ~10 | Minor | No |
allow_swearingskipsprofanity_harshandprofanity_mild.nsfw_serverskipsnsfw_terms. (Thesexual_explicitpackage stays enforced even withnsfw_serveron, because it covers content that is not safe for adult-only servers either.)
custom_words field on a rule. If your community would benefit from a curated starter pack in another language, email support@arkanis.gg and we will prioritise the languages with the most demand. Native-speaker contributions for hate-speech and harassment lists are welcome through the same channel.Per-package action overrides
By default, every matched word runs the rule's configured action. The optional package_actions map lets you override that on a per-package basis — ban for hate speech, strike for harassment, delete for mild swears.
{
"package_actions": {
"hate_speech": {
"action": "ban",
"severity": "major",
"discord_ban": true,
"reason_text": "Hate speech"
},
"profanity_mild": {
"action": "none"
}
}
}actioncan bedelete,warn,mute,strike,ban, ornone.action: "none"degrades to a plain delete — the message is still removed, but no enforcement action follows.- Severity, reason codes, and mute durations can all be overridden per package.
- Words added to
custom_wordsare taggedcustom— target that tag inpackage_actionsto give your own list its own action.
Recommended starter settings
A balanced baseline for most community servers:
{
"preset_packages": [
"hate_speech",
"harassment_threats",
"sexual_explicit",
"nsfw_terms",
"profanity_harsh"
],
"allow_swearing": false,
"nsfw_server": false,
"custom_words": []
}Run with Mode: Log Only, case-insensitive matching, and word boundary on until you have watched the Event Log for a week and tuned anything noisy. Then flip to Live.
Common false positives
- Word-boundary collisions — a word like
hellmatches insidehellcatonly if word boundaries are off, but still inside phrases likehell-yeahbecause-is a non-word character. - Medical or educational discussion — anatomical words flagged in every context, including book club threads.
- Quoted slurs in a news story, academic citation, or song lyric — the filter has no concept of context.
- Loanwords from other languages that overlap with English slurs (
assinside Spanish or French words). - Nicknames and usernames inside the message body — a mention like
@somerudeis treated as plain content.
How to test this rule safely
Set the rule to Log Only
Log Only records matches without taking any action. It is the right starting point for every AutoMod rule.
Add a harmless custom word
Add a nonsense word like frobnicate to custom_words. You can trigger the rule without typing anything embarrassing.
Send a test message
In a private channel, post "I hate frobnicate-ing". Check the Event Log dashboard — you should see an entry with matched_pattern = frobnicate.
Confirm allowlist and exempt roles work
Add frobnicate to allowlist_words temporarily and post again — no Event Log entry. Remove it, add one of your roles to Exempt Roles, post as that role — no Event Log entry.
Remove the test word and flip to Live
Drop frobnicate from the custom list and switch the rule from Log Only to Live.
Known current behavior
- Current behavior: word_filter always deletes the matching message first, even when the configured action is Warn, Mute, Strike, or Ban. The content never stays visible once the rule fires. This is by design — a slur left in channel while the bot issues a warn is the wrong outcome.
- Current behavior: allowlist words apply to content-match triggers only. Word Filter is one of them. If any allowlist word appears anywhere in the message (substring-matched, lowercase), the rule is skipped entirely. A short allowlist entry like
hellwould accidentally whitelist messages containinghello— use specific phrases rather than common fragments. Volumetric triggers (Mention Spam, Spam Detection, etc.) are not affected by the allowlist. - Current behavior: the legacy
wordsfield is ignored whenpreset_packageshas any entries. Older rules may carry a rawwordsarray — migrate it tocustom_wordsor leavepreset_packagesempty. - Current behavior: matching does not normalise Unicode. Stylised fonts (mathematical italic, fullwidth, accented letters) bypass the filter. Add important variants as custom words if coverage matters.
- Current behavior: word boundary follows Python's
\brules. Underscores and digits count as word characters, soshit_will not match the wordshit. - Current behavior: per-package overrides replace the rule's default action for that package's matches. A rule with default action Warn and a
hate_speechoverride of Ban will ban on slur matches and warn on everything else.
Action reference
Pair this trigger with any of the five AutoMod actions. Unique to word_filter: the message is always deleted first, even on non-delete actions — a slur should never stay visible while the bot issues a warn or a strike.
delete, warn, mute, strike, and ban actually do, plus every action_config field and required Discord permission.