Search code examples
pythondiscorddiscord.py

Delete select menu after interaction Discord.py


I have several buttons that each bring up a different select menu. I have been trying to figure out a way to delete a select menu after a selection is made so when the user clicks on the next buttons it stays clean with only the current menu showing.

I tried attaching a "submit" button to the menu's view that deletes the message but I get this error:

AttributeError: 'Button' object has no attribute 'message'

I also tried to edit the message after the interaction to add 'delete_after' but that didn't work either.

The menu is ephemeral and through research I see that you can't delete ephemeral messages due to the bot not seeing it. Is there any way around this?


    class selectMenu(discord.ui.Select):
        def __init__(self):
        super().__init__(placeholder=placeholder, options=players, min_values=1, 
                         max_values=1)

        async def callback(self, interaction:discord.Interaction):
            await interaction.response.defer()


    class selectMenuView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
        self.add_item(selectMenu())

    *Tried this*
    @discord.ui.button(label="Cancel", style=discord.ButtonStyle.red, 
                       row=3, disabled=False, emoji="✖️")
    async def cancel_callback(self, button: discord.ui.Button, 
                              interaction: discord.Interaction):
        await interaction.message.delete()

Solution

  • As the messages are ephemeral, we can just edit the message content and set the view to None so that view disappears.

    class selectMenuView(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=None)
            self.add_item(selectMenu())
    
        # a cancel button
        # will keep the message but remove the view and replace the text with "Cancelled"
        @discord.ui.button(label="Cancel", style=discord.ButtonStyle.red, row=3, disabled=False, emoji="✖️")
        async def close_callback(self, button: discord.ui.Button, interaction: discord.Interaction):
            # if the message is
            await interaction.response.edit_message(content="Cancelled", view=None)
    
        @discord.ui.button(label="Submit", style=discord.ButtonStyle.green, row=3, disabled=False)
        async def submit_callback(self, button: discord.ui.Button, interaction: discord.Interaction):
            # defer in case processing the selected data takes a while
            await interaction.response.defer()
            
            # do your data processing
    
            # use followup to edit the original message
            await interaction.followup.edit_message(interaction.message.id, content="Submitted data!", view=None)
    

    The cancel callback uses response to edit the message. The submit callback uses the followup to edit the message with the message ID. Both work with ephemeral messages. The user can then press the "Dismiss this message" to get rid of the ephemeral message(s) they can see.