I've been programming a bot with discord.py (the rewrite branch) and I want to add a ban command. The bot still doesn't ban the member, it just shows an error:
#client.command(aliases=['Ban'])
async def ban(ctx,member: discord.Member, days: int = 1):
if "548841535223889923" in (ctx.author.roles):
await client.ban(member, days)
await ctx.send("Banned".format(ctx.author))
else:
await ctx.send("You don't have permission to use this command.".format(ctx.author))
await ctx.send(ctx.author.roles)
It'll ban the pinged user and confirm that it did ban
Member.roles is a list of Role objects, not strings. You can use discord.utils.get to search through that list using the id (as an int).
from discord.utils import get
#client.command(aliases=['Ban'])
async def ban(ctx, member: discord.Member, days: int = 1):
if get(ctx.author.roles, id=548841535223889923):
await member.ban(delete_message_days=days)
await ctx.send("Banned {}".format(ctx.author))
else:
await ctx.send("{}, you don't have permission to use this command.".format(ctx.author))
await ctx.send(ctx.author.roles)
There also is no longer a Client.ban coroutine, and the additional arguments to Member.ban must be passed as keyword arguments.
async def ban(ctx, member: discord.Member=None, *, reason=None):
if reason:
await member.send(f'You got banned from {ctx.guild.name} by {ctx.author}, reason: ```{reason}```')
await member.ban()
await ctx.send(f'{member.mention} got banned by {ctx.author.mention} with reason: ```{reason}```')
if reason is None:
await ctx.send("please specify a reason")
Related
I find that I am unable to kick members or other bots using the kick command in my bot. Both I and the bot have administrator permissions. Why could this be happening? I get no compilation errors.
#client.command() ##kick
#has_permissions(kick_members = True) # to check the user itself
async def kick(ctx, member : discord.Member, *, reason=None):
try:
await member.kick(reason=reason)
await ctx.send(+member.mention + " has been sent to the ministry of love for reeducation.")
except:
await ctx.send("You cannot!")
EDIT: Thanks for the fixes in the comments below. I also came to the realization that I was trying to kick a user of equal level (deprecated bot) and so that also played a part in it not working. I tried to kick a standard user and it worked great!
Guessing that the message received from the bot is "You cannot!", the exception thrown is a TypeError, and it is handled because you have wrapped it in try/except. To make sure, remove the error handling and check your result.
The complete error would look like this: TypeError: bad operand type for unary +: 'str'.
Resources
TypeError
Bug
In line 6, you have added a bad binary operator + in the beginning of argument list, but the operator requires two operands and they are not provided.
await ctx.send(+member.mention + " has been sent to the ministry of love for reeducation.")
Hence a TypeError is thrown, but it is also handled, so the only result you will see is the "You cannot!" message from the bot.
Fix
Simply remove the bad operator, and it should be working fine.
await ctx.send(member.mention + " has been sent to the ministry of love for reeducation.")
In the #has_permissions(kick_members = True) line, you have to add commands. Here's the fixed command.
#client.command()
#commands.has_permissions(kick_members=True)
async def kick(ctx, member: discord.Member, *, reason=None):
try:
await member.kick(reason=reason)
await ctx.send(+member.mention + " has been sent to the ministry of love for reeducation.")
except:
await ctx.send("You cannot!")
import discord
from discord.ext import commands
import os
client = commands.Bot(command_prefix = '!')
#client.command()
#commands.has_permissions(kick_members=True)
async def kick(ctx, member: discord.Member, *, reason=None):
await member.kick(reason=reason)
await ctx.send(f'User {member} has been kicked')
await member.send(f"You have been kicked from {member.guild.name} | reason: {reason}")
client.run('WRITE YOUR TOKEN HERE')
I wanna do a ban appeal system on my server. I wanna remove every single role of someone and give them the [Banned] role. I cannot just do something like I did for the member role for all of them since there are a lot of roles, even some custom ones that are made and deleted every day.
member_role = get(user.guild.roles, name="γβ
γΒ· πΌπππππ")
await user.remove_roles(member_role, reason=None, atomic=True)
I tried this: discord.py trying to remove all roles from a user but it didn't work. Also tried this:
for role in user.roles:
if role.name == '[Banned]':
pass
else:
await user.remove_roles(role)
but couldn't get it to work. (I have no experience in python or discord.py)
So. How can I remove every role from a user instead of only the member_role ?
#bot.command()
#commands.has_permissions(ban_members=True)
async def ban(ctx, user: discord.Member, *, reason=None):
await asyncio.sleep(1)
banned_role = get(user.guild.roles, name="[Banned]")
await user.add_roles(banned_role, reason=None, atomic=True)
member_role = get(user.guild.roles, name="γβ
γΒ· πΌπππππ")
await user.remove_roles(member_role, reason=None, atomic=True)
banemb = discord.Embed(title="Ban", description=f"{user.mention} a fost banat/a. ", colour=discord.Colour.dark_red())
banemb.add_field(name="Motiv:", value=reason, inline=False)
await ctx.send(embed=banemb)
You can't get the list of roles that way.
To remove all the roles of the user you have to apply an edit to it and provide an empty list of roles.
It also changes the order of your code as you first have to remove and then re-assign a role to the user.
Have a look at the following code:
#bot.command()
#commands.has_permissions(ban_members=True)
async def ban(ctx, user: discord.Member, *, reason=None):
await asyncio.sleep(1)
banned_role = discord.utils.get(user.guild.roles, name="[Banned]")
await user.edit(roles=[]) # Remove all roles
await user.add_roles(banned_role, reason=None) # Assign the new role
banemb = discord.Embed(title="Ban", description=f"{user.mention} a fost banat/a. ",
colour=discord.Colour.dark_red())
banemb.add_field(name="Motiv:", value=reason, inline=False)
await ctx.send(embed=banemb)
I have changed/removed a few things from the code. Of course you have to add them again, according to your wishes.
I am trying to make a bot using the discord.py library. The following function is supposed to kick the user. When the user doesn't pass the name of the user it's supposed to kick, The bot should send the message: "Please specify the user you want to kick". Except when I type in the following code
#kick command
#bot.command()
#has_permissions(kick_members=True)
async def kick(ctx, member : discord.Member, *, reason=None):
await member.kick(reason=reason)
await ctx.send(f'User {member.mention} has been kicked for: "{reason}".')
#this is where the error should be written
#bot.event()
async def on_command_error(ctx, errors):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("Please specify the user you want to kick")
I get 2 errors: The first one is about the #bot in the #bot.event() line of code. The error is "No value for argument 'coro' in method call"
The other one is about the "error" in the if isinstance(error, commands.MissingRequiredArgument): Line of code. The error is: Undefined variable 'error'. Does anyone know how to fix this?
1- The #bot.event should be without ()
2- It is commands.errors.MissingRequiredArgument You were missing the errors
3- async def on_command_error(ctx, error): it is error not errors
#kick command
#bot.command()
#has_permissions(kick_members=True)
async def kick(ctx, member : discord.Member, *, reason=None):
await member.kick(reason=reason)
await ctx.send(f'User {member.mention} has been kicked for: "{reason}".')
#this is where the error should be written
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.errors.MissingRequiredArgument):
await ctx.send("Please specify the user you want to kick")
Note: The error message is general for all commands.
I am setting up a mute command for my new discord bot, I am fairly new to the discord.py stuff, and do not understand what is going wrong.
I keep getting the error that a member is not being specified, when it clearly is.
I have tried many tutorials on youtube etc, but it always skims over a detail or two so I can't fully figure it out. I would appreciate it if someone could correct my code, because I am still learning discord.py.
#client.command()
async def mute(context, member: discord.Member=None):
if not member:
await client.say('Please specify a member')
return
role = get(member.server.roles, name="Muted")
await client.add_roles(member, role)
await client.say('{member.mention} was muted.')
It is just supposed to add the muted role to someone, and be done with it. I am having the same issue with specifying a member when using my ban and kick commands too, which are done in the same fashion.
I am open to all suggestions, thank you!
You need to change the decorator to #client.command(pass_context=True). The member name is being assigned to context, leaving member to take the default value.
#client.command(pass_context=True)
async def mute(context, member: discord.Member=None):
if not member:
await client.say('Please specify a member')
return
role = get(member.server.roles, name="Muted")
await client.add_roles(member, role)
await client.say(f'{member.mention} was muted.') # You forgot the f
Also, I would probably just let the conversion fail and then handle the error:
#client.command(pass_context=True)
async def mute(ctx, member: discord.Member):
role = get(member.server.roles, name="Muted")
await client.add_roles(member, role)
await client.say(f'{member.mention} was muted.')
#mute.error:
async def mute_error(error, ctx):
if isinstance(error, ConversionError):
await client.send_message(ctx.message.channel, 'Please specify a member')
else:
raise error
I have this Python code for discord.py rewrite:
#bot.command(pass_context=True)
async def clean(ctx):
if ctx.author.guild_permissions.administrator:
llimit = ctx.message.content[10:].strip()
await ctx.channel.purge(limit=llimit)
await ctx.send('Cleared by <#{.author.id}>'.format(ctx))
await ctx.message.delete()
else:
await ctx.send("You cant do that!")
But every time i get this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: '<=' not supported between instances of 'str' and 'int'
Can someone here help me?
You can treat single argument callables (like int) like converters for the purpose of declaring arguments. I also changed your permissions check to be handled automatically by a commands.check
#bot.command(pass_context=True)
#commands.has_permissions(administrator=True)
async def clean(ctx, limit: int):
await ctx.channel.purge(limit=limit)
await ctx.send('Cleared by {}'.format(ctx.author.mention))
await ctx.message.delete()
#clean.error
async def clear_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.send("You cant do that!")
The limit argument of the purge function takes an integer as a value
Try doing something like this
#bot.command(pass_context=True)
async def clean(ctx):
if ctx.author.guild_permissions.administrator:
llimit = ctx.message.content[10:].strip()
await ctx.channel.purge(limit=int(llimit))
await ctx.send('Cleared by <#{.author.id}>'.format(ctx))
await ctx.message.delete()
else:
await ctx.send("You cant do that!")
I'm not entirely sure what you're trying to accomplish with content[10:].strip() but if you're trying to ignore the !clean part of your command you are using too large of a number. content[7:] would suffice
Also to make the bot check errors you can even do like this
#bot.command(pass_context=True)
#commands.has_permissions(administrator=True)
async def clean(ctx, limit: int):
await ctx.channel.purge(limit=limit)
await ctx.send(f'Cleared by {ctx.author.mention}')
await ctx.message.delete()
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.send("You cant do that!")
Also this way it will remove errors of every command so that will be better
This is the easiest way I've been able to do this, hope it helps!
#client.command(pass_context=True)
async def purge(ctx, limit: int):
await ctx.message.delete()
await ctx.channel.purge(limit=limit)