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
Blocklist or Allowlist — Your Choice

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.

Setup time: about 5 minutesDifficulty: Easy. Most users get through it first try.
How this rule works
Checks:URLs found in the message's text content (http://, https://, and bare www. forms).
Triggers when:A URL's hostname matches your blocklist, or (in allowlist mode) fails to match your allowlist.
Ignores:Exempt roles, exempt channels, and allowlist words (Link Filter is a content-match trigger, so allowlist entries short-circuit the rule if the message contains any of them).
Counts toward spam buffers:No — this trigger is per-message, not volumetric.

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.

Example Match
S
scammer42Today at 21:07
free nitro here https://suspicious-link.ru/offer
AutoMod: matched URL 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:, or steam://.
  • Bare domains typed without a scheme or www. prefix — youtube.com on its own is not picked up, only https://youtube.com or www.youtube.com.
  • URL shorteners — bit.ly/xyz is compared as bit.ly, not resolved to the destination.
  • Homoglyph domains — a lookalike like раураl.com (Cyrillic letters) is treated as its own distinct hostname.

Configuration

FieldTypeDefaultWhat it means
block_allbooleanfalseWhen 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_domainslist of strings[]Exact hostnames to block. Used only when block_all is off. Compared case-insensitively against the parsed hostname.
allowed_domainslist of strings[]Exact hostnames to permit. Used only when block_all is on. Compared case-insensitively against the parsed hostname.
ℹ️
Note
Hostname matching is exact. 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 in blocked_domains fire 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 in allowed_domains pass. Best for locked-down servers, kids' servers, or support-only channels where the full list of acceptable domains is short and known.
⚠️
Warning
When both 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 subdomainsm.youtube.com is blocked when only youtube.com is allowed. List every subdomain your members actually use.
  • www. vs bare domainhttps://www.example.com parses to hostname www.example.com, while https://example.com parses to example.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, so matched_pattern may 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

1

Set the rule to Log Only

Log Only records matches without taking any action. It is the right starting point for every AutoMod rule.

2

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.

3

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.

4

Confirm an unrelated URL passes

Post "And https://example.org/foo". No Event Log entry should appear — only exact hostname matches fire.

5

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.

6

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.com in a list does not cover m.youtube.com, music.youtube.com, or www.youtube.com. Each subdomain must be added explicitly.
  • Current behavior: only http://, https://, and www. URLs are extracted. A bare domain written as youtube.com with 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_pattern is 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=xyz and https://example.com are 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: false and an empty blocked_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).

💡
Tip
See: AutoMod Actions → for the canonical reference on what delete, warn, mute, strike, and ban actually do, plus every action_config field and required Discord permission.