How to add options to a argument in slash command? - discord.py

How do I add options to a slash command like:
I'm not asking for a code, but I can't find out how to add options like these into a slash command.
Please answer this.

I use nextcord but its similiar for discord.py replace nextcord with discord
#nextcord.slash_command
async def command(self, interaction: Interaction, category: str = nextcord.SlashOption(name="", description="", choices=["option1", "option2"])):
if category == "option1":
await interaction.response.send_message("hello")
elif category == "option2":
await interaction.response.send_message("bye")
This slash command is inside a cog

Related

Custom help command

Hi I’m trying to code a simple discord bot using discord.py, and one of the things I want my bot to do is send a nice custom embed when a user uses the !help command. So far I know that this simple code, which some people provided in other questions on stackoverflow about custom help commands:
class help(commands.MinimalHelpCommand):
async def send_pages(self):
destination = self.get_destination()
e = discord.Embed(title="Help:", description="description", colour=discord.Colour.blurple(), timestamp=datetime.datetime.utcnow())
await destination.send(embed=e)
client.help_command = help()
works, but the thing is when someone wants to use !help on a specific command or category, the bot will only send the send_pages command. I tried modifying the code and added
async def send_page_command(self, *, command):
destination = self.get_destination
command_e = discord.Embed(title="Dogluva:robot's Help:", description=f"{command.description}", colour=discord.Colour.blurple(), timestamp=datetime.datetime.utcnow())
await destination.send(embed=command_e)
But this doesn’t help. Anyone know what I’m doing wrong here? I’ve set the description for all the commands I wrote in my cogs using commands.command(description=“description") but I don’t know how to make a custom help command access those descriptions.
First, remember to delete the default help command (discord automatically has help command), so you need to delete it first:
client.remove_command('help') # before your own "help" command
# or
client = commands.Bot(command_prefix="<your prefix>", help_command=None) # when you create client
Basic help command:
#client.command()
async def help(ctx):
embed = discord.Embed(title="Help", description="Write your own description here", colour=discord.Color.blue())
await ctx.send(embed=embed)
But you can make it even better. Read more about Embeds in the documentation and check this template:
instead of send_page_command(self, *, command): you can try using send_command_help(self, command):
https://gist.github.com/InterStella0/b78488fb28cadf279dfd3164b9f0cf96
#client.command()
async def help(ctx, *, command=None):
if command == None:
e = discord.Embed(title="Dogluva:robot:'s Help:", description=“Custom Description", colour=discord.Colour.blurple(), timestamp=datetime.datetime.utcnow())
elif command == “{command}":
e = discord.Embed(title="Dogluva:robot:'s Help:", description=“Command Description", colour=discord.Colour.blurple(), timestamp=datetime.datetime.utcnow())
await ctx.send(embed=e)
I just created different cases for each command

Why cant I restrict command use for my bot - discord.py

'''
#client.event
#commands.has_role('xrole')
async def on_message(message):
#Commands
if message.content.startswith("!set"):
credits_message = message.content.split(" ", 2)
user_name = credits_message[1]
credit_add_amount = credits_message[2]
db[user_name] = int(credit_add_amount)
#DB Stuff
await message.channel.send(user_name + "has been set with " + credit_add_amount + ", For further credit adgustment use !add")
'''
For some reason Users with or without the xrole can acces the bot even with the #commands restriction
User without xrole^
user with xrole ^
firstly don't use on_message for commands, it's much better to use #bot.command
second: this code should work well for you
#bot.command(pass_context=True)
#commands.has_role("xrole")
async def role_check(ctx):
await ctx.channel.send('''you have the role "xrole"''')
#role_check.error
async def info_error(ctx, error):
if isinstance(error, (commands.MissingRole, commands.MissingAnyRole)):
await ctx.channel.send('''you do not have the role "xrole"''')
Because Checks are for Commands, not for Events, so the has_role decorator will never be used. You should be using commands instead of manually parsing everything in on_message anyways, it makes a lot of stuff way less cumbersome.
Here's an explanation from the docs how to make proper commands instead: https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html

Check if a user id is in a list of user ids to allow command access - discord.py

im fairly new to python and have been writing a discord bot for a server with me and a few friends as practice. I've added a few commands that could be pretty disruptive if all users had access to them at all times and have been trying to add a method to enable and disable access to them without using discord roles but a python list instead. I added a command that i can use to to add their user id to a list, but when the user tries to use the command they receive a permission error.
the code below is the problematic code from a cog
modlist = []
def ListCheck():
async def IsInList(ctx):
member = ctx.message.author.id
return member in modlist
return commands.check(IsInList)
#commands.command()
async def AddUser(self, ctx, *, question):
modlist.append(question)
#commands.command()
async def ViewModList(self, ctx):
await ctx.send('User ids that have access:')
for i in range(0, len(modlist)):
await ctx.send(modlist[i])
#commands.command()
async def ClearModList(self, ctx):
modlist.clear()
await ctx.send('Modlist cleared')
#commands.command()
#ListCheck()
async def PermTest(self, ctx):
await ctx.send('user is in modlist')
Any help would be hugely appreciated
One way you could do it would be to use commands.check(). The function in the code below checks if the message author, ctx.author, is in the given list, modList. If the author is in this list when the command 'test' is invoked, then the bot will send "You are a mod!", otherwise it will raise a check error.
modList = [394506589350002688, 697725862128386048] # just some ids as examples
def check_Mod(ctx):
if ctx.author.id in modList:
return ctx.author.id in modList
#commands.command()
#commands.check(check_Mod)
async def test(ctx):
await ctx.send("You are a mod!")
The above working is shown in the image below:
To answer is there is a way to add user ids to the list via a command?, you may either use a json or text file. In this case, I will use a text file since it's simpler, and also because my json isn't as fluent as others.
Here's an example of how your text file may look like:
394506589350002688
697725862128386048
First you need to read the file and check whether the author's id is in the file. We will be changing the check_Mod function for this. If you want to know more about reading through a text file, or feel that you may need a more efficient way, you may have a look at this: How to search for a string in text files?
def check_Mod(ctx):
with open('Mod.txt') as f: # do change the 'Mod.txt' to the name that suits you. Ensure that this file is in the same directory as your code!
if str(ctx.author.id) in f.read(): # this is reading the text file and checking if there's a matching string
return ctx.author.id
Now for writing the author id into your text file.
#commands.command()
#commands.check(check_Mod)
async def add_Mod(ctx, user:discord.Member=None):
if user == None:
await ctx.send("Please provide a user to add as a Mod!")
return
# First we'll make some functions for cleaner, more readable code #
def is_Mod(user_id):
## This function will check if the given id is already in the file. True if in file, False if not ##
with open('Mod.txt', 'r') as f:
if str(user_id) in f.read():
return True
else:
return False
def add_Mod(user_id):
## This function will add the given user id into the given text file, Mod.txt ##
with open('Mod.txt', 'a') as f: # 'a' is used for appending, since we don't want to overwrite all the ids already in the file
f.write(f"{str(user_id)}\n")
f.close()
# Now we put those functions to use #
if is_Mod(user.id) == True:
await ctx.send(f"The user {user} is already a Mod!")
else:
add_Mod(user.id)
await ctx.send(f"{user} added as a Mod!")
The above should work as seen in the image below.
p.s. If you have any other questions, please post them as a new question, thank you!

discord.py rewrite/delete standard help command

I want to make a custom !help command but I have to disable the standard one first. When I do:
client = commands.Bot(command_prefix='!')
client.remove_command('help')
Or
client = commands.Bot(command_prefix='!', help_command=None)
It still shows this message:
[1]: https://i.stack.imgur.com/Ut9dO.png
Anyone how to delete it?
A better way of making a help command is by using groups.
Firstly remove the default command;
client.remove_command("help")
After that make a help command by using this method:
#client.group(invoke_without_command= True)
async def help(ctx):
# insert your help command embed or message here
embed= discord.Embed(title="Help", description="List of commands")
embed.add_field(name="Moderation", value="!help moderation")
embed.add_field(name="Misc", value="!help misc")
await ctx.send(embed=embed)
You are done with the help command, now when you have to make help for a category or command. You can do it like this:
#help.command()
async def moderation(ctx):
embed= discord.Embed(title="Moderation", description="List of Moderation commands")
embed.add_field(name="Commands", value="ban, kick, warn, mute, unban")
await ctx.send(embed=embed)
Now if user will type, !help moderation the above embed/message will be sent.
With the recent changes in discord.py-rewrite you do not need to delete the standard help command to create your own help command. To achieve what you want you will need to subclass HelpCommand or MinimalHelpCommand, then pass it to bot.help_command.
The following code shows the standard way of subclassing MinimalHelpCommand:
class MyHelpCommand(commands.MinimalHelpCommand):
def get_command_signature(self, command):
return '{0.clean_prefix}{1.qualified_name} {1.signature}'.format(self, command)
class MyCog(commands.Cog):
def __init__(self, bot):
self._original_help_command = bot.help_command
bot.help_command = MyHelpCommand()
bot.help_command.cog = self
def cog_unload(self):
self.bot.help_command = self._original_help_command
Following the code above you will get the behaviour that you want to achieve, but if you still want to disable the default help command for any reasons, nowadays you can do it passing None to the help_command kwarg.
For more info, discord.py documentation:
https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#help-commands

Is there a way to get the parameters of a command?

I was wondering if there is a way to get the parameters of a command to show how to use it. I have a custom help command, but I tried doing something that uses the same description thing that you put in the decorator. It doesn't work (doesn't give me any errors or anything) but I don't know why.
#commands.command()
async def format(self, ctx, command):
formatting = discord.Embed(title=f"Formatting for .{command}", description=command.description)
formatting.set_thumbnail(url=self.bot.avatar_url)
formatting.set_footer(text=f"Requested by {ctx.author.mention}", icon_url=ctx.author.avatar_url)
ctx.send(embed=formatting)
Here's one of my commands that has the description thing:
"""Change Nickname command"""
#commands.command(aliases=['chnick'], description="Usage: .nick [member mention] [nickname to change to]")
#commands.has_permissions(manage_channels=True)
async def change_nick(self, ctx, member: discord.Member, nick):
"""Changes a user's nickname\nAliases: chnick"""
await member.edit(nick=nick)
await ctx.send(f"Nickname was changed for {member.mention}")
You need to get the command using get_command()
#commands.command()
async def format(self, ctx, command):
command = self.bot.get_command(command)
formatting = discord.Embed(title=f"Formatting for .{command.name}", description=command.description)
formatting.set_thumbnail(url=self.bot.avatar_url)
formatting.set_footer(text=f"Requested by {ctx.author.mention}", icon_url=ctx.author.avatar_url)
await ctx.send(embed=formatting)

Resources