Right now I'm working on a command for my discord bot where I create a role named after a user, and then automatically assign it to that user. The only problem I'm running into is trying to assign the role without knowing its id yet to the person mentioned.
My command so far:
#client.command(aliases = ["cmr", "CMR"])
#commands.has_permissions(manage_roles=True)
async def creatememberrole(ctx, *, member:discord.Member):
author = ctx.message.author
guild = ctx.guild
print(author.display_name)
await guild.create_role(name=str(member.display_name))
await member.add_roles()
#need help here ^
It can be done by utils.get easily, no need of for loop
role = discord.utils.get(ctx.guild.roles, name=member.display_name)
await member.add_roles(role)
In your case there is no need of any for loop/utils.get, just assign the create_role() method to a variable and use that variable
#client.command(aliases = ["cmr", "CMR"])
#commands.has_permissions(manage_roles=True)
async def creatememberrole(ctx, *, member:discord.Member):
author = ctx.message.author
guild = ctx.guild
print(author.display_name)
role = await guild.create_role(name=str(member.display_name))
await member.add_roles(role)
You could go trough the list of all the roles, and find the role you created and assign this role. Here's an example:
for role in message.channel.guild.roles:
if role.name == str(member.display_name):
await member.add_roles(role)
Related
so my code looks like this:
#bot.command()
async def admin(ctx, user: discord.Member):
await ctx.send("hellooooooo")
guild = ctx.guild
await guild.create_role(name="role name")
await user.add_roles(guild)
but the role is created but it fails to give the role to the person
What you're doing here is trying to add the role guild to the member. The problem is that guild is not a role at all, but the whole server.
You must add the newly created role, the one that is returned by guild.create_role(name="role name").
Here's how to do it :
#bot.command()
async def create_and_add_role(ctx, user: discord.Member):
guild = ctx.guild
role = await guild.create_role(name="New role")
await user.add_roles(role)
await ctx.send("Role created and added!")
Some code
Something like this should work:
#Bot.command()
#commands.has_permissions(administrator = True)
async def CreateAddRole(ctx, User:discord.Member, RoleName:str):
await ctx.message.delete()
role = await ctx.guild.create_role(name = RoleName)
await User.add_roles(role)
await ctx.send(embed = discord.Embed(title = "NEW ROLE", description = f"{ctx.message.author.mention} created the role {role.mention} and assigned it to {User.mention}", color = discord.Color.green())
Try running the code above, because the embed seems more professional than a simple message.
so i want to make a command that removed all the roles from a member and adds a role to the member after clearing the roles from him/her
here is what i have
#client.command()
async def prison(ctx, member: discord.Member):
role = discord.utils.get(ctx.guild.roles, name='Prisoner')
await member.remove_roles(member.roles)
await member.add_roles(role)
await ctx.send(f"{member} is imprisoned!")
now this adds the role to them but doesnt clear roles, anyone know why?
If you just want to remove all the roles it is easier to use the edit() method. Like this:
#client.command()
async def prison(ctx, member: discord.Member):
role = discord.utils.get(ctx.guild.roles, name="Prisoner")
await member.edit(roles=[])
await member.add_roles(role)
await ctx.send(f"{member} is imprisoned!")
*Also if you get the MissingPermissions error it means that the Bot is lower in hierarchy then the user that you want to "imprison". To fix that, in guild settings move bots role higher then this user role.
If you have any more problems feel free to ask in comments.
my bot has a command called mute and basically, it creates a role and gives it to the person but the problem is when it does that ppl with higher roles still are able to talk. how can I put the mute role on top of every role in the server? and I mean in every server, not just one
So you can't put the mute role above the bot role, but the following should help:
#commands.command()
async def mute(self, ctx, member: discord.Member):
guild = ctx.guild
role = await guild.create_role(name='muted', hoist=True)
all_roles = await guild.fetch_roles()
num_roles = len(all_roles)
print(f'The server has {num_roles} roles.')
await role.edit(reason=None, position=num_roles - 2)
print('Created new role!')
await member.add_roles(role)
await ctx.send(f'{member} has been muted.)
So what we did is check how many roles the server has, create a new role and put it to the top/under the bot role.
If you're changing a role to a position lower than the top, I would suggest using the role.edit method, passing a position value.
However, as for your question, which is putting a role at the top after creating this, you should use the discord.Client.move_role()
As for actually creating the role:
If you're on the rewrite, use this
guild = ctx.guild
await guild.create_role(name="role name")
and change "role name" with the name of the role you want to create. If you want to make the role depending on what the user says you can do something likes this:
#client.command()
async def rolecreate(ctx, arg):
guild = ctx.guild
await guild.create_role(name=arg)
Here, you'd have to do (lets say your prefix is !): "!rolecreate Moderator" and it would only create a role.
For the async branch:
author = ctx.message.author
await client.create_role(author.server, name="role name")
Just in case you want the bot to have a command that adds the role here you go:
For the rewrite branch
role = discord.utils.get(ctx.guild.roles, name="role to add name")
user = ctx.message.author
await user.add_roles(role)
If you want to add a role mentioned in the command, you do for example:
#client.command()
async def addrole(ctx, arg):
role = discord.utils.get(ctx.guild.roles, name=arg)
user = ctx.message.author
await user.add_roles(role)
For the async branch:
user = ctx.message.author
role = discord.utils.get(user.server.roles, name="role to add name")
await client.add_roles(user, role)
Hope this helped!
my program doesn't output any errors telling me what's wrong but I'm trying to assign a role to me when I type .role it just says no... go away
code:
async def role(ctx):
if ctx.message.author == 'ItsJustLogic#9893':
user = ctx.message.author
await user.add_roles('The Great Mountain Chicken')
await ctx.send('done')
else:
await ctx.send('no... go away')
ctx.message.author returns you discord.Member so you cannot compare it with a string. You should use ctx.author.name and ctx.author.discriminator. name returns you the name, in this case it's ItsJustLogic, and discriminator returns you 9893. So you can check your name with combining them.
Also, you can't add role with the name of the role, you have to get role with discord.utils.get or guild.get_role() then you can add the role.
async def role(ctx):
member = ctx.author
if f'{member.name}#{member.discriminator}' == 'ItsJustLogic#9893':
role = discord.utils.get(ctx.guild.roles, name='The Great Mountain Chicken')
# or you can use role = ctx.guild.get_role(role id)
await member.add_roles(role)
await ctx.send('done')
else:
await ctx.send('no... go away')
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