Search code examples
pythondiscorddiscord.pypycorddiscord-buttons

Trying to check if text channel already exists when a button is pressed


I have a command that creates a button that is supposed to create a new private text channel for you and a targeted role (typically mods) and upon clicking it a second time, I want it to acknowledge the existing text channel (because it's named after the button clicker) so it doesn't create duplicates.

My issue is that it is not acknowledging the duplicates.

Here is the setup of the Button

class MyView(discord.ui.View): 
    def __init__(self):
        super().__init__(timeout=None)
        self.value = None

    @discord.ui.button(label="Create new private channel", style=discord.ButtonStyle.gray)
    async def menu1(self, interaction: discord.Interaction, button: discord.ui.Button):
        
        guild = interaction.guild
        targeted_role = guild.get_role(1056649402330132551)
        
        overwrites = {
         guild.default_role: discord.PermissionOverwrite(read_messages=False),
         targeted_role: discord.PermissionOverwrite(read_messages=True),
         interaction.user: discord.PermissionOverwrite(read_messages=True)
        }

        name = "Bot-made channel for " + interaction.user.__str__()
        cat = discord.utils.get(guild.categories, name = 'brendan')
        all_channels = interaction.channel.category.channels

        channel_exists = discord.utils.get(interaction.channel.category.text_channels, name= name)
        if not channel_exists:
            await guild.create_text_channel(name= "Bot-made channel for " + interaction.user.name, category=cat, overwrites=overwrites)
        else:
            await interaction.response.send_message("You have already created a private channel.", ephemeral = True)

This particular block of code is where I'm struggling with the logic I need to check for the channel. I thought it was perhaps maybe because it's not acknowledging new channels being made on the same button but debugging made it clear that all text channels retrieved by the .get() were always being updated.

channel_exists = discord.utils.get(interaction.channel.category.text_channels, name= name)
        if not channel_exists:
            await guild.create_text_channel(name= "Bot-made channel for " + interaction.user.name, category=cat, overwrites=overwrites)
        else:
            await interaction.response.send_message("You have already created a private channel.", ephemeral = True)

I'm debating simply revoking the view permissions of the button's original channel for the user who clicked it.

Anyways, I'm new to Python, so any and all advice would be appreciated. Thank you for your time.


Solution

  • so first issue is that the interaction parameter comes after the button parameter. So async def menu1(self, interaction: discord.Interaction, button: discord.ui.Button): should be async def menu1(self, button: discord.ui.Button, interaction: discord.Interaction):

    Also discord text channels are in lowercase and contain no spaces which is why when you searched for the channel it didn't give anything.

    Here is the code modified to show how I would fix that. I did test it and it works. Also I made it send a message mentioning the channel/existing channel but you can remove that if you want.

    class MyView(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=None)
            self.value = None
    
        @discord.ui.button(
            label="Create new private channel", style=discord.ButtonStyle.gray
        )
        async def menu1(self, button: discord.ui.Button, interaction: discord.Interaction):
            ROLE = 1056649402330132551
            CATEGORY_NAME = "brendan"
    
            guild = interaction.guild
            targeted_role = guild.get_role(ROLE)
    
            overwrites = {
                guild.default_role: discord.PermissionOverwrite(read_messages=False),
                targeted_role: discord.PermissionOverwrite(read_messages=True),
                interaction.user: discord.PermissionOverwrite(read_messages=True),
            }
    
            name = f"Bot made channel for {interaction.user.name}"
            name = name.lower().replace(" ", "-") # because discord channels are lowercase no spaces
    
            cat = discord.utils.get(guild.categories, name=CATEGORY_NAME)  # get category
            channel_exists = discord.utils.get(cat.channels, name=name) # check if channel with same name exists in category
    
            if channel_exists is None:  # if it doesnt exist create channel
                channel = await guild.create_text_channel(
                    name=name,
                    category=cat,
                    overwrites=overwrites,
                )
                await interaction.response.send_message(
                    f"A channel has been made for you: {channel.mention}",
                    ephemeral=True,
                )
    
            # if it does exist just tell user to use that one
            await interaction.response.send_message(
                f"You have already have a private channel: {channel_exists.mention}",
                ephemeral=True,
            )
    

    Also a suggestion i have is that instead of using the users name interaction.user.name you should consider using their ID. This is because they user can change their name but not their discord ID.