Discord py, проблема с работой on_button_click

@client.command()

@commands.has_permissions(administrator=True)
async def button(ctx, *, priz):
timeID = 5
embed=discord.Embed(title=f"Мероприятие :tada:", description=f"Через пять секунд отправится сообщение с кнопкой. Вам необходимо нажать на эту кнопку быстрее всех", color=0xFFFFFF, timestamp=ctx.message.created_at)
embed.add_field(name=f"Приз:", value=f"**{priz}**",inline=False)
await ctx.send(embed=embed)
await asyncio.sleep(timeID)

emb=discord.Embed(title=f"Мероприятие :tada:", description=f"Нажмите на реакцию.", color=0xFFFFFF, timestamp=ctx.message.created_at)
await ctx.send(
    embed = emb,

    components = [
        Button(
            custom_id = 'MP',
            label = "Нажми",
            style = ButtonStyle.green,
            emoji ='?')
    ]
)

@client.event
async def on_button_click(interaction):
if interaction.component.custom_id == "MP":
    await interaction.send("Принято!")

Существует вот такой код.

введите сюда описание изображения

А мне нужно сделать так, чтобы после этого всего, бот вывел топ-пользователей кто первый нажал и последний нажал на эту реакцию в течении 3 секунд. Можно использовать {interaction.user} <@{interaction.user.id}>, только я не понимаю, как это сделать. Буду очень рад если поможете.


Ответы (1 шт):

Автор решения: q r t s

Я использую discord.ui.View, что и вам советую.

И так. Это будет команда которая вызовет кнопку для участия в мероприятии.

@client.command()
async def button(ctx, *, priz):
    timeID = 5
    embed=discord.Embed(title=f"Мероприятие :tada:", description=f"Через пять секунд отправится сообщение с кнопкой. Вам необходимо нажать на эту кнопку быстрее всех", color=0xFFFFFF, timestamp=ctx.message.created_at)
    embed.add_field(name=f"Приз:", value=f"**{priz}**",inline=False)
    await ctx.send(embed=embed)
    cursor.execute(f"UPDATE guilds SET tada_top1 = 'Нет', tada_top2 = 'Нет', tada_top3 = 'Нет', tada_top4 = 'Нет', tada_top5 = 'Нет' WHERE id = {ctx.guild.id}")
    await asyncio.sleep(timeID)

    emb=discord.Embed(title=f"Мероприятие :tada:", description=f"Нажмите на реакцию.", color=0xFFFFFF, timestamp=ctx.message.created_at)
    await ctx.send(embed=emb, view=Buttons())

Пример

Теперь сделаем саму кнопку. Для этого создаем class (discord.ui.View):

class Buttons(discord.ui.View):
    def __init__(self, *, timeout=180):
        super().__init__(timeout=timeout)

timeout можно указать как в секундах так и None. None - кнопка будет работать постоянно.

Далее добавляем кнопку:

    @discord.ui.button(style=discord.ButtonStyle.gray, emoji="?")
    async def gray_button(self, interaction:discord.Interaction, button:discord.ui.Button):

Так же забыл упомянуть, что раннее вы должны создать таблицу:

    cursor.execute("""CREATE TABLE IF NOT EXISTS guilds (
        id INT, #заносим ID гильдии
        tada_top1 TEXT, #заносим текст 'Нет'
        tada_top2 TEXT, #заносим текст 'Нет'
        tada_top3 TEXT, #заносим текст 'Нет'
        tada_top4 TEXT, #заносим текст 'Нет'
        tada_top5 TEXT #заносим текст 'Нет'
    )""")

Теперь подключимся к нашей базе данных и занесём в неё пользователя в одну из переменных:

        for row in cursor.execute(f"SELECT tada_top1, tada_top2, tada_top3, tada_top4, tada_top5 FROM guilds WHERE id = {interaction.guild.id}"):
            if row[0] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top1 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 1️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[1] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top2 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 2️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[2] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top3 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 3️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[3] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top4 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 4️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[4] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top5 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 5️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return

Так же добавим проверку на то, участвует ли уже реагирующий в событии:

            if row[0] == interaction.user.mention or row[1] == interaction.user.mention or row[2] == interaction.user.mention or row[3] == interaction.user.mention or row[4] == interaction.user.mention:
                await interaction.response.send_message(content="Вы уже участвуете в мероприятии. Ожидайте, скоро объявят победителей.", ephemeral=True)

Так же проверка на то, закончились ли места в топе:

            if row[0] and row[1] and row[2] and row[3] and row[4] != 'Нет':
                await interaction.response.send_message(content="Мероприятие окончено. Скоро объявят победителей.", ephemeral=True)

Пример

И соответственно сделаем саму команду Топ:

@client.command()
async def top(ctx):
    for row in cursor.execute(f"SELECT tada_top1, tada_top2, tada_top3, tada_top4, tada_top5 FROM guilds WHERE id = {ctx.guild.id}"):
        if row[0] or row[1] or row[2] or row[3] or row[4] == 'Нет':
            await ctx.send("Не хватает участников для подведения итогов.")
            return
        embed = discord.Embed(title=f"Мероприятие завершено:")
        embed.add_field(name="1 место:", value=row[0], inline=False)
        embed.add_field(name="2 место:", value=row[1], inline=False)
        embed.add_field(name="3 место:", value=row[2], inline=False)
        embed.add_field(name="4 место:", value=row[3], inline=False)
        embed.add_field(name="5 место:", value=row[4], inline=False)
        await ctx.send(embed=embed)

Полный код:

@client.command()
async def button(ctx, *, priz):
    timeID = 5
    embed=discord.Embed(title=f"Мероприятие :tada:", description=f"Через пять секунд отправится сообщение с кнопкой. Вам необходимо нажать на эту кнопку быстрее всех", color=0xFFFFFF, timestamp=ctx.message.created_at)
    embed.add_field(name=f"Приз:", value=f"**{priz}**",inline=False)
    await ctx.send(embed=embed)
    cursor.execute(f"UPDATE guilds SET tada_top1 = 'Нет', tada_top2 = 'Нет', tada_top3 = 'Нет', tada_top4 = 'Нет', tada_top5 = 'Нет' WHERE id = {ctx.guild.id}")
    await asyncio.sleep(timeID)

    emb=discord.Embed(title=f"Мероприятие :tada:", description=f"Нажмите на реакцию.", color=0xFFFFFF, timestamp=ctx.message.created_at)
    await ctx.send(embed=emb, view=Buttons())

class Buttons(discord.ui.View):
    def __init__(self, *, timeout=180):
        super().__init__(timeout=timeout)
    @discord.ui.button(label="Button", custom_id="TEST", style=discord.ButtonStyle.gray)
    async def gray_button(self, interaction:discord.Interaction, button:discord.ui.Button):
        for row in cursor.execute(f"SELECT tada_top1, tada_top2, tada_top3, tada_top4, tada_top5 FROM guilds WHERE id = {interaction.guild.id}"):
            if row[0] and row[1] and row[2] and row[3] and row[4] != 'Нет':
                await interaction.response.send_message(content="Мероприятия окончено. Скоро объявят победителей.", ephemeral=True)
            if row[0] == interaction.user.mention or row[1] == interaction.user.mention or row[2] == interaction.user.mention or row[3] == interaction.user.mention or row[4] == interaction.user.mention:
                await interaction.response.send_message(content="Вы уже участвуете в мероприятии. Ожидайте, скоро объявят победителей.", ephemeral=True)
            if row[0] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top1 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 1️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[1] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top2 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 2️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[2] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top3 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 3️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[3] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top4 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 4️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return
            if row[4] == 'Нет':
                cursor.execute(f"UPDATE guilds SET tada_top5 = '{interaction.user.mention}' WHERE id = {interaction.guild.id}")
                await interaction.response.send_message(content="Вы заняли 5️⃣ место! Ожидайте, скоро объявят победителей.", ephemeral=True)
                return

@client.command()
async def top(ctx):
    for row in cursor.execute(f"SELECT tada_top1, tada_top2, tada_top3, tada_top4, tada_top5 FROM guilds WHERE id = {ctx.guild.id}"):
        if row[0] or row[1] or row[2] or row[3] or row[4] == 'Нет':
            await ctx.send("Не хватает участников для подведения итогов.")
            return
        embed = discord.Embed(title=f"Мероприятие завершено:")
        embed.add_field(name="1 место:", value=row[0], inline=False)
        embed.add_field(name="2 место:", value=row[1], inline=False)
        embed.add_field(name="3 место:", value=row[2], inline=False)
        embed.add_field(name="4 место:", value=row[3], inline=False)
        embed.add_field(name="5 место:", value=row[4], inline=False)
        await ctx.send(embed=embed)
→ Ссылка