Profanity Filter
The Profanity module scans every message sent in your server and acts when it finds banned language. It combines a built-in dictionary that works with no setup and custom word rules you define yourself.
::: info Enable the module first Nothing is filtered until the module is switched on from Dashboard → Moderation → Profanity. Once enabled, the built-in dictionary starts filtering immediately — you do not have to add any words. :::
How it works
Every message from a human member is checked as it is posted:
- Custom rules are matched first. They are what you explicitly asked for, so a custom rule always wins over the built-in dictionary.
- The built-in dictionary is checked next, if it is enabled.
- If the member is excluded from the matching rule (by role or channel), that rule is skipped and the remaining rules are still checked — an exclusion on one rule never grants immunity to the others.
- The first matching rule’s action is applied, and the hit is recorded.
Messages from bots — including Strom’s own response messages — are never moderated.
The built-in dictionary
The built-in filter ships with a large word list and needs no configuration. It catches:
- Plain profanity as whole words.
assignmentnever trips onass, because the scan matches full words, not substrings. - Lookalike and leetspeak variants such as
a55hole, which plain word lists miss.
The built-in filter has its own action, delete switch, timeout duration, response message, and exclusions — configured independently of your custom rules. It is on by default when the module is enabled.
If the dictionary is too aggressive for your community, disable the built-in filter and rely purely on custom rules.
Custom word rules
Each rule is one word or phrase plus the settings that apply when it matches.
| Setting | Description |
|---|---|
| Word | The word or phrase to match, up to 120 characters. Matched as a whole word, case-insensitive. |
| Action | What happens to the member — block, warn, or timeout. |
| Delete message | Whether the offending message is removed. Independent of the action. |
| Duration | How long a timeout lasts. Ignored by other actions. |
| Response message | An optional notice Strom posts in the channel. Supports placeholders, and self-deletes after 30 seconds. |
| Exclude roles | Members with any of these roles bypass this rule. Up to 25. |
| Exclude channels | This rule does not apply in these channels. Up to 25. |
| Status | Toggle a rule off without deleting it. |
Symbols are safe to use in a word — c++ and $$$ both match correctly.
Rule limits
| Tier | Custom rules |
|---|---|
| Free | 6 |
| Premium | 12 |
The limit is enforced by the server, not just the dashboard.
Actions
| Action | Effect |
|---|---|
| Block | Records the hit. Pair with Delete message to remove the content. |
| Warn | Records the hit as a warning. Pair with a response message to tell the member why. |
| Timeout | Times the member out for the configured duration. |
Delete message is a separate switch, not an action. Any action can be paired with or without deleting the offending message, so you can time a member out and leave the message up, or delete silently with no punishment.
Timeout durations
1 minute, 5 minutes, 10 minutes, 30 minutes, 1 hour (default), 6 hours, 1 day, 1 week.
Response message
The response message is posted as an embed in the channel where the match happened. It shows the member, the action taken, and a live countdown to its own removal. Leave it empty to act silently. Up to 600 characters, with these placeholders:
::: info The notice cleans itself up Response embeds are deleted automatically 30 seconds after they are posted, so the channel is not left littered with moderation notices. The countdown is shown on the embed itself. :::
| Placeholder | Replaced with |
|---|---|
{user.tag} | A mention of the member. |
{user.name} | The member’s display name. |
{user.username} | The member’s username. |
{user.id} | The member’s ID. |
{user.discriminator} | The member’s discriminator. |
{guild.name} | The server name. |
{guild.id} | The server ID. |
{guild.memberCount} | The server’s member count. |
Example
{user.tag} that word is not allowed in {guild.name}.
Exclusions
Exclusions are set per rule, and the built-in filter has its own set.
- Roles — a member holding any excluded role bypasses that rule. Use it for staff and trusted roles.
- Channels — the rule does not apply in those channels. Use it for age-gated or off-topic channels.
Excluding a role from one rule does not exclude it from the rest. To exempt staff entirely, add the role to every rule and to the built-in filter.
Statistics
The dashboard reports totals derived from the hit log:
| Stat | Meaning |
|---|---|
| Blocked | Hits where the action was block. |
| Warnings | Hits where the action was warn. |
| Timeouts | Hits where the action was timeout. |
| Deleted | Hits where the message was removed. |
Each custom rule also shows its own trigger count. Counts come from the hit log, so a rule keeps its count across edits.
Troubleshooting
::: details A banned word got through Check that the module is enabled, that the rule’s status is on, and that the member does not hold an excluded role or post in an excluded channel. Remember that matching is whole-word — a rule for spam does not match spamming. :::
::: details Clean messages are being flagged The built-in dictionary also catches leetspeak variants, which can occasionally over-match. Disable the built-in filter and use custom rules, or exclude the channel where it is a problem. :::
::: details The message was not deleted Deleting needs Manage Messages in that channel. Confirm the Delete message switch is on for the rule that matched. :::
::: details The member was not timed out Strom needs Moderate Members, and its highest role must sit above the member’s. Server owners and members with a higher role cannot be timed out. :::
Need help?
Join the Strom support server from the Discord link in the header if you need help configuring the Profanity module.
