Link Filter
Block or allowlist URL domains in chat. Run in blocklist mode to stop known-bad hosts, or allowlist mode to permit only trusted domains.
Open AutoMod →Link Filter extracts every URL from a message, parses the hostname, and compares it against your lists. Run it in blocklist mode to stop known-bad hosts, or flip block_all on and run it in allowlist mode to permit only a curated set of domains.
What is this?
A rule that scans every URL in a message and either blocks domains on your blocklist or allows only domains on your allowlist. It handles URLs hidden inside Discord markdown links, so a sneaky [click here](https://bad.example) still gets caught.
Why you might want it
For the shady redirect links that get posted in welcome channels and the scam URLs that keep landing in DMs. Most servers run a small blocklist of known-bad hosts and call it done. Servers with stricter rules flip allowlist mode on and only permit YouTube, Twitch, and a short list of trusted domains.
http://, https://, and bare www. forms).Why use this rule?
- Stops scam links, IP-grabber sites, and phishing pages before they spread.
- Lets you run a locked-down server where only a handful of trusted domains are postable.
- Handles URLs hidden inside Discord markdown like
[click here](https://bad.example)— the URL is still in the message content. - Pairs well with Word Filter: a word list catches the pitch, a link list catches the payload.
What it detects
URLs extracted from the message text. The evaluator runs a regex that finds every http://, https://, or bare www. URL, parses the hostname (lowercased), and compares it to your lists. The first URL that matches your policy fires the rule and is recorded as matched_pattern.
https://suspicious-link.ru/offer (hostname suspicious-link.ru in blocked_domains). Action: delete.What it does NOT detect
- URLs inside embeds or attachment metadata — only the message's text content is scanned.
- Non-HTTP schemes like
ftp://,ws://,mailto:, orsteam://. - Bare domains typed without a scheme or
www.prefix —youtube.comon its own is not picked up, onlyhttps://youtube.comorwww.youtube.com. - URL shorteners —
bit.ly/xyzis compared asbit.ly, not resolved to the destination. - Homoglyph domains — a lookalike like
раураl.com(Cyrillic letters) is treated as its own distinct hostname.
Configuration
| Field | Type | Default | What it means |
|---|---|---|---|
| block_all | boolean | false | When on, every URL is blocked unless its hostname appears in allowed_domains. When off, the rule only fires on URLs whose hostname is in blocked_domains. |
| blocked_domains | list of strings | [] | Exact hostnames to block. Used only when block_all is off. Compared case-insensitively against the parsed hostname. |
| allowed_domains | list of strings | [] | Exact hostnames to permit. Used only when block_all is on. Compared case-insensitively against the parsed hostname. |
youtube.com in a list does not cover m.youtube.com, music.youtube.com, or www.youtube.com. Each subdomain must be listed explicitly.Two modes of operation
Pick the mode that matches your server's risk profile:
- Blocklist mode (
block_all: false) — URLs pass by default; only hostnames inblocked_domainsfire the rule. Best for permissive community servers where you want to stop scam and IP-logger hosts without restricting normal sharing. - Allowlist mode (
block_all: true) — URLs fire by default; only hostnames inallowed_domainspass. Best for locked-down servers, kids' servers, or support-only channels where the full list of acceptable domains is short and known.
block_all is off and blocked_domains is empty, the rule extracts URLs but never fires. If the Event Log shows no matches, check that one of the two modes is actually configured.Recommended starter settings
Permissive server — block a handful of known-bad hosts:
{
"block_all": false,
"blocked_domains": [
"grabify.link",
"iplogger.org",
"bit.ly"
],
"allowed_domains": []
}Strict server — allow only trusted domains:
{
"block_all": true,
"blocked_domains": [],
"allowed_domains": [
"youtube.com",
"www.youtube.com",
"discord.com",
"github.com",
"x.com"
]
}Run with Mode: Log Only until you have watched the Event Log for a week and tuned anything noisy. Then flip to Live.
Common false positives
- Strict mode and subdomains —
m.youtube.comis blocked when onlyyoutube.comis allowed. List every subdomain your members actually use. www.vs bare domain —https://www.example.comparses to hostnamewww.example.com, whilehttps://example.comparses toexample.com. List both forms.- URLs inside code blocks — a URL wrapped in backticks is still extracted and checked. Staff posting scam examples for review can trigger the rule on themselves unless exempt.
- Trailing punctuation — the extractor includes trailing
.,,,!, and?in the URL string, somatched_patternmay look slightly off in the Event Log. - Masked links —
[safe text](https://bad.example)is still matched because the raw URL remains in the message 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.
Pick a harmless test domain
Add example.com to blocked_domains. It is a reserved domain for documentation and testing, so there is no real-world traffic to disrupt.
Post a test URL
In a private channel, post "Check out https://example.com/foo". Check the Event Log dashboard — you should see an entry with matched_pattern = https://example.com/foo.
Confirm an unrelated URL passes
Post "And https://example.org/foo". No Event Log entry should appear — only exact hostname matches fire.
Confirm allowlist and exempt roles work
Add the URL (or a fragment of it) 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 domain and flip to Live
Drop example.com from the blocklist and switch the rule from Log Only to Live.
Known current behavior
- Current behavior: hostname matching is exact, not subdomain-aware.
youtube.comin a list does not coverm.youtube.com,music.youtube.com, orwww.youtube.com. Each subdomain must be added explicitly. - Current behavior: only
http://,https://, andwww.URLs are extracted. A bare domain written asyoutube.comwith no prefix passes through untouched. - Current behavior: URL extraction uses a 50ms regex timeout per call. On pathological inputs (extremely long messages or adversarial patterns), extraction is skipped for that message and the rule does not fire.
- Current behavior:
matched_patternis the full raw URL that triggered the rule, not just the hostname. The URL ends up in the Event Log visible to staff — avoid pasting live scam or phishing URLs into test rules. - Current behavior: query strings and paths are irrelevant — only the hostname is compared against your lists.
https://example.com/abc?token=xyzandhttps://example.comare treated the same. - Current behavior: allowlist words apply to this trigger. If any allowlist word appears anywhere in the message (substring-matched, lowercase), the rule is skipped entirely. This is the rule-level word allowlist — do not confuse it with
allowed_domains, which is the Link Filter's own hostname list. - Current behavior: with
block_all: falseand an emptyblocked_domains, the rule never fires. URLs are still extracted, but no decision applies. If you see no matches, confirm one of the two modes is populated.
Action reference
Pair this trigger with any of the five AutoMod actions. delete is the most common pairing for link filtering; mute with a short duration is a good follow-up for repeat offenders (combine with per_user_cooldown_seconds to avoid chain-mutes).
delete, warn, mute, strike, and ban actually do, plus every action_config field and required Discord permission.