Discord.py | How can i add role to members? - python

I was wondering how I can set a role for a member, after he reacted to an emoji.
I've tried several ways but it hasn't worked anything yet.
AttributeError: 'Guild' object has no attribute 'add_roles'
I always get this error, I tried to replace Guild with User, Payload or Member, but it doesn't find it anyway
I have two file in my 'cogs' folder:
• roles.py - Handles the message with reactions (This file works perfectly)
• reaction.py - 'Listen' to the reactions to the message
import discord
import asyncio
import emoji
from discord.ext import commands
from discord.utils import get
client = commands.Bot(command_prefix='/',preload=True)
class Reaction(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
guild_id = payload.guild_id
guild = self.client.get_guild(guild_id)
user_id = payload.user_id
user = self.client.get_user(user_id)
message_id = payload.message_id
channel = self.client.get_channel(payload.channel_id)
emoji = payload.emoji.name
if message_id == 809523588721934336 and emoji == "🐍" and user_id != 799612948213399572:
message = await channel.fetch_message(message_id)
await message.remove_reaction("🐍", user)
dev = get(guild.roles, id=799632281639321632)
await guild.add_roles(dev)
def setup(client):
client.add_cog(Reaction(client))

I think it makes sense, how are you supposed to add a role to a guild? You must add it to a discord.Member instance, you can get it with payload.member
dev = get(guild.roles, id=799632281639321632)
member = payload.member
await member.add_roles(dev)
Also remember that you must have intents.members enabled
Reference:
RawReactionAddEvent.member
Member.add_roles

In the API reference you can see that Guild does not have the method add_roles. Members do have that method.

Related

How do I give roles to a person that reacted to my message?

In the code below I am trying to give a role to a person whenever they react to my message but this code throws me an error saying that 'int' object has no attribute 'id' the code says that the problem is with this code: await user.add_roles(user.guild.id, user.id, role, reason='reason') how do I solve this issue?
import discord
from discord.ext import commands
import random
client = discord.Client()
#client.event
async def on_ready():
print('ready')
#client.event
async def on_reaction_add(reaction, user):
channel = reaction.message.channel
await channel.send(f'{user.name} has reacted by using {reaction.emoji} emoji, his message was {reaction.message.content}')
role = discord.utils.get(user.guild.roles, name = 'Test_Bot')
await user.add_roles(user.guild.id, user.id, role, reason='reason')
client.run('TOKEN')
As Dominik said, you do not need user.guild.id, user.id if you say await user.add_roles. What is happening is that it is trying to use the user.id (an integer) you passed instead of the user object you use when calling the function to begin with: await user.add_roles(...).
So, get rid of await user.add_roles(user.guild.id, user.id, role, reason='reason'), and make it just: await user.add_roles(role).
Fixed code should be:
import discord
from discord.ext import commands
import random
client = discord.Client()
#client.event
async def on_ready():
print('ready')
#client.event
async def on_reaction_add(reaction, user):
channel = reaction.message.channel
await channel.send(f'{user.name} has reacted by using {reaction.emoji} emoji, his message was {reaction.message.content}')
role = discord.utils.get(user.guild.roles, name = 'Test_Bot')
await user.add_roles(role, reason='reason')
client.run('TOKEN')
TL;DR: Discord.py expects the full member object when you use add_roles(). You give it the integer of the member's ID instead.

I'm getting no results while trying to make a reaction bot with discord.py

My code is:
#client.event
async def on_raw_reaction_add(payload):
message_id = payload.message_id
if message_id == 768549092674502666:
if payload.emoji.name == 'white_check_mark':
role = '<:Member:765291826151555104>'
await member.add_role(role)
and i'm getting no results from the debugger or except when the bot adds a reaction or logs on which are other code completely inaccosiated with this part of the code.
In the new version of discord.py(1.5.x), there're some updates about Intents. Intents are like permissions and for using some of the events or getting members, channels etc. you need to define it before you define the client = discord.Bot(prefix='').
Then, you need to define the member to add role. You can simply do member = payload.member.
And also you need to get role with discord.utils.get(). You can't define a role with string.
import discord
intents = discord.Intents().all()
client = discord.Bot(prefix='', intents=intents)
#client.event
async def on_raw_reaction_add(payload):
if payload.message_id == 768549092674502666 and payload.emoji.name == 'white_check_mark':
guild = client.get_guild(guild id)
role = discord.utils.get(guild.roles, name="role's name")
await payload.member.add_roles(role)
If you want to get more information about Intents, you can check the API References

name 'guild' is not defined

 I am coding a bot to find users with the 'Admin' role on my discord server and do print information (admin username) and store all roles in a list peopleWithRole:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="$")
role_name = "Admin"
peopleWithRole = []
#bot.event
async def on_ready():
print("Logged in as")
print(bot.user.name)
print("------")
role = discord.utils.find(
lambda r: r.name == role_name, guild.roles)
for user in guild.members:
if role in user.roles:
peopleWithRole.append(user)
bot.run("My token")
However, when I run this, returns error 'guild' is not defined. I am just starting out with discord python module. How should I use client or bot in this situation?.
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="$")
role_name = "Admin"
peopleWithRole = []
#bot.event
async def on_ready():
print("Logged in as")
print(bot.user.name)
print("------")
guild = bot.guilds[0]
role = discord.utils.find(
lambda r: r.name == role_name, guild.roles)
for user in guild.members:
if role in user.roles:
peopleWithRole.append(user)
bot.run("My token")
In your find call you reference guild.roles but have never defined guild. You need to select the guild (I believe guilds is a member of bot)
This is a fairly basic python error to debug, and any IDE would identify what is wrong. I suggest you look up some tutorials on how to debug.

channel set permissions and move_to channel

So I am using discord.py to make a discord Client. I am using on_voice_state_update to see if the VoiceState of a member changes.
If a member is inside a specific VoiceChannel, I want the client to create a new voice channel, using the member's username as the name of the channel, and move the member inside that new voice channel. Here is my code:
import discord, asyncio
app = discord.Client()
#app.event
async def on_voice_state_update(user_name, user_id, after):
name2 = str(user_name)
ch = app.get_channel(660213767820410918)
guild = app.get_guild(660213767820410893)
member = str(user_id)
if after.channel == ch:
await guild.create_voice_channel(name=(name2+'`s Room'), category=guild.get_channel(660213767820410908) ,user_limit=99 ,overwrites=(user_name ,{'manage_channels': True}))
await guild.member.move_to(channel, reason=None)
This doesn't work. Could anyone please help me?
There were a couple of errors.
First of all, the event on_voice_state_update accepts three parameters, which are member, before and after instead of user_name, user_id and after.
When you used the guild.create_voice_channel function, you did not pass a proper dictionary and you forgot to assign channel to the newly created channel (that is why channel was undefined).
Finally, you should have used member.move_to instead of guild.member.move_to as guild.member is undefined.
import discord, asyncio
app = discord.Client()
#app.event
async def on_voice_state_update(member, before, after):
username = str(member)
guild = app.get_guild(660213767820410893)
ch = guild.get_channel(660213767820410918)
if after.channel == ch:
channel = await guild.create_voice_channel(
name = (username+"'s Room"),
category = guild.get_channel(660213767820410908),
user_limit = 99,
overwrites = {member: discord.PermissionOverwrite(manage_channels=True)}
)
await member.move_to(channel)
Finally please check that the app is in the server and has the Move Members permission on the server, otherwise member.move_to will throw a discord.Forbidden error.

Discord bot fails to add a role to a user using discord.py

I simply want my bot to add a role to a user in discord. Although the syntax seems simply, apparently I'm doing something wrong.I'm new to python, so I'd appreciate some pointers in the right direction!
bot = commands.Bot(command_prefix='!')
def getdiscordid(discordname):
for guild in bot.guilds:
for member in guild.members:
if member.name == discordname:
return member.id
#bot.command(name='role')
async def role(ctx):
await ctx.message.channel.send("Testing roles")
discordid = getdiscordid("Waldstein")
print ("id: " , discordid)
member = bot.get_user(discordid)
print ("member: ", member)
role = get(ctx.message.guild.roles, name="Egg")
print("role: ", role.name)
await member.add_roles(role)
print("done")
# error handler
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.errors.CheckFailure):
await ctx.send(error)
bot.run(TOKEN)
In this example he successfully retrieves the member, he can't find the Egg role, and doesn't add the role. [Edit: I corrected the line to retrieve the role, that works but still no added role. Added the error handler]
The key issue is that add_roles() adds roles to a Member object not a user.
Made a couple of tweaks...
Changed the get id to get member and return the member object.
changed the name of the command to add_role() to avoid using role as the command and a variable.
changed to await member.add_roles(role)
Try:
def get_member(discordname):
for guild in bot.guilds:
for member in guild.members:
if member.name == discordname:
return member
#bot.command(name='add_role')
async def add_role(ctx):
await ctx.message.channel.send("Testing roles")
member = get_member("Waldstein")
print(f'member is {member} type {type(member)}')
role = get(ctx.guild.roles, name="Egg")
print("role: ", role.name)
await member.add_roles(role)
print("done")
For the answer's sake, I'm writing the whole discord.utils.get instead of just get. Here's your command rewritten:
import discord
#bot.command()
async def role(ctx):
await ctx.send("Testing roles!")
member = discord.utils.get(bot.get_all_members(), name="Waldstein")
# be careful when getting objects via their name, as if there are duplicates,
# then it might not return the one you expect
print(f"id: {member.id}")
print(f"member: {member}")
role = discord.utils.get(ctx.guild.roles, name="Egg") # you can do it by ID as well
print(f"role: {role.name}")
await member.add_roles(role) # adding to a member object, not a user
print("Done!")
If this doesn't work, try printing out something like so:
print(ctx.guild.roles)
and it should return each role that the bot can see. This way you can manually debug it.
One thing that might cause this issue is that if the bot doesn't have the necessary permissions, or if its role is below the role you're attempting to get i.e. Egg is in position 1 in the hierarchy, and the bot's highest role is in position 2.
References:
Guild.roles
Client.get_all_members()
Member.add_roles()
utils.get()
commands.Context - I noticed you were using some superfluous code, take a look at this to see all the attributes of ctx

Categories

Resources