The Problem
I am running a bot event on a cog and I want to delete a message if it is not in the right channel. However, on_message only seems to take the messages argument so I cannot delete the message sent in context:
#commands.Cog.listener()
async def on_message(self, message):
musicchannel = self.bot.get_channel(705116959804489898)
if message.content.startswith('-p'):
if message.channel.id == musicchannel.id:
pass
else:
await message.channel.send("```ini\n[Music commands only in the appropriate channel]```", delete_aft$
await asyncio.sleep(4)
message.delete()
Usually you would have the ctx argument so it's as simple as ctx.message.delete() but that will not work in this case.
What I've tried
I have attempted to fetch the message with self.bot.fetch_message(message.id) but bot does not take the attribute fetch_message().
Solution
Somehow I didn't notice it straight away but all you need is await as .delete() is a co-routine.
All you're missing is await. As delete() is a co-routine, you just need to modify the event so that:
#commands.Cog.listener()
async def on_message(self, message):
musicchannel = self.bot.get_channel(705116959804489898)
if message.content.startswith('-p'):
if message.channel.id == musicchannel.id:
pass
else:
#code
await message.delete()
References:
Message.delete()
Related
#client.event
async def on_message(message):
channel = client.get_channel(927625164038996019)
if message.channel == channel:
if message.author.id == 927033032882405517:
pass
else:
await message.add_reaction("✅")
await message.add_reaction("❌")
else:
pass
I would like to add:
if message.reactions == 2 await message.pin()
but it is not working, and every way I tried, it did not worked.
Don't use on_message it will be called once the message sent and it will not called for reacting the message with emoji. To tackle this issue you can use on_raw_reaction_add which will be called upon reacting the message with emoji.
Use the below code to solve this problem
#client.event
async def on_raw_reaction_add(payload):
channel=await client.fetch_channel(payload.channel_id)
message=await channel.fetch_message(payload.message_id)
user = await message.reactions[0].users().flatten()
if len(user)==2:
await message.pin()
So I have an AntiSpam system in place, which is made in on_message event of discord.py. The code to the same is below -->
#bot.event
async def on_message(message):
await bot.wait_until_ready()
if message.author == bot.user:
return
bucket = bot.AntiSpam.get_bucket(message)
retry_after = bucket.update_rate_limit()
if retry_after:
print('Someone was being naughty')
await message.channel.purge(before=datetime.utcnow(), after=datetime.utcnow()-timedelta(seconds=5))
await message.channel.send(f'Please don\'t spam, {message.author.mention}', delete_after=5.0)
This deletes every single message sent since the last 5 seconds. How to make it so that it would only delete the message sent by that spammer? I know I have to use the check kwarg of TextChannel.purge(), but I need a way to make the check. Can I get any help regarding this?
The check would be very simple:
def check(m):
return m.author == message.author
await message.channel.purge(before=datetime.utcnow(), after=datetime.utcnow()-timedelta(seconds=5), check=check)
We're checking if the author of the message passed into the check is the same as the author of the previous message.
I'm trying to make a only allowed message in a chat. The code I tried deletes every message even if is the correct one. What am I doing wrong?
#bot.event
async def on_message(message):
if message != '!d bump':
await message.delete()
You're comparing a Message instance to a string, to get the actual content of the message use the content attribute
#bot.event
async def on_message(message):
if message.content != '!d bump':
await message.delete()
Code:
import discord
class MyClient(discord.Client):
async def on_ready(self):
print('Logged in as')
print(self.user.name)
print(self.user.id)
print('------')
async def on_message(self, message):
words = [] # List of words to look for
if message.author.id == self.user.id:
return
for i in words:
if i in message.content.lower():
await message.channel.send(f"Hey <#{message.author.id}>, i have noticed that in your message is a word on a list")
break
await message.add_reaction("✅")
await client.wait_for("reaction_add")
await message.delete()
client = MyClient()
client.run("TOKEN")
How Could i make the bot add reaction to its own message and if the user uses it delete its own message
i did look for the answer but god is discord.py messy, i have seen 6 answers that did not work and all of them seemed like they use different modules
i apologize if the answer was easy to find, but i just couldnt
First of all, you should always try to find your answer in the documentation (discord.py documentation). (Off-topic: it's not discord.py that's messy; it's likely the method you are using to find answers which is messy.)
The TextChannel.send() method returns the message which was sent. So, you could just assign that return value to a variable.
For the other issue, there is an event listener which detects message deletions, on_message_delete()
import discord
class MyClient(discord.Client):
async def on_ready(self):
...
async def on_message(self, message):
words = []
if message.author.id == self.user.id:
return
for i in words:
if i in message.content.lower():
sent_message = await message.channel.send(
f"Hey {message.author.mention}, I have noticed that in your message is a word on a list"
)
break
await sent_message.add_reaction("reaction")
await message.add_reaction("✅")
await client.wait_for("reaction_add")
await message.delete()
async def on_message_delete(self, message):
# Do stuff here
client = MyClient()
client.run("TOKEN")
(On a side note, you can use Member.mention to mention/ping a member, instead of "<#{message.author.id}>".)
In my opinion, it is preferable to use the #client.event method decorator above your event methods instead of putting them in their own class. You would declare the client object as client=discord.Client() at the top, then put #client.event above your event handling methods. The on_reaction_add method can have reaction and message parameters to respond.
I made a working AFK code, but i need it to slice (delete) '[AFK]' if the user sends a message. The code is:
#client.command()
async def afk(ctx, *, message="Dind't specify a message."):
global afk_dict
if ctx.author in afk_dict:
afkdict.pop(ctx.author)
await ctx.send('Welcome back! You are no longer afk.')
await ctx.author.edit(nick=ctx.author.display_name(slice[-6]))
else:
afk_dict[ctx.author] = message
await ctx.author.edit(nick=f'[AFK] {ctx.author.display_name}')
await ctx.send(f"{ctx.author.mention}, You're now AFK.")
I got no errors. i only need await ctx.author.edit(nick=ctx.author.display_name(slice[-6])) to be working and i'll be happy.
You need to have a on_message event. Something like this should work.
#client.event
async def on_message(message):
if message.author in afk_dict.keys():
afk_dict.pop(message.author.id, None)
nick = message.author.display_name.split('[AFK]')[1].strip()
await message.author.edit(nick=nick)
I also recomend you to store user id's instead of usernames.
To do that you just have to use member.id instead of member.