discord.py ignore bots (client.command) - python

I want to role everyone in my server with a command I call p!roleall <role>, but it's not ignoring bots and I need help. No errors were provided. Thanks.
#client.command()
async def roleall(ctx, role: discord.Role):
for i in ctx.guild.members:
if i == i.bot:
ctx.send('e')
try:
await i.add_roles(role)
except discord.errors.Forbidden:
await ctx.send(f'`i do not have permissions to role {i.name}`')
pass

There are a few issues with your code. Firstly, each ctx.send() requires an await. In regards to the i.bot, this returns a boolean, so no need to compare it.
The issue of it not ignoring bots stems from you not instructing the program to skip the rest of the code. A continue statement will do that for you.
#client.command()
async def roleall(ctx, role: discord.Role):
for i in ctx.guild.members:
if i.bot:
await ctx.send('e')
continue
try:
await i.add_roles(role)
except discord.errors.Forbidden:
await ctx.send(f'`i do not have permissions to role {i.name}`')
pass

try putting an
else:
before the try.
Also, change ctx.send('e') to await ctx.send('e')

Related

discord.py ban all members command

I'm working on a bot for educational use and I'm looking for a banall command I seen the others but it doesn't work no errors just when I use it nothing executes
This is what I used
#bot.command()
#commands.has_permissions(ban_members=True)
async def banall(ctx):
for member in list(ctx.guild.members):
try:
await member.ban(reason='test')
except:
pass
await ctx.message.delete()
I think your issue is that guild.members isn't fully populated - so we need to fetch the members to be able to ban them. You will need the members Intent enabled though to do so.
#bot.command()
#commands.has_permissions(ban_members=True)
async def banall(ctx):
async for member in ctx.guild.fetch_members():
try:
await member.ban(reason='test')
except Exception as e:
print(f"Exception {e} banning {member}")
await ctx.message.delete()
Modified the try/except so that it will at least print an error message if it has an issue banning a member.
Member intents.

Discord.py massban

I've been working really hard with a massban command but it doesn't work. Here is the code. Basically it doesn't do anything and I get no error in console.
#bot.command()
async def massban(ctx, user: discord.User ):
for user in ctx.guild.members:
try:
await user.ban(user)
except:
pass
If you want you can ban all members that your bot can see.
#bot.command()
async def massban(ctx):
for member in bot.get_all_members():
await member.ban()
It seems like the problem is here:
await user.ban(user)
You do not need to mention the user in the brackets. It is enough if you remove the "argument":
#bot.command()
async def massban(ctx):
for user in ctx.guild.members:
try:
await user.ban()
except:
pass
This command bans all the user from your guild.
so, you need a guild your bot can see.
#bot.command()
async def massban(ctx):
await ctx.message.delete()
guild = ctx.guild
for user in ctx.guild.members:
try:
await user.ban()
except:
pass

Is there a way to do a check for pinned messages, and only purge a certain members messages using discord.py?

I want to make a purge command similar to Dyne's, where you can input a user, and it doesn't purge pinned, only the user's messages (if you input a user). I've tried making a seperate check function, but it doesn't purge anything. I get no error, it just won't purge.
#commands.command()
#commands.has_permissions(manage_messages=True)
async def purge(self, ctx, user: discord.Member = None, num: int = 10000):
if user:
def check_func(user: discord.Member, message: discord.Message):
return not msg.pinned
return user.id
await ctx.message.delete()
await ctx.channel.purge(limit=num, check=check_func)
verycool = await ctx.send(f'{num} messages deleted.')
await verycool.delete()
else:
await ctx.message.delete()
await ctx.channel.purge(limit=num, check=lambda msg: not msg.pinned)
verycool = await ctx.send(f'{num} messages deleted.')
await verycool.delete()
I have manage messages permissions on the server. Does anyone know how to make the check_func work properly?
The changes I have made should solve your issue as well as deal with a few other issues.
#commands.command()
#commands.has_permissions(manage_messages=True)
async def purge(self, ctx, num: int = None, user: discord.Member = None):
if user:
check_func = lambda msg: msg.author == user and not msg.pinned
else:
check_func = lambda msg: not msg.pinned
await ctx.message.delete()
await ctx.channel.purge(limit=num, check=check_func)
await ctx.send(f'{num} messages deleted.', delete_after=5)
Just changing the function based on the arguments looks better and is more efficient as otherwise you have duplicated code. Furthermore, the message you send at the end was being deleted effectively immediately. channel.send has an argument delete_after which will automatically deletes a message after a given amount of seconds. There are a few other syntax issue I haven't mentioned such as the check function only taking one argument but you parsing two which I have also fixed. Technically PEP8 prohibits storing lambda's in variables but I think this could be excused.
Edit: you could do something like check if num == "*" and delete all messages if it does.

How to display error message if member doesn't have permissions? Discord.py

I'm trying to make a simple clear command & have it return an error message if the member does not have the manage messages permission.
#bot.command()
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount=10):
await ctx.channel.purge(limit=amount)
This will do the trick.
#bot.command()
async def clear(ctx, amount = 10):
authorperms = ctx.author.permissions_in(ctx.channel)
if authorperms.manage_messages:
await ctx.channel.purge(limit=amount)
else:
await ctx.send("You don't have the permissions to do that!")
There is probably a better way of doing this by using the Exception raised when someone without the right permissions tries to use the command, or by overwriting the on_error method but I don't know how. This should fix the problem for you until you can find a better solution.

Permission Check Discord.py Bot

I am working on a discord bot for basic moderation which does kick, ban and mute for now at least. But the problem is other members can use it too. I want only a few specified role who can use it.
Don't want to work on it depending on the #role either because the name of the roles across different servers aren't the same. Also wanting to keep the bot as simple as possible.
Now, I started out as this:
#client.command(name='ban')
async def mod_ban(member: discord.User):
try:
await client.ban(member, delete_message_days=0)
await client.say('**{0}** has been banned.'.format(str(member)))
except Exception as error:
await client.say(error)
But any member can use the commands then. So, tried follow this one = Permission System for Discord.py Bot and ended up with this:
#client.command(name='ban')
async def mod_ban(context, member: discord.User):
if context.message.author.server_premission.administrator:
try:
await client.ban(member, delete_message_days=0)
await client.say('**{0}** has been banned.'.format(str(member)))
except Exception as error:
await client.say(error)
else:
await client.say('Looks like you don\'t have the perm.')
Which lands me with this error: ;-;
raise MissingRequiredArgument('{0.name} is a required argument that is missing.'.format(param))
discord.ext.commands.errors.MissingRequiredArgument: member is a required argument that is missing.
Also, besides context.message.author.server_premission.administrator I don't only want the roles with Admin perm to use this command. I also want a few other roles with have few perms like manage message, manage roles etc. to use to command too.
Thanks in advance for the help! Also, sorry if I've missed anything stupid or silly ;-;
You aren't passing the context into the coroutine in your second example (and as #Andrei suggests, you can only ban members):
#client.command(name='ban', pass_context=True)
async def mod_ban(context, member: discord.Member):
...
Also, I should probably update my answer to that question. In the context of commands, you can use the very powerful checks built into discord.ext.commands to do a lot of this for you. has_permissions does exactly what you're looking for, validating that the user has any of the necessary permissions.
from discord.ext.commands import has_permissions, CheckFailure
#client.command(name='ban', pass_context=true)
#has_permissions(administrator=True, manage_messages=True, manage_roles=True)
async def mod_ban(ctx, member: discord.Member):
await client.ban(member, delete_message_days=0)
await client.say('**{0}** has been banned.'.format(str(member)))
#mod_ban.error
async def mod_ban_error(error, ctx):
if isinstance(error, CheckFailure):
await client.send_message(ctx.message.channel, "Looks like you don't have the perm.")
As far as I can see in the discord.py documentation discord.User is not the same as discord.Member.
Try to change
async def mod_ban(context, member: discord.User):
to
async def mod_ban(context, member: discord.Member):
If you are using discord.py rewrite, you can use checks (Discord.py rewrite checks)
Which (obviusly) checks for certain things suchs as roles or permissions on the command invoker
You can use both of this decorators, below your first decorator
#commands.has_role("rolename"/roleid)
#commands.has_any_role("rolename"/roleid,"rolename"/roleid,"rolename"/roleid ...)
Where rolename is a string containing the EXACT name of the role, letter by letter and space by space, and roleid is the id of the role, which, in case it's mentionable, you can get it by typing #rolename on any of your server chatrooms
Note how you must use the second decorator if you want to pass more than one role to check

Categories