Reputation: 166
Im trying to make a command where the bot "snipes" the last deleted message. this is my current code:
snipe_message_content = None
snipe_message_author = None
@client.event
async def on_message_delete(message):
snipe_message_author.remove(None)
snipe_message_content.remove(None)
snipe_message_content.append(message.content)
snipe_message_author.append(message.author.id)
await asyncio.sleep(str(60))
snipe_message_author.remove(message.author.id)
snipe_message_content.remove(message.content)
@client.command()
async def snipe(message):
if snipe_message_content==None:
await message.channel.send("Theres nothing to snipe.")
else:
embed = discord.Embed(description=f"{snipe_message_content}")
embed.set_footer(text=f"Asked by {message.author.name}#{message.author.discriminator}", icon_url=message.author.avatar_url)
embed.set_author(name= f"<@{snipe_message_author}>")
await message.channel.send(embed=embed)
return
the await message.channel.send("Theres nothing to snipe.")
part works perfectly fine, but the rest wont work. Can anyone help?
Upvotes: 3
Views: 11029
Reputation: 555
Well your on_message_delete()
function is just not working.
First of all, your variables snipe_message_author
and snipe_message_content
are of the type None
, but the methods remove
and append
are part of the type list
, so you'd have to declare lists
snipe_message_content = []
snipe_message_author = []
in order for them to work.
Still, you wouldn't have to do this anyway. Just give your current variables a new value:
snipe_message_content = None
snipe_message_author = None
@client.event
async def on_message_delete(message):
global snipe_message_content
global snipe_message_author
# Variables outside a function have to be declared as global in order to be changed
snipe_message_content = message.content
snipe_message_author = message.author.id
await asyncio.sleep(60)
snipe_message_author = None
snipe_message_content = None
Also, do not convert 60 to a string. time.sleep
and asyncio.sleep
both need an integer
in order to work (side note: if you wanted 60 to be a string, just write "60"
in quotation marks).
At last, be aware of the following case: If a message x
gets deleted, but 50 seconds after that, a new message y
gets deleted, snipe_message_author
and snipe_message_content
would be assigned to the new message y
. But 10 seconds later, the function executed by message x
would set the value of snipe_message_author
and snipe_message_content
to None.
Therefore, after await asyncio.sleep(60)
, check whether your message is still the same as before:
snipe_message_content = None
snipe_message_author = None
snipe_message_id = None
@client.event
async def on_message_delete(message):
global snipe_message_content
global snipe_message_author
global snipe_message_id
snipe_message_content = message.content
snipe_message_author = message.author.id
snipe_message_id = message.id
await asyncio.sleep(60)
if message.id == snipe_message_id:
snipe_message_author = None
snipe_message_content = None
snipe_message_id = None
Upvotes: 6
Reputation: 78
Your command works now probably, but there's a problem. If I delete a message in my server, and you run the command in your server, you'll probably see the message.
What you should do is make the snipe_message_author
and snipe_message_content
variables dictionaries.
This is how the event should be:
snipe_message_author = {}
snipe_message_content = {}
@client.event
async def on_message_delete(message):
snipe_message_author[message.channel.id] = message.author
snipe_message_content[message.channel.id] = message.content
await sleep(60)
del snipe_message_author[message.channel.id]
del snipe_message_content[message.channel.id]
@client.command(name = 'snipe')
async def snipe(ctx):
channel = ctx.channel
try: #This piece of code is run if the bot finds anything in the dictionary
em = discord.Embed(name = f"Last deleted message in #{channel.name}", description = snipe_message_content[channel.id])
em.set_footer(text = f"This message was sent by {snipe_message_author[channel.id]}")
await ctx.send(embed = em)
except KeyError: #This piece of code is run if the bot doesn't find anything in the dictionary
await ctx.send(f"There are no recently deleted messages in #{channel.name}")
#If the bot sends the embed, but it's empty, it simply means that the deleted message was either a media file or another embed.
To summarize it, here's what this fixes for you:
Hope this helped :)
Upvotes: 4