PermissionsRolesIntents4 min read

Manage bot permissions and roles

Bot permissions calculator, role hierarchy, permission checks in commands and intents.


Discord permission hierarchy

Discord uses a hierarchical permission system. The bot can only manage roles that are below its highest role in the server's role list.

Step 1: Understanding the permissions calculator

Each permission is a bit in an integer. You can combine them:

javascript
const { PermissionFlagsBits } = require('discord.js');

// Common bot permissions
const botPermissions = [
  PermissionFlagsBits.SendMessages,
  PermissionFlagsBits.EmbedLinks,
  PermissionFlagsBits.ManageMessages,
  PermissionFlagsBits.ManageRoles,
  PermissionFlagsBits.KickMembers,
  PermissionFlagsBits.BanMembers
];

// Calculate the permissions integer
const permissionInteger = botPermissions.reduce((acc, perm) => acc | perm, 0n);
console.log(`Permission integer: ${permissionInteger}`);

Step 2: Check permissions in commands

Always verify permissions before executing actions:

javascript
client.on('interactionCreate', async interaction => {
  if (commandName === 'ban') {
    // Check user has permission
    if (!interaction.member.permissions.has(PermissionFlagsBits.BanMembers)) {
      return interaction.reply({
        content: 'You do not have permission to ban.',
        ephemeral: true
      });
    }

    // Check bot has permission
    if (!interaction.guild.members.me.permissions.has(PermissionFlagsBits.BanMembers)) {
      return interaction.reply({
        content: 'I do not have permission to ban. Check my roles.',
        ephemeral: true
      });
    }

    // Check role hierarchy
    const target = interaction.options.getMember('user');
    if (target.roles.highest.position >= interaction.guild.members.me.roles.highest.position) {
      return interaction.reply({
        content: 'I cannot ban someone with a role equal to or higher than mine.',
        ephemeral: true
      });
    }
  }
});

Step 3: Configure intents correctly

Intents control which events your bot receives:

javascript
const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,           // Always needed
    GatewayIntentBits.GuildMessages,     // To read messages
    GatewayIntentBits.MessageContent,    // To read content (privileged)
    GatewayIntentBits.GuildMembers,      // For member events (privileged)
    GatewayIntentBits.GuildModeration,   // For moderation events
  ]
});

Privileged intents require manual activation in the Developer Portal.

Step 4: Per-command permissions with defaultMemberPermissions

javascript
new SlashCommandBuilder()
  .setName('ban')
  .setDescription('Ban a user')
  .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
  .setDMPermission(false) // Only works in servers

This hides the command from users without the required permission.

Recommendations

  • Only request permissions your bot actually needs
  • Check both user and bot permissions before acting
  • Use defaultMemberPermissions to restrict sensitive commands
  • Document what permissions your bot needs and why

Was this guide helpful?