I start creating a Discord bot with the Python API of Discord. So, I tried to make a command that give roles on a discord server. Here is my code :
client = commands.Bot(command_prefix = '/')
#client.command()
async def addrole(ctx, role: discord.Role, user: discord.Member):
if ctx.author.guild_permissions.administrator:
await user.add_roles(role)
await ctx.send(f"Successfully given {role.mention} to {user.mention}.")
When I try to use the command, any error happear. I try to make like the websearch I've done but still don't work. Can someone help me ?
I don't believe basic things like these would require Discords intents, especially the "member intent". What I have done is I've cleaned up your code and required a member to be passed before a multiple string role, if needed.
#client.command()
#commands.has_permissions(manage_roles=True)
async def addrole(ctx, member: discord.Member = None, *, role: discord.Role = None):
if role == None:
await ctx.send(f'Provide a role to add')
return
if member == None:
await ctx.send(f'Provide a member to add a role')
return
await member.add_roles(role)
await ctx.send(f"Successfully added role, {role} to {member.name}")
Related
My Goals:
When the user tried to use the command but mentioning a roles, it will sends an errors to the users.
My Current Codes:
#bot.command()
async def say(ctx, *, message: str):
try:
take_roles = ctx.guild
roles = [role.mention for role in take_roles.roles]
if message in roles:
await ctx.send(
f"{ctx.author.mention}, Hm? Trying to Abusing Me? Mention `#roles` is **NOT** Allowed on Say Command!"
)
else:
await ctx.message.delete()
await ctx.send(message)
You were trying to find the whole message in roles. A better idea is to look for role mentions inside of the message.
#bot.command()
async def say(ctx, *, message: str):
for role in ctx.guild.roles:
if role.mention in message:
await ctx.send(f"{ctx.author.mention}, Hm? Trying to Abusing Me? Mention `#roles` is **NOT** Allowed on Say Command!")
return # stops function if the role mention is in message
# if it didn't match any roles:
await ctx.message.delete()
await ctx.send(message)
I created an add role command. It works fine but my problem is that it works only with the id of the role. I was wondering how could I somehow convert the id of the role to the name of the role.
This is the code.
#commands.has_permissions(manage_messages=True)
async def addrole(self, ctx, member: discord.Member,rolename):
if member is None:
member=ctx.author
role = discord.utils.get(ctx.guild.roles, id=rolename)
await member.add_roles(role)
await ctx.send(f"{member.mention}was added {rolename}")
Any help is appreciated.edit
solution
I made use of the 2 comments and created this command which works perfectly.
#commands.command()
#commands.has_permissions(manage_messages=True)
async def addrole(self, ctx, role: discord.Role, member: discord.Member=None):
if member is None:
member=ctx.author
await member.add_roles(role)
await ctx.send(f"{member.mention} was added {role}")```
You could declare your rolename variable as a discord.Role and make use of the implicit role converter that will be applied, just like what happens to your member object. Your function would look something like this:
#commands.has_permissions(manage_messages=True)
async def addrole(self, ctx, member: discord.Member, role: discord.Role):
await member.add_roles(role)
await ctx.send(f"{member.mention} was added {rolename}")
You can use role converter just like you used member converter. You can pass role: discord.Role in arguments. Then, you just have to mention the role.
Also, you have to assign a default value None to the member argument in order to check if it's None.
#commands.has_permissions(manage_messages=True)
async def addrole(self, ctx, role: discord.Role, member: discord.Member=None):
if not member:
member=ctx.author
await member.add_roles(role)
await ctx.send(f"{member.mention}was added {role.name}")
References
RoleConverter
discord.Role.name
So I tried to make an add role command for my bot:
#bot.command()
async def addrole(ctx, member: discord.Member, role: discord.Role):
await member.add_roles(role)
await ctx.send(f'{member} now has the {role} role')
but it did not work, the bot didn't add the role or send the message, no errors either, is there something I did wrong?
Sorry for being late on this but the answer is simple. Your code is fine just when typing the command use
(prefix) #user mention #role
Ex. !addrole #huss_a #example
I would also recommended putting #commands.has_permissions reference at the beginning so only admins can use this and users can't give themselves any role they want like so:
#bot.command()
#commands.has_permissions(manage_roles=True)
async def addrole(ctx, member: discord.Member, role: discord.Role):
await member.add_roles(role)
await ctx.send(f"{member} now had the {role} role")
You can also use this code:
#bot.command()
#commands.has_permissions(manage_roles=True)
async def addrole(ctx, role: discord.Role, user: discord.Member):
await user.add_roles(role)
await ctx.send(f"{role.mention} was added to {user.mention})
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)
I have tried and researched a lot of times but still could not find it. I want to make a command that deletes a selected role in the server. Here is what I came up with (Don't currently care about permissions):
#bot.command(pass_context=True)
async def delrole(ctx, role: discord.Role):
await bot.delete_role(role)
await bot.say("The role {} has been deleted!".format(role.name))
If you could help that would be awesome. I used role: discord.Role and delete_role(). Thank you for reading. If you have a solution, feel free to comment it.
NOTICE: This post was for the old version of discord.py and will no longer work. If you are looking for an equivalent solution for the rewrite (v1) version of discord.py, you can use the following code:
#bot.command(pass_context=True)
async def delrole(ctx, *, role_name):
role = discord.utils.get(ctx.message.guild.roles, name=role_name)
if role:
try:
await role.delete()
await ctx.send("The role {} has been deleted!".format(role.name))
except discord.Forbidden:
await ctx.send("Missing Permissions to delete this role!")
else:
await ctx.send("The role doesn't exist!")
You could do something like this to avoid being able to only delete roles that are mentionable
#bot.command(pass_context=True)
async def delrole(ctx, *,role_name):
role = discord.utils.get(ctx.message.server.roles, name=role_name)
if role:
try:
await bot.delete_role(ctx.message.server, role)
await bot.say("The role {} has been deleted!".format(role.name))
except discord.Forbidden:
await bot.say("Missing Permissions to delete this role!")
else:
await bot.say("The role doesn't exist!")
where you do !delrole name_of_role and use discord.utils.get to find the role by its name from the list of roles on the server.
Then if it's found you can delete it with bot.delete_role which takes 2 arguments, the server you want to delete the role from and the role itself
All you're missing is the server argument to delete_role, (which it shouldn't need, as every Role knows what Server it is from)
#bot.command(pass_context=True)
async def delrole(ctx, role: discord.Role):
await bot.delete_role(role.server, role)
await bot.say("The role {} has been deleted!".format(role.name))
You were already on the right track using converters
The above solutions will not work server has to be guild and the actual role deletion can be a lot easier.
#bot.command(pass_context=True)
async def delrole(ctx, *, role_name):
role = discord.utils.get(ctx.message.guild.roles, name=f"{role_name}")
await role.delete()
await ctx.send(f"[{role_name}] Has been deleted!")
This solution is working as of 28/08/2021.