Remove a specific reaction from message - python

I'm making a simple game in discord.py/pycord and I would like my bot to be able to delete a specific reaction. Is there a way to do this?
I want the reaction to delete after I click.
Like this:
Here is my code (I'm using pycord):
import discord
from discord.ext import commands
intents = discord.Intents().all()
bot = commands.Bot(intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == 'test':
me = await message.reply('Is this cool?')
await me.add_reaction("👎")
await me.add_reaction("👍")
try:
reaction, user = await bot.wait_for("reaction_add", check=lambda reaction, user:
user == message.author and reaction.emoji in ["👎", "👍"], timeout=30.0)
except asyncio.TimeoutError:
await message.reply("Tmieout bro")
else:
if reaction.emoji == "👍":
await message.reply('Like it.')
await reaction.delete()
else:
await message.reply("NO like")
await reaction.delete()

You first get the reaction object, then you remove it. Docs
Code:
#bot.slash_command(name='removereaction', description="I'm helping someone with their Stack post")
async def removereaction(ctx, message: discord.Option(discord.Message)):
print(message)
for i in message.reactions:
async for user in i.users():
await i.remove(user)
await ctx.respond(message.reactions)
How this works is it gets the message from the parameter message that has type discord.Option. The discord.Option is set so that you can use a message from a link or ID. Then, it uses this to cycle through all of the message's reactions. Then it cycles through each user that reacted with said reaction. It must be async, because i.users() is async (See here).
The full code that may help you:
import discord
from discord.ext import commands
intents = discord.Intents().all()
bot = commands.Bot(intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == 'test':
me = await message.reply('Is this cool?')
await me.add_reaction("👎")
await me.add_reaction("👍")
try:
reaction, user = await bot.wait_for("reaction_add", check=lambda reaction, user:
user == message.author and reaction.emoji in ["👎", "👍"], timeout=30.0)
except asyncio.TimeoutError:
await message.reply("Tmieout bro")
else:
if reaction.emoji == "👍":
await message.reply('Like it.')
async for user in reaction.users():
await reaction.remove(user)
else:
await message.reply("NO like")
async for user in reaction.users():
await reaction.remove(user)
If you want to remove JUST the bot's reactions change the following line:
async for user in reaction.users():
await reaction.remove(user)
To:
await reaction.remove(bot.user)

Related

Mod mail command

Someone know how to make the bot close the modmail? Like the member start spamming on the bot dms and you want to like block him
here is my modmail code
#client.event
async def on_message(message):
channel = client.get_channel(909853337510371449)
if message.author.id == client.user.id:
return
if message.author != message.author.bot:
if not message.guild:
await channel.send(f"[{message.author.mention}] {message.content}")
await client.process_commands(message)

How to detect a message from a specific user and delete it

I'm trying to detect a message from a specific user (me), delete it and send the same message again.
#client.event
async def on_message(message):
if message.author.id == 881583268569436200:
await message.delete(message)
await client.process_commands(message)
I don't know what I'm doing wrong. Please help
You don't have to use await message.delete(message) you already got the message after await statement. Just use await message.delete().
#client.event
async def on_message(message):
if message.author.id == 881583268569436200:
msg = message.content
await message.delete()
await message.channel.send(msg)
await client.process_commands(message)

Wait for reaction in DMs discord.py

I am trying to make a command that waits for a reaction on a DM and then gets the reaction emoji. I'm using discord.py. My code works in a normal text channel but not in DMs I also am getting no error messages it just doesn't work!
#bot.command()
async def ping(ctx, user: discord.User):
if user != None:
if user != ctx.author:
players = [ctx.author, user]
for player in players:
message = await player.send("test")
await message.add_reaction('👍')
await message.add_reaction('👎')
def check(reaction, user):
return user == player and str(reaction.emoji) in ['👍', '👎']
response = await bot.wait_for("reaction_add", check=check)
if str(response[0]) == "👍":
await player.send(str(response[0]))
else:
await player.send("👎")
Many thanks in advance
Edit: I do not have intents enabled

Actually waiting for a reaction with discord bot (Python)

I am trying to actually let my bot wait till it receives a reaction on its message and meanwhile do nothing. Just waiting. First as soon as it receives the reaction it should continue with the rest of the code. Here is a (shitty) example code:
#client.command()
async def test(ctx):
await ctx.send("waiting for players to join ...")
for i in range(5):
botMsg = await ctx.send("User X do you want to play?")
await botMsg.add_reaction("✔️")
await botMsg.add_reaction("❌")
try:
reaction, player = await client.wait_for('reaction_add', timeout=20, check=lambda reaction, player: reaction.emoji in ["✔️", "❌"])
except asyncio.TimeoutError:
await ctx.send("No one reacted.")
if client.user != player and reaction.emoji == "✔️":
await ctx.send(f"{player.mention} reacted with ✔️.")
elif client.user != player and reaction.emoji == "❌":
await ctx.send(f"{player.mention} reacted with ❌.")
Excecuting this code ends up in a big mess without the bot waiting in between the messages. How can I implement that the bot waits for a reaction between every message without already sending all of the other ones?
I'd appreciate anyone's help
There might be some problems with the way you check the emojis... I'm not really sure :/
Anyways here's what I got working:
#client.command()
async def test(ctx):
for i in range(5):
msg = await ctx.send("Waiting for reactions...")
emojis = [u"\u2714", u"\u274C"]
await msg.add_reaction(emojis[0])
await msg.add_reaction(emojis[1])
try:
reaction, user = await client.wait_for('reaction_add', timeout=20.0, check=lambda reaction, user: user.id != client.user.id and reaction.emoji in emojis)
if reaction.emoji == emojis[0]:
await ctx.send(f"{user.mention} said yes!")
else:
await ctx.send(f"{user.mention} said no :(")
except asyncio.TimeoutError:
await ctx.send("You\'re out of time!")

Discord.py make 'wait_for' to only work in private messages

I ran into an issue when making this discord bot. Whenever a user runs the command !!bug, there shall be a private message where the user has to answer a few questions. The issue is that whenever you run the command, you can still answer the question in the chat you ran the command.
I want it to only wait for the user response if the user wrote in private messages, and not the chat the command was run at. So this line of code:
responseDesc = await self.client.wait_for('message', check=lambda message: message.author == ctx.author, timeout=300)
Should only work when the user writes in private messages.
Here is my code:
import discord
from discord.ext import commands
import asyncio
emojis = ["\u2705", "\U0001F6AB", "\u274C"]
class Bug(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
async def bug(self, ctx, desc=None, rep=None):
await ctx.channel.purge(limit=1)
user = ctx.author
await ctx.author.send('```Please explain the bug```')
responseDesc = await self.client.wait_for('message', check=lambda message: message.author == ctx.author, timeout=300)
description = responseDesc.content
await ctx.author.send('```Please provide pictures/videos of this bug```')
responseRep = await self.client.wait_for('message', check=lambda message: message.author == ctx.author, timeout=300)
replicate = responseRep.content
await ctx.author.send('Your bug report has been sent.')
embed = discord.Embed(title='Bug Report', color=0x00ff00)
embed.add_field(name='Description',
value=description, inline=False)
embed.add_field(name='Replicate', value=replicate, inline=True)
embed.add_field(name='Reported By', value=user, inline=True)
adminBug = self.client.get_channel(733721953134837861)
message = await adminBug.send(embed=embed)
for emoji in emojis:
await message.add_reaction(emoji)
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
reaction_message = reaction.message
message = await reaction_message.channel.fetch_message(reaction_message.id)
my_embed = message.embeds[0]
emoji = reaction.emoji
if user.bot:
return
if emoji == "\u2705":
fixed_channel = self.client.get_channel(733722567449509958)
await fixed_channel.send(embed=my_embed)
elif emoji == "\U0001F6AB":
notBug = self.client.get_channel(733722584801083502)
await notBug.send(embed=my_embed)
elif emoji == "\u274C":
notFixed = self.client.get_channel(733722600706146324)
await notFixed.send(embed=my_embed)
else:
return
def setup(client):
client.add_cog(Bug(client))
You can check if the channel is private like if isinstance(message.channel, discord.DMChannel)

Categories