Reputation: 13
When trying to do await member.add_roles(role)
where member
is a User, it gives me the following error:
'User' object has no attribute 'add_roles'
However, when I look online, there is no mention of such an error, implying that this error isn't supposed to happen.
If it helps, this is the section of the code where this error happens:
@bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
guild = discord.utils.get(bot.guilds, name='The Molehill')
channel = bot.get_channel(740608959207047250)
member = await bot.fetch_user(payload.user_id)
message = await channel.fetch_message(payload.message_id)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
rules_message = message=await channel.fetch_message(740891855666806866)
role = discord.utils.get(guild.roles, name="Worker Mole", id=739514340465705027)
if payload.emoji.name == EMOJI:
if message == rules_message:
await member.add_roles(role)
await bot.send(MESSAGE)
Upvotes: 1
Views: 4051
Reputation: 1173
A user object is not directly linked with a guild. This is the reason it doesnt have functions to add roles to it. As roles are part of guild functionality.
If we want to fix this we need to get an object that is linked with a guild. The closest match is in this case the member
object.
So instead of retrieving the user object and retrieving a member object instead should solve the problem:
@bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
guild = discord.utils.get(bot.guilds, name='The Molehill')
channel = bot.get_channel(740608959207047250)
member = await guild.get_member(payload.user_id)
message = await channel.fetch_message(payload.message_id)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
rules_message = message=await channel.fetch_message(740891855666806866)
role = discord.utils.get(guild.roles, name="Worker Mole", id=739514340465705027)
if payload.emoji.name == EMOJI:
if message == rules_message:
await member.add_roles(role)
await bot.send(MESSAGE)
But when we read the documentation about the on_raw_reaction_add
. We see that this can be much more efficient without needing lookups through the bot.
For example in the event documentation you see we get a payload object. The payload object has the following data (and more just read the documentation):
Notice that we have a member object. We can retrieve the following from it:
So updating the old code to the following increases the performance as we dont need to look up stuff through the bot unnessecarily. Note: I removed some redundant code in this example, I assume you only run this bot in 1 guild, because you are using specific ID's that wont work in other guilds.
@bot.event
async def on_raw_reaction_add(payload):
EMOJI = '✅'
member = payload.member
guild = member.guild
# If you want to run your bot on multiple guilds. Then the code under this comment should be updated.
channel = guild.get_channel(740608959207047250)
MESSAGE = "{user.name} is now part of the Mole Workforce!"
role = guild.get_role(739514340465705027)
if payload.emoji.name == EMOJI:
await member.add_roles(role)
await bot.send(MESSAGE)
Upvotes: 2
Reputation: 96
You are trying to add a role to a user
object, however they can only be added to member
objects. While a user
represents a user on discord a member
represents a member of a guild.
More information on members in the documentation
Upvotes: 2