I have a discord.py bot that I want to code to do the following things:
Now based on the docs and previous projects, I came up with this function for adding reactions:
async def get_reacts(user, client, message, emojis, timeout=None):
for emoji in emojis:
await message.add_reaction(emoji)
try:
def check(reaction, reactor):
return reactor.id == user.id and reaction.emoji in emojis
reaction, user = await client.wait_for("reaction_add", check=check, timeout=timeout)
return reaction.emoji
except:
pass
This code works perfectly when in a server, but when the message is in a DM, it does something peculiar. First, it doesn't detect the user reactions at all. When I put a print statement within the check function, it told me that it parsed one reaction, and that reaction was the bot itself reacting with the thumbs down. When I reacted to the message, the check function was never called.
I saw some other solutions used a Cog listener to go through all added reactions, and use a global list of messages. However, this won't work for my bot as everything it does is in one command. Additionally, it takes up a lot of memory. This is why I went with the client.wait_for
approach instead.
Is there a problem with using client.wait_for
in DMs? Should I use Cog listeners instead? Or is it a problem with my code? Any help is appreciated. Thanks in advance!
EDIT: Intents enabled: None (Do I need an intent to check DM reactions?)
EDIT 2: Added default intents, still the same issue
EDIT 3: How I am using the get_reacts
function:
msg = await context.author.send("Message")
reaction = await get_reacts(context.author, self.client, msg, ["👍", "👎"])
In order to receive reactions event in DM from users you need to enable the members
intent.
So the only thing you need to do is create your default intent and then set the members
value to True:
intents = discord.Intents.default()
intents.members = True
Op was asking for clarification so here it is.
If you take a look at the discord.Intents.default()
code:
@classmethod
def default(cls):
self = cls.all()
self.presences = False
self.members = False
return self
You can see it does two things:
presence
and members
So the assumptions of op:
This makes me think that maybe dm_reactions and reactions are not included in default intents
is not true. Because only presence and members are removed, all the other ones are in it.
Now, turns out even with dm_reactions
, reactions
, and dm_messages
on, you still need to have the members
on. So that is what is happenning in the solution.
And as OP pointed out, it does work with discord.Intents.all()
because, in this case, the member
intent is enabled.
Yes, you need intents. dm_reactions
and reactions
(It shouldn't work without them). Easiest for you would be to simply enable default intents
intents = discord.Intents.default()
client = commands.Bot(..., intents=intents)
Adding on to Łukasz's answer, I tried some experimentation, and found that using discord.Intents.all()
worked, but not discord.Intents.default()
. This makes me think that maybe dm_reactions
and reactions
are not included in default intents, but are included in all intents? Any clarification on this is still appreciated, as I just started learning discord.py a few months ago.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.