The Problem: Your Discord bot is failing to reliably capture deleted message events because it relies on Discord.py’s cache, which is cleared on restarts. The standard on_message_delete event only works for messages currently in the cache. You want a solution that allows you to capture deleted message information even after your bot restarts, ideally without the need for a full-blown database.
Understanding the “Why” (The Root Cause):
Discord.py’s on_message_delete event is inherently limited by the bot’s cache. The cache is a performance optimization; it doesn’t persist across bot restarts. When a message is deleted and is no longer in the cache, the on_message_delete event won’t fire. To reliably track deletions, you need a persistent storage mechanism to hold message information beyond the scope of the bot’s volatile cache. While a full database is one option, this might be overkill for simple tracking.
Step-by-Step Guide:
This guide uses a hybrid approach: a rolling in-memory store (using Redis) to capture recent messages for immediate deletion events, combined with logging of raw deletion events for those beyond the memory window. This balances performance and reliability without the overhead of a full database for every message.
Step 1: Set up Redis:
Install and configure Redis on your server. Redis is an in-memory data store that is ideal for this kind of task because of its speed and ability to set expiry times on key-value pairs. Ensure Redis is running and accessible.
Step 2: Install the redis Python Library:
Install the necessary Redis library:
pip install redis
Step 3: Modify Your Bot Code:
This code uses on_message to store messages in Redis with a Time-To-Live (TTL) and on_raw_message_delete to retrieve information from Redis if the message is no longer cached.
import discord
from discord.ext import commands
import redis
import asyncio
import json
# Redis connection
r = redis.Redis(host='localhost', port=6379, db=0)
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.event
async def on_ready():
print(f'{bot.user} has connected to Discord!')
@bot.event
async def on_message(message):
if message.author == bot.user:
return
#Store message in Redis with a 48-hour TTL
r.set(message.id, json.dumps({'content': message.content, 'author': message.author.id, 'channel': message.channel.id}), ex=172800)
@bot.event
async def on_raw_message_delete(payload):
msg_id = payload.message_id
message_data = r.get(msg_id)
if message_data:
data = json.loads(message_data.decode('utf-8'))
channel = bot.get_channel(data['channel'])
author = await bot.fetch_user(data['author']) #Fetch user info if needed
await channel.send(f"Message deleted by {author.mention}: {data['content']}")
r.delete(msg_id) #Remove entry from Redis
else:
# Log raw deletion event (user ID, channel ID, message ID) for messages outside the Redis TTL
print(f"Message with ID {msg_id} deleted (not in cache or Redis).")
bot.run('YOUR_BOT_TOKEN')
Step 4: Test and Monitor:
Run your bot and test message deletion. Monitor the Redis usage and adjust the TTL (48 hours in this example) as needed to balance memory usage and the desired message retention period.
Common Pitfalls & What to Check Next:
- Redis Configuration: Ensure Redis is correctly configured and accessible from your bot. Check your host, port, and database settings.
- Error Handling: The provided code includes basic logging for messages outside the Redis TTL. Add more robust error handling for potential issues (e.g., Redis connection errors, JSON parsing errors).
- Rate Limits: Be mindful of Discord’s API rate limits, particularly if your server is very active. Adjust the frequency of Redis access or add rate limiting mechanisms if necessary.
- Data Integrity: Consider adding a checksum or other verification to ensure data integrity in Redis if you are concerned about data corruption.
- Scaling: If your server experiences high message volumes, consider scaling Redis or exploring alternative database solutions for long-term storage.
Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!