Reputation: 45
I want all users who have the role "notify" to receive a DM. But I would like to do that with a @client.event, but it gives me a lot of problems.
It is a voice support offered on e.g. the message "1" plays a file in a voice channel. If someone needs help from a supporter, all supporters should receive a direct message. The problem is that you can't use a ctx for a client.event.
@client.event
async def on_message(message):
if message.content.startswith('1'):
print('Hi')
role = 'notify'
msg = 'Hello World!'
members = [m for m in '''What do I must put in here?''' if discord.guild.User in m.roles]
for m in members:
try:
await m.send(msg)
print(f":white_check_mark: Message sent to {m}")
except:
print(f":x: No DM could be sent to {m}")
return
else:
print('Error')
Upvotes: 0
Views: 710
Reputation: 4743
You should get the guild and the role with discord.utils.get
or guild.get_role()
, client.get_guild()
. After that, you can iterate through the member's role and check if they have the role, if they have, you can send message.
@client.event
async def on_message(message):
if message.content.startswith('1'):
print('Hi')
guild = client.get_guild(guild id)
role = guild.get_role(role id)
msg = 'Hello World!'
members = [member for member in guild.members if role in member.roles]
for m in members:
try:
await m.send(msg)
print(f":white_check_mark: Message sent to {m}")
except:
print(f":x: No DM could be sent to {m}")
return
else:
print('Error')
But this code is really inefficient because you're iterating through all the members every time someone sends a message. So you should add a on_ready
event in your code and you should create the members
list in there.
@client.event
async def on_ready():
global members
guild = client.get_guild(guild id)
role = guild.get_role(role id)
members = [member for member in guild.members if role in member.roles]
on_ready
event runs only once, so if you add the specific role to someone after you run the bot, it won't send dm to that member. So you also need to create a task loop to check this every 120 seconds or more(if you're sure that you won't give that role to anybody else, you don't need to create a task).
@tasks.loop(seconds=120)
async def check_role():
global members
guild = client.get_guild(guild id)
role = guild.get_role(role id)
members = [member for member in guild.members if role in member.roles]
check_role.start()
So, finally, your code should seem like that:
@client.event
async def on_ready():
global members
guild = client.get_guild(guild id)
role = guild.get_role(role id)
members = [member for member in guild.members if role in member.roles]
@tasks.loop(seconds=120)
async def check_role():
global members
guild = client.get_guild(guild id)
role = guild.get_role(role id)
members = [member for member in guild.members if role in member.roles]
@client.event
async def on_message(message):
if message.content.startswith('1'):
print('Hi')
for m in members:
try:
await m.send(msg)
print(f":white_check_mark: Message sent to {m}")
except:
print(f":x: No DM could be sent to {m}")
return
else:
print('Error')
Also, I'm not sure but you can try to use AuditLogs
. I don't know how to use it very good but you can check the API References audit log data.
Upvotes: 1