Advanced Discord Ban Command - discord.py

i need a ban command that bans a member and than dms the banned member to inform them about it and when it happened.
I have a few problems:
What if the user's dms are closed?
It is not dming the banned member.
Also includes a perm ban like `!Ban
If anyone can help me out that will be great and i will greatly appricate it.
Thanks!

Like you want, this is example of simple ban member for discord.py
#client.command()
async def ban(ctx, member:discord.Member, *, reason=None)
await member.ban
await member.send(f"You've been banned by {ctx.author}\nReason = {reason}")
If you looking for .cogs version
#commands.command()
async def ban(self, ctx, member:discord.Member, *, reason = None)
await member.ban
await member.send(f"You've been banned by {ctx.author}\nReason = {reason}") ##this send message by DMs for banned member to tell him/her why getting banned
If you using discord-py-slash-command you can create new question

for the 1:
try:
await user.send("msg")
except discord.errors.Forbidden:
code here
I don't know if this can help you

Related

trying to ban all but only attempting to ban the bot executing

I'm making a ban all function for proof of concept but whenever I execute it, the code only attempts to ban the bot that is running the command (and fails) and doesn't ban anyone one else, no error message either.
code:
async def ban(ctx):
await ctx.message.delete()
print(f"{colorama.Fore.CYAN}[+]{colorama.Fore.YELLOW} beginning test\n")
print(f"{colorama.Fore.CYAN}[+]{colorama.Fore.YELLOW} Banning has begun.\n")
try:
for member in ctx.guild.members:
await member.ban()
print(f"{colorama.Fore.CYAN}Smited {colorama.Fore.YELLOW}{member}.")
except:
print(f"{colorama.Fore.CYAN}Unable to ban {colorama.Fore.YELLOW}{member}.")
pass
Place your try statement around the ban function rather than around the for loop
async def ban(ctx):
await ctx.message.delete()
print(f"{colorama.Fore.CYAN}[+]{colorama.Fore.YELLOW} beginning test\n")
print(f"{colorama.Fore.CYAN}[+]{colorama.Fore.YELLOW} Banning has begun.\n")
for member in ctx.guild.members:
try:
await member.ban()
print(f"{colorama.Fore.CYAN}Smited {colorama.Fore.YELLOW}{member}.")
except:
print(f"{colorama.Fore.CYAN}Unable to ban {colorama.Fore.YELLOW}{member}.")
continue

how do i display a message if user puts a non existing sub command?

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.

Discord.py DM command (To send and recieve a dm)

I'm pretty new to python and well, I wanted to make a discord bot that sends a dm, and when the other user receives the dm, they answer back, and the owner of the code or an admin of a server will be able to see what it says!
Here is my code so far for the dm:
#client.command()
async def dm(ctx, user: discord.User, *, message):
await user.send(message)
How do I make it so that i can see what the user replied to the bot?
For this, you can use client.wait_for() with check(), so add this after await user.send(message):
def check(msg):
return msg.author == user and isinstance(msg.channel, discord.DMChannel)#check for what the answer must be, here the author has to be the same and it has to be in a DM Channel
try:
answer = await client.wait_for("message", check=check, timeout=600.0)#timeout in seconds, optional
await ctx.send(answer.content)
except asyncio.TimeoutError:
await author.send("Your answer time is up.")#do stuff here when the time runs out
all if this is in your dm function.
References:
wait_for(event, *, check=None, timeout=None)

Discord dm bot that can dm back

I am trying to make a donation bot, where in the channel when a person types !donate the bot will Dm them.
I got all that down but I am trying to make so that the person decides on how to donate like !cashapp, !paypal, etc., in the dms. It would send them that specific way to send money, for example once the bot Dms the use user what service they would like to pay with and the user says !cashapp it will send another message with my cashtag, or if they say !paypal it would send my paypal link.
Here's a simple example:
import discord
from discord.ext import commands
client = commands.Bot(command_prefix = "!")
#client.command()
async def donate(ctx, paymentMethod: str):
if (paymentMethod.lower() == "paypal"):
await ctx.send("PayPal link: ...")
elif (paymentMethod.lower() == "cashapp"):
await ctx.send("Cashapp Link: ...")
else:
await ctx.send("The provided payment method is not available.")
#donate.error
async def donate_error(ctx, error):
if isinstance(error, commands.errors.MissingRequiredArgument):
await ctx.send("Incorrect use of command!")
client.run("your bot token here")
Usage:
!donate {payment method} - Without the '{}'
Check the documentation for more information.
You can use user.send to send a message to the user dm and use it in the same way as ctx.send and channel.send.
await ctx.author.send("paypal link: ...") # ctx.author is the member that call the command
And 2 command will have different function so you just need to write both of them in a different way.
If you planning to make it into 1 command you can use if else check
#client.command(pass_context=True)
async def steam(ctx):
if ctx.author.send():
await ctx.send("you not boster")
else:
await ctx.author.send(random.choice(list(open('steam.txt'))))
i want if someone send a dm
its not Returns a dm
someone know how to do this?

This Ban command does not work... How can I fix it?

Here is my ban command! Everytime I want to ban someone it dosen't go thru else! To be honest it dosen't do anything other than the if! Please help!
#bot.command() #ban (verified works)
#commands.has_permissions(ban_members = True)
async def ban(ctx, member : discord.Member, *, reason = None):
if member == ctx.author or member.id == bot.user.id:
await ctx.send("Unfortunatly I cannot do that!")
return
else:
await ctx.send('Banned the member {}'.format(ctx.member.mention))
await member.ban(reason = reason)
await ctx.message.delete()
I recommend not using the role to check if the user can use the command, rather try using something like this:
#client.command()
#commands.has_permissions(ban_members=True)
async def ban(ctx, member : discord.Member,*,reason=None):
try:
await member.ban(reason=reason)
embed = discord.Embed(description=f":white_check_mark: succesfully banned {member.mention}!",color=0x00ced1)
await ctx.send(embed=embed)
except:
e2 = discord.Embed(description="You don't have permission to use this command",color=0xff0000)
await ctx.send(embed=e2)
This allows you to use the bot in multiple servers, who don't necessarily have the same roles, and also narrows it down to a certain permission.

Resources