【问题标题】:Discord buttons all triggering at once. Discord.pyDiscord 按钮全部同时触发。不和谐.py
【发布时间】:2021-12-18 02:09:34
【问题描述】:

我正在尝试在我的 discord 机器人上创建审核,将单词标记为不合适,然后允许审核团队轻松禁止/超时用户,而无需在活动期间在场。所有的审核都有效,但前提是我运行了一次代码。如果有多个按钮组,当其中一个被按下时,它们都会同时触发。例如,如果我在一条消息上按下了禁止按钮,它将禁止所有发言不当的用户,而不是仅仅禁止一个人。

我该如何解决这个问题?

编辑:我设法解决了一次按下所有按钮并遇到新按钮的问题。现在,当按下一个按钮时,如果按下,其余按钮都会失败。很明显,代码正在解析 button_cxt 的所有实例,但我不确定如何防止或解决它。

更新代码:

@bot.event
async def on_profanity(message, word):

    try:
        guildID = message.guild.id
        guild = bot.get_guild(guildID)
        channel = discord.utils.get(guild.text_channels, name="moderation-logs")
        channel_id = channel.id
    except:
        return None

    channel = bot.get_channel(channel_id) 
    embed = discord.Embed(title="Profanity Alert!", description=f"{message.author.name} just said ||{message.content}||. The bad word was: ||{word}||", color=discord.Color.blurple()) # Let's make an embed!
    await channel.send(embed=embed)

    buttons = [
            manage_components.create_button(
                style=ButtonStyle.red,
                label="Ban!",
                custom_id="ban"
            ),
            manage_components.create_button(
                style=ButtonStyle.gray,
                label="Give them a Warning",
                custom_id="warning"
            ),
            manage_components.create_button(
                style=ButtonStyle.green,
                label="Nope!",
                custom_id="noBan"
            ),
          ]

    ActionRow = manage_components.create_actionrow(*buttons)

    if "warning" in [y.name.lower() for y in message.author.roles]:
        botMessage = await channel.send("They have already been warned. Do you wish to ban them?", components=[ActionRow])
    else:
        botMessage = await channel.send("Do you wish to ban them?", components=[ActionRow])


    button_ctx: ComponentContext = await manage_components.wait_for_component(bot, components=ActionRow)
    origin_id = button_ctx.origin_message.id

    if (botMessage.id == origin_id):
        await botMessage.delete()
        if button_ctx.custom_id == "ban":    
            await channel.send("The deed has been done.")
            bot.dispatch('ban', message, guild)

        elif button_ctx.custom_id == "warning":
            await channel.send("The warning has been sent!")
            bot.dispatch('warning', message, guild, channel)

        elif button_ctx.custom_id == "noBan":
            await channel.send("No action taken")

【问题讨论】:

    标签: discord.py


    【解决方案1】:

    所以我花了很长时间和一些思考,但我终于解决了这个问题。问题在于这两个部分:

    button_ctx: ComponentContext = await manage_components.wait_for_component(bot, components=ActionRow)
    

    按钮上下文正在侦听具有组件 ActionRow 的任何按钮,这是我所有按钮的所有组件。因此,所有按钮都会立即触发它们的函数实例。我的小检查意味着只有按下的那个才起作用,但它并没有阻止其余按钮触发该事件侦听器。

    所以,我想到的解决方法是递归地重新启动所有侦听器,如果它们没有被按下的话。执行按下按钮的操作,然后重新启动其余功能。因此,我现在运行的代码如下所示:

    @bot.event
    async def on_profanity(message, word):
    
        try:
            guildID = message.guild.id
            guild = bot.get_guild(guildID)
            channel = discord.utils.get(guild.text_channels, name="moderation-logs")
            channel_id = channel.id
        except:
            return None
    
        channel = bot.get_channel(channel_id) 
        embed = discord.Embed(title="Profanity Alert!", description=f"{message.author.name} just said ||{message.content}||. The bad word was: ||{word}||", color=discord.Color.blurple())
        await channel.send(embed=embed)
    
        buttons = [
            manage_components.create_button(
                style=ButtonStyle.red,
                label="Ban!",
                custom_id="ban"
                ),
            manage_components.create_button(
                style=ButtonStyle.gray,
                label="Give them a Warning",
                custom_id="warning"
                ),
            manage_components.create_button(
                style=ButtonStyle.green,
                label="Nope!",
                custom_id="noBan"
                ),
              ]
    
        ActionRow = manage_components.create_actionrow(*buttons)
    
        if "warning" in [y.name.lower() for y in message.author.roles]:
            botMessage = await channel.send("They have already been warned. Do you wish to ban them?", components=[ActionRow])
        else:
            botMessage = await channel.send("Do you wish to ban them?", components=[ActionRow])
    
        await modButtons(guild, message, channel, botMessage, ActionRow)
    
    
    
    async def modButtons(guild, message, channel, botMessage, ActionRow):
    
        button_ctx: ComponentContext = await manage_components.wait_for_component(bot, components=ActionRow)
        origin_id = button_ctx.origin_message.id
    
        if (botMessage.id == origin_id):
            await botMessage.delete()
            if button_ctx.custom_id == "ban":    
                #await channel.send("The deed has been done.")
                bot.dispatch('ban', message, guild)
    
            elif button_ctx.custom_id == "warning":
                #await channel.send("The warning has been sent!")
                bot.dispatch('warning', message, guild, channel)
    
            elif button_ctx.custom_id == "noBan":
                await channel.send(f"No action taken for {message.author.name}")
    
        else:
            await modButtons(guild, message, channel, botMessage, ActionRow) #recursion HERE!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-20
      • 2021-05-09
      • 1970-01-01
      • 2021-06-07
      • 2021-06-28
      • 2020-12-17
      • 2021-11-24
      • 1970-01-01
      相关资源
      最近更新 更多