Kick Command (discord.py) - python

So I'm trying to make a kick command so that if the reason is nothing, then it says "no reason" instead of none. Don't ask why.
Here's my code:
#client.command()
#commands.has_permissions(kick_members=True)
async def kick(ctx, user: discord.Member, *, reason: str):
if reason is None:
await user.kick()
await ctx.send(f"**{user}** has been kicked for **no reason**.")
else:
await user.kick(reason=reason)
await ctx.send(f"**{user}** has been kicked for **{reason}**.")
And here's the error:
Ignoring exception in command kick:
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 847, in invoke
await self.prepare(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 784, in prepare
await self._parse_arguments(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 699, in _parse_arguments
kwargs[name] = await self.transform(ctx, param)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 535, in transform
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: reason is a required argument that is missing.
I don't understand why it says that "reason is a required argument that is missing" because I said that if reason is None it would say no reason?

If you assign None to the reason, then you can check it. For example reason = None. After that you can check in the commmand if the reason is None. Here is the code:
#client.command()
#commands.has_permissions(kick_members=True)
async def kick(ctx, user: discord.Member, *, reason = None):
if not reason:
await user.kick()
await ctx.send(f"**{user}** has been kicked for **no reason**.")
else:
await user.kick(reason=reason)
await ctx.send(f"**{user}** has been kicked for **{reason}**.")

You're getting that error because your function looks like this:
async def kick(ctx, user: discord.Member, *, reason: str):
Reason is not optional here, so it is a required argument. That means that calling this function without that argument will result in an error. Adding in a default value makes it optional.
def function(requiredArgument, optionalArgument=defaultValue)
In this case, defaultValue should be None. Now, when you don't pass in anything for that argument, it's default value will be used. That way, you no longer have to add a reason.

Related

discord.py mute role permission adding

So i made mute command for discord bot. it works, but doesn't add any permissions to 'Muted' role? Any ideas what's wrong?
Code:
#client.command(name = 'mute')
#commands.has_permissions(manage_permissions = True)
async def mute(ctx, member: discord.Member, *, reason = None):
muted = discord.utils.get(ctx.guild.roles, name = 'muted')
perms = discord.Permissions(send_messages = False)
if muted not in ctx.guild.roles:
muted = await ctx.guild.create_role(name = 'muted', permissions = perms)
memroles = discord.utils.get(member.roles)
if muted in memroles:
await ctx.send(f':x: This person is already muted')
await member.add_roles(muted)
await ctx.send(f':white_check_mark: **User <#{member.id}> was muted!**')
print(f'User {member} was muted!')
Error:
Traceback (most recent call last):
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "D:\endport_semegen\discordpy\smth.py", line 62, in mute
if muted in memroles:
TypeError: argument of type 'Role' is not iterable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\endport\AppData\Local\Programs\Python\Python310\lib\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: argument of type 'Role' is not iterable```
The issue is when you discord.utils.get on the member roles.
From the docs, emphasis mine:
A helper that returns the first element in the iterable that meets all the traits passed in attrs. This is an alternative for find().
Since you didn't provide anything for it to check, it will return the first role that satisfies the requirements - the first role the member has. Obviously, this is not the list of roles that you wanted.
The solution is to simply remove the get. There's no reason to do it. Now, member.roles will be a list that you can do checking with.
memroles = member.roles
if muted in memroles:
await ctx.send(f':x: This person is already muted')

TempMute | NotFound: 404 Not Found (error code: 10011): Unknown Role

I'm trying to do something like the 'tempmute' command, but an error keeps popping up
:
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/opt/virtualenvs/python3/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: NotFound: 404 Not Found (error code: 10011): Unknown Role
And here is the command code
#commands.command()
#commands.has_permissions(ban_members=True)
async def tempmute(self, ctx, member: discord.Member = None, * time):
if not member:
await ctx.send(embed=discord.Embed(title='Вы должны указать участника!', color=random.choice(colors)))
else:
LMUTED = discord.utils.get(ctx.message.guild.roles, name='LMUTED')
if not LMUTED:
perms=discord.Permissions(send_messages=False)
await ctx.guild.create_role(name='LMUTED',
colour=discord.Colour(0x0000FF),
permissions = perms)
await ctx.send(f'Я создал роль `{LMUTED}`!')
await member.add_roles(member, LMUTED)
await ctx.send(f'Я замьютил {member} на {time}!')
await s(time * 60)
await ctx.remove_roles(member, LMUTED)
Make sure you know how to read python errors.
But the main issue here is that you don't assign LMUTED a value after you create a new role, so it is still None and thus discord.py fails to add the role.
Also, keep in mind that when you do things that expire over time, simply sleeping/waiting in the method is not a good way to handle it, as the thread might be locked. Instead you should use some sort of scheduler. Basically a thing that waits a certain amount of time before running some code.

Discord.py — discord.ext.commands.errors.MemberNotFound If I try to ban a user who is not on the server

I am trying to write a command that can ban a user Using ID and #. But there is a problem: the bot cannot ban a user if he is not on the server.
There's code:
async def ban(ctx, member: discord.Member = None, *, reason=None):
await member.ban()
await ctx.send("You have banned a user")
There's result:
Traceback (most recent call last):
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 855, in invoke
await self.prepare(ctx)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 789, in prepare
await self._parse_arguments(ctx)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 697, in _parse_arguments
transformed = await self.transform(ctx, param)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 552, in transform
return await self.do_conversion(ctx, converter, argument, param)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 505, in do_conversion
return await self._actual_conversion(ctx, converter, argument, param)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 451, in _actual_conversion
ret = await instance.convert(ctx, argument)
File "C:\Users\FreezeGames\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\converter.py", line 195, in convert
raise MemberNotFound(argument)
discord.ext.commands.errors.MemberNotFound: Member "467762820734386196" not found.
UPDATED: Using "member: discord.User", how do I write a condition if the user has a specific role?
Thanks in advance for any help you can offer, and let me know if you need any more information out of me.
A member converter is going to be useless if you want to get a user who is not on your server. Use the user converter instead:
async def ban(ctx, member: discord.User, *, reason=None):
await member.ban()
await ctx.send("You have banned a user")
async def ban(ctx, member: discord.Member = None, *, reason=None):
running = True
while running:
try:
await member.ban()
await ctx.send("You have banned a user")
except:
continue
else:
running = False
This could possibly work. I am not sure though.

How to send message if there is no argument passed in python

so I tried to make a discord bot, and whenever I type the .clear command it will delete the message but I have to type the number of messages I want to delete in the command e.g .clear 5. However, I want to send a message whenever someone types the command without defining the number, and I use try exceptions but it still doesn't work as I expected
here's the code
#client.command()
async def clear(ctx, amount):
try:
await ctx.channel.purge(limit=int(amount))
except MissingRequiredArgument:
await ctx.send(f"give the number of message you want to delete - e.g '.clear 5' ")
error messages
Traceback (most recent call last):
File "/home/yves/.local/lib/python3.9/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/home/yves/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 855, in invoke
await self.prepare(ctx)
File "/home/yves/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 789, in prepare
await self._parse_arguments(ctx)
File "/home/yves/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 697, in _parse_arguments
transformed = await self.transform(ctx, param)
File "/home/yves/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 542, in transform
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: amount is a required argument that is missing.
Python supports default arguments:
#client.command()
async def clear(ctx, amount=None):
if amount is None:
await ctx.send(f"give the number of message you want to delete - e.g '.clear 5' ")
else:
await ctx.channel.purge(limit=int(amount))
Basically, if amount is None, you know that the user didn't supply the amount argument in their command.
You can write a command extension that accepts a variable number of arguments. You can then test len(args) in your code.
For example:
#client.command()
async def clear(ctx, *args):
if len(args) != 1:
await ctx.send(f"give the number of message you want to delete - e.g '.clear 5' ")
else:
await ctx.channel.purge(limit=int(args[0]))

What is the Solution to MissingRequiredArgument Error in discord.py Module?

I want to create a bot that will display server information such as server name, server owner's name, total number of members, etc. whenever called upon. I read up on the module's document many times and tried many things. Regardless of all attempts, I have been getting this error whenever I invoke the bot by command. I am using Python 3.9.2 and discord.py module of version 1.6.0, by the way. How can I solve the issue? Thanks in advance!
My Code:
#bot.command()
async def server(ctx, guild: discord.Guild):
await ctx.send(guild.name)
await ctx.send(guild.owner)
await ctx.send(guild.owner_id)
await ctx.send(guild.members)
await ctx.send(guild.member_count)
Error:
Ignoring exception in command server:
Traceback (most recent call last):
File "...\AppData\Roaming\Python\Python39\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "...\AppData\Roaming\Python\Python39\site-packages\discord\ext\commands\core.py", line 856, in invoke
await self.prepare(ctx)
File "...\AppData\Roaming\Python\Python39\site-packages\discord\ext\commands\core.py", line 790, in prepare
await self._parse_arguments(ctx)
File "...\AppData\Roaming\Python\Python39\site-packages\discord\ext\commands\core.py", line 706, in _parse_arguments
kwargs[name] = await self.transform(ctx, param)
File "...\AppData\Roaming\Python\Python39\site-packages\discord\ext\commands\core.py", line 542, in transform
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: guild is a required argument that is missing.
Do you need the guild parameter, why don't you just do:
#bot.command()
async def server(ctx):
await ctx.send(ctx.guild.name)
await ctx.send(ctx.guild.owner)
await ctx.send(ctx.guild.owner_id)
await ctx.send(ctx.guild.members)
await ctx.send(ctx.guild.member_count)
You have requested 2 arguments , ctx and guild : discord.Guild when you run the command , you have to use the command in the format !server <guild id/name> , since you didn't mention the <guild id/name> the error was triggered , either you can remove the argument as mentioned in answer given by #PythonProgrammer or you can mention the guild you want to request info of

Categories

Resources