Search code examples
pythonpython-3.xdiscorddiscord.py

Discord.py UI send selectionOption when clicking button. (Version = DPY 2.0a)


@client.tree.command(name = "roles", description = "Role Test Menu.", guild =TEST_GUILD)
async def roles(interaction: discord.Interaction):
    await interaction.response.send_message(view=RoleButton(), ephemeral = True)
##################################################################################################
class RoleButton(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
    @discord.ui.button(label='Role Menu', style=discord.ButtonStyle.green, custom_id='Role Menu')
    async def rolebutton(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.defer()
        test1 = discord.utils.get(interaction.guild.roles, name='Test1')
        test2 = discord.utils.get(interaction.guild.roles, name='Test2')
        if test1 in interaction.user.roles:
            df = True
        elif test2 in interaction.user.roles:
            df = True
        else:
            df = False
        options = [
            discord.SelectOption(label="Test 1", value="Test 1", default = df),
            discord.SelectOption(label="Test 2", value="Test 2", default = df)
        ]
        @discord.ui.select(placeholder="Select",custom_id="test",max_values=2, options=options)
        async def _action_select(self, interaction: discord.Interaction, select: discord.ui.Select):
            await interaction.response.send_message("Done!", ephemeral = True)
##################################################################################################

So, this obviously doesn't work, and I know that. But this is an example of what I am trying to do; essentially, I want the slash command to send the "Role Menu" button. Then when it it clicked by a user, check if the user has "test1" and "test2" roles. If they do/don't, then set the default selectionOption to T/F, then send the select. How can I change this to have it work how I want it to?


Solution

  • To add a ui.Button or a ui.Select to a message, you need a ui.View to which you add those things. The view then gets added to the message.

    Solution:

    import discord
    from discord import ui
    
    bot = commands.Bot()
    
    class Select(ui.Select):
        def __init__(self, options):
    
            # placeholder: Will be shown when no option is chosen
            # custom_id: The id of the select menu
            # options: The dropdown options which can be chosen
            # max_values: Indicates that max. 2 options can be picked
            super().__init__(placeholder="Select", custom_id="test", options=options, max_values=2)
    
        # This function is called when the user has chosen an option
        async def callback(self, interaction: discord.Interaction):
            # With the interaction parameter, you can send a response message.
            # With self.values you get a list of the user's selected options.
            print(self.values)
            await interaction.response.send_message(f"Done!", ephemeral=True)
    
    class ViewButton(ui.View):
    
        # label: The label of the button which is displayed
        # style: The background color of the button
        @ui.button(label="Role Menu", style=discord.ButtonStyle.blurple)
        async def role_menu_btn(self, interaction: discord.Interaction, button_obj: ui.Button):
            # This function is called when a user clicks on the button
    
            # get the roles
            test1_role = interaction.guild.get_role(1007237710295081020)
            test2_role = interaction.guild.get_role(1007237773230620728)
    
            # check if user has the role or not
            df1 = True if test1_role in interaction.user.roles else False
            df2 = True if test2_role in interaction.user.roles else False
            options = [
                discord.SelectOption(label="Test 1", value="Test 1", default=df1),
                discord.SelectOption(label="Test 2", value="Test 2", default=df2)
            ]
    
            # create ui.Select instance and add it to a new view
            select = Select(options=options)
            view_select = ui.View()
            view_select.add_item(select)
    
            # edit the message with the new view
            await interaction.response.edit_message(content="Choose an option", view=view_select)
    
    
    @bot.tree.command(name="btn", description="Wonderful button")
    async def btn(interaction: discord.Interaction):
        await interaction.response.send_message("Click it!", view=ViewButton())
    
    

    References: