Hey everyone! I’m working on a Discord bot and I’ve hit a snag. I want my bot to ignore direct messages from users with certain roles. I’ve got it working for specific user IDs, but I can’t figure out how to check for roles. Here’s what I’ve got so far:
ignored_roles = ['NewMember', 'Muted']
ignored_users = []
@bot.event
async def on_message(msg):
if msg.author == bot.user or msg.author.id in ignored_users or any(role.name in ignored_roles for role in msg.author.roles):
return
if isinstance(msg.channel, discord.DMChannel):
target_channel = bot.get_channel(some_id)
await target_channel.send(f'{msg.author} said:\n{msg.content}')
await bot.process_commands(msg)
Can anyone point me in the right direction? I’m not sure if I’m checking the roles correctly. Thanks in advance for any help!
Your approach is on the right track, Samuel. The issue lies in accessing roles for DM messages. In Discord.py, roles are associated with server members, not DM users. To solve this, you’ll need to fetch the member object from a specific guild before checking roles. Here’s a modified version of your code that should work:
@bot.event
async def on_message(msg):
if msg.author == bot.user:
return
if isinstance(msg.channel, discord.DMChannel):
guild = bot.get_guild(your_guild_id)
member = await guild.fetch_member(msg.author.id)
if any(role.name in ignored_roles for role in member.roles):
return
target_channel = bot.get_channel(some_id)
await target_channel.send(f'{msg.author} said:\n{msg.content}')
await bot.process_commands(msg)
Replace ‘your_guild_id’ with the ID of the server you want to check roles against. This should effectively ignore DMs from users with specified roles.
hey samuel, i think ur almost there! try changing the line with ‘roles’ to:
if msg.guild and any(role.name in ignored_roles for role in msg.author.roles):
cuz DMs dont have guild info, so u need to check if its a server msg first. hope this helps!
I’ve dealt with a similar issue before, and I can share what worked for me. Instead of checking roles in the on_message event, I found it more reliable to use a custom check function. Here’s an approach that might help:
def is_not_ignored(ctx):
if isinstance(ctx.channel, discord.DMChannel):
guild = bot.get_guild(your_main_guild_id)
member = guild.get_member(ctx.author.id)
return member and not any(role.name in ignored_roles for role in member.roles)
return True
@bot.command()
@commands.check(is_not_ignored)
async def some_command(ctx):
# Your command logic here
@bot.event
async def on_message(message):
if message.author == bot.user:
return
if isinstance(message.channel, discord.DMChannel) and is_not_ignored(await bot.get_context(message)):
# Your DM handling logic here
await bot.process_commands(message)
This method allows for more flexibility and can be easily applied to multiple commands or events. Remember to replace ‘your_main_guild_id’ with the ID of the server you’re checking against. Hope this helps!