Reputation: 161
I am currently building a discord bot using Discord py with one of its command can only be used by a user with one of several roles that I have set up.
Currently, I store all of the role name in a list since I also have a command to add new role to that list. This is a snippet of what I have right now
role_name = ["Moderator"]
@bot.command(name='role',help='adding role for staff moderating role (admin only command)')
@commands.has_permissions(administrator=True)
async def add_role(ctx, role):
if role not in role_name:
role_name.append(role)
print(*role_name) #use case 1: when run this command to add 'mine' it print "Moderator mine"
@bot.command(name='add',help='Add channel, when you run this command, you must be in the channel ')
@commands.has_any_role(role_name)
async def add_channel(ctx):
if ctx.channel.id not in channel_id:
channel_id.append(ctx.channel.id)
I have double check on my account's role on discord and it already have Moderator role
However, when I run the command to test - this is what i got
discord.ext.commands.errors.MissingAnyRole: You are missing at least one of the required roles: '['Moderator']'
Is there any way to do what I want?
/Edit: Add the adding role to the role_name for the sake of clarity. I also have tried ",".join(role_name)
in has_any_role()
however, I still get this issue discord.ext.commands.errors.MissingAnyRole: You are missing at least one of the required roles: ''
Upvotes: 0
Views: 1402
Reputation: 161
After some extra research regarding the decorator. Apparently, based on this answer https://stackoverflow.com/a/64544809/10467473 -
A decorator is invoked once as soon as the module is imported, and then the function that gets called is whatever was provided by the decorator definition.
Therefore, I tried a different approach to check the role like how I wanted it to be and now it works perfectly fine! This is the method that I use.
role_name=[]
@bot.command(name='role',help='adding role for staff moderating role (admin only command)')
@commands.has_permissions(administrator=True)
async def add_role(ctx, role):
if role not in role_name:
role_name.append(role)
@bot.command(name='add',help='Add channel, when you run this command, you must be in the channel ')
async def add_channel(ctx):
global role_name
user_role = ctx.author.roles
for rl in user_role:
if (rl.name in role_name):
if ctx.channel.id not in channel_id:
channel_id.append(ctx.channel.id)
break
Upvotes: 0
Reputation: 333
has_any_role()
accepts *items
and is looking for str
or int
objects. The list is read as a string '["Moderator"]'
. You can check this by trying to rename your rolename as well.
A simple fix for this would be:
@commands.has_any_role(*role_name)
for your bot from read the list as a string.
So it looks like this:
role_name = ["Moderator"]
@bot.command(name='add',help='Add channel, when you run this command, you must be in the channel ')
@commands.has_any_role(*role_name)
async def add_channel(ctx):
if ctx.channel.id not in channel_id:
channel_id.append(ctx.channel.id)
Upvotes: 1