-
Notifications
You must be signed in to change notification settings - Fork 2
Extension: automod
Automate a variety of moderation tasks.
-
database
: The database configuration. This must be set explicitly, as it otherwise defaults to an in-memory cache that does not persist data.
A rule is a piece of logic detailing how to perform an automated task.
Rules are comprised of three main components: triggers, conditions, and actions. This is how they are processed:
- A rule will trigger when any of its triggers fire.
- When a rule is triggered, it will check all of its conditions in sequence.
- If all of a rule's conditions pass, it will run all of its actions in sequence.
Here's what a basic rule looks like:
name: Forbid owo
description: Delete owo and warn the author
triggers:
- type: message_sent
description: Whenever a message is sent
conditions:
- type: message_content_matches
description: If it contains the word owo
matches:
- pattern: \bowo\b
ignore_case: true
use_search: true
actions:
- type: reply_to_message
description: Warn the author
content: owo is forbidden on this server
The following fields are available on rules:
-
name: str
- The name of the rule. Can be any arbitrary string, but snake_case tends to be easier to type into chat.
-
disabled: bool
- Whether the rule is currently disabled. Defaults to false.
-
description: Optional[str]
- A human-readable description of the rule.
-
log: Optional[LogOptions]
- Override logging configuration for this rule.
-
triggers: List[Trigger]
- A list of events that may trigger the rule.
-
conditions: List[Condition]
- A list of conditions that must all pass for the actions to run.
-
actions: List[Action]
- A list of actions that will all run if the conditions pass.
All triggers have the following fields:
-
description: Optional[str]
- A human-readable description of the trigger.
Available triggers:
member_joined
member_left
member_typing
member_updated
message_deleted
message_edited
message_sent
message
reaction_added
reaction_removed
reaction_removed
reaction
thread_created
thread_updated
user_banned
user_unbanned
user_updated
Fires when an on_member_join
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_join
Fires when an on_member_remove
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_remove
Fires when an on_typing
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_typing
Additional fields:
-
channel_types: Optional[ChannelTypesGuard]
- The channel types to match against. If empty, all channel types will match.
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
roles: Optional[RolesGuard]
- The roles to match against. If empty, all roles will match.
Fires when an on_member_update
event is received.
This occurs when one or more of the following things change:
- status
- activity
- nickname
- roles
- pending
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_update
Additional fields:
-
roles: Optional[RolesGuard]
- The roles to match against. If empty, all roles will match.
Fires when mentions are removed from a message.
This triggers listens for on_message_edit
and on_message_delete
events, and uses different logic based on which type of event was received.
This can be used for detecting suspected ghost pings.
Additional fields:
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
author_roles: Optional[RolesGuard]
- The author roles to match against. If empty, all roles will match.
-
victim_roles: Optional[RolesGuard]
- The victom roles to match against. If empty, all roles will match.
Event metadata:
-
removed_user_mentions: str
- Space-delimited mentions of all users that were mentioned.
-
removed_user_mention_names: str
- Space-delimited names of all users that were mentioned.
-
removed_role_mentions: str
- Space-delimited mentions of all roles that were mentioned.
-
removed_role_mention_names: str
- Space-delimited names of all roles that were mentioned.
-
removed_mentions: str
- Space-delimited mentions of all users and roles that were mentioned.
-
removed_mention_names: str
- Space-delimited names of all users and roles that were mentioned.
Fires when an on_message_delete
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_message_delete
Otherwise identical to message
.
Fires when an on_message_edit
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_message_edit
Otherwise identical to message
.
Fires when an on_message
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_message
Otherwise identical to message
.
Fires when an on_message
or on_message_edit
event is received.
See:
- https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_message
- https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_message_edit
Additional fields:
-
content: Optional[str]
- The exact message content to match. If provided, the message must match one of these strings exactly. For more complex/flexible matching logic, consider using the
message_content_contains
ormessage_content_matches
conditions.
- The exact message content to match. If provided, the message must match one of these strings exactly. For more complex/flexible matching logic, consider using the
-
channel_types: Optional[ChannelTypesGuard]
- The channel types to match against. If empty, all channel types will match.
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
author_roles: Optional[RolesGuard]
- The author roles to match against. If empty, all roles will match.
Fires when an on_reaction_add
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_reaction_add
Additional fields:
-
reactions: Optional[ReactionsGuard]
- The reactions to match against. If empty, all reactions will match.
-
channel_types: Optional[ChannelTypesGuard]
- The channel types to match against. If empty, all channel types will match.
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
author_roles: Optional[RolesGuard]
- The author roles to match against. If empty, all roles will match.
-
actor_roles: Optional[RolesGuard]
- The actor roles to match against. If empty, all roles will match.
Fires when an on_reaction_remove
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_reaction_remove
Additional fields:
-
reactions: Optional[ReactionsGuard]
- The reactions to match against. If empty, all reactions will match.
-
channel_types: Optional[ChannelTypesGuard]
- The channel types to match against. If empty, all channel types will match.
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
author_roles: Optional[RolesGuard]
- The author roles to match against. If empty, all roles will match.
-
actor_roles: Optional[RolesGuard]
- The actor roles to match against. If empty, all roles will match.
Fires when an on_thread_create
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html#discord.on_thread_create
Additional fields:
-
parent_channels: Optional[ChannelsGuard]
- The parent channels to match against. If empty, all channels will match.
Fires when an on_thread_update
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html#discord.on_thread_update
Additional fields:
-
parent_channels: Optional[ChannelsGuard]
- The parent channels to match against. If empty, all channels will match.
Fires when an on_reaction_add
or on_reaction_remove
event is received.
See:
- https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_reaction_add
- https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_reaction_remove
Additional fields:
-
reactions: Optional[ReactionsGuard]
- The reactions to match against. If empty, all reactions will match.
-
channel_types: Optional[ChannelTypesGuard]
- The channel types to match against. If empty, all channel types will match.
-
channels: Optional[ChannelsGuard]
- The channels to match against. If empty, all channels will match.
-
author_roles: Optional[RolesGuard]
- The author roles to match against. If empty, all roles will match.
-
actor_roles: Optional[RolesGuard]
- The actor roles to match against. If empty, all roles will match.
Fires when an on_member_ban
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_ban
Fires when an on_member_unban
event is received.
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_unban
Fires when an on_user_update
event is received.
This occurs when one or more of the following things change:
- avatar
- username
- discriminator
See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_user_update
All conditions have the following fields:
-
description: Optional[str]
- A human-readable description of the condition.
Available conditions:
actor_account_age
actor_is_bot
actor_is_not_bot
actor_is_not_self
actor_is_self
actor_member_for
actor_roles
any_of
all_of
author_account_age
author_is_bot
author_is_not_bot
author_is_not_self
author_is_self
author_member_for
author_roles
member_for
message_content_contains
message_content_matches
message_has_attachments
message_has_embeds
message_has_links
message_has_mentions
message_mentions_roles
message_mentions_users
none_of
not
thread_auto_archive_duration
throw_error
wait
Check if the actor's account is a certain age.
Additional fields:
-
more_than: Optional[timedelta]
- The lower bound to check against, if any.
-
less_than: Optional[timedelta]
- The upper bound to check against,if any.
Check if the actor in context is a bot.
Check if the actor in context is not a bot.
Check if the actor in context is not the bot itself.
Check if the actor in context is the bot itself.
Check if the actor has been on the server for a certain amount of time.
Additional fields:
-
at_least: Optional[timedelta]
- The lower bound to check against, if any.
-
at_most: Optional[timedelta]
- The upper bound to check against,if any.
Check if the actor in context has certain roles.
Additional fields:
-
roles: RolesGuard
- The roles to match against.
Check if a number of sub-conditions pass (logical OR).
Additional fields:
-
conditions: Tuple[Condition]
- The sub-conditions to check.
-
count: Optional[int]
- The number of sub-conditions that must pass. If unspecified, only a single sub-condition is required to pass.
Check if all sub-conditions pass (logical AND).
Note that this is effectively equivalent to any_of
with a count
set to the number of sub-conditions. The distinction exists for clarity and convenience.
Additional fields:
-
conditions: Tuple[Condition]
- The sub-conditions to check.
Check if the author's account is a certain age.
Additional fields:
-
more_than: Optional[timedelta]
- The lower bound to check against, if any.
-
less_than: Optional[timedelta]
- The upper bound to check against,if any.
Check if the author in context is a bot.
Check if the author in context is not a bot.
Check if the author in context is not the bot itself.
Check if the author in context is the bot itself.
Check if the author has been on the server for a certain amount of time.
Additional fields:
-
at_least: Optional[timedelta]
- The lower bound to check against, if any.
-
at_most: Optional[timedelta]
- The upper bound to check against,if any.
Check if the author in context has certain roles.
Additional fields:
-
roles: RolesGuard
- The roles to match against.
Check if the member has been on the server for a certain amount of time.
Additional fields:
-
at_least: Optional[timedelta]
- The lower bound to check against, if any.
-
at_most: Optional[timedelta]
- The upper bound to check against,if any.
Check if message content contains a number of substrings.
Additional fields:
-
contains: Tuple[str]
- The substrings to find. Unless
count
is specified, all substrings must be found in order to pass.
- The substrings to find. Unless
-
count: Optional[int]
- The number of unique substrings to find. For example: a value of 1 requires any of the substrings to be found, whereas a value of 2 requires at least 2 to be found. If unspecified, all substrings must be found.
-
ignore_case: Optional[bool]
- Whether to ignore upper vs lower case.
-
use_normalization: Optional[bool]
- Whether to use unicode normalization or process the string as-is.
-
normalization_form: Optional[str]
- If enabled, the type of normalization to apply. Defaults to NFKD.
Check if message content matches a number of regular expressions.
Additional fields:
-
matches: Tuple[PatternWrapper]
- The patterns (regular expressions) to match. Unless
count
is specified, all patterns must be matched in order to pass.
- The patterns (regular expressions) to match. Unless
-
count: Optional[int]
- The number of unique patterns to match. For example: a value of 1 requires any of the patterns to be matched, whereas a value of 2 requires at least 2 to be matched. If unspecified, all patterns must be matched.
-
use_search: Optional[bool]
- Whether to search the entire string instead of using an anchored match.
-
use_normalization: Optional[bool]
- Whether to use unicode normalization or process the string as-is.
-
normalization_form: Optional[str]
- If enabled, the type of normalization to apply. Defaults to NFKD.
Check if the message has attachments.
Additional fields:
-
count: Optional[IntegerRange]
- The number of attachments to check for, if bounded.
Check if the message has embeds.
Additional fields:
-
count: Optional[IntegerRange]
- The number of embeds to check for, if bounded.
Check if the message has links.
Additional fields:
-
count: Optional[IntegerRange]
- The number of links to check for, if bounded.
Check if the message has mentions.
Additional fields:
-
count: Optional[IntegerRange]
- The number of mentions to check for, if bounded.
Check if the message contains role mentions.
Additional fields:
-
roles: Optional[RolesGuard]
- The roles to match against. If empty, all roles will match.
Event metadata:
-
mentioned_roles: str
- Space-delimited mentions of all roles that were mentioned.
-
mentioned_role_names: str
- Space-delimited names of all roles that were mentioned.
Check if the message contains user mentions.
Event metadata:
-
mentioned_users: str
- Space-delimited mentions of all users that were mentioned.
-
mentioned_user_names: str
- Space-delimited names of all users that were mentioned.
Passes if and only if none of the sub-conditions pass.
Additional fields:
-
conditions: Tuple[Condition]
- The sub-conditions to check.
Passes if any of the sub-conditions fail.
Additional fields:
-
conditions: Tuple[Condition]
- The sub-conditions to check.
Passes if the thread's auto archive duration is within the given range.
-
auto_archive_duration: IntegerRange
- The range of the auto archive duration to check.
Throw an error when checking the condition.
Intended for testing and debugging.
Additional fields:
-
error: str
- A human-readable error message.
Wait a certain amount of time before continuing.
Additional fields:
-
delay: Optional[timedelta]
- How long to wait for.
All actions have the following fields:
-
description: Optional[str]
- A human-readable description of the action.
Available actions:
add_reactions
add_roles_to_actor
add_roles_to_author
add_users_to_thread
check_messages
delete_message
dm_member
join_thread
log_message
remove_all_reactions
remove_own_reactions
remove_reactions
remove_roles_from_actor
remove_roles_from_author
reply_to_message
send_message
throw_error
wait
Add reactions to the message in context.
Additional fields:
-
reactions: Tuple[str]
- The reactions to add.
Add roles to the actor in context.
Additional fields:
-
roles: Tuple[RoleID]
- The roles to add.
-
reason: Optional[str]
- The reason why roles were added, if any.
Add roles to the author in context.
Additional fields:
-
roles: Tuple[RoleID]
- The roles to add.
-
reason: Optional[str]
- The reason why roles were added, if any.
Add users to the thread in context.
Additional fields:
-
users: Tuple[UserID]
- The users to add to the thread.
-
roles: Tuple[RoleID]
- The roles to add to the thread. Any user with any of these roles will be added.
Check recent messages and apply actions to those that pass the conditions.
Additional fields:
-
conditions: Tuple[AutomodCondition]
- The conditions to check messages against.
-
actions: Tuple[AutomodAction]
- The actions to apply to messages that pass the conditions.
-
lookup_limit: Optional[int]
- The number of messages to fetch and check. Defaults to 100.
-
channel: Optional[ChannelID]
- The channel to perform the search in. Defaults to the channel in context.
Delete the message in context.
Send a direct message to the member in question.
Additional fields:
-
content: str
- The content of the message to send.
Delete the message in context.
Additional fields:
-
name: Optional[str]
- The new name of the thread.
-
archived: Optional[bool]
- Whether to archive the thread or not.
-
locked: Optional[bool]
- Whether to lock the thread or not.
-
slowmode_delay: Optional[int]
- Specifies the slowmode rate limit for user in this thread, in seconds. A value of
0
disables slowmode. The maximum value possible is21600
.
- Specifies the slowmode rate limit for user in this thread, in seconds. A value of
-
auto_archive_duration: Optional[int]
- The new duration in minutes before a thread is automatically archived for inactivity. Must be one of
60
,1440
,4320
, or10080
.
- The new duration in minutes before a thread is automatically archived for inactivity. Must be one of
Join the thread in context.
Even though bots receive events for a thread, they are not listed as a member of the thread automatically. This can cause issues with sending messages; for example, the first message may be duplicated if the bot is not listed as a member of it.
Send a log message, with pings disabled by default.
Additional fields:
-
content: Optional[str]
- The content of the message to send.
-
channel: Optional[ChannelID]
- The channel to send the message in. Defaults to the channel in context.
-
emoji: Optional[str]
- The emoji used to represent the type of message.
-
color: Optional[Color]
- The emoji used to represent the type of message.
-
fields: Optional[Dict[str, str]]
- A custom set of fields to display as part of the message. The key should correspond to an event field, and the value is the title to use for it.
-
allowed_mentions: Optional[AllowedMentions]
- The types of mentions allowed in the message. Unless otherwise specified, all mentions will be suppressed.
Examples:
name: Member joined
description: Log when a member joins the server
triggers:
- type: member_joined
actions:
- type: log_message
content: "{member_mention} joined the server."
channel: 111222333444555666
emoji: ":wave:"
fields:
member_name: Name
member_id: ID
member_joined_at: Joined
member_created_at: Account created
name: Member left
description: Log when a member leaves the server
triggers:
- type: member_left
actions:
- type: log_message
content: "{member_mention} left the server."
channel: 111222333444555666
emoji: ":door:"
fields:
member_name: Name
member_id: ID
member_joined_at: Member since
member_for: Member for
Remove all reactions from the message in context.
Remove the bot's own reactions from the message in context.
Additional fields:
-
reactions: Tuple[str]
- The reactions to remove.
Remove certain reactions from the message in context.
Additional fields:
-
reactions: Tuple[str]
- The reactions to remove.
Remove roles from the actor in context.
Additional fields:
-
roles: Tuple[RoleID]
- The roles to remove.
Remove roles from the author in context.
Additional fields:
-
roles: Tuple[RoleID]
- The roles to remove.
Reply to the message in context.
Additional fields:
-
content: str
- The content of the message to send.
-
allowed_mentions: Optional[AllowedMentions]
- The types of mentions allowed in the message. Unless otherwise specified, only "everyone" mentions will be suppressed.
Send a message.
Additional fields:
-
content: str
- The content of the message to send.
-
channel: Optional[ChannelID]
- The channel to send the message in. Defaults to the channel in context.
-
allowed_mentions: Optional[AllowedMentions]
- The types of mentions allowed in the message. Unless otherwise specified, only "everyone" mentions will be suppressed.
-
delete_after: Optional[timedelta]
- The amount of time to delete the message after, if at all.
Throw an error when running the action.
Intended for testing and debugging.
Additional fields:
-
error: str
- A human-readable error message.
Wait a certain amount of time before continuing.
Additional fields:
-
delay: Optional[timedelta]
- How long to wait for.
The following additional data structures are available:
AllowedMentions
LogOptions
ChannelsGuard
ChannelTypesGuard
datetime.datetime
datetime.timedelta
IntegerRange
ReactionsGuard
RolesGuard
- Sets and tuples
Extends discord.AllowedMentions
to simplify de/serialization.
This is a wrapper class with some additional utilities to help keep things DRY. See the discord.py documentation of AllowedMentions
for details on the base implementation.
Generally when something asks for an AllowedMentions
, it can be either a string:
allowed_mentions: all
Or an object with fields explicitly declared:
allowed_mentions:
everyone: false
users: false
roles: false
replied_user: true
Individual fields may be ommitted, in which case the final value will assume that of the bot's default allowed_mentions
confguration.
The following strings correspond to frequently-used factory methods:
-
all
does not suppress any mentions. -
not_everyone
suppresses "everyone" mentions. -
only_replies
suppresses all mentions except for replies. -
none
suppresses all mentions.
Data container for various log options.
The following fields are available:
-
channel: ChannelID
- The ID of the channel to log in.
-
stacktrace: Optional[bool]
- Whether to print error stacktraces.
-
emoji: Optional[str]
- The emoji used to represent the type of message.
-
color: Optional[Color]
- The color used for embed stripes.
-
allowed_mentions: Optional[AllowedMentions]
- The types of mentions allowed in log messages. Unless otherwise specified, all mentions will be suppressed.
Python's built-in datetime.datetime
is serialized into a string using .isoformat()
and deserialized using datetime.fromisoformat()
.
Python's built-in datetime.timedelta
is serialized into an object with 3 fields:
more_than:
days: 0
seconds: 3600
microseconds: 500
However it can be deserialized either from a number interpreted as the number of milliseconds:
more_than: 2500
Or from an object with a variety of fields available in the timedelta
constructor:
more_than:
weeks: 0
days: 0
hours: 0
minutes: 0
seconds: 0
milliseconds: 0
microseconds: 0
Check whether a channel matches a set of channels.
The following fields are available:
-
include: Set[ChannelID]
- The channels to include. A channel will match if it is in this set.
-
exclude: Set[ChannelID]
- The channels to exclude. A channel will match if it is not in this set.
Works similar to other guards but with channel IDs:
channels: [123456789987654321, 111222333444555666]
Check whether a channel is of a certain type.
The following fields are available:
-
include: Set[ChannelID]
- The channel types to include. A channel will match if it's one of these types.
-
exclude: Set[ChannelID]
- The channel types to exclude. A channel will match if it's not one of these types.
The following channel types are available:
text
thread
other
An integer range with optional upper and lower bounds.
The following fields are available:
-
min: Optional[int]
- The lower bound of the range.
-
max: Optional[int]
- The upper bound of the range.
A single integer will result in an equal lower and upper bound:
count: 5
Which is equivalent to:
count:
min: 5
max: 5
Either min
or max
can be omitted for an unbounded range.
This will create an unbounded range with only an upper bound:
count:
max: 1
Check whether a reaction matches a set of reactions.
The following fields are available:
-
include: Set[str]
- The reactions to include. A reaction will match if it is in this set.
-
exclude: Set[str]
- The reactions to exclude. A reaction will match if it is not in this set.
-
count: Optional[IntegerRange]
- The number of reactions to check for.
Works similar to other guards but with emoji strings:
reactions: ["π", "π"]
Custom emoji can be provided like so:
reactions: ["π", "π", "<:my_emoji:123456789987654321>"]
There's also an option to match the number of reactions within a certain range. This will only trigger on the first of any reaction:
reactions:
include: ["π", "π"]
count: 1
This will trigger when there is anywhere from 2 to 4 of any reaction:
reactions:
include: ["π", "π"]
count: [2, 4]
Note that if a user is able to remove and/or re-apply their reaction, it may cause the trigger to fire repeatedly.
Check whether a role matches a set of roles.
The following fields are available:
-
include: Set[RoleID]
- The roles to include. A member will match if they have at least one of these.
-
exclude: Set[RoleID]
- The roles to exclude. A member will match if they have none of these.
A list of role IDs is converted into an include-list:
roles: [123456789987654321, 111222333444555666]
Otherwise, an object can be provided with an include
or exclude
field.
With include
, a member will match if they have at least one of the roles:
roles:
include: [123456789987654321, 111222333444555666]
With exclude
, a member will match if they have none of the roles:
roles:
exclude: [123456789987654321, 111222333444555666]
Anywhere a Set
or Tuple
is asked for, the value is deserialized from a list. If a Set
is used, duplicates will be removed and ordering will not be preserved.
Events contain metadata that can be accessed in string templates using braces: {some_metadata_key}
.
The following fields are available by default for all events that contain the respective object:
- Events with a channel:
channel_id
channel_name
channel_mention
- Events with a thread:
thread_id
thread_name
thread_mention
thread_archived
thread_locked
thread_slowmode_delay
thread_auto_archive_duration
- Events with a message:
message_id
message_content
message_clean_content
message_jump_url
- Events with a reaction:
reaction_emoji
reaction_count
- Events with a user:
author_id
author_name
author_username
author_discriminator
author_mention
- Events with an author/actor/member:
-
author_id
/actor_id
/member_id
-
author_name
/actor_name
/member_name
-
author_username
/actor_username
/member_username
-
author_discriminator
/actor_discriminator
/member_discriminator
-
author_mention
/actor_mention
/member_mention
-
author_display_name
/actor_display_name
/member_display_name
-
author_nick
/actor_nick
/member_nick
-
author_joined_at
/actor_joined_at
/member_joined_at
-
author_member_for
/actor_member_for
/member_member_for
-
author_created_at
/actor_created_at
/member_created_at
-
- Events with a thread owner:
thread_owner_id
thread_owner_name
thread_owner_username
thread_owner_discriminator
thread_owner_mention
thread_owner_display_name
thread_owner_nick
thread_owner_joined_at
thread_owner_member_for
thread_owner_created_at
Some triggers, conditions, and actions will provide additional event metadata based on context.