How to clear if I have member.mention? - python

#bot.command()
#commands.has_permissions(manage_messages=True)
async def clear(ctx,member : discord.Member,amount=200):
await ctx.channel.purge(limit=amount)
if amount > 200:
await ctx.send(f"{member.mention}merci de clear entre 0-200 message(s)")
else:
await ctx.send(f"j'ai clear {amount} message(s)",delete_after=5)```
error:
File "C:\Users\dzzdz\PycharmProjects\pythonProject12\venv\lib\site-packages\discord\ext\commands\core.py", line 451, in _actual_conversion
ret = await instance.convert(ctx, argument)
File "C:\Users\dzdz\PycharmProjects\pythonProject12\venv\lib\site-packages\discord\ext\commands\converter.py", line 195, in convert
raise MemberNotFound(argument) discord.ext.commands.errors.MemberNotFound: Member "300" not found.
In this error, we can see that the command works only if I do !clear # (amount).
If I remove the discord.member it's working. I can't remove the discord.member because one can't have an optional argument that comes before a default argument.
So what can I do?

Here are some errors that I noticed:
First) Since you are looking for the author of the message, member is not relevant here at all. We can simply use ctx.author for this and then display it as desired.
Second) You have a logic error in your code. Your if amount >200 statement is not considered the way your code is and then more than 200 messages can be deleted without the error message showing up.
One possible code would be:
#client.command() / #bot.command() / #commands.command() # Depends on what you use
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount=200):
if amount > 200:
await ctx.send(f"{ctx.author.mention} merci de clear entre 0-200 message(s)")
return # Do not proceed
else:
await ctx.send(f"j'ai clear {amount} message(s)", delete_after=5)
await ctx.channel.purge(limit=amount) # Clear messages if lower than 200

I interpreted your question as "I want to have a user, but if I don't mention the person I get an error. Help?" There are a few ways to do this of course, so I will show you two of them.
Method 1: Using None
If you do not want to use any extra imports, you can move your member to the front and make it None. For both the methods, you will need to use an if statement to change your member to the ctx.author.
#bot.command()
#commands.has_permissions(manage_messages=True)
async def clear(ctx,amount=200,member : discord.Member=None): # moved the member to the right
if member == None: # if no one is mentioned
member = ctx.author # default to ctx.author
await ctx.channel.purge(limit=amount)
if amount > 200:
await ctx.send(f"{member.mention}merci de clear entre 0-200 message(s)")
else:
await ctx.send(f"j'ai clear {amount} message(s)",delete_after=5)
Method 2: Using typing.Optional.
This is often used as an optional argument. This allows for your member to be left in the middle.
import typing
# ...
# other code
#bot.command()
#commands.has_permissions(manage_messages=True)
async def clear(ctx, member: typing.Optional[discord.Member]=None, amount=200): # member is kept in the middle
if member == None: # if no one is mentioned
member = ctx.author # default to ctx.author
await ctx.channel.purge(limit=amount)
if amount > 200:
await ctx.send(f"{member.mention}merci de clear entre 0-200 message(s)")
else:
await ctx.send(f"j'ai clear {amount} message(s)",delete_after=5)

Related

why are my if and elif statements not running properly?

Hi so I've changed the code from past questions to try and simplify it, however now I'm having another problem,
So I have this code which checks for a certain role and changes the roles, however when I input the command into discord which is //leave #name time reason, neither the 'if' or 'elif' statements run.
I get no feedback, no errors, just no reaction from the bot whatsoever.
Here's the code, if someone can tell me what's going on for the statements to not run properly I'd appreciate it.
(I've tried interchanging the 'elif' statements with 'if' statements but to no avail.)
#client.command()
#commands.has_role(876994087214018571)
async def leave(ctx, member: discord.Member = None, time: str = '', *, reason: str = ''):
if not member:
member = ctx.author
loa = ctx.guild.get_role(848032714715561985)
mod = ctx.guild.get_role(848032880709074944)
smod = ctx.guild.get_role(851617257138028645)
amod = ctx.guild.get_role(848057125283954688)
if member.has_role(848032880709074944):
await member.add_roles(loa)
await member.remove_roles(mod)
await ctx.send("I have filed your Leave, take care, we look forward to your return!")
elif member.has_role(851617257138028645):
await member.add_roles(loa)
await member.remove_roles(smod)
await ctx.send("I have filed your Leave, take care, we look forward to your return!")
elif member.has_role(848057125283954688):
await member.add_roles(loa)
await member.remove_roles(amod)
await ctx.send("I have filed your Leave, take care, we look forward to your return!")
modLogEmbed = discord.Embed(title='Leave Logs',
description="A member of Staff is going on leave! " + '<#' + str(member.id) + '>', color=0x000000)
modLogEmbed.add_field(name="Time",
value=(time), inline=False)
modLogEmbed.add_field(name="Reason for Leave:",
value=(reason), inline=False)
modLogEmbed.set_footer(text="LeaveManager Bot")
modLogEmbed.set_author(name='Leave Manager')
botLogChannel = client.get_channel(874959002172268685)
await botLogChannel.send(embed=modLogEmbed)
Also I really do sincerely apologise for the way the code is set out, I genuinely can't figure out how to get it to layout properly like other members questions.
Well, member.has_roles is the problem, member does not have the attribute 'has_role'
maybe try this- using find and lambda to find if your id in any element of roles
I've test it using other role, it works fine.
#commands.command()
#commands.has_role(876994087214018571)
async def leave(ctx, member: discord.Member = None, time: str = '', *, reason: str = ''):
if not member:
member = ctx.author
loa = ctx.guild.get_role(848032714715561985)
mod = ctx.guild.get_role(848032880709074944)
smod = ctx.guild.get_role(851617257138028645)
amod = ctx.guild.get_role(848057125283954688)
result = find(lambda x: x.id == 848032880709074944, member.roles)
if result:
await member.add_roles(loa)
await member.remove_roles(mod)
await ctx.send("I have filed your Leave, take care, we look forward to your return!")
await ctx.send('done')

What is causing the ticket system to not function?

sorry that this is probably rather easy to fix (I don't really understand the docs)
But, I want a channel to be opened, so only the user and mods can see it. It will be opened when the user adds a reaction to the message, the reaction will then be deleted (leaving just the bot's reaction)
Currently, my code is:
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if reaction.emoji == '📩':
if user.channel.id == 850622999577231370:
await message.remove_reaction("📩", user)
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
guild.me: discord.PermissionOverwrite(read_messages=True)
}
n = random.randomint(1, 1000)
await guild.create_text_channel(f'Ticket {n}', overwrites=overwrites, categoty="Tickets")
else:
pass
else:
pass
It doesn't seem to run, since there is no error message, but no channels are created either
A few things I noticed:
random.randomint does not exist, it must be random.randrange.
You didn't define guild in the provided code, we'll just use user.guild instead.
To get the channel we use if reaction.message.channel.id and not if user.channel.id, that makes little sense here.
Here is a possible new code:
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if reaction.emoji == '📩':
print("Reaction")
if reaction.message.channel.id == Your_Channel_ID:
await reaction.message.remove_reaction("📩", user)
guild = user.guild # We get the guild
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
guild.me: discord.PermissionOverwrite(read_messages=True)
}
n = random.randrange(1, 1000) # We choose a number from randrange 1-1000
await guild.create_text_channel(f'Ticket {n}', overwrites=overwrites, categoty="Tickets")
else:
pass
else:
pass

How do you get 2 users from bot.wait_for('reaction_add')?

So i have this code:
msg = await channel.send("React to this with ✅ to ready up. ``(0/2)``")
await msg.add_reaction('✅')
def check(reaction, user):
return reaction == '✅' and user.id == initiator or user.id == challenger
reaction, user = await self.bot.wait_for('reaction_add', timeout=30, check=check)
print(user)
And when i print the user i want it to print both of them not only 1. Because When they react I want to edit the message that 1 has readied up. I've tried multiple methods such as looping through but none seem to work. Kind Regards.
I'm assuming you want both initiator and challenger to react to your message in a particular order.
First off there is no point in adding a timeout if you're not handling the TimeoutError accordingly.
A good solution would be to embed your code in a endless loop with a try:except clause to catch the timeout error and escape the loop.
In your case you should also define some sort of flag to determine whose turn it is to react:
#bot.command
async def my_command(ctx, challenger: discord.Member):
initiator = ctx.author
msg = await channel.send("React to this with ✅ to ready up. ``(0/2)``")
await msg.add_reaction('✅')
in_turn = initiator
while True:
try:
reaction, user = await self.bot.wait_for('reaction_add', timeout=30, check=lambda r, u: r == "✅" and u == in_turn
turn = 1 if in_turn == initiator else 2
await msg.edit(f"React to this with ✅ to ready up. ``({turn}/2)``")
if in_turn == initiator:
in_turn = challenger
else:
break
except asyncio.TimeoutError:
await ctx.send(f"{in_turn.display_name} didn't react in time")
Obviously this is just my idea of how this could be implemented, but then you'd have to do something with those reactions (which you didn't clearly state in your question) otherwise the entire task is pointless.

Mute Command with Time Limit

I was wondering how I can make my mute command mute someone for a certain amount of time. For example p/mute #User 1h would mute someone for 1 hour.
#client.command()
#commands.has_permissions(manage_roles = True)
async def mute(ctx, member : discord.Member = None):
if member == None:
await ctx.send("Please mention a user to mute")
else:
user = member
role = discord.utils.get(ctx.guild.roles, name="Muted")
if role is None:
await ctx.send("Please make a muted role name `Muted` or make sure to name the role `Muted` and not `muted` or `MUTED`")
else:
await user.add_roles(role)
await ctx.send(f"{member.name} has been muted by {ctx.author.name}")
This site has an example on one way to do this, however I found it needed some slight modifications to work - it was giving me errors in some spots prior to my edits. Below code worked in my server:
#client.command(aliases=['tempmute'])
#commands.has_permissions(manage_messages=True)
async def mute(ctx, member: discord.Member=None, time=None, *, reason=None):
if not member:
await ctx.send("You must mention a member to mute!")
return
elif not time:
await ctx.send("You must mention a time!")
return
else:
if not reason:
reason="No reason given"
#Now timed mute manipulation
try:
time_interval = time[:-1] #Gets the numbers from the time argument, start to -1
duration = time[-1] #Gets the timed manipulation, s, m, h, d
if duration == "s":
time_interval = time_interval * 1
elif duration == "m":
time_interval = time_interval * 60
elif duration == "h":
time_interval = time_interval * 60 * 60
elif duration == "d":
time_interval = time_interval * 86400
else:
await ctx.send("Invalid duration input")
return
except Exception as e:
print(e)
await ctx.send("Invalid time input")
return
guild = ctx.guild
Muted = discord.utils.get(guild.roles, name="Muted")
if not Muted:
Muted = await guild.create_role(name="Muted")
for channel in guild.channels:
await channel.set_permissions(Muted, speak=False, send_messages=False, read_message_history=True, read_messages=False)
else:
await member.add_roles(Muted, reason=reason)
muted_embed = discord.Embed(title="Muted a user", description=f"{member.mention} Was muted by {ctx.author.mention} for {reason} to {time}")
await ctx.send(embed=muted_embed)
await asyncio.sleep(int(time_interval))
await member.remove_roles(Muted)
unmute_embed = discord.Embed(title='Mute over!', description=f'{ctx.author.mention} muted to {member.mention} for {reason} is over after {time}')
await ctx.send(embed=unmute_embed)
This should create a new role called "Muted" in your server if it doesn't already exist, move the targeted member into said role for the time denoted, and then remove them from the role once time expires.
Example command using code (prefix of .):
.tempmute #SomeUser 10s Because I said so!
I have a pretty easy way of doing that. That will be efficient and less code required. I have been using that in my Bots for a long time. I have answered another question of the one user here: Bot unmuting member when use tempmute command
In the answer there I have explained on how to write a perfect command.
This command is completely another command. You don't have to modify your mute command. But just create a new command named tempmute.
I will copy and paste my answer from there to here. Please pay attention to every single statement. :)
TEMPMUTE Command.
Step 1: Define the function and permissions
We are going to define the function with some permissions restrictions on the use. People with the permissions specified permissions.
Before you use this, you need to have the following in your code:
from discord.ext import commands
(Ignore if you have it)
Here is how:
#bot.command()
#commands.has_permissions(manage_roles=True)
async def tempmute(ctx, member: discord.Member, time, *, reason=None):
You can add many more permission if you want and use True or False to allow or deny.
Step 2: Making a role finding condition. If the role doesn't exist then create a Muted role, if exist then use it.
So I am creating a condition for if the role exist. It will check if the role exist. If it exist then we will simply use it but if it doesn't we will create one with specific permissions.
Here is how:
if discord.utils.get(ctx.guild.roles, name="Muted"):
mute_role = discord.utils.get(ctx.guild.roles, name="Muted")
else:
perms = discord.Permissions(send_messages=False, add_reactions=False, connect=False, speak=False)
await bot.create_role(name="Muted", permissions=perms)
mute_role = discord.utils.get(ctx.guild.roles, name="Muted")
Step 3: Checking if someone is muted or not.
Now I am creating a condition for if the member is muted or not. We will through the member's roles and check it.
Here is how:
if mute_roles in member.roles:
await ctx.channel.send(f"{member.mention} is already muted!")
else:
# code here (more steps will explain how)
Step 4: Adding conditions and muting the member.
Now we will add restriction permissions for this command. Who all people can't be muted and who all can be.
First we add our first condition, that administrators can not be muted.
Here is how:
if member.guild_permissions.administrator:
isadminembed=discord.Embed(title="Tempmute", description=f"Hi {ctx.author.mention}, you can't mute {member.mention} as they are a Server Administrator.", color=discord.Colour.red())
isadminembed.set_author(name="Bot")
await ctx.channel.send(embed=isadminembed)
Now we will add else condition, that all other members except administrators can be muted.
Here is how:
else:
time_conversion = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800, "M": 2419200, "y": 29030400}
mute_time = int(time[:-1]) * time_conversion[time[-1]]
await member.add_roles(mute_role)
mutedembed=discord.Embed(title="Tempmute", description=f"The member, {member.mention} has been muted by the moderator {ctx.author.mention}. \n \nTime: {mute_time} seconds \nReason: {reason}", color=discord.Colour.random())
mutedembed.set_author(name="Bot")
await ctx.channel.send(embed=mutedembed)
await asyncio.sleep(mute_time)
await member.remove_roles(mute_role)
await ctx.channel.send(f"{member.mention} has been unmuted!")
I have added time conversion here. The time input has to be:
1s for one second, 1m for one minute, etc. You can use it for years too.
Tempmute Command Compiled
This is all the code compiled together as the command.
#bot.command()
#commands.has_permissions(manage_roles=True)
async def tempmute(ctx, member: discord.Member, time, *, reason=None):
if discord.utils.get(ctx.guild.roles, name="Muted"):
mute_role = discord.utils.get(ctx.guild.roles, name="Muted")
else:
perms = discord.Permissions(send_messages=False, add_reactions=False, connect=False, speak=False)
await bot.create_role(name="Muted", permissions=perms)
mute_role = discord.utils.get(ctx.guild.roles, name="Muted")
if mute_roles in member.roles:
await ctx.channel.send(f"{member.mention} is already muted!")
else:
if member.guild_permissions.administrator:
isadminembed=discord.Embed(title="Tempmute", description=f"Hi {ctx.author.mention}, you can't mute {member.mention} as they are a Server Administrator.", color=discord.Colour.red())
isadminembed.set_author(name="Bot")
await ctx.channel.send(embed=isadminembed)
else:
time_conversion = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800, "M": 2419200, "y": 29030400}
mute_time = int(time[:-1]) * time_conversion[time[-1]]
await member.add_roles(mute_role)
mutedembed=discord.Embed(title="Tempmute", description=f"The member, {member.mention} has been muted by the moderator {ctx.author.mention}. \n \nTime: {mute_time} seconds \nReason: {reason}", color=discord.Colour.random())
mutedembed.set_author(name="Bot")
await ctx.channel.send(embed=mutedembed)
await asyncio.sleep(mute_time)
await member.remove_roles(mute_role)
await ctx.channel.send(f"{member.mention} has been unmuted!")
TEMPMUTE Command Error Handling
Step 1: Defining the function as an event.
We will define the function in the script as tempmute command's error and declare it as an error.
Here is how:
#bot.error
async def tempmute_error(ctx, error):
Step 2: Adding the instance of the error.
We will now add a condition for the error. Our error will be: MissingRequiredArgument error as the command can lack necessary arguments.
So the isinstance will check the error and then do the stuff.
Here is how:
if isinstance(error, discord.ext.commands.MissingRequiredArgument):
tempmuteerrorembed=discord.Embed(title=f"Missing Argument! {error}", description=f"Hello {ctx.author.mention}! You have not entered the needed argument. \n Either you forgot to **mention the member** or you forgot to **enter the time of the mute** you want. \n \n Please check this again and add the necessary argument in the command. \n \nThis is the syntax: \n```!tempmute <mention member> <time: 1s, 2h, 4y etc..> <reason (optional)>```", color=discord.Colour.red())
tempmuteerrorembed.set_author(name="Bot")
await ctx.send(embed=tempmuteerrorembed)
This will work for MissingRequiredArguement and show the error with the syntax in it for the command's correct usage.
TEMPMUTE Command Error Handling Compiled
Here is the compiled code of Error Handling of TEMPMUTE Command.
#bot.error
async def tempmute_error(ctx, error):
if isinstance(error, discord.ext.commands.MissingRequiredArgument):
tempmuteerrorembed=discord.Embed(title=f"Missing Argument! {error}", description=f"Hello {ctx.author.mention}! You have not entered the needed argument. \n Either you forgot to **mention the member** or you forgot to **enter the time of the mute** you want. \n \n Please check this again and add the necessary argument in the command. \n \nThis is the syntax: \n```!tempmute <mention member> <time: 1s, 2h, 4y etc..> <reason (optional)>```", color=discord.Colour.red())
tempmuteerrorembed.set_author(name="Bot")
await ctx.send(embed=tempmuteerrorembed)
I hope I was able to explain to you the answer and how to write the command. Please ask in the comments for any issue that arises.
Thank You! :D

Discord.py getting unexpected parentheses in output

This is my discord.py bot. When I type m!rate (person) It sends me a text like this. However, I don't want the (' and ',) at the beginning and end of the message.
This is my code:
#client.command()
async def rate(ctx, *member):
if len(member) == 0:
await ctx.send("You forgot to mention someone")
else:
value = random.randint(1,10)
await ctx.send(f"I rate {member} {value}/10")
When I change it, the message works but the error doesn't. I can't find any solution.
Using * in a parameter makes the function pass positional arguments into a tuple, hence the brackets. This is usually for when you want to unpack an arbitrary amount of arguments.
To fix it, just remove *, and also add a type for the parameter if you want:
#client.command()
async def rate(ctx, member: discord.Member = None): # setting a default value of None
if not member: # testing to see if the default value is None
await ctx.send("You forgot to mention someone")
else:
value = random.randint(1,10)
await ctx.send(f"I rate {member.mention} {value}/10")
References:
Using * in Python
discord.Member
Member.mention
If you want your bot to mention one person per command :
#client.command()
async def rate(ctx, *member):
if member:
"".join(member)
value = random.randint(1,10)
for user in ctx.guild.members:
if user.name.lower() == member.lower() or user.nick.lower() == member.lower():
await ctx.send(f"I rate {user.mention} {value}/10")
else:
await ctx.send("Member not found!")
else:
await ctx.send("You forgot to mention someone")
If you want your bot to mention multiple people per command :
#client.command()
async def rate(ctx, *members):
if members:
embed = Discord.embed(color = discord.color.blue(), title = "title")
count = 0
for member in members:
value = random.randint(1,10)
for user in ctx.guild.members:
if user.name.lower() == member.lower() or user.nick.lower() == member.lower():
embed.add_field(name = f"{user.mention}", value = f"I rate him {value}/10")
count += 1
if count != 0:
await ctx.send(embed=embed)
else:
await ctx.send("Members not found!")
else:
await ctx.send("You forgot to mention someone")

Categories

Resources