How to Audit Discord Permission Changes With Bot-Polled Audit Log Endpoint
🔍 WiseChecker

How to Audit Discord Permission Changes With Bot-Polled Audit Log Endpoint

You need to track who changed a role permission or channel override in your Discord server. Manual review of the audit log is slow and unreliable for large servers. Discord provides a REST API endpoint that lets bots poll the audit log programmatically. This article explains how to set up a bot that uses the Get Guild Audit Log endpoint to capture permission changes automatically.

Key Takeaways: Building a Bot to Poll Audit Log for Permission Changes

  • Get Guild Audit Log endpoint (GET /guilds/{guild.id}/audit-logs): Returns a list of audit log entries that include action type, target, user, and changes.
  • Action type 24 (MEMBER_ROLE_UPDATE) and 31 (CHANNEL_OVERWRITE_UPDATE): Filter for these specific action types to capture permission modifications.
  • Bot with ‘view_audit_log’ permission: The bot must have this permission in the server to access the audit log endpoint.

ADVERTISEMENT

How the Discord Audit Log Endpoint Works for Permission Auditing

The Discord Audit Log API allows bots to retrieve a server’s audit log entries. Each entry contains an action type, the user who performed the action, the target object (role, channel, or member), and a changes array that lists what was modified. For permission changes, the relevant action types are 24 for member role updates, 31 for channel overwrite updates, 3 for role create, 4 for role delete, 5 for role update (includes permission bitfield changes), and 10 for channel update (includes permission overwrites).

The endpoint is rate-limited. Bots can make 10 requests per 60 seconds per server. Each request returns up to 100 entries. To capture all changes, you must poll the endpoint repeatedly and store the last processed entry ID to avoid duplicates.

Prerequisites for Using the Audit Log Endpoint

Before writing code, ensure your bot has the following:

  • The view_audit_log permission (bitwise value 0x80) in the target server.
  • A bot token with the bot scope and the guilds intent enabled.
  • Access to the server ID where you want to audit permission changes.

Steps to Build a Bot That Polls Audit Log for Permission Changes

The following steps use Python with the discord.py library version 2.3 or later. You can adapt the logic to other languages and libraries.

  1. Install discord.py and set up the bot client
    Run pip install discord.py. Create a bot client with the intents.default() and intents.guilds = True. Replace YOUR_BOT_TOKEN with your actual token.
  2. Define the audit log action type constants
    Import the AuditLogAction enum from discord.py. The constants you need are AuditLogAction.member_role_update (24), AuditLogAction.channel_overwrite_update (31), AuditLogAction.role_update (5), and AuditLogAction.channel_update (10).
  3. Create a polling function that fetches audit log entries
    Define an async function that calls guild.audit_logs(limit=100, after=last_entry_id). The after parameter ensures you only get new entries since the last poll. Store last_entry_id in a file or database.
  4. Filter entries by action type and extract change details
    Loop through the returned entries. For each entry, check entry.action against the relevant action types. If it matches, extract entry.user (the moderator), entry.target (the role or channel), and entry.changes (a list of AuditLogChange objects). Each change has before and after values.
  5. Parse the changes array to identify permission modifications
    For role updates, the changes include permissions (a bitfield). Compare before.value and after.value using bitwise operations to determine which permission bits were added or removed. For channel overwrites, the changes include allow and deny bitfields for the overwrite target.
  6. Log or send the audit data to a designated channel
    Format the extracted data into a readable message. Use an embed with fields for user, target, action type, and changed permissions. Send the embed to a private logging channel using channel.send(embed=embed).
  7. Run the polling loop on a timer
    Use tasks.loop(seconds=10) from discord.py to run the polling function every 10 seconds. This respects the rate limit while keeping the audit log relatively up to date.

ADVERTISEMENT

Common Issues and Limitations When Polling the Audit Log

Bot Does Not See Recent Audit Log Entries

The audit log endpoint only returns entries that the bot has permission to see. If the bot lacks the view_audit_log permission on a specific channel or role, it may not see entries related to that object. Grant the bot the Administrator permission temporarily for testing, then reduce to the minimum required permissions.

Rate Limits Cause Missed Entries

If your poll interval is longer than 10 seconds, you might miss entries if many changes happen in a short burst. The audit log endpoint has a 10-request-per-minute limit per server. Set your poll interval to 6 seconds or longer to stay under the limit. If you need near-real-time auditing, consider using Discord’s Gateway events instead of polling.

Change Objects Contain Opaque Bitfields

The before and after values for permission changes are integers representing bitfields. You must decode these using Discord’s permission flag constants. In discord.py, use Permissions(before.value) to convert to a readable Permissions object. Then compare the Permissions objects to list added and removed permissions.

Entry IDs Are Not Sequential Across Restarts

If your bot restarts, the stored last_entry_id might be stale. The audit log endpoint returns entries in reverse chronological order. Always use the after parameter with the ID of the last entry you successfully processed. If you lose the stored ID, start from the current time and accept that you may miss entries from the downtime.

Item Polling via REST API Gateway Events (GUILD_AUDIT_LOG_ENTRY_CREATE)
Real-time delivery No, polled every N seconds Yes, pushed immediately
Rate limit 10 requests per 60 seconds per server No rate limit on event receipt
Implementation complexity Low, simple HTTP requests Medium, requires intent and event handler
Data completeness May miss entries between polls Complete if connection is stable
Permission requirement view_audit_log view_audit_log

The table above compares the two main methods for capturing audit log data. For most permission auditing needs, polling is sufficient and easier to implement. Use the Gateway event approach only if you require sub-second notification of changes.

You can now build a bot that polls the Discord audit log endpoint to track permission changes in your server. Start by implementing the polling loop with a 10-second interval and storing the last processed entry ID in a persistent database. For advanced auditing, consider combining the polling approach with a background task that also listens for the GUILD_AUDIT_LOG_ENTRY_CREATE Gateway event to reduce latency. Always test your bot in a small server before deploying to production to ensure the permission filtering logic works correctly.

ADVERTISEMENT