Python Discord bot: Setting interaction permissions programmatically

I’m having trouble with my Python Discord bot’s interaction permissions. Right now I can only set which roles can see an interaction or which channels it’s visible in through the server settings manually. But I want to do this automatically in my code.

I’ve tried using some permission settings in my script, but they don’t seem to work. The interaction stays visible to everyone. What I’m looking for is a way to make the interaction completely invisible to users without the right role or in the wrong channel, not just denying them access when they try to use it.

Here’s a simplified version of my interaction code:

@bot.command()
async def verify(ctx, code: str):
    role = ctx.guild.get_role(ROLE_ID)
    if role in ctx.author.roles:
        await ctx.send('Already verified!')
        return

    if code.upper() == user_codes.get(ctx.author.id):
        await ctx.author.add_roles(role)
        await ctx.send('Verification successful!')
    else:
        await ctx.send('Incorrect code. Try again.')

How can I modify this to set the interaction permissions programmatically?

hey there! i’ve dealt with this before. you could try using discord.permissions to set up custom overrides. something like this might work:

@bot.command()
async def verify(ctx, code: str):
    # your existing code
    
    overwrites = {
        ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
        ctx.guild.get_role(ROLE_ID): discord.PermissionOverwrite(read_messages=True)
    }
    
    await ctx.channel.edit(overwrites=overwrites)

this should hide the command from everyone except the verified role. goodluck!

To set interaction permissions programmatically, you’ll need to use the discord.app_commands module and define the permissions when creating the command. Here’s how you can modify your code:

from discord import app_commands
import discord

@bot.tree.command()
@app_commands.default_permissions(administrator=True)
async def verify(interaction: discord.Interaction, code: str):
    role = interaction.guild.get_role(ROLE_ID)
    if role in interaction.user.roles:
        await interaction.response.send_message('Already verified!', ephemeral=True)
        return

    if code.upper() == user_codes.get(interaction.user.id):
        await interaction.user.add_roles(role)
        await interaction.response.send_message('Verification successful!', ephemeral=True)
    else:
        await interaction.response.send_message('Incorrect code. Try again.', ephemeral=True)

bot.tree.sync()

This approach uses slash commands and sets default permissions to administrators only. You can adjust the permissions as needed. The ephemeral=True parameter ensures responses are only visible to the user who triggered the command.

As someone who’s wrestled with Discord bot permissions, I feel your pain! One approach I’ve found effective is using the discord.permissions module to create custom permission overrides. Here’s a snippet that might help:

from discord import PermissionOverwrite

@bot.command()
async def verify(ctx, code: str):
    # Your existing code here

    # Set up permission overrides
    overwrite = PermissionOverwrite()
    overwrite.send_messages = False
    overwrite.read_messages = False

    # Apply overrides to all roles except the verified one
    for role in ctx.guild.roles:
        if role != verified_role:
            await ctx.channel.set_permissions(role, overwrite=overwrite)

    # Allow the verified role to see and use the command
    await ctx.channel.set_permissions(verified_role, send_messages=True, read_messages=True)

This dynamically sets permissions so only verified users can see and use the command in the channel. You might need to tweak it based on your specific setup, but it should give you a good starting point. Hope this helps!