const { PermissionFlagsBits, MessageFlags } = require( "discord.js" ); /* * ============================================================ * CONFIG * ============================================================ * * .env: * * BOT_AUTHOR_ID=123456789012345678 * * Do not hard-code the author ID into commands. */ function getBotAuthorId() { return ( process.env.BOT_AUTHOR_ID ?? null ); } /* * ============================================================ * BOT AUTHOR * ============================================================ */ function isBotAuthor( userId ) { const authorId = getBotAuthorId(); if ( !authorId || !userId ) { return false; } return ( String( userId ) === String( authorId ) ); } /* * ============================================================ * GUILD ADMINISTRATOR * ============================================================ */ function isAdministrator( interaction ) { if ( !interaction ?.memberPermissions ) { return false; } return interaction .memberPermissions .has( PermissionFlagsBits.Administrator ); } /* * ============================================================ * ADMIN COMMAND ACCESS * ============================================================ * * Access is granted when: * * - the user is the configured bot author * OR * - the user has Discord Administrator * * Bot author is checked first so the owner can use admin * utilities even without Discord Administrator in the guild. */ function canUseAdminCommands( interaction ) { if ( !interaction ?.user ?.id ) { return false; } return ( isBotAuthor( interaction.user.id ) || isAdministrator( interaction ) ); } /* * ============================================================ * STANDARD ACCESS DENIAL * ============================================================ * * Administrative access failures are intentionally ephemeral. */ async function denyAdminAccess( interaction, message = "You don't have permission to use this command." ) { const payload = { content: message, flags: MessageFlags.Ephemeral }; if ( interaction.replied || interaction.deferred ) { return interaction.followUp( payload ); } return interaction.reply( payload ); } /* * ============================================================ * REQUIRE ADMIN ACCESS * ============================================================ * * Convenience helper: * * if (!await requireAdminAccess(interaction)) { * return; * } */ async function requireAdminAccess( interaction ) { if ( canUseAdminCommands( interaction ) ) { return true; } await denyAdminAccess( interaction ); return false; } /* * ============================================================ * EXPORTS * ============================================================ */ module.exports = { getBotAuthorId, isBotAuthor, isAdministrator, canUseAdminCommands, requireAdminAccess, denyAdminAccess };