I can't figure out how to create the purge command in discord.py. This is what I am currently using it creates no errors in the code but the bot doesn't respond to the command.
client = discord.Client()
#client.event
async def on_message(message):
if message.content.startswith('!purge'):
tmp = await client.send_message(message.channel, 'Clearing messages...')
async for msg in client.logs_from(message.channel):
await client.delete_message(msg)
By the looks of it you're using the async branch (please switch to rewrite) of discord.py
For one doing the whole command invocation in on_message thing is not, while it works, a good way of doing it. Try out the commands extension!
Secondly there is already a method for this in async see here
Thirdly the reason why your code isn't working or why it doesn't look like it's working is because you are using client.logs_from with no limit specified so it's downloading every message in that channel and this will take a while to do before it executes the code below it.
Related
The Question
Is there something like an event listener for slash commands in discord.py or discord-py-slash-command, that execudes code when a slash command was send?
What I know
As we all know, in discord.py there are event listeners, like on_message:
#bot.event
async def on_message(message: discord.Message):
await message.channel.send(f'You said {message.content}.')
And with discord.ext there a listeners for commands:
#bot.command()
async def hello(ctx):
await ctx.send('Hi!')
And with discord_slash there are slash commands:
#slash.slash(
name='hello',
description='Say hello.'
)
async def _hello(ctx):
await ctx.send('Hi!')
What I need
Regardless, I want to execute some code, whenever a slash command is used. I would imagine it to work like this:
#slash.event()
async def on_slash(ctx):
# Something
Is there such a functionality in the mentioned libaries and if not, can I still somehow execude some code whenever a slash command was used?
PS: First question, so I'm open to improvement suggestions.
I'm fairly certain that you cannot listen to the slash command interactions of other bots, but if you want to set up a listener for your own slash commands you can use the on_interaction listener:
#bot.event
async def on_interaction(interaction):
if str(interaction.type) == "InteractionType.application_command":
print("test")
application_command is a slash command interaction, here are the docs for the other types.
And here's the doc for on_interaction in general.
Also please keep in mind that this only got added in the discord.py 2.0 alpha version, so if you do not have the newest version installed already, you can install it with pip install -U git+https://github.com/Rapptz/discord.py.
Hope this is at least somewhat useful.
So I am trying to have an event where, once the user types a specific word (not a command, literally a word/string), the event will trigger an existing command. Yeah you may wonder "Why not have the user type the command itself?" well, the reason why this isn't the case it's kinda hard to explain. Check this out:
My event will work only if the person types "nothing" (literally the word nothing). Eventually, the person won't expect the bot to actually take this as a command, and so he/she won't type it as command (with the prefix and all that) This is my code:
#client.command()
async def menu(ctx)
#here, well, goes what I want the command to do but it's not the issue
#client.event
async def on_message(message):
if message.content.startswith("nothing"):
#here idk how to execute the command up there. That's my question
I hope I am being clear with my issue. Don't worry about what the command exectues, or why the message for the event is "nothing". I just really want to know how to make this work.
Some friends suggested me to invoke the command, but I didn't really know how to do that, and everytime I would try it wouldn't work. Others suggested to call the function, but I also tried that and it wouldn't work. I don't know if I typed it correctly or if it simply won't work. I hope someone helps me out here.
Thanks in advance.
get_context, this takes a message object. Then invoke. Keep in mind, there are 3 downsides to using this method.
The converters (the type hints) won't be triggered. You need to pass the correct types into the arguments.
Checks will be bypassed. You could invoke an owner only command with a non-owner and it would still work.
If you still want to run all the checks, see can_run, which will run all the checks and raise an error if any checks fail.
If ctx.invoke was invoked outside of a command (eg eval), the error handler won't fire.
#client.command()
async def menu(ctx):
await ctx.send("Hello")
#client.event
async def on_message(message):
if message.content.startswith("nothing"):
ctx = await client.get_context(message)
await ctx.invoke(menu)
await client.process_commands(message)
If your client is a Bot instance you can use Bot.get_context() to create your own context and invoke the command from there:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.command()
async def menu(ctx):
await ctx.send('bar')
#bot.event
async def on_message(message):
if message.content.startswith('foo'):
ctx = await bot.get_context(message, cls=commands.Context)
ctx.command = bot.get_command('menu')
await bot.invoke(ctx)
await bot.process_commands(message)
TIA for your help and apologies, I'm a newbie so this may be a foolish question. I've searched through and can't find anything specific on how to make a discord bot (in Python) delete messages only within a specific channel. I want all messages sent to a specific channel to be deleted, their contents sent via PM to the user and the user's role changed.
Is there a way to use on_message and specify in an specific channel?
#client.event
async def on_message(message):
user = message.author
if message.content.startswith("Cluebot:"):
await message.delete()
await user.send("Yes?")
await user.remove_roles(get(user.guild.roles, "Investigator"))
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
Is it possible to make this work through a command instead of an event?
Thanks for your help. :)
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
About this problem the clue is:
await bot.process_commands(message)
as docs says Without this coroutine, none of the commands will be triggered.
about the main question you could try using get_channel by ID and then purge it:
eg.
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1)
you can add check to purge() to check for deleting specific message:
eg.:
def check(message):
return message.author.id == [author's ID]
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1, check=check)
So I am trying to create an event in discord.py where, whenever a user mentions/pings the bot, it will say something. The code below runs without errors, however the only way this will work is if my command prefix is in the message.
For my bot, the prefix is "/", so whenever I mention the bot with a "/" in the message it will say something. And if I decide to just mention the bot, the bot does not respond. I am pretty sure it's got something to do with the last line of code but I don't know how to fix this issue.
#client.event
async def on_message(message):
if client.user.mention in message.content.split():
await message.channel.send('You mentioned me!')
else:
await client.process_commands(message)
The code is written in Python 3.7.4.
All help would be appreciated!
When someone mentions a user the bot reads <#userid>. So if you want to use an on_message function you would want to include an
if '<#bot/user id>' in message.content:
await message.channel.send('hi')
You can also do something like...
if bot.user in message.mentions:
await message.channel.send('hi')
Whenever I run my discord python code, and test it in the discord chat, it says the ping command is not found even though I defined it in the code.
I've tried to use both Bot and Client and both gave the same error.
import discord
from discord.ext import commands
bot_prefix= "]"
bot = commands.Bot(command_prefix=bot_prefix)
bot.run("*")
#bot.event
async def on_ready():
print("ok")
#bot.event
async def on_message(message):
print(message.content)
#bot.command()
async def ping(ctx):
latency = bot.latency
await ctx.send(latency)
Personal information replaced with "*"
The bot should send a message in the user's channel saying the latency of the bot, but instead I just get an error that says:
"Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "ping" is not found" even though I defined the ping command in the code.
Also, it should be noted that the on_ready event never runs; I never get the print statement in the console log.
Any help is appreciated thanks :)
bot.run must be the last line in your code. Python executes sequentially, so all of the stuff below bot.run isn't called until after the bot is finished running.
Okay I got it fixed!!
Apparently there's an issue with the on_message function, I guess I just skipped over it in the FAQ. Anyone confused about this, just add the line:
await bot.process_commands(message)
into your on_message function. When you define your own on_message function it overrides the original one that passes the message into the commands handler.
Also make sure to use bot.run() at the end of your code, after your function declarations. Simple mistakes, but they're all fixed now :)