Skip to content

Extension: automod

Ersatz edited this page Mar 8, 2023 · 1 revision

automod

Automate a variety of moderation tasks.

Options

  • database: The database configuration. This must be set explicitly, as it otherwise defaults to an in-memory cache that does not persist data.

Rules

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.

Triggers

All triggers have the following fields:

  • description: Optional[str]
    • A human-readable description of the trigger.

Available triggers:

member_joined trigger

Fires when an on_member_join event is received.

See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_join

member_left trigger

Fires when an on_member_remove event is received.

See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_remove

member_typing trigger

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.

member_updated trigger

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.

mentions_removed_from_message trigger

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.

message_deleted trigger

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.

message_edited trigger

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.

message_sent trigger

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.

message trigger

Fires when an on_message or on_message_edit event is received.

See:

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 or message_content_matches conditions.
  • 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.

reaction_added trigger

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.

reaction_removed trigger

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.

thread_created trigger

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.

thread_updated trigger

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.

reaction trigger

Fires when an on_reaction_add or on_reaction_remove event is received.

See:

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.

user_banned trigger

Fires when an on_member_ban event is received.

See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_ban

user_unbanned trigger

Fires when an on_member_unban event is received.

See: https://discordpy.readthedocs.io/en/stable/api.html?highlight=events#discord.on_member_unban

user_updated trigger

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

Conditions

All conditions have the following fields:

  • description: Optional[str]
    • A human-readable description of the condition.

Available conditions:

actor_account_age condition

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.

actor_is_bot condition

Check if the actor in context is a bot.

actor_is_not_bot condition

Check if the actor in context is not a bot.

actor_is_not_self condition

Check if the actor in context is not the bot itself.

actor_is_self condition

Check if the actor in context is the bot itself.

actor_member_for condition

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.

actor_roles condition

Check if the actor in context has certain roles.

Additional fields:

  • roles: RolesGuard
    • The roles to match against.

any_of condition

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.

all_of condition

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.

author_account_age condition

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.

author_is_bot condition

Check if the author in context is a bot.

author_is_not_bot condition

Check if the author in context is not a bot.

author_is_not_self condition

Check if the author in context is not the bot itself.

author_is_self condition

Check if the author in context is the bot itself.

author_member_for condition

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.

author_roles condition

Check if the author in context has certain roles.

Additional fields:

  • roles: RolesGuard
    • The roles to match against.

member_for condition

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.

message_content_contains condition

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.
  • 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.

message_content_matches condition

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.
  • 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.

message_has_attachments condition

Check if the message has attachments.

Additional fields:

  • count: Optional[IntegerRange]
    • The number of attachments to check for, if bounded.

message_has_embeds condition

Check if the message has embeds.

Additional fields:

  • count: Optional[IntegerRange]
    • The number of embeds to check for, if bounded.

message_has_links condition

Check if the message has links.

Additional fields:

  • count: Optional[IntegerRange]
    • The number of links to check for, if bounded.

message_has_mentions condition

Check if the message has mentions.

Additional fields:

  • count: Optional[IntegerRange]
    • The number of mentions to check for, if bounded.

message_mentions_roles condition

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.

message_mentions_users condition

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.

none_of condition

Passes if and only if none of the sub-conditions pass.

Additional fields:

  • conditions: Tuple[Condition]
    • The sub-conditions to check.

not condition

Passes if any of the sub-conditions fail.

Additional fields:

  • conditions: Tuple[Condition]
    • The sub-conditions to check.

thread_auto_archive_duration condition

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_error condition

Throw an error when checking the condition.

Intended for testing and debugging.

Additional fields:

  • error: str
    • A human-readable error message.

wait condition

Wait a certain amount of time before continuing.

Additional fields:

  • delay: Optional[timedelta]
    • How long to wait for.

Actions

All actions have the following fields:

  • description: Optional[str]
    • A human-readable description of the action.

Available actions:

add_reactions action

Add reactions to the message in context.

Additional fields:

  • reactions: Tuple[str]
    • The reactions to add.

add_roles_to_actor action

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_author action

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_thread action

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_messages action

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_message action

Delete the message in context.

dm_member action

Send a direct message to the member in question.

Additional fields:

  • content: str
    • The content of the message to send.

edit_thread action

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 is 21600.
  • 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, or 10080.

join_thread action

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.

log_message action

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 action

Remove all reactions from the message in context.

remove_own_reactions action

Remove the bot's own reactions from the message in context.

Additional fields:

  • reactions: Tuple[str]
    • The reactions to remove.

remove_reactions action

Remove certain reactions from the message in context.

Additional fields:

  • reactions: Tuple[str]
    • The reactions to remove.

remove_roles_from_actor action

Remove roles from the actor in context.

Additional fields:

  • roles: Tuple[RoleID]
    • The roles to remove.

remove_roles_from_author action

Remove roles from the author in context.

Additional fields:

  • roles: Tuple[RoleID]
    • The roles to remove.

reply_to_message action

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_message action

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_error action

Throw an error when running the action.

Intended for testing and debugging.

Additional fields:

  • error: str
    • A human-readable error message.

wait action

Wait a certain amount of time before continuing.

Additional fields:

  • delay: Optional[timedelta]
    • How long to wait for.

Other data structures

The following additional data structures are available:

AllowedMentions

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.

LogOptions

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.

datetime.datetime

Python's built-in datetime.datetime is serialized into a string using .isoformat() and deserialized using datetime.fromisoformat().

datetime.timedelta

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

ChannelsGuard

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]

ChannelTypesGuard

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

IntegerRange

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

ReactionsGuard

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.

RolesGuard

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]

Sets and tuples

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.

Event metadata

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.

Clone this wiki locally