I have a trigger to time users out for 30 minutes if they spam commands on the bot too quickly. I want to also have the bot delete its command responses ie the output of the help command, as well as the users spamming !help message. The idea is to keep chat clear automatically when anyone spams. I can get the bot to tell me the method is beginning and ending in logs, but it never actually deletes the messages.
Can someone provide some guidance? Cant find much at all online and I've tried most of the documentation I could find as well as people having similar issues.
async def timeout_user(self, user):
guild = user.guild
# Get the timeout role
timeout_role = discord.utils.get(guild.roles, name="Timeout")
# Add the timeout role to the user
await user.add_roles(timeout_role)
# Remove the spam commands from the user
await self.remove_spam_commands(user)
# Send a message to the user
timeout_message = "removed because inappropriate outside testing "
await user.send(timeout_message)
# Send a message in the channel
timeout_channel = discord.utils.get(guild.channels, name="testing")
if timeout_channel:
await timeout_channel.send(f"{user.mention}, removed because inappropriate outside testing")
# Remove the timeout role after the specified duration
await asyncio.sleep(1800) # 30 minutes
await user.remove_roles(timeout_role)
async def remove_spam_commands(self, user):
print("Removing spam commands...") # Debug print statement
async for message in user.history(limit=15):
if message.content.startswith('!'):
await message.delete()
print(f"Deleted message from user {user.id}: {message.content}")
print("Finished removing spam commands.") # Debug print statement
@commands.Cog.listener()
async def on_message(self, message):
print("on_message event triggered!")
print(f"Received message from {message.author}: {message.content}")
if message.author.bot:
return
# Check if the message is from the user you want to timeout
user_id = message.author.id
if user_id == QUARTERMASTER_ID:
await message.channel.send("This is a test message from the bot.")
await message.delete()
print(f"Deleted message from Quartermaster: {message.content}")
else:
print(f"Message is not from the Quartermaster.")
# Update command usage for the user
user_id = message.author.id
await self.check_command_limit(message.author)
self.command_limits[user_id]['count'] += 1
Logs:
Removing spam commands...
Finished removing spam commands.
(Removed output of message due to sensitivity of text)
on_message event triggered!
(Removed output of message due to sensitivity of text)
on_message event triggered!
If you respond to command messages using something like context.reply()
or message.reply()
, one idea would be to go through the bot's message history and delete messages that are in response to the user:
async def remove_spam_commands(self, user):
print("Removing spam commands...") # Debug print statement
user_message_ids = []
async for message in user.history(limit=15):
if message.content.startswith('!'):
await message.delete()
# save the id of user messages that were deleted
user_message_ids.append(message.id)
print(f"Deleted message from user {user.id}: {message.content}")
async for message in user.guild.me.history(limit=100):
# You need to set a higher limit here, as the bot send more messages
if message.reference and message.reference.message_id in user_message_ids:
await message.delete()
print("Finished removing spam commands.") # Debug print statement
But anyway, using await message.delete()
to delete multiple messages is slow. I recommend you change your strategy to clean by channel and use bulk delete with channel.delete_messages() or channel.purge().