I am trying to make a giveaway bot. The bot is supposed to take the users who reacted and randomly select one from that list, but I can't figure out how to get the users who reacted.
#client.command()
#commands.guild_only()
#commands.has_role('giveaway')
async def giveaway(ctx, wait, *, reward):
end = int(wait)
giveEmbed = discord.Embed(title='A giveaway has begun!', description='React to this message to enter the giveaway.', color=discord.Colour.from_rgb(255, 107, 33))
giveEmbed.add_field(name='Prize:', value=f'{reward}', inline=True)
giveEmbed.add_field(name='Time:', value=f'{time} hour(s) after message sent.', inline=True)
message = await ctx.send(embed=giveEmbed)
reaction = await message.add_reaction('🎁')
time.sleep(5)
#can't figure out how to get the users who reacted here.
You have to fetch the message again to get the 'updated' reactions:
fetched_message = await ctx.channel.fetch_message(message.id)
reactions = fetched_message.reactions
for reaction in reactions:
if str(reaction) == '🎁':
# This if the list of the users that reacted with `🎁` to the message
users = await reaction.users().flatten()
And btw time.sleep(5) it's blocking your code, change it to await asyncio.sleep(5)
Reference:
TextChannel.fetch_message
Message.reactions
Related
I am creating a discord bot, and with this bot I want to create a verify command. I started working on it, and everything works to the point of giving the reaction (Sending message with the "yes and "no" reactions), when I run the code, it doesn't throw any errors. If you do help me, I would please also like an explanation of why my code doesn't work and why your's does if you can, so I can learn.
Thank you! -JJ
Code:
#client.command()
async def verify(ctx):
verifier = ctx.author
jj = await client.fetch_user(270397954773352469)
validReactions = ['✅', '🚫']
role = discord.utils.get(ctx.guild.roles, name="Verified")
await ctx.send(f'{verifier}... Awaiting Verification, you will recieve a dm when you are verified')
dm = await jj.send(f'{verifier.mention} is trying to be verified, do you know him/her?')
await dm.add_reaction("✅")
await dm.add_reaction("🚫")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in validReactions
reaction, user = await client.wait_for('reaction_add', timeout=float('inf') , check=check) #float('inf') for no timeout on when I can add the reaction for yes or no
if str(reaction.emoji) == "✅":
await verifier.send("You have been verified")
await client.add_roles(verifier, role)
elif str(reaction.emoji) == "🚫":
await verifier.send("You have not been verified, please try again if you think this was a mistake, or contact the owner")
You send a message to person called jj and user == ctx.author in check function is always True. (Because ctx.author can not see that message). So, try to replace
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in validReactions
with
def check(reaction, user):
return user == jj and str(reaction.emoji) in validReactions
I have a verification process on my server that takes the inputs of the new member (First name and section and whatever) then sends it to a channel in a server where admins click on an emote to accept/deny the person. The problem is, once 2+ people open tickets, it basically becomes unusable.
To make me sane while writing it, I'll make a scenario.
x, y join the server.
Both send verification requests.
Admin accepts request for x.
Instead of x being approved, x and y gets approved.
This is really bugging me as I might as well do it without the wait_for() checks.
Code:
#commands.Cog.listener()
async def on_member_join(self, member: discord.Member):
channel = member.guild.get_channel(734637251681583164)
verichannel = member.guild.get_channel(849593765097373696)
embed = discord.Embed(
title=f"Welcome {member.name}, keep in mind that this is NOT an [woah privacy] server!",
description=f"This is not a family-friendly server, so please leave if you're not comfortable with it. \n Make sure to read <#734639183737389060> & <#750190162000216215> before proceeding! \n To get access to our server, please verify at <#848430448223977512>.",
color=0x2ecc71
)
embed.set_thumbnail(url=member.avatar_url)
await channel.send(member.mention, embed=embed)
# DM verification
def check(m):
return m.guild == None and m.author == member
awaitingverification = discord.Embed(title="Verification Request", description=f"User: {member.mention}", color = 0x01c618)
embed= discord.Embed(title="What is this?",
description="This is a verification program for the unofficial [woah privacy] server. We do this to ensure the safety and privacy of our members. We are going to ask information that will be sent to our admins for further processing.",
color=0x00d118)
embed.set_author(name="[woah privacy] Verification program")
embed.add_field(name="1st Question: What is your first name?", value="Example: Jordan",
inline=False)
await member.send(embed=embed)
try:
first_name = await self.bot.wait_for('message',timeout=30, check=check)
except asyncio.TimeoutError:
await member.send("Timed out. Re-Join.")
return
awaitingverification.add_field(name="First Name", value=first_name.content, inline=True)
embed = discord.Embed(title="Verification: 2nd step",
description="This is the second step of the verification process.", color=0x00d118)
embed.set_author(name="[woah privacy] Verification program")
embed.add_field(name="2nd Question: What is your section? If you are not enrolled, reply 'Visitor'.", value="Example: LS208", inline=False)
await member.send(embed=embed)
try:
section = await self.bot.wait_for('message',timeout=30, check=check)
except asyncio.TimeoutError:
await member.send("Timed out. Re-Join.")
return
awaitingverification.add_field(name="Section", value=section.content, inline=True)
embed = discord.Embed(title="Verification: 3rd step",
description="This is the third step of the verification process.", color=0x00d118)
embed.set_author(name="[woah privacy] Verification program")
embed.add_field(name="3rd Question: Do you agree with all our rules? Reply with 'Yes' if you do.",
value="Below is a skimmed version of our full rules, so be sure to read them after.",
inline=False)
embed.add_field(name="This is not an official [woah privacy] server.", value="If there is one, then... we dont care.",
inline=False)
embed.add_field(name="Names in the server are your real first names.", value="If not: kicked out the door.",
inline=False)
embed.add_field(name="This is not a family friendly server.",
value="It's a mess here sometimes but thats what's good about it.", inline=False)
embed.add_field(name="Don't be an asshole.", value="We wont hesitate to swing that ban hammer.", inline=False)
embed.add_field(name="No loopholes.", value="Because.. Well... It's bad.", inline=False)
embed.add_field(name="Read the Discord ToS (Terms of Service)", value="TL:DR: Must be 13+ to use discord.",
inline=False)
await member.send(embed=embed)
try:
rulestatus = await self.bot.wait_for('message',timeout=30, check=check)
except asyncio.TimeoutError:
await member.send("Timed out. Re-Join.")
return
awaitingverification.add_field(name="Rules", value=rulestatus.content, inline=True)
awaitingverification.set_footer(text="🟩: Student, 🟨: Visitor, 🟥: Deny and Kick")
await member.send("Thank you. Your application will be processed in due time.")
verification = await verichannel.send(embed=awaitingverification)
await verification.add_reaction("🟩")
await verification.add_reaction("🟨")
await verification.add_reaction("🟥")
def check(reaction, user):
return str(reaction.emoji) in ["🟩", "🟨", "🟥"] and user != self.bot.user
reaction, user = await self.bot.wait_for("reaction_add", check=check)
if str(reaction.emoji) == "🟩":
embed = discord.Embed(title="Verification Request", description=f"User: {member.mention}")
embed.add_field(name="Status:", value=f"Approved by {user}: Student", inline=False)
await verification.edit(embed=embed)
await verification.clear_reactions()
role1 = discord.utils.get(member.guild.roles, name="Students")
await member.add_roles(role1)
if discord.utils.get(member.guild.roles, name=f"Section: {section.content}"):
sectionrole = discord.utils.get(member.guild.roles, name=f"Section: {section.content}")
await member.add_roles(sectionrole)
else:
await member.guild.create_role(name=f"Section: {section.content}")
sectionrole = discord.utils.get(member.guild.roles, name=f"Section: {section.content}")
await member.add_roles(sectionrole)
await member.send("Your Verification Request has been granted as Student. Have a good time and check the rules!")
return
elif str(reaction.emoji) == "🟨":
embed = discord.Embed(title="Verification Request", description=f"User: {member.mention}")
embed.add_field(name="Status:", value=f"Approved by {user}: Visitor", inline=False)
await verification.edit(embed=embed)
await verification.clear_reactions()
role2 = discord.utils.get(member.guild.roles, name="Visitors")
await member.add_roles(role2)
await member.send("Your Verification Request has been granted as Visitor. Have a good time and check the rules!")
return
elif str(reaction.emoji) == "🟥":
embed = discord.Embed(title="Verification Request", description=f"User: {member.mention}")
embed.add_field(name="Status:", value=f"Denied by {user}", inline=False)
await verification.edit(embed=embed)
await verification.clear_reactions()
await member.send("Your Verification Request has been denied.")
await member.kick()
return
p.s sorry, I didn't skim any of the code, I wanted to share it as is because maybe it's my spaghetti's fault.
To solve this, check if it's the same message in check:
verification = await verichannel.send(embed=awaitingverification)
await verification.add_reaction("🟩")
await verification.add_reaction("🟨")
await verification.add_reaction("🟥")
def check(reaction, user):
return str(reaction.emoji) in ["🟩", "🟨", "🟥"] and user != self.bot.user and reaction.message == verification
reaction, user = await self.bot.wait_for("reaction_add", check=check)
References:
reaction.message
I have this embed with rules to my discord server and the embed also has a reaction, the reaction is a check mark(✅). If you react to that embed with that check mark you will get a "Verify" role and your reaction will be deleted.
So it always gonna be one reaction and if u react you get "Verify" role and your reaction get deleted.
But that is the problem, I don't get my role when I react and my reaction doesn't get deleted either. I don't have any errors don't know how to fix this.
This is my code
#bot.command(name='rules', pass_ctx=True)
async def rules(ctx):
rules_embed = discord.Embed(title='DISCORD RULES', color=0xf30000)
rules_embed.add_field(name="**1. No spamming** ", value="Don't send a lot of small/big messages right after "
"each other. Do not disrupt chat by spamming.",
inline=False)
rules_embed.add_field(name="**2. No NSFW material** ", value="This is a community server and not meant to "
"share this kind of material.", inline=False)
rules_embed.add_field(name="**3. No bullying or threats** ", value="Threats to other users of DDoS(Distributed "
"Denial of Service), Death, DoX/Doxx, abuse, "
"and other "
"malicious threats are absolutely not okay.",
inline=False)
rules_embed.add_field(name="**4. Don't beg for ranks** ", value="Don't beg for staff or other ranks", inline=False)
rules_embed.add_field(name="**5. No racism** ", value="Racism is absolutely not okay in this discord server",
inline=False)
rules_embed.add_field(name="**6. Have fun** ", value="Just have fun and be nice", inline=False)
send_rules = await ctx.message.channel.send(embed=rules_embed)
reactions = ['✅']
for i in reactions:
await send_rules.add_reaction(i)
#bot.event
async def on_raw_reaction_add(payload):
channel = bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
guild = bot.get_guild(payload.guild_id)
reaction = discord.utils.get(message.reactions, emoji=payload.emoji.name)
# only work if it is the client
if payload.member.id == bot.user.id:
return
if payload.message_id == 784182764009947177 and reaction.emoji == '✅':
roles = discord.utils.get(guild.roles, name='Verify')
await payload.member.add_roles(roles)
await reaction.remove(payload.member)
Thanks for the help!
You had several mistakes in the code, I have fixed them and commented a few of them. Please check the following CODE.
#bot.event
async def on_raw_reaction_add(payload):
#You forgot to await the bot.get_channel
channel = await bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
guild = bot.get_guild(payload.guild_id)
#Put the following Line
member = guild.get_member(payload.user_id)
reaction = discord.utils.get(message.reactions, emoji=payload.emoji.name)
# only work if it is the client
if payload.user_id == bot.user.id:
return
if payload.message_id == 784182764009947177 and reaction.emoji == '✅':
roles = discord.utils.get(guild.roles, name='Verify')
await member.add_roles(roles)
await reaction.remove(payload.member)
I am trying to make an command for hosting events within discord. How I am trying to get it to work is when any users react to the message's pre-sent reaction the field "entered" is edited to add the username of any user that reacts. I have got the bot to await for a reaction and it effectively edits an embedded message to add a field. Problem is i need it to accept more then one users reaction (multiple users) and update the field every time so it shows everyone who has reacted in the embed field. The code I have right now works for the first user but stops working for anyone after that.
Here is my code so far:
# Event creation command
#bot.command()
async def eventcreate(ctx, arg1, arg2):
eventembed = discord.Embed(
title= ":partying_face: GIVEAWAY!!! :partying_face:",
color=7419530
)
eventembed.add_field(
name= "Event",
value=arg1,
inline=False
)
eventembed.add_field(
name= "Prize",
value=arg2,
inline=False
)
message = await ctx.send(embed=eventembed)
await message.add_reaction('🥳')
def check (reaction, user):
return str(reaction.emoji) == '🥳' and user != bot.user
while True:
try:
reaction, user = await bot.wait_for('reaction_add', timeout=604800, check=check)
if str(reaction.emoji) == '🥳':
reacted = user.name
eventembed.add_field(
name= "Entered:",
value= f"```{reacted}```",
inline=False
)
await message.edit(embed=eventembed)
await message.remove_reaction(reaction, user)
except asyncio.TimeoutError:
await message.remove_reaction('🥳')
Any help with this would be greatly appreciated. Thanks in advance!!
This is because the await bot.wait_for only waits for 1 event. You'll need to put that inside a loop.
The bot asks the user to select a type. I have used the client.wait_for() function to get user input. The command prefix is '.' In case the user types a message starting with '.' , I do not want the bot to read it as a command and execute that command. How do I do that?
This is the code:
#client.command()
async def search(ctx):
try:
await ctx.send("Enter '"+selected_type[0]+"' or '"+selected_type[1]+"' to search for required type")
msg = await client.wait_for('message', timeout=10, check=lambda message: message.author == ctx.author)
selection = msg.content.title()
except asyncio.TimeoutError as e: #if user does not give input in 10 sec, this exception occurs
await ctx.send("Too slow")
except:
await ctx.send("Search failed.")```
Will something like this work for you?
if not msg.content.startswith('.'): selection = msg.content.title()