Automations - Conditions Reference
Conditions decide whether a rule's actions run. A rule with no conditions runs every time its trigger fires.
Groups, AND, OR and NOT
The Condition builder in the rule editor works in two levels:
- Conditions inside a group combine with the group's Match switch: AND (every condition must pass) or OR (any one is enough).
- Groups combine with Groups must AND / OR match to fire at the top.
- NOT on a condition inverts it: User has any of these roles with NOT passes for members who have none of those roles.
Click Add Condition inside a group for another condition, and Add Condition Group for another group. An empty group always passes.
A new rule starts with no conditions, so it runs every time its trigger happens until you add some. The editor only offers the conditions and actions its trigger can use: picking another trigger removes the ones the new trigger cannot use and says which.
For example, "the message contains discord.gg/ or discord.com/invite/, and the author is not a moderator" is two groups: Group 1 (Match OR) with the two content conditions, and Group 2 with the role condition set to NOT, joined with AND.
Conditions
The conditions are grouped as in the editor's picker, where you can also search them by name or by what they check. Offered on lists the triggers whose rules can use the condition.
Channel & Thread
Where the event happened, and the thread or channel itself.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Channel is | The channel the event happened in. A message in a thread counts for its parent channel too. | on_message, on_invite_create, every message spam trigger, both reaction triggers | in_channel |
| Channel category is | The category of the event's channel. | on_message, on_channel_create, on_thread_create_spam, every message spam trigger, every on_thread_* trigger, both reaction triggers | in_category |
| Channel type is | The kind of channel the event happened in. | on_message, on_thread_create, on_channel_create, every message spam trigger, both reaction triggers | channel_type |
| Channel is a thread | The event happened in a thread or a forum post. | on_message, every message spam trigger, both reaction triggers | is_thread |
| Thread is archived | Whether the thread is archived. | on_message, on_thread_create, on_thread_delete, on_thread_update, every message spam trigger, both reaction triggers | thread_archived |
| Thread is locked | Whether the thread is locked. | on_message, every message spam trigger, every on_thread_* trigger, both reaction triggers | thread_locked |
| Thread is private | Private threads only (members see them when invited), or public ones only. | on_thread_create_spam, every on_thread_* trigger | thread_is_private |
| Thread is in channel | The channel or forum the thread was made in. | on_thread_create_spam, every on_thread_* trigger | thread_in_channel |
| Thread name contains text | Matches when the thread's or forum post's title contains any of these. | on_thread_create_spam, every on_thread_* trigger | thread_name_contains |
| Forum post has tags | Tags the forum post has, such as Solved or Bug. | on_thread_create_spam, every on_thread_* trigger | forum_post_tags |
| Channel name contains text | Matches when the new channel's name contains any of these. | on_channel_create | channel_name_contains |
| Channel name matches pattern | A regular expression the new channel's name must match. | on_channel_create | channel_name_matches |
Message
The message's text, links, invites, files, mentions and kind.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Content contains text | Matches when the text contains any of these anywhere. Paste a list to add one per line. | on_message, every message spam trigger, both reaction triggers | content_contains |
| Content contains whole word | Matches any of these as a whole word (scam, not scampi). | on_message, every message spam trigger, both reaction triggers | content_contains_word |
| Content matches pattern | A regular expression the text must match. | on_message, every message spam trigger, both reaction triggers | content_matches |
| Content starts with | Matches when the text starts with any of these. | on_message, every message spam trigger, both reaction triggers | content_starts_with |
| Content ends with | Matches when the text ends with any of these. | on_message, every message spam trigger, both reaction triggers | content_ends_with |
| Content longer than | Messages longer than this many characters. | on_message, every message spam trigger, both reaction triggers | content_length_gt |
| Content shorter than | Messages shorter than this many characters. | on_message, every message spam trigger, both reaction triggers | content_length_lt |
| Has attachments | The message has at least one file. | on_message, every message spam trigger, both reaction triggers | has_attachments |
| Attachment type includes | The kinds of file the message has. | on_message, every message spam trigger, both reaction triggers | attachment_type |
| Attachment MIME type is | The files' types as the uploader's device named them. | on_message, every message spam trigger, both reaction triggers | attachment_mime_type |
| Attachment count is at least | Messages with at least this many files. | on_message, every message spam trigger, both reaction triggers | attachments_count_gte |
| Attachment is larger than | A file in the message is bigger than this. | on_message, every message spam trigger, both reaction triggers | attachment_larger_than |
| Has embeds | The message has an embed (a link preview counts). | on_message, every message spam trigger, both reaction triggers | has_embeds |
| Has mentions | The message mentions a member or a role. | on_message, every message spam trigger, both reaction triggers | has_mentions |
| Mentions at least | Members and roles mentioned in the message, each counted once (a pinged reply counts its author). | on_message, every message spam trigger, both reaction triggers | mention_count_gte |
| Mentions any of these | The message mentions one of these members or roles (a pinged reply counts its author). | on_message, every message spam trigger, both reaction triggers | mentions_any |
| Mentions @everyone or @here | The message tries to ping everyone, also when its author is not allowed to. | on_message, every message spam trigger, both reaction triggers | mentions_everyone |
| Replies to | The message is a reply to a member with one of these roles, or to this bot. | on_message, every message spam trigger, both reaction triggers | replies_to |
| Contains links | The message has a link. The domain rules narrow it down. | on_message, every message spam trigger, both reaction triggers | has_links |
| Link contains domain text | A link's domain contains any of these pieces of text. | on_message, every message spam trigger, both reaction triggers | link_matches_domain |
| Link matches these domain rules | A link that the domain, word and pattern rules pick out. | on_message, every message spam trigger, both reaction triggers | link_filter |
| Link is a known phishing or malware site | A link to a site on the FishFish list of phishing and malware domains. | on_message, every message spam trigger, both reaction triggers | link_is_malicious |
| Contains a masked link | A link hidden behind text, like free nitro: a common phishing trick. | on_message, every message spam trigger, both reaction triggers | has_masked_link |
| Contains Discord invites | The message has a Discord invite. The server and code rules narrow it down. | on_message, every message spam trigger, both reaction triggers | has_invites |
| Invite matches these rules | An invite that the server and code rules pick out. | on_message, every message spam trigger, both reaction triggers | invite_filter |
| Has stickers | The message has a sticker. | on_message, every message spam trigger, both reaction triggers | has_stickers |
| Is a reply | The message replies to another message. | on_message, every message spam trigger, both reaction triggers | is_reply |
| Message is a system message | A message Discord posts, such as a join, boost or pin notice. | on_message, on_spam_detected, on_message_spam, on_mention_spam, on_link_spam, on_attachment_spam, on_emoji_spam, both reaction triggers | message_is_system |
| Author is a webhook | The message was posted by a webhook. | on_message, every message spam trigger, both reaction triggers | message_author_is_webhook |
| Message is a forward, poll or voice message | Matches any of the kinds you tick. | on_message, every message spam trigger, both reaction triggers | message_kind |
| Message is one of | Only these messages (paste their links or IDs): reaction roles, or a rules message people react to. For messages sent, it matches edits of them. | on_message, both reaction triggers | message_is |
| Message was edited | An edit, with Also check edited messages on. With NOT, new messages only. | on_message | message_is_edit |
| Is the member's first message | The first message the member ever sent in this server, counted since this condition existed (members who posted before are never counted as new). | on_message | first_message |
| Mostly capital letters | Shouting: at least this share of the message's letters are capitals, in a message with at least this many letters. | on_message, every message spam trigger, both reaction triggers | mostly_caps |
| Emoji count is at least | Emoji in the message: every emoji once (a family or a flag is one), server emoji included. | on_message, every message spam trigger, both reaction triggers | emoji_count_gte |
| Line count is at least | Lines in the message: tall messages that push the chat off screen. | on_message, every message spam trigger, both reaction triggers | line_count_gte |
| Contains spoilers or code | Matches any of the kinds you tick. A spoiler file counts as a spoiler. | on_message, every message spam trigger, both reaction triggers | has_formatting |
| Uses emojis from other servers | A custom emoji that is not one of this server's (Nitro members can post emoji from any server they are in). | on_message, every message spam trigger, both reaction triggers | external_emojis |
| Contains zalgo or invisible characters | Glitch text and characters that show nothing, often used to slip past word filters. | on_message, every message spam trigger, both reaction triggers | weird_text |
Reaction
The reaction and the message it is on.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Reaction emoji is | The emoji added or removed: any of these. | both reaction triggers | reaction_emoji |
| Reaction count is at least | The message has at least this many of the emoji now: a starboard, or a vote that passes. | both reaction triggers | reaction_count_gte |
| Message author has any of these roles | Who wrote the message reacted to (not who reacted): reactions on staff messages. | both reaction triggers | message_author_has_role |
| Message was sent by this bot | Reactions on the bot's own messages, such as a panel it posted. | both reaction triggers | message_author_is_bot |
| Reacted to their own message | The member reacted to a message they wrote: self-votes on a starboard or a poll. | both reaction triggers | reacted_to_own_message |
Member
Who the member is: roles, permissions, account, names, status and history.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| User is one of | Matches these users, also when they are no longer members (bans and unbans). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_mod_* trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_is |
| User has any of these roles | The member has at least one of these roles. | on_message, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_has_role |
| User has all of these roles | The member has every one of these roles. | on_message, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_has_all_roles |
| User has no roles | The member has no role at all besides @everyone, such as members who were never verified. | on_message, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_has_no_roles |
| User is a bot | A bot account (with NOT: people only). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_is_bot |
| User is bot staff | Has one of the server's staff roles (Settings > Permission Roles), or is an admin. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_is_staff |
| User is a bot admin | Has one of the server's admin roles, Administrator, or owns the server. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | user_is_admin |
| User has these permissions | Discord permissions the member has (in the event's channel), for example to leave moderators alone with NOT. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_has_permission |
| User joined within | Members who joined the server less than this long ago. | on_message | user_joined_within |
| Account age is less than | Accounts created less than this long ago, for example 1 hour to catch brand-new accounts on join. | on_message, on_member_join | user_account_age_lt |
| Uses the default avatar | No profile picture of their own: raid and spam accounts often have none. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_mod_* trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | default_avatar |
| Discord flags them as a likely spammer | Discord marks some accounts as likely spammers; catch them as they join. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_mod_* trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | likely_spammer |
| Has not accepted the rules yet | Still pending Discord's membership screening (Rules Screening in the server's settings). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_pending |
| User is boosting | The member boosts the server. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_is_premium_subscriber |
| Boosting for at least | The member has boosted the server for at least this long: reward long-time boosters. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | boosting_for |
| Joined with this invite | The invite they joined with, or who made it (needs the bot's Manage Server permission to see invites). The rule waits a moment while the bot works it out. | on_member_join | joined_with_invite |
| Has been in the server before | The member was in the server before (as far as the bot has seen them), for rejoins. | on_member_join | rejoined |
| User has nickname | The member set a server nickname. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_has_nickname |
| User name contains text | Matches when a name contains any of these. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_name_contains |
| User name matches pattern | A regular expression on their username, display name or nickname. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_name_matches |
| Custom status contains text | Matches when their custom status contains any of these (needs the presences intent). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_status_contains |
| Online status is | Their status right now: any of the ones you tick. Needs the presences intent (without it everyone reads as offline). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_status_is |
| Activity contains text | What they are playing, streaming or listening to contains any of these (needs the presences intent). | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | activity_contains |
| Is in a voice channel | The member is in a voice channel now: one of these, or any when none is picked. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | in_voice_channel |
| Server tag is | The server tag Discord shows next to their name: this server's, or one of these tags. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_mod_* trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | server_tag |
| Activity rule score is at least | Select an activity rule and require the member to be at or above that score. Needs the Analytics module. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, on_spam_detected, on_message_spam, on_mention_spam, on_link_spam, on_attachment_spam, on_emoji_spam, on_line_spam, on_character_spam, every on_thread_* trigger, both reaction triggers, both level-up triggers | activity_score_gte |
| Activity rule score is below | Select an activity rule and require the member to be below that score. Needs the Analytics module. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, on_spam_detected, on_message_spam, on_mention_spam, on_link_spam, on_attachment_spam, on_emoji_spam, on_line_spam, on_character_spam, every on_thread_* trigger, both reaction triggers, both level-up triggers | activity_score_lt |
| Level is | Their level in the Levels module: from a level on, or below it. Needs the Levels module. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | member_level |
| Infractions are at least | Repeat offenders: their infraction points now (after decay), or how many moderation cases they have (warnings, timeouts, kicks, bans...; notes, lifted punishments and voided cases do not count). Needs the Moderation module. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, every message spam trigger, every on_mod_* trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | infractions |
| Birthday is today | It is their birthday today in their timezone (or the server's), from the Birthdays module. Needs the Birthdays module. | on_message, on_member_join, on_member_leave, on_member_update, on_voice_state, on_invite_create, on_custom_status_update, on_mod_warn, on_mod_timeout, on_mod_kick, on_mod_ban, on_mod_untimeout, on_mod_note, every message spam trigger, every on_thread_* trigger, both reaction triggers, both level-up triggers | birthday_today |
Member changes
What changed about the member.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Member was given a role | The member was given one of these roles, or any role when none is picked. | on_member_update | role_added |
| Member lost a role | The member lost one of these roles, or any role when none is picked. | on_member_update | role_removed |
| What changed is | The trigger fires for roles, nicknames and boosts: this picks which. Matches any you tick. | on_member_update | member_change_is |
| Started or stopped boosting | The member started boosting the server (thank them), or stopped. | on_member_update | boost_changed |
Voice
Voice channels and what the member did in them.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Voice channel is | The voice channel joined or moved to, or the one left. | on_voice_state | voice_channel_is |
| Voice action is | What the member did: any of the ones you tick. | on_voice_state | voice_action |
| Came from voice channel | The channel they were in before: a move or a leave out of one of these. | on_voice_state | came_from_voice_channel |
| Voice channel has members | How many are in the channel now: the one joined or moved to, or the one left (0 or fewer: it just emptied). | on_voice_state | voice_channel_members |
| Was in voice for at least | On a leave: how long they were in voice (moves included). Not known for someone who joined before the bot started. | on_voice_state | voice_session_at_least |
Moderation
The moderation case: who, why and how long.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Moderator is | Who took the action: one of these members, or a member with one of these roles. For a case the bot made itself, the bot. | every on_mod_* trigger | moderator_is |
| Reason contains text | The case's reason (or the anti-raid level change's) contains any of these. | on_antiraid_level, every on_mod_* trigger | reason_contains |
| Duration is at least | Timeouts and bans at least this long. A ban without an end counts as longer than any. | on_mod_timeout, on_mod_ban | duration_at_least |
Levels & Anti-raid
The level reached and the anti-raid level.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Level reached is | The level the member just reached: exactly one, from one on, or every so many levels (every 5: levels 5, 10, 15...). | both level-up triggers | level_reached |
| Anti-raid level is | Match one exact anti-raid level. | every trigger | antiraid_level_is |
| Anti-raid level is at least | Match anti-raid levels at or above this threshold. | every trigger | antiraid_level_gte |
| Anti-raid level went | Whether the level was raised or lowered: different rules for each. | on_antiraid_level | antiraid_direction |
| Anti-raid level changed by | A staff member (the command or the dashboard), or the bot on its own (the detector, decay or an automation rule). | on_antiraid_level | antiraid_changed_by |
Role & Invite
The role updated or the invite created.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Role is | The role that was updated is one of these. | on_role_update | role_is |
| Role gained these permissions | The update gave the role these permissions: an alert when a role gets Administrator or another dangerous one. | on_role_update | role_gained_permissions |
| Role became mentionable or hoisted | Settings that change who can ping the role or how it shows in the member list. Matches any you tick. | on_role_update | role_setting_changed |
| Invite never expires or has no use limit | Spot permanent invites: matches when the invite is everything you tick. | on_invite_create | invite_is_unlimited |
Time & Chance
The time and date in the server's timezone, and luck.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Time of day is between | From the start time up to the end time; a range past midnight (22:00 to 06:00) wraps to the next day. | every trigger | time_between |
| Day of week is | Today is one of these days. | every trigger | weekday_is |
| Date is between | From the first date through the last, every year: seasonal events. A range past New Year wraps. | every trigger | date_between |
| Random chance | Passes this share of the time: fun replies, small giveaways. | every trigger | random_chance |
Server
The whole server: members and boosts.
| Condition | What it checks | Offered on | Key |
|---|---|---|---|
| Member count is | The server's member count now: from a number on, exactly a number, or every so many (a multiple of 1,000 celebrates each thousand on join). | every trigger | member_count |
| Boost level is | The server's boost level now: any of the ones you tick. | every trigger | boost_level_is |
Words and phrases
Content contains text, Content contains whole word, Content starts with and Content ends with each take a list of words or phrases, and any one of them is enough. Type one and press Enter, or paste a list with one per line (or separated by commas). Content contains whole word matches scam but not scampi.
Under Matching options:
- Match case: off by default, so
SPAM,Spamandspamare the same. - Ignore formatting: removes Discord's formatting characters (
*,_,|,~and backticks) first, sob*a*d,__bad__and||b||adread asbad. - Normalize look-alike text: reads fancy fonts (
๐๐ซ๐๐), full-width letters, accents (frรฉe), look-alike Cyrillic and Greek letters, circled or boxed letters and hidden zero-width characters as plain letters. It also ignores case. The words in your list are folded the same way, so write them normally. - Read leetspeak (with normalize): also reads
4as a,3as e,1and!as i,0as o,5and$as s,7as t and@as a. Real numbers change too, so only turn it on for word lists where that does not matter. - Loose spacing: also matches words with up to the chosen number of spaces or
. , - _ ! ?between their letters, such asf r e eorf.r.e.e. A longer run of them splits the word. Spaces and punctuation inside a listed phrase are loose too, sofree nitroalso matchesfreenitroandfree-nitro.
A list holds up to 1000 words of up to 200 characters, 20000 characters in all. Words are looked up as plain text, never as one big pattern, so even a full list with loose spacing takes a few milliseconds on the longest message.
Match sources choose which text the condition reads: the message content (on by default), its embeds, and the author's username, display name, nickname and custom status. Names and status are always the message author's, also on reaction triggers.
Content matches pattern takes a regular expression (test yours on a site such as regex101.com). The pattern is checked when you save the rule, and a broken one is refused with the position of the mistake. A pattern may repeat something at most 1000 times (a{1000}), and repeats nested inside each other must stay small, since the bot writes them out before it can search. Each pattern condition gets 50 milliseconds per message. A pattern that takes longer leaves its condition undecided: it does not match, and with NOT (or inside None of) it does not pass either, so a slow pattern never lets a rule run. The first time, a bot alert names the rule; a condition that keeps running out of time is paused for a few minutes (only that condition, the rule's other conditions keep working) and another bot alert says so.
User name contains text and Custom status contains text take the same kind of list and matching options, for a member's names and custom status. Both work on any trigger with a member, not only on messages. User name matches pattern takes a regular expression for the names instead, with the same time limit as Content matches pattern. Thread name contains text, Channel name contains text, Activity contains text and Reason contains text take a word list too, with Whole words only to match bug but not debug.
Links
A link is a real link, starting with http:// or https://, as Discord shows it. Turn off Only real links (under Where to look) to also count bare domains such as example.com/page. Only names that end in a real top-level domain count, but some file names do too (setup.py, notes.zip).
Link matches these domain rules checks every link in the message on its own, so an allowed link never exempts a forbidden one next to it:
- Match listed domains: links to the domains under Domains to match match (an empty list matches a link to any domain). Links to Except these domains never match, but other links in the same message still do.
- Allow only listed domains: any link to a domain that is not listed matches, for example "every link except YouTube and Twitch".
- Include subdomains makes
cdn.example.comcount asexample.com. - Words and patterns match or skip links by any part of the address. Each link is checked in this order, and the first rule that applies decides: skipped patterns, matched patterns, skipped words, matched words, then the domains. When a match list is set, a link must hit one of them.
Contains links without settings matches any link; its settings are the same as Link matches these domain rules. Link contains domain text looks for pieces of text in the domain of each link.
Link is a known phishing or malware site checks each link, and the domains it sits under, against FishFish's list of scam sites, which the bot downloads every 6 hours. It needs a FishFish API key that only the bot owner can set (FISHFISH_API_KEY in the bot's config/.env), one key for every server on the bot: without it the condition shows unavailable in the editor and never matches.
Invites
Invite matches these rules (and Contains Discord invites with settings) checks every invite on its own. Formatting and spoilers around an invite link do not hide it.
- An ignored code or server exempts only that invite: a message with your own server's invite and another server's still matches.
- With Only match invite codes or Only match destination servers, only invites on those lists match.
- The server lists need the invite looked up. The bot looks up three new invites per message at most (answers are remembered for a few minutes); an expired invite, a group DM invite or one past those three counts as a match unless Ignore invites that cannot be checked is on. Rules saved with the old Allow group DM invites switch keep what it meant.
Attachments
Attachment type includes takes file extensions (png, exe) and the kinds image, video and audio, which cover every file of that kind. Attachment MIME type is takes types such as image/png, or image for every image type. Both have two modes:
- Match listed types: matches when any attachment is of a listed type.
- Allow only listed types: matches when any attachment is not, for example an
.exenext to a.pngwhen only images are allowed. A file without an extension counts as not listed.
Message shape and kind
- Mentions at least counts the members and roles a message mentions, each once; a reply that pings its author counts that author. Mentions any of these picks members and roles. Mentions @everyone or @here matches the words in the text, also when the author is not allowed to ping everyone and nobody was pinged.
- Replies to matches a reply to a member with one of the roles you pick, or to the bot itself.
- Mostly capital letters matches when at least the share you set of a message's letters are capitals, in a message with at least the number of letters you set. Mentions, server emoji and links do not count as letters, and neither do scripts without capitals.
- Emoji count is at least counts every emoji once (a family, a flag or a skin tone is one), server emoji included. Line count is at least counts a message's lines.
- Message is a forward, poll or voice message and Contains spoilers or code match any of the kinds you tick. A spoiler file counts as a spoiler, and
||text||inside a code block does not. - Contains a masked link matches a link hidden behind text, like
[free nitro](https://...). - Uses emojis from other servers matches a server emoji that is not one of this server's.
- Contains zalgo or invisible characters finds glitch text (three or more accent marks stacked on one letter) and characters that show nothing, such as zero-width spaces, fillers and direction marks. The joiners that build emoji (a family, a flag) do not count. It reads the message, and with its switches the author's names.
- Attachment is larger than takes a size in KB or MB.
- Is the member's first message matches the first message a member ever sends in the server. The bot remembers who has posted from the update that added this condition on: members who joined before it are never counted as new, and members who join after are counted on their first message.
- Message was edited matches edits on a rule with Also check edited messages on; with NOT, only new messages.
- Message is one of takes message links (or IDs), for reaction roles or a rules message people react to. On When a message is sent it matches edits of those messages.
Reactions
- Reaction emoji is matches the emoji added or removed.
- Reaction count is at least reads how many of that emoji the message has now: a starboard, or a vote that passes. On When a reaction is removed it is the count after the removal.
- Message author has any of these roles and Message was sent by this bot check who wrote the message reacted to, not who reacted. Reacted to their own message catches self-votes.
Members
- User is one of matches the members you pick. On moderation triggers it also works for someone who is no longer a member (a ban after they left, an unban).
- User is bot staff and User is a bot admin use the bot's own levels: the staff and admin roles from the server settings, plus Manage Server (staff) and Administrator or server ownership (admin). With NOT they are the usual way to leave staff alone.
- User has these permissions checks Discord permissions, any or all of them. When the event has a channel, that channel's permission overrides count.
- User joined within and Account age is less than take an amount and a unit (seconds, minutes, hours or days), so a join rule can catch accounts less than an hour old. Rules saved before the unit existed keep reading seconds and days.
- Custom status contains text needs the presences intent, which the bot owner turns on in the bot's settings and the Discord Developer Portal; without it no status is seen. The trigger When a member changes their custom status fires when a member sets or changes a status (also when they come online with one), not when they clear it. Online status is and Activity contains text (the game, stream or song, not the custom status) need it too; without it everyone reads as offline with no activity.
- User has all of these roles needs every role you pick; User has no roles matches members with only @everyone.
- Uses the default avatar, Discord flags them as a likely spammer and Has not accepted the rules yet (Discord's membership screening) are quick checks for new accounts on join.
- Is in a voice channel matches a member in one of the voice channels you pick, or in any when none is picked.
- Server tag is reads the tag Discord shows next to a member's name: this server's tag, or tags you type.
- Boosting for at least reads how long the member has boosted the server.
- Level is reads the member's level in the Levels module (text, voice or both combined), Infractions are at least their infraction points or cases in the Moderation module (voided cases do not count) and Birthday is today the Birthdays module, in the member's own timezone or else the server's. Each needs its module on in the server, and passes for nobody while it is off.
- Joined with this invite (on When a member joins) matches the invite codes you list, invites made by the members you pick, or the server's vanity link. The bot finds the invite by comparing the invites' use counts, which needs its Manage Server permission. Has been in the server before matches a member the bot has seen in the server before, from an earlier join or a command. Join rules wait up to a few seconds while the bot works both out, so their variables
{invite.code},{inviter}and{member.rejoined}are filled in too.
Member changes and voice
- When a member changes fires when a member's roles or nickname change, and when they start or stop boosting. What changed is tells those apart, and Started or stopped boosting picks a direction. Member was given a role and Member lost a role match the role that was just added or removed.
- Voice action is matches any of the actions you tick: joined, left, moved, muted or deafened themselves (and back), was server muted or deafened (and back), started or stopped streaming, turned their camera on or off. Joining while muted is a join, not a mute.
- Came from voice channel matches a move or a leave out of one of the channels you pick.
- Voice channel has members counts the people in the channel joined or moved to, or in the one left (At most 0: it just emptied). Bots count only with Count bots too.
- Was in voice for at least reads how long a member was in voice when they leave, moves included. It is not known for someone who joined before the bot started, so it does not pass for them.
Moderation, levels and anti-raid
- Moderator is matches actions by the members or roles you pick. For a case the bot made itself (an automation rule, a threshold), the moderator is the bot.
- Duration is at least reads the timeout or ban length; a ban without an end counts as longer than any.
- Level reached is reads the level from the level-up triggers: exactly one, from one on, or every so many levels (every 5: levels 5, 10, 15...).
- Anti-raid level is / is at least read the Moderation module's current anti-raid level, and every trigger offers them. To make a rule behave differently at each level, make one rule per level. On When the anti-raid level changes, Anti-raid level went tells a raise from a drop, and Anti-raid level changed by a staff member's change from the bot's own (the detector, decay or an automation rule).
Roles, invites and channels
- Role is, Role gained these permissions (any or all of the ones you pick) and Role became mentionable or hoisted read the role on When a role is updated: an alert when a role gets Administrator, for example.
- Invite never expires or has no use limit (on When an invite is created) matches an invite that is everything you tick.
- Channel name contains text and Channel name matches pattern read the name of a channel just created.
Time, chance and the server
- Time of day is between, Day of week is and Date is between read the time in the timezone the condition shows, which is the server's when you add the condition. A time range past midnight (22:00 to 06:00) and a date range past New Year (December 20 to January 5) wrap. Every trigger offers them, scheduled rules included.
- Random chance passes the share of the time you set, for fun replies and small giveaways. The rule tester and
/automations debugtake it as passing. - Member count is reads the server's member count now: from a number on, exactly a number, or a multiple of one (a multiple of 1000 on When a member joins celebrates every thousandth member). Boost level is reads the server's boost level.
More notes
- Activity rule score is at least / is below read a member's score in an Analytics activity rule.
- A condition that needs a module shows unavailable in the picker when that module is off on this bot, and never passes until it is on, with NOT neither.
- On the thread triggers, the member conditions check the thread's creator.
- Author is a webhook and User is a bot can only match on When a message is sent for a rule with Include bots and webhooks on: other rules never see those messages. For a webhook's message, User is and User is a bot read the webhook (Discord marks webhooks as bots); the member conditions do not pass, since a webhook is no member.
- The editor only offers conditions that fit the trigger. A condition that cannot be checked for a particular event does not pass: a member condition when the person is no longer a member (a thread whose creator left, a timeout lifted after they left) or the message came from a webhook, a content condition without a message. With NOT set, such a condition passes instead, so NOT User has any of these roles also matches a webhook.