Reputation: 47
I am currently updating my discord bot and wanted to add new functionality which allows me to add and remove commands through discord, without having to modify the code directly.
I found out that there are already existing methods (namely "Bot.add_command" and "Bot.remove_command" which do exactly what I want.
The "remove_command" part works perfectly, but I'm having trouble adding back the command using the add_command function. I've read the documentation but I don't seem to understand what's causing my error (outlined below).
Code:
@client.command()
@commands.has_permissions(administrator = True)
async def removecommand(ctx, command):
try:
client.remove_command(command)
except Exception as err:
print(err)
await ctx.message.add_reaction('✅')
@client.command()
@commands.has_permissions(administrator = True)
async def addcommand(ctx, command):
command = client.get_command(command)
await client.add_command(command)
await ctx.message.add_reaction('✅')
Error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: The command passed must be a subclass of Command
Could someone please help me? I don't seem to understand what this means. Thank you.
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "/Users/name/Desktop/discord mj market/1 mainmarketplace.py", line 121, in addcommand
await client.add_command(command)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/ext/commands/core.py", line 1132, in add_command
raise TypeError('The command passed must be a subclass of Command')
TypeError: The command passed must be a subclass of Command
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/ext/commands/core.py", line 859, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: The command passed must be a subclass of Command
Upvotes: 1
Views: 1100
Reputation: 1037
discord.utils.find(lambda cmd: str(cmd) == "yourcmdname", client.commands)
This will find your bot's command if exists else returns None
. Also if you will use that removed command again, you can disable it.
@client.command()
async def toggle(ctx, cmd):
command = discord.utils.find(lambda c: str(c) == cmd, client.commands)
if command:
command.enabled = not command.enabled
if command.enabled:
await ctx.send(f"{cmd} enabled.")
else:
await ctx.send(f"{cmd} disabled.")
else:
await ctx.send("Command not found")
Upvotes: 3
Reputation: 4700
The argument command
passed to add_command
or remove_command
must be a discord.ext.commands.Command
object. When members of your guild call the command, they will be passing strings to the argument (hence the error message).
There are two ways to get the Command
object corresponding to a command name:
Bot.get_command()
method. This will return the Command
object corresponding to a command name (or alias) or None
, if the command cannot be found. Note: Command names are case-sensitive.Bot.walk_commands()
method. This will return a generator yielding each Command
object connected to the Bot
object.As for the add_command()
method, the argument must also be a Command
object. Thus, you would have to create your own Command
object (which requires a function func
and a name name
, among other things). It would be best to have the functions already defined as Command
objects (using the Bot.command()
decorator). If that is the case, then the above two methods will work as well.
@client.command()
@commands.has_permissions(administrator = True)
async def removecommand(ctx, command):
cmd = client.get_command(command)
if cmd is None:
await ctx.channel.send(f"Command `{command}` does not exist")
client.remove_command(cmd)
await ctx.message.add_reaction('✅')
@client.command()
@commands.has_permissions(administrator = True)
async def removecommand(ctx, command):
for cmd in client.walk_commands():
if cmd.name.lower() == command.lower():
client.remove_command(cmd)
await ctx.message.add_reaction('✅')
return
await ctx.channel.send(f"Command `{command}` does not exist")
Upvotes: 1