Basically, I'm making a poll command. I want it to put the user's vote in the embed field, and obviously make it so they can't vote again, again, and again. No idea how to do this.
Here's the code:
class Buttons(discord.ui.View):
def __init__(self, *, timeout = 180):
super().__init__(timeout=timeout)
@discord.ui.button(label="Yes", style=discord.ButtonStyle.success, emoji='👍')
async def upvote_button(self, button : discord.ui.Button, interaction : discord.Interaction):
pass
@discord.ui.button(label="No", style=discord.ButtonStyle.danger, emoji='👎')
async def downvote_button(self, button : discord.ui.Button, interaction : discord.Interaction):
pass
class Poll(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="poll", description="Ask a question and receive upvotes or downvotes (Yes/No)")
async def poll(self, interaction : discord.Interaction, *, question : str):
embed = discord.Embed(
description=question,
color = 0xb037e1
)
embed.set_author(name="Poll", icon_url=self.bot.user.avatar)
embed.set_footer(text="Asked by: " + str(interaction.user), icon_url=interaction.user.avatar)
embed.add_field(name="Upvotes", value="X", inline=True)
embed.add_field(name="Downvotes", value="X", inline=True)
await interaction.response.send_message(embed=embed, view=Buttons())
Probably very simple, although I still haven't thought about a way
The easiest way to do this is by using dictionaries
, lists
, or even sets
to store the users that have clicked.
For this example, I will use one list to store the users who have clicked the upvote and downvote buttons. Like here:
class Buttons(discord.ui.View):
def __init__(self, *, timeout=None):
super().__init__(timeout=timeout or 180)
self.voted_users = []
self.upvote_count = 0
self.downvote_count = 0
@discord.ui.button(
label="Yes", style=discord.ButtonStyle.success, emoji="👍"
)
async def upvote_button(
self, interaction: discord.Interaction, button: discord.ui.Button
):
if (
interaction.user in self.voted_users
): # check if the user has already voted or not and return if true
return await interaction.response.send_message(
content="You've already voted!", ephemeral=True
)
self.upvote_count += 1
self.voted_users.append(interaction.user) # add the user to voted list
await interaction.response.send_message("Upvoted!", ephemeral=True)
@discord.ui.button(label="No", style=discord.ButtonStyle.danger, emoji="👎")
async def downvote_button(
self, interaction: discord.Interaction, button: discord.ui.Button
):
if (
interaction.user in self.voted_users
): # check if the user has already voted or not and return if true
return await interaction.response.send_message(
content="You've already voted!", ephemeral=True
)
self.downvote_count += 1
self.voted_users.append(interaction.user) # add the user to voted list
await interaction.response.send_message("Downvoted!", ephemeral=True)
By the way, interaction
always comes before the button
in the button callback argument if you're using discord.py
.