`!logs <user> <page>` Lists previous modmail logs with the specified user. If there are a lot of logs, they will be paginated. In this case, you can specify the page number to view as the second argument.
`!block <user> <time>` Blocks the specified user from using modmail. If a time is specified, the block is temporary.
`!unblock <user> <time>` Unblocks the specified user from using modmail. If a time is specified, the user will be scheduled to be unblocked after that time.
`!is_blocked <user>` Checks whether the user is blocked and for how long
`!s <shortcut> <text>` Adds a snippet (a canned response). Supports {1}, {2}, etc. for arguments. See below for how to use it.
`!edit_snippet <shortcut> <text>` Edits an existing snippet (alias `!es`)
`!delete_snippet <shortcut>` Deletes the specified snippet (alias `!ds`)
`!snippets` Lists all available snippets
`!version` Print the version of the bot you're running
`!reply <text>` Sends a reply to the user in the format "(Role) User: text" (alias `!r`)
`!anonreply <text>` Sends an anonymous reply to the user in the format "Role: text" (alias `!ar`)
`!close <time>` Closes the modmail thread. If a time is specified, the thread is scheduled to be closed later. Scheduled closing is cancelled if a message is sent to or received from the user.
`!logs <page>` Lists previous modmail logs with this user. If there are a lot of logs, they will be paginated. In this case, you can specify the page number to view as an argument.
`!block <time>` Blocks the user from using modmail. If a time is specified, the block is temporary.
`!unblock <time>` Unblocks the user from using modmail. If a time is specified, the user will be scheduled to be unblocked after that time.
`!!shortcut` Reply with a snippet. Replace `shortcut` with the snippet's actual shortcut.
`!!!shortcut` Reply with a snippet anonymously. Replace `shortcut` with the snippet's actual shortcut.
`!move <category>` If `allowMove` is enabled, moves the thread channel to the specified category
`!loglink` Shows the link to the current thread's log
`!suspend` Suspend a thread. The thread will act as closed and not receive any messages until unsuspended.
To automatically reply without using !reply or !r, enable `alwaysReply` in the config. `alwaysReplyAnon` sets whether to reply anonymously. If you do not wish to reply, it will ignore any message starting in the prefix (which defaults to !), such as !note
|**token**|None|**Required!** The bot user's token|
|**logChannelId**|None|**Required!** Channel where to post log links to closed threads and other alerts|
|**mailGuildId**|None|**Required!** The inbox server's ID|
|**mainGuildId**|None|**Required!** ID (or array of IDs) of the main server where people contact the bot from. Used for displaying users' nicknames and join dates, and catching bot pings.|
|attachmentStorage|"local"|Controls where sent/received attachments are saved.<br><br>**"local"** - Files are saved locally on the machine running the bot<br>**"discord"** - Files are saved as attachments on a special channel on the inbox server. Requires `attachmentStorageChannelId` to be set.|
|attachmentStorageChannelId|null|When using "discord" attachment storage, the id of the channel on the inbox server where attachments should be saved|
|botMentionResponse|None|If set, the bot auto-responds to bot mentions with this message. Allows `{userMention}` to be added to mention the user who mentioned the bot.|
|categoryAutomation|{}|Various ways of automating thread categories on the inbox server. **Note that the options below with a dot in the name are object properties for `categoryAutomation`.**|
|categoryAutomation.newThread|None|Same as `newThreadCategoryId`. Specifies a category to open all new threads in. Also functions as a fallback for `categoryAutomation.newThreadFromGuild`.|
|categoryAutomation.newThreadFromGuild|None|Allows you to open threads in specific categories based on which guild the user is messaging the bot from. The value is an object with guild ids as the keys and category ids as the values.|
|guildGreetings|None|When using multiple mainGuildIds, this option allows you to configure greetings on a per-server basis. The syntax is an object with the guild ID as the key, and another object with `message` and `attachment` properties as the value (identical to greetingMessage and greetingAttachment)|
|ignoreAccidentalThreads|false|If set to true, the bot attempts to ignore common "accidental" messages that would start a new thread, such as "ok", "thanks", etc.|
|inboxServerPermission|None|Permission name, user id, or role id required to use bot commands on the inbox server. Also supports arrays. See ["Permissions" on this page](https://abal.moe/Eris/docs/reference) for supported permission names (e.g. `kickMembers`).|
|mentionRole|"here"|Role that is mentioned when new threads are created or the bot is mentioned. Accepted values are "here", "everyone", or a role id as a string. Set to null to disable these pings entirely. Multiple values in an array are supported.|
|pingOnBotMention|true|If enabled, the bot will mention staff (see mentionRole above) on the inbox server when the bot is mentioned on the main server.|
|requiredAccountAge|None|Required account age for contacting modmail (in hours). If the account is not old enough, a new thread will not be created and the bot will reply with `accountAgeDeniedMessage` (if set) instead.|
|requiredTimeOnServer|None|Required amount of time (in minutes) the user must be a member of the server before being able to contact modmail. If the user hasn't been a member of the server for the specified time, a new thread will not be created and the bot will reply with `timeOnServerDeniedMessage` (if set) instead.|
|responseMessage|"Thank you for your message! Our mod team will reply to you here as soon as possible."|The bot's response to DMs that start a new thread|
|threadTimestamps|false|Whether to show custom timestamps in threads, in addition to Discord's own timestamps. Logs always have accurate timestamps, regardless of this setting.|
This example adds a command `!mycommand` that replies with `"Reply from my custom plugin!"` when the command is used inside a modmail inbox thread channel.
(Note the use of [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_function_parameter) in the function parameters)
This example adds a custom type for the `attachmentStorage` option called `"original"` that simply returns the original attachment URL without rehosting it in any way.