I would like to find a way to disable all commands at once using discord.py, I'm semi-new to discord.py and I have not found a way to get it working yet. Here is my code below:
ID='no'
...............
#commands.command()
#commands.is_owner()
async def nocmdrun(self,ctx):
global ID
ID = "yes"
await ctx.send('No Command Run has been activated.')
#commands.command()
#commands.is_owner()
async def yescmdrun(self,ctx):
try:
global ID
ID = "no"
await ctx.send('No Command Run has been deactivated.')
except:
await ctx.send('Failed to deactivate No Command Run.')
def is_no_cmd_run_activated(self):
global ID
ID = "no"
#commands.command()
#commands.check(is_no_cmd_run_activated)
async def tester(self,ctx):
await ctx.send('congrats')
(This is in a cog called developer.py)
Firstly, add import os to the beginning of your main .py file. Then, to load and unload all your cog commands, add this code into the main .py file:
#bot.command()
async def unload(ctx):
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
bot.unload_extension(f'cogs.{filename[:-3]}')
await ctx.send('commands unloaded successfully.')
Also, make sure that the folder that your cog files are in is named cogs.
If you want to create a command to load all of the cog commands, you can simply do this:
#bot.command()
async def load(ctx):
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
bot.load_extension(f'cogs.{filename[:-3]}')
await ctx.send('commands loaded successfully.')
Related
So I made a sub command that just sends a message back. I found that if the user types a non existing command it still displays the message from the sub command. It sounds confusing but here's an example.
User: ;id
Bot: This command help you find the name of anyone in the server!
User: ;id Slayer
Bot: Bob Miller
So while testing I found if the user sends some thing like ;id jgfjkag the bot still sends the original message for ;id which is "This command help you find the name of anyone in the server!". How would I make the bot send a specific message if the user trys to use a non existing sub command? Here's the code:
#commands.group()
async def id(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send("This command help you find the name of anyone in the server! ")
#id.command()
async def Slayer(self, ctx):
await ctx.send("Bob Miller")
#id.command()
async def Skel(self, ctx):
await ctx.send("John Dove")
Check ctx.subcommand_passed first:
#commands.group()
async def id(self, ctx):
if ctx.subcommand_passed is None:
await ctx.send("This command help you find the name of anyone in the server!")
elif ctx.invoked_subcommand is None:
await ctx.send(f"Subcommand '{ctx.subcommand_passed}' does not exist.")
This is my favorite method of doing it:
#commands.group(invoke_without_command=True)
async def group(self, ctx):
await ctx.send_help(ctx.command) # invokes the help command for the group
#group.command()
async def subcommand(self, ctx):
await ctx.send("You passed a valid subcommand!")
The invoke_without_command parameter, when set to true, will only call the command if there are no (valid) subcommands passed. This means that if the code inside if the group() function is called, you can safely assume that they didn't pass a subcommand (or passed an invalid one).
I also like to use ctx.send_help, since that will automatically list subcommands. You could replace this with something like:
await ctx.send("You didn't pass a valid subcommand!")
[EDIT]
More careful reading of your question revealed that the subcommand already has some functionality. This makes it more difficult, but this will work:
#commands.group(invoke_without_command=True, ignore_extra=False)
async def group(self, ctx):
await ctx.send("This is a group command!")
#group.error
async def on_group_error(self, ctx, error):
if isinstance(error, commands.TooManyArguments):
await ctx.send("You passed an invalid subcommand!")
#group.command()
async def subcommand(self, ctx):
await ctx.send("You passed a VALID subcommand!")
Here is what it would look like:
!group
Bot: This is a group command!
!group bla
Bot: You passed an invalid subcommand!
!group subcommand
Bot: You passed a VALID subcommand!
NOTE: The ignore_extra field raises the commands.TooManyArguments error, which then invokes the error handler allowing the bot to send the error message. Unfortunately, the default on_command_error hook will still be called. I would suggest ignoring the commands.TooManyArguments error inside of your main error handler to fix this.
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!
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)
How to add multiple commands in discord.py? If we put another commands right below it,the command will not work
To create a new command you just create a new command reference:
The code:
#client.command()
async def command_1(ctx):
await ctx.send("This is command #1")
#client.command()
async def command_2(ctx):
await ctx.send("THis is command #2")
So for each command you just create a new client.command() and async def function
lets say on_member_join event
#commands.Cog.listener()
async def on_member_join(self, member):
# On member joins we find a channel called general and if it exists,
# send an embed welcoming them to our guild
channel = discord.utils.get(member.guild.text_channels, name="welcome")
if channel:
embed = discord.Embed(
description="Welcome to our guild!",
color=random.choice(self.bot.color_list),
)
embed.set_thumbnail(url=member.avatar_url)
embed.set_author(name=member.name, icon_url=member.avatar_url)
embed.set_footer(text=member.guild, icon_url=member.guild.icon_url)
embed.timestamp = datetime.datetime.utcnow()
await channel.send(embed=embed)
This is my event (I know it works) how can I test it in any way to execute command to emit the event (not manually by adding and removing someone)?
[something like .emit on_member_join #user where arg1 is event and if needed arg2 is mention or id of channel ]
Any command for that ?
something like Discord.js: Manually triggering events but in discord.py not in JavaScript
Currently there isn't official support in the discord.py api to do something like that but you can always make a command in the cog like follows:
#commands.command()
async def test_join(self, ctx, member: discord.Member):
await self.on_member_join(member)
Technically there is a way to probably do it that isn't documented...
Line 131 in here. I will not offer addition support for that because it isn't documented.