How to send a message when a command is not found? - discord.py

I am trying to send a message when a command is not found but it is not working:
#client.event
async def on_ready():
change_status.start()
print("----------------------")
print("Logged In As")
print("Username: %s" % client.user.name)
print("ID: %s" % client.user.id)
print("----------------------")
async def on_message(ctx, error):
if isinstance(error, commands.CommandNotFound):
text = ('Sorry {}, this command does not exist check $help for a more detailed list of').format(ctx.author.mention)
msg = await ctx.send(text)
await ctx.message.delete()
await asyncio.sleep(5)
await msg.delete()
else:
pass
raise error

You're looking for on_command_error event
#client.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
await ctx.send("Command does not exist.")
Reference:
on_command_error

I have found an answer to my issue instead of running it through a client.event decorator, I have ran it through a client.listen, decorator:
#client.event
async def on_ready():
change_status.start()
print("----------------------")
print("Logged In As")
print("Username: %s" % client.user.name)
print("ID: %s" % client.user.id)
print("----------------------")
#client.listen()
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
text = ('Sorry {}, this command does not exist check $help for a more detailed list of').format(ctx.author.mention)
msg = await ctx.send(text)
await ctx.message.delete()
await asyncio.sleep(5)
await msg.delete()

The on_command_error event is called when an error happens on any command.
and inside the on_command_error event you can check whether the error is an instance of CommandNotFound, which is thrown when the typed command is not found, or it doesn't exist. And if so, you can send a message to the channel, where the command was used.
#client.event
async def on_command_error(ctx, error):
"""Command error handler"""
embed = discord.Embed(color=discord.Color.red())
if isinstance(error, commands.CommandNotFound):
embed.title = "Command not Found"
embed.description = "Recheck what you've typed."
#await ctx.send(embed=embed)

Related

How do i remove a command message in discord.py

I am trying to delete the command message (the one sent by the user not by bot)
Ive tried it like this.
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content.startswith("-"):
wait(5)
await message.delete()
and this
#bot.command()
async def creator(ctx, message):
await ctx.send(f"Example text")
wait(5)
await message.delete()
but none of them work. If you know why please post a solution. Thanks!
In the first code :
import time
#bot.event
async def on_message(message):
if message.author.bot : return
if message.content.startswith("-"):
time.sleep(5)
await message.delete()
Second Code
import time
#bot.command()
async def creator(ctx):
await ctx.send("Example text")
time.sleep(5)
await ctx.message.delete()
If you are using the both of on_message and commands in your bot,
You may want to add this in the end of on_message Event So your bot will handle the on_message event, Then it goes to process commands.
Without it the bot commands wont work .
await bot.process_commands(message)
Eg :
#bot.event
async def on_message(message) :
await message.channel.send("Example")
await bot.process_commands(message)

Trying to make an auto purge/delete event discord.py

#client.event
async def on_message(message):
if message.author == client.user:
return
if message.channel.get_channel(763827099084521484):
await asyncio.sleep(5)
await message.delete()
Though I get the error:
File “main.py”, line 24, in on_message
if message.channel.get_channel(763827099084521484):
AttributeError: ‘TextChannel’ object has no attribute ‘get_channel’
This should be a good solution to the question:
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.channel.id == 763827099084521484):
await asyncio.sleep(5)
await message.delete()
(Credit to Dominik)
Thanks, and welcome to Stack Overflow :D

I want to improve my kick command in discord.py

I have made a bot in discord.py which has a kick command. But I want the bot to say "please tell me whom to kick" when someone uses the command without saying whom to kick. I mean if someone uses the kick command without mentioning whom to kick, the bot will say "please tell me whom to kick".
I am trying to make a good bot so please help me.
async def kick(ctx, member : discord.Member, *, reason=None):
if (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kickded for {reason}")
if not (ctx.message.author.permissions_in(ctx.message.channel).kick_members):
await ctx.send("You don't perms to play football with Araforce and kick them. Sed")
if not user:
await ctx.message.delete()
msg = await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and the go away.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("Hmm.. Why I will kick him? Specify a reason please.")
await sleep(4.7)
await msg2.delete()
return```
async def kick(ctx, user: discord.User = None, *, reason=None):
if not user:
await ctx.message.delete()
msg = await ctx.send("You must specify a user.")
await sleep(4.7)
await msg.delete()
return
if not reason:
await ctx.message.delete()
msg2 = await ctx.send("You must specify a reason.")
await sleep(4.7)
await msg2.delete()
return
I changed ifs to the error handler, which is necessary because if you won't pass one of the arguments (user or reason) you would get an error.
Full code:
#client.command()
async def kick(ctx, member: discord.Member, *, reason): #if you will change "member" and "reason" to something else remember to also change it in error handler
await member.kick(reason=reason)
await ctx.send(f"{member.mention} has successfully been kicked for {reason}")
#kick.error #cool mini error handler
async def kick_error(ctx, error):
if isinstance(error, discord.ext.commands.errors.MissingRequiredArgument):
if str(error) == "member is a required argument that is missing.": #change this if you changed "member"
await ctx.message.delete()
await ctx.send("You are a bit idiot, don't you know I can't kick anyone if you don't tell whom to kick? Tell me whom to kick and then go away.", delete_after=4.7) #you don't have to use "await sleep" you can use "delete_after" parameter
elif str(error) == "reason is a required argument that is missing.": #change this if you changed "reason"
await ctx.message.delete()
await ctx.send("Hmm.. Why I will kick him? Specify a reason please.", delete_after=4.7)
elif isinstance(error, discord.ext.commands.errors.MissingPermissions):
await ctx.send("You don't have perms to play football with Araforce and kick them. Sed")
Discord error handling example

How do I combine 3 on_message functions into 1 on_message function

Basically I need to combine these 3 on_message functions into 1 on_message function cause you can't have more than 1 on_message function in a discord.py bot. Here's my code:
#client.event
async def on_message(message):
if message.content.startswith('Jason derulo'):
await message.channel.send('Wiggle wiggle wiggle')
await client.process_commands(message)
#client.event
async def on_message(message):
if message.content.startswith('fast'):
await message.channel.send('She a runner she a track star')
await client.process_commands(message)
#client.event
async def on_message(message):
await client.process_commands(message)
if message.author.bot:
return
for badword in file:
if badword in message.content.lower():
await message.delete()
warnMessage = f"Hey {message.author.mention}! Don't say that!"
await message.channel.send(warnMessage, delete_after=5.0)
print(f"{message.author.name} tried saying: {badword}")
channel = client.get_channel(836232733126426666)
embed = discord.Embed(title=f"Someone tried to swear!", colour=0x2D2D2D)
embed.add_field(name="Person who tried to swear:", value=f"{message.author.name}", inline=False)
embed.add_field(name="What they tried to say:", value=f"{badword}", inline=False)
await channel.send(embed=embed)
return
await client.process_commands(message)
You just add all the if together, but only use one await client.process_commands(message) at the bottom:
#client.event
async def on_message(message):
if message.author.bot:
return
for badword in file:
if badword in message.content.lower():
await message.delete()
warnMessage = f"Hey {message.author.mention}! Don't say that!"
await message.channel.send(warnMessage, delete_after=5.0)
print(f"{message.author.name} tried saying: {badword}")
channel = client.get_channel(836232733126426666)
embed = discord.Embed(title=f"Someone tried to swear!", colour=0x2D2D2D)
embed.add_field(name="Person who tried to swear:", value=f"{message.author.name}", inline=False)
embed.add_field(name="What they tried to say:", value=f"{badword}", inline=False)
await channel.send(embed=embed)
return
await client.process_commands(message)
if message.content.startswith('Jason derulo'):
await message.channel.send('Wiggle wiggle wiggle')
if message.content.startswith('fast'):
await message.channel.send('She a runner she a track star')
await client.process_commands(message)

Discord.py echo command

So I am trying to make a discord.py echo/say command, but no response or errors are happening, if you know how to fix this please help me out!
import discord, os, keep_alive, asyncio, datetime, pytz, requests
from discord.ext import tasks, commands
client = commands.Bot(
command_prefix=':',
self_bot=True
)
async def on_ready():
client.remove_command('help')
await client.change_presence(status=discord.Status.online, activity=discord.Game("TEST"))
#client.command()
async def echo(ctx, *,args):
if ctx.message.author.id in [782258096210051102]:
await ctx.send(args)
await ctx.message.delete()
else:
await ctx.send("Bot developers only :<")
keep_alive.keep_alive()
client.run(os.getenv("TOKEN"), bot=False)
It's not working because the ctx.author is None, to fix that enable intents.members
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(..., intents=intents)
Also make sure to enable them in the developer portal
Reference
Uhhhhhh it is better to do something like
#bot.command()
async def echo(ctx,*,arg):
#the star is required
if ctx.authir.id==782258096210051102:
await ctx.send(arg)
else:
await ctx.send("devs only :<")
You can use ' '.join(ctx.message.content.split()[1:]) to join all words after the first space. So something like:
#client.command()
async def echo(ctx, *args):
await ctx.send(' '.join(ctx.message.content.split()[1:]))
To See Where The Problem Is From First Try:
#client.command()
async def echo(ctx, *,args):
await ctx.send(args[0])
await ctx.message.delete()
Ok so actually you have need to do this:
#client.command(name='echo')
async def echo(ctx, *, what_bot_need_to_say: str):
if ctx.message.author.id == 782258096210051102:
await ctx.channel.purge(limit=1) # This delete an message in the channel
await ctx.send(what_bot_need_to_say) # This the echo
else:
await ctx.send("Bot developers only :<")
#bot.command()
async def say(ctx, *, msg):
await ctx.send(msg)
Just copy me it is the simplest and gives the correct format
import discord
from discord.ext import commands
bot = commands.Bot('?')
#bot.command()
async def repeat(ctx,*,repeat:str):
if ctx.author.id == 782258096210051102:
await ctx.send(f"{repeat}")
await ctx.message.delete()
return
else:
await ctx.send("Only devs")
return
#bot.event
async def on_ready():
print("bot online")
bot.run("YOUR_TOKEN_HERE")
try this:
import discord, os, keep_alive, asyncio, datetime, pytz, requests
from discord.ext import tasks, commands
client = commands.Bot(
command_prefix=':',
self_bot=True
)
async def on_ready():
client.remove_command('help')
await client.change_presence(status=discord.Status.online, activity=discord.Game("TEST"))
#client.command()
async def echo(ctx, *,args):
if ctx.author.id in [782258096210051102]:
await ctx.send(args)
# await ctx.message.delete() # i am not sure of delete you can add it if you want
else:
await ctx.send("Bot developers only :<")
keep_alive.keep_alive()
client.run(os.getenv("TOKEN"), bot=False)

Resources