Adding a reason to a command - discord.py

With this I'm wanting to have the reason work, I would like it similar to the *ban command where you have a reason, but instead of it logging in audit logs the reason you give replaces {reason} in the embed. It doesn't throw up any error codes when I try it out but it doesn't send the embed to my dm's.
#Command to send a user their denied outcome
#bot.command()
async def deny(ctx, *, user : discord.User, reason):
await ctx.message.add_reaction(f'✅')
embed = Embed(title="Application Denied",
description=f"Hello {user.name}, your application is being denied due to {reason}. Feel free to re-apply in 2 weeks, we wish you luck!",
color=0xffffff,
timestamp=datetime.utcnow())
embed.set_image(url="https://media.discordapp.net/attachments/935059565588930601/946167642207686686/rejected-stamp.gif")
embed.set_footer(text=f'Denied By {ctx.author.name} | {ctx.guild.name}', icon_url="https://media.discordapp.net/attachments/935059565588930601/945768014958178324/ezgif-1-5c3f7a6a54.gif?width=778&height=778")
await user.send(embed=embed)

#bot.command()
async def deny(ctx, user : discord.User,*,reason = "No reason was provided"):
reason = "".join(reason)
embed = discord.Embed(title="Application Denied",
description=f"Hello {user.name}, your application is being denied due to {reason}. Feel free to re-apply in 2 weeks, we wish you luck!",
color=0xffffff,
timestamp=datetime.utcnow())
embed.set_image(url="https://media.discordapp.net/attachments/935059565588930601/946167642207686686/rejected-stamp.gif")
embed.set_footer(text=f'Denied By {ctx.author.name} | {ctx.guild.name}', icon_url="https://media.discordapp.net/attachments/935059565588930601/945768014958178324/ezgif-1-5c3f7a6a54.gif?width=778&height=778")
await ctx.message.add_reaction(f'✅')
await user.send(embed=embed)

Related

Discord.py commands.BotMissingPermissions

I want to send an error message when my bot's role is insufficient, but I can't. I tried all the "MissingRole" commands but none of them work...
#Bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.BotMissingPermissions):
.
.
.
await ctx.channel.send(embed=embed)
if isinstance(error, commands.BotMissingPermissions):
await ctx.message.add_reaction("❌")
aEmbed = discord.Embed(
title=f"**__Error__**",
description="Whatever you want the bot to say to the user",
colour=discord.Colour.red()
)
await ctx.send(embed=aEmbed)
return
This is how I made the "BotMissingPermissions". The code is pretty basic, it just puts a "X" reaction to the message that made the error and then sends an embed saying what went wrong then returns so that it can continue functioning without any problems
Also the response you told the bot to do (await ctx.channel.send("Something something")) could be changed to await ctx.send("Something").

Advanced Discord Ban Command

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

Bot is unresponsive even when a "message.channel.send" await is called. What is wrong?

This discord.py project I have been working on in the past few days has given me nothing but trouble. To state what the issue is here. Basically the entire application is unresponsive, even when every await and every intent is enabled(on the commands.Bot main.py this is just an extension). I have tried every solution possible. I tried retyping keys and values for the dictionaries. And I even removed the embedded messages and replaced them with normal string messages. And I still got nothing. Here is a little snippet of the "problem". Anyways, I'd appreciate it if I could get some help on this?
#commands.Cog.listener()
async def on_message(self, message, member:discord.Member=None):
ARI=discord.utils.get(message.guild.roles,name=teamnames['ARI'])
ATL=discord.utils.get(message.guild.roles,name=teamnames['ATL'])
if message.content.startswith('<:ARI:844709003871387648> sign'):
member = message.mentions[0]
if ARI or ATL in member.roles:
embed=discord.Embed(title="Signing Failed", description=f"**{member.mention} Wasnt Signed due to there being another team role in that users role. If this is incorrect, have this user either: \nAsk for Release or Demand from the team that they are currently roled as. . .**")
await message.channel.send(embed=embed)
else:
embed=discord.Embed(title="Signing Transaction", description=f"**{member.mention} Was Signed to the <:ARI:844709003871387648> as the **`{len(ARI.members)}`** Player Signed Accordingly. If this was an error use command: <:ARI:844709003871387648> **`Release #user.mention`** To release the player of your initially signed roster.")
await member.add_roles(ARI)
await message.channel.send(embed=embed)
Resolved the issue by reverting to dictionary keys and values, but a new error is now showing. And the bot is still for some reason unresponsive? Snippet below:
#commands.Cog.listener()
#commands.has_any_role('Franchise Owner', 'General Manager', 'Head Coach')
async def on_message(self, message):
if 'have signed' in message.content:
member = message.mentions[0]
teamemojis = ["ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE"]
teamsids = [784827425422573608, 784827426093793330, 784827440324804639, 784827439221047317, 784827427029385246, 784827427796025364, 784827441205477386, 784827442174623745,]
teams=[]
if teamsids.id in teamsids:
teams.append(teamsids.id)
step2=str(teams)
step3=step2.replace("[","")
step4=step3.replace("]","")
print(step4)
step5=teamsids.index(int(step4))
print(step5)
emote=discord.utils.get(message.guild.emojis,name=teamemojis[step5])
team = discord.utils.get(message.guild.roles,id=int(step4))
pass
if team not in message.author.roles:
print('return')
return
elif team in message.author.roles:
print('pass')
pass
if team not in member.roles:
for role in message.author.roles:
role.name == team.name
await member.add_roles(role, reason="Signed by the Bot!")
embed=discord.Embed(title="Signing Transaction", description=f"**{member.mention} Was Signed to the {str(emote)} accordingly. If this was a mistake, please refer to the `have released` Command in the bot commands**")
embed.set_thumbnail(url=emote.url)
await message.channel.send(embed=embed)
elif team in member.roles:
await message.channel.send("**Cannot sign this user, as this user is already signed!**")
return
For an on_message event. Read the docs here: https://discordpy.readthedocs.io/en/stable/faq.html#why-does-on-message-make-my-commands-stop-working
Adding the line:
await bot.process_commands(message)
at the bottom of the on_message event should make it function correctly again

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.

decorator still calls function after failing

I understand why the error check is printed, but I don't understand why despite the fact that the user calling does not have the mod label, it runs the function anyway, maybe I don't really understand decorators (user also has a token role but I commented that part out for this test)
# token check
#bot.command(name='wallet', help='display if a token is available for user')
#commands.has_role('mod') # remove later
# #commands.has_any_role('PBToken 3', 'PBToken 6')
async def token_check(ctx):
name = ctx.author.name
response = name + ', You have a token available!'
await ctx.send(response)
# error message if user has no token currently
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.errors.MissingRole):
name = ctx.author.name
# await ctx.send(name + ', you currently do not have a token, keep leveling up!')
await ctx.send('error check')
Here is the output:
Intead of using the mod role, why don't you run it using the check for whether the user has server administrator. To do that, all you do would be to replace:
#commands.has_role('mod')
with:
#commands.has_guild_permissions(administrator=True)
This would make the command only run if the specified user has server admin.
Please feel free to reply if you need any more help! :)

Resources