Moderation
Content moderation, thread management, trade enforcement, and comprehensive audit logging.
Zagreus provides layered moderation tools that cover content filtering, trade enforcement, thread management, and audit logging. Every moderator action is permanently recorded and queryable, ensuring accountability and transparency.
Trade bans prevent users from posting in any monitored trade channel. Banned users' messages are automatically deleted and they receive an ephemeral notification explaining the ban.
Content Moderation
Per-user content blocking allows moderators to restrict specific types of content from individual users. This is more granular than channel-level permissions and does not require modifying Discord roles.
Blockable Content Types
| Content Type | Description |
|---|---|
| Images | Attached image files (PNG, JPG, GIF, WebP) |
| Videos | Attached video files (MP4, MOV, WebM) |
| Links | Any URL in the message content |
| Embeds | Rich embeds from links (previews, OpenGraph cards) |
| Files | Non-media file attachments (ZIP, PDF, etc.) |
| Sound | Voice messages and audio file attachments |
| Forwarded Messages | Messages forwarded from other channels or servers |
How It Works
- A moderator runs
/content-block add @user <type>to block a content type for a specific user - When the user posts a message containing the blocked content type, the message is automatically deleted
- The user receives an ephemeral message explaining what was blocked and why
- Optionally, a timeout can be applied — the block expires automatically after the specified duration
- Multiple content types can be blocked for the same user simultaneously
- Blocks are logged in the audit trail with the moderator who set them
Trade Enforcement
Trade Bans
Trade bans prevent a user from posting in any monitored trade channel across the entire server.
Temporary Bans
- Set a duration (hours, days, weeks) for the ban
- The ban auto-expires when the duration elapses
- The user receives a DM notification when banned and when the ban expires
- A reason is recorded in the audit log
Permanent Bans
- No expiry date — the ban persists until manually removed by a moderator
- The user is notified via DM
- Permanent bans are visually distinguished in the audit log and dashboard
Ban Behavior
- Messages posted by banned users in monitored channels are immediately deleted
- The user receives an ephemeral message with the ban reason and expiry (if temporary)
- Ban status is visible on the user's trade profile
- Bans are enforced even if the user leaves and rejoins the server
Trade Mutes
Trade mutes are a lighter alternative to bans. A muted user's messages are not deleted, but they are flagged and the user is rate-limited.
- Always temporary: Mutes require a duration and auto-expire
- Rate limiting: Muted users can only post one trade per configurable interval
- Visual indicator: Muted users' trades may be marked with a mute indicator
- DM notification: The user is informed of the mute, its reason, and when it expires
Suspicious Activity Detection
Zagreus automatically flags potentially suspicious trading behavior:
- New account trading: Users with accounts younger than a configurable threshold posting trades
- Rapid trade posting: Posting more than a configurable number of trades within a short window
- Cross-channel duplication: Identical trade content posted in multiple monitored channels
- Edited prices: Trade posts where the price was modified after initial posting
- Deleted and reposted: Trades that are deleted and immediately reposted (potential scam pattern)
Flagged activity is sent to the configured notification channel for moderator review. No automatic action is taken.
Thread Management
Thread Rules
Per-thread content restrictions that function similarly to content blocks but apply to everyone within a specific thread.
- Configure which content types are restricted in a thread (images, links, files, etc.)
- Messages violating thread rules are auto-deleted with an ephemeral explanation
- Optionally apply a timeout to rule violators — users who repeatedly break thread rules receive a Discord timeout
- Thread rules persist until manually removed or the thread is archived
| Configuration | Description |
|---|---|
| Restricted types | Which content types are blocked in the thread |
| Timeout duration | How long to timeout repeat violators (optional) |
| Warning threshold | Number of violations before a timeout is applied |
| Exempt roles | Roles that are not subject to thread rules |
Thread Bans
Thread bans prevent specific users from participating in a thread.
Temporary Thread Bans
- Set a duration for the ban
- The user is removed from the thread and cannot rejoin until the ban expires
- Auto-expiry with DM notification
Permanent Thread Bans
- The user is permanently removed from the thread
- If the user attempts to rejoin (via thread member updates), they are automatically removed again
- Join attempt notifications are sent to the moderator who set the ban
Thread Ban Enforcement
- When a banned user is detected joining a thread, they are immediately removed
- The
threadMembersUpdateevent handler monitors for banned users rejoining - A notification is sent to the configured log channel when enforcement occurs
Delete and Edit Logging
Zagreus can log deleted and edited messages to a designated channel, providing a record of removed content.
Configurable Log Channels
- Set one or more channels to receive delete/edit logs
- Different channels can be configured for different categories (trades vs. general)
Who-Deleted Detection
When a message is deleted, Zagreus attempts to determine who deleted it:
- Self-delete: The author deleted their own message
- Moderator delete: A moderator or bot deleted the message (detected via audit logs)
- Unknown: Could not determine the deleter (Discord audit log limitations)
Filtering
Fine-tune what gets logged to avoid noise:
| Filter | Description |
|---|---|
| Ignored channels | Messages deleted in these channels are not logged |
| Ignored roles | Messages from users with these roles are not logged when deleted |
| Ignored prefixes | Messages starting with these prefixes are not logged (useful for bot command prefixes) |
Uncached Message Logging
When a message is deleted that was not in the bot's cache (sent before the bot started or too old):
- The log entry shows "[Uncached Message]" with the message ID and channel
- If the message was a trade, the trade database record is referenced
Attachment Metadata
When a deleted message contained attachments:
- File names, sizes, and types are logged
- Image dimensions are recorded when available
- Attachment URLs are included (may expire after Discord's CDN retention period)
Audit Log
Every moderation action taken through Zagreus is permanently recorded in the audit log. This provides a complete, tamper-proof history of all moderation activity.
Recorded Actions
- Trade bans and unbans (with reason, duration, moderator)
- Trade mutes and unmutes
- Content blocks added and removed
- Thread bans and unbans
- Thread rules changes
- Giveaway moderation (end, cancel, reroll)
- Configuration changes (channel monitoring, role assignments)
Querying the Audit Log
The audit log can be queried via:
- Slash command:
/trade audit-logwith filters for user, action type, date range, and moderator - Web dashboard: Full-featured audit log viewer with search, filters, pagination, and export
Audit Log Fields
| Field | Description |
|---|---|
| Timestamp | When the action occurred |
| Action | The type of moderation action |
| Moderator | Who performed the action |
| Target | The user affected by the action |
| Reason | The reason provided (if any) |
| Duration | For temporary actions, the duration |
| Details | Additional context specific to the action type |
Commands
| Command | Description |
|---|---|
/content-block <add|remove|list> <user> [type] | Manage per-user content type restrictions. Add or remove blocks for images, videos, links, embeds, files, sound, or forwarded messages. List shows all active blocks for a user. |
/thread-rules <set|clear|view> [thread] | Configure content restrictions for a specific thread. Set restricted types, timeout duration, warning threshold, and exempt roles. |
/thread-ban <add|remove|list> <user> [thread] [duration] | Ban or unban a user from a specific thread. Supports temporary and permanent bans with duration. List shows all active thread bans. |
/log-prefs <set|view> | Configure delete/edit logging preferences. Set log channels, ignored channels, ignored roles, and ignored prefixes. |
All moderation commands require the Trade Moderator role. Admin-level actions (like configuring log channels) require Discord Administrator permission.
Moderation Cases
Moderation cases provide a structured record of every warning, timeout, ban, and other disciplinary action taken against a user. Each case is assigned a unique number and tracked permanently, giving moderators a complete enforcement history.
How It Works
- A moderator issues a warning with
/case warn @user [reason] - The target user receives a DM notification with the reason
- A numbered case is created and stored in the database
- If auto-escalation rules are configured, the bot checks whether the user has crossed a threshold (e.g., 3 warnings within 30 days triggers an automatic timeout)
Auto-Escalation
Auto-escalation rules allow the server to define automatic consequences when a user accumulates too many cases within a time window.
| Setting | Description |
|---|---|
| Trigger count | Number of cases required to trigger escalation (e.g., 3) |
| Time window | The rolling period in which cases are counted (e.g., 30 days) |
| Escalation action | The automatic action taken — timeout, trade mute, or trade ban |
| Escalation duration | How long the escalated punishment lasts |
Auto-escalation is configured via the web dashboard at Moderation > Settings.
Case Commands
| Command | Description |
|---|---|
/case warn @user [reason] | Warn a user with an optional reason. The user is DM'd and a case is created. Triggers auto-escalation check. |
/case view <number> | View full details of a specific case by its number. |
/case edit <number> <reason> | Edit the reason on an existing case. The edit is recorded in the audit log. |
/case resolve <number> | Mark a case as resolved. Admin only. Resolved cases are excluded from auto-escalation counts. |
/case history @user | View the complete moderation history for a user, including all case types, dates, and outcomes. |
/case recent [type] | View recent cases across the server, optionally filtered by type (warn, timeout, ban, mute). |
/warn @user [reason] | Legacy alias for /case warn. |
Native Timeouts
Discord native timeouts temporarily prevent a user from sending messages, reacting, or joining voice channels. Zagreus wraps this functionality with case tracking, DM notifications, and audit logging.
| Command | Description |
|---|---|
/timeout add @user [duration] [reason] | Apply a Discord native timeout to a user. Maximum duration is 28 days (Discord limit). A moderation case is automatically created. |
/timeout remove @user [reason] | Remove an active timeout from a user. The removal reason is recorded in the audit log. |
Discord enforces a maximum timeout duration of 28 days. Attempting to set a longer duration will be capped at 28 days.
Timeout Behavior
- The target user receives a DM with the timeout reason and duration before the timeout is applied
- A moderation case is automatically created and linked to the timeout
- Timeout application and removal are both logged in the audit trail
- Timeouts are enforced by Discord itself — they persist even if the bot goes offline
Logging System
The logging system captures server events and posts formatted log entries to designated channels. Events are organized into five categories, each independently configurable.
Log Categories
| Category | Events Logged |
|---|---|
| Message | Message edits, deletions, bulk deletes, pin changes |
| Member | Joins, leaves, role changes, nickname changes, avatar updates |
| Server | Channel creates/deletes/edits, role creates/deletes/edits, emoji and sticker changes |
| Voice | Voice channel joins, leaves, moves, mute/deafen state changes |
| Moderation | Bans, unbans, kicks, timeouts, moderation case actions |
Configuration
Logging is configured through the web dashboard at Settings > Logging. Each category can be assigned its own log channel, or multiple categories can share a single channel.
Ignore Lists
Each category supports ignore lists to reduce noise:
| Ignore Type | Description |
|---|---|
| Channels | Events in these channels are not logged |
| Users | Events involving these users are not logged |
| Roles | Events involving users with these roles are not logged |
Bot users are automatically excluded from member and message logging to prevent log spam from automated actions.
Anti-Nuke Protection
Anti-nuke protection detects and responds to destructive actions that may indicate a compromised admin account or malicious bot. When suspicious activity is detected, the bot can automatically quarantine the offending account and alert moderators.
Detection
| Threat | Description |
|---|---|
| Channel deletion | Multiple channels deleted within a short time window |
| Role deletion | Multiple roles deleted within a short time window |
| Mass ban | Large number of members banned in rapid succession |
| Mass kick | Large number of members kicked in rapid succession |
| Webhook spike | Unusual number of webhooks created in a short period |
| Permission escalation | A user or role granted Administrator or dangerous permissions unexpectedly |
Quarantine Actions
When a threat is detected, the bot can take one or more of the following actions against the responsible account:
| Action | Description |
|---|---|
| Strip roles | Remove all roles from the compromised account, neutralizing their permissions |
| Kick | Kick the account from the server |
| Ban | Ban the account from the server |
Server State Snapshots
Zagreus takes a snapshot of the server's channel structure, role hierarchy, and permissions every 6 hours. These snapshots serve as a reference point for detecting unexpected changes and can aid in manual recovery if a nuke event occurs.
Configuration
Anti-nuke thresholds and quarantine actions are configured through the web dashboard at Moderation > Security. You can adjust:
- Detection thresholds (how many deletions/bans/kicks trigger the alert)
- Time windows (how quickly actions must occur to be considered suspicious)
- Quarantine response (strip roles, kick, or ban)
- Notification channel for alerts
Anti-nuke protection requires the bot to have a role positioned above the roles it needs to quarantine. Ensure the bot's role is near the top of the role hierarchy.
Protected Roles
Protected roles prevent unauthorized role assignments. When a role is designated as protected, any assignment of that role to a user is monitored — if the assignment was not performed through an approved workflow, it is automatically reverted.
How It Works
- Server admins designate specific roles as protected via the dashboard
- When a protected role is assigned to a user, the
guildMemberUpdateevent checks whether the assignment was authorized - Unauthorized assignments are automatically reverted — the role is removed from the user
- An alert is sent to the configured moderation channel with details about the unauthorized assignment, including who made the change (from the Discord audit log)
Use Cases
- Admin roles: Prevent compromised accounts from granting themselves admin access
- Moderator roles: Ensure only senior staff can promote moderators
- Verified roles: Ensure verification can only happen through the intended flow
Protected role enforcement uses the Discord audit log to determine who made the role change. There may be a brief delay (typically under 2 seconds) between the role assignment and the revert.
User Reports
Members can report other users to the moderation team. Reports appear in the configured report channel with action buttons.
Commands
| Command | Description | Permission |
|---|---|---|
/report <user> <reason> [message-link] | Report a user to moderators | Everyone |
How It Works
- Reporter provides a user, reason (max 1000 characters), and optional message link
- If a message link is provided, the bot snapshots the message content (first 500 characters)
- An embed is posted to the mod report channel with: report ID, reported user, reporter, reason, and message snippet
- Moderators can Resolve, Dismiss, or Escalate to a formal case using action buttons
- Cooldown between reports (default 60 seconds, configurable per server)
- Cannot report yourself or bots
Modmail
A DM-based support system where members message the bot and a private channel is created for staff to respond.
Commands
| Command | Description | Permission |
|---|---|---|
/modmail setup <category> [log-channel] [ping-role] | Enable modmail with a category for threads | Manage Guild |
/modmail close [reason] | Close the current modmail thread | Moderator |
/modmail disable | Disable the modmail system | Manage Guild |
Workflow
Admin sets up modmail
Run /modmail setup with the category where modmail channels should be created. Optionally set a log channel and a role to ping on new threads.
Member sends a DM
A user DMs the bot. The bot creates a private channel in the configured category, visible only to staff.
Staff responds in the channel
Staff messages in the modmail channel are relayed back to the user's DMs. The user's replies continue to appear in the channel.
Thread is closed
A moderator runs /modmail close in the thread. The user receives a notification and the channel is deleted after a brief delay.
Temporary Roles
Assign roles that automatically expire after a specified duration.
Commands
| Command | Description | Permission |
|---|---|---|
/temprole assign <user> <role> <duration> [reason] | Assign a temporary role | Manage Roles |
/temprole list | List all active temporary roles in the server | Manage Roles |
/temprole remove <id> | Remove a temporary role early | Manage Roles |
Duration Formats
| Format | Example |
|---|---|
| Minutes | 30m, 30min |
| Hours | 2h, 2hr |
| Days | 7d |
| Weeks | 2w |
Duration range: 1 minute to 30 days. The role is immediately assigned and automatically removed when the duration expires.