First remember that you're limited to 20 reactions per message.
To add a reaction, you have to pass through its Unicode version, or the discord.Emoji
object. As said in the faq, you need to use the Client.add_reaction
, which takes the message and the emoji to react with as arguments.
To get the discord.Message
object, simply assign the sent message to a variable: reacted_message = await client.send_message(channel, embed=embed)
.
You may iterate on a tuple containing the reactions to add (with a simple for loop) to make the bot react to the message.
Instead of using the Client.wait_for_reaction
method, which is useful when you can only react in a limited time, I suggest you use the on_reaction_add
event, which will feedback a discord.Reaction
and the discord.User
whom reacted.
In this event, you need to compare the message which got a reaction, accessible with discord.Reaction.message
with the message you are watching. That's why the message we kept in a variable before should be saved somewhere accessible, such as an attribute of your bot (let's say self.watched_messages
), so you can first check if the message is a "watched one". Instead of using the message object directly, I suggest you use its ID as a key in a dict (self.watched_messages
), the value being another dict: the 'role-giving' reactions (their Unicode value, or ID if customs) and the roleID to give.
If the reacted message ID is in the dict, and if the emoji is in the list indexed by the messageID in the key, then you use Client.add_roles
to add the role to the Member.
As you only get the discord.User
which reacted, you need to get the right discord.Member
to add a role to. You may pass by the discord.Message.server
.
Similarly (keeping the same nested dicts), use the on_reaction_remove
event to remove the role, with Client.remove_roles
.
this is a pseudo-code for what I had in mind
# template of the nested dict:
watched_messages = {
messageID: {
regularEmojiName: roleID,
customEmojiID: roleID
}
}
async def manage_reaction(self, reaction, user, added: bool):
if not reaction.message.id in self.watched_messages:
return
messageID = reaction.message.id
mapping = self.watched_messages[messageID]
if not reaction.emoji in mapping:
# reaction.emoji is str if normal emoji or ID if custom, but we use both as keys in mapping
return
member = discord.utils.get(reaction.message.server.members, id=user.id)
role = discord.utils.get(reaction.message.server.roles, id=mapping[reaction.emoji])
if added:
await client.add_roles(member, role)
else:
await client.remove_roles(member, role)
@client.event
async def on_reaction_add(self, reaction, user):
await self.manage_reactions(reaction, user, True)
@client.event
async def on_reaction_remove(self, reaction, user):
await self.manage_reactions(reaction, user, False)