Check for Slash Command Permission

Hey, I want to check if a user has the permission to use a slash command while taking into account all the different overrides (channel, roles, user etc.). (Im using this to match my prefix commands permissions with the slash commands)
60 Replies
d.js docs
d.js docs3y ago
• What's your exact discord.js npm list discord.js and node node -v version? • Post the full error stack trace, not just the top part! • Show your code! • Explain what exactly your issue is. • Not a discord.js issue? Check out method TextChannel#permissionsFor() Gets the overall set of permissions for a member or role in this channel, taking into account channel method GuildMember#permissionsIn() Returns channel.permissionsFor(guildMember). Returns permissions for a member in a guild channel, taking into account roles and permission overwrites.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
thats not for slash commands only for channel permissions
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Sago
Sago3y ago
Aren’t you able to set those up within the server settings?
Lianecx
LianecxOP3y ago
Yes, im talking about the permission v2 that you can manage under the server settings > integrations
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
doesnt take channel overrides into account
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
theres also channel overrides for slash commands though those arent managed in the channel settings
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
its just that
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
A friend made like a really complicated check for this and i was just wondering if you could do it with less code. I can send you his code snippet if you want to.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
globalThis.hasPerm = (member, perm, channel) => {
if (perm === null) return true
if (!member.guild) return true
let has
if (channel) has = channel.permissionsFor(member)?.has?.(Discord.PermissionsBitField.Flags[perm] ?? perm)
else has = member.permissions.has(Discord.PermissionsBitField.Flags[perm] ?? perm)
return has === undefined ? true : has
}
globalThis.hasPerm = (member, perm, channel) => {
if (perm === null) return true
if (!member.guild) return true
let has
if (channel) has = channel.permissionsFor(member)?.has?.(Discord.PermissionsBitField.Flags[perm] ?? perm)
else has = member.permissions.has(Discord.PermissionsBitField.Flags[perm] ?? perm)
return has === undefined ? true : has
}
const slashCommand = await getCommand(command.slashCommand, {guild: testMode ? message.guild : undefined})
if (slashCommand) {
let canRun = true
if (!hasPerm(message.member, "Administrator")) {
let perms = await message.guild.commands.permissions.fetch({command: slashCommand.id}).catch(e => undefined)
if (!perms) perms = await message.guild.commands.permissions.fetch({command: client.user.id}).catch(e => undefined)
if (perms) {
perms = perms.map(e => {
e.type = getType.commandPermission(e.type)
return e
})
const channels = perms.filter(e => e.type === "Channel")
const users = perms.filter(e => e.type === "User")
const roles = perms.filter(e => e.type === "Role")
let everyone = message.guild.roles.cache.find(e => e.name === "@everyone")
if (!everyone) everyone = await message.guild.roles.fetch().then(e => e.find(e => e.name === "@everyone"))
everyone = roles.find(e => e.id === everyone.id)?.permission
if (!everyone) canRun = false
const currentChannel = channels.find(e => e.id === message.channelId)?.permission
if (currentChannel === false) canRun = false
else {
if (!currentChannel && channels.find(e => BigInt(message.guildId) - 1n === BigInt(e.id))?.permission === false) canRun = false
else {
const memberRoles = roles.filter(e => message.member._roles.includes(e.id))
if ([true, undefined].includes(currentChannel) && memberRoles.some(e => e.permission === true)) canRun = true
else if (memberRoles.every(e => e.permission === false)) canRun = false
const user = users.find(e => e.id === message.member.id)?.permission
if (user) canRun = true
else if (user === false) canRun = false
}
}
} else if (!hasPerm(message.member, slashCommand.defaultMemberPermissions, message.channel)) canRun = false
}
if (!canRun) return sendError(message, {
description: "You do not have the permissions required to run that command"
})
}
const slashCommand = await getCommand(command.slashCommand, {guild: testMode ? message.guild : undefined})
if (slashCommand) {
let canRun = true
if (!hasPerm(message.member, "Administrator")) {
let perms = await message.guild.commands.permissions.fetch({command: slashCommand.id}).catch(e => undefined)
if (!perms) perms = await message.guild.commands.permissions.fetch({command: client.user.id}).catch(e => undefined)
if (perms) {
perms = perms.map(e => {
e.type = getType.commandPermission(e.type)
return e
})
const channels = perms.filter(e => e.type === "Channel")
const users = perms.filter(e => e.type === "User")
const roles = perms.filter(e => e.type === "Role")
let everyone = message.guild.roles.cache.find(e => e.name === "@everyone")
if (!everyone) everyone = await message.guild.roles.fetch().then(e => e.find(e => e.name === "@everyone"))
everyone = roles.find(e => e.id === everyone.id)?.permission
if (!everyone) canRun = false
const currentChannel = channels.find(e => e.id === message.channelId)?.permission
if (currentChannel === false) canRun = false
else {
if (!currentChannel && channels.find(e => BigInt(message.guildId) - 1n === BigInt(e.id))?.permission === false) canRun = false
else {
const memberRoles = roles.filter(e => message.member._roles.includes(e.id))
if ([true, undefined].includes(currentChannel) && memberRoles.some(e => e.permission === true)) canRun = true
else if (memberRoles.every(e => e.permission === false)) canRun = false
const user = users.find(e => e.id === message.member.id)?.permission
if (user) canRun = true
else if (user === false) canRun = false
}
}
} else if (!hasPerm(message.member, slashCommand.defaultMemberPermissions, message.channel)) canRun = false
}
if (!canRun) return sendError(message, {
description: "You do not have the permissions required to run that command"
})
}
there we go you might have to load that into an editor because of formatting
d.js docs
d.js docs3y ago
Codeblocks: ```js const Discord = require("discord.js"); // further code ``` becomes
const Discord = require("discord.js");
// further code
const Discord = require("discord.js");
// further code
Inline Code: `console.log('inline!');` becomes console.log('inline!'); To share long code snippets use a service like gist, sourcebin, starbin, or similar instead of posting them as large code blocks.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
oh
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
pog they fixedit
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
ohh wait another problem the has method returns true if a permission exists. that permission could also allow the user to access the command
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
I dont think the channel permissions matter at all only the slash command overrides
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
yeah thats what this does
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
right thats what this does
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
how would you shorten it
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
You can take a look at the code, he did the checks in the order the types are applied Im not sure about the roles wdym overrides are missing?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
I am pretty sure they completely override the defaults thats the purpose of the permissions manager I gtg for today, bye :)
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
monbrey
monbrey3y ago
Can I ask what it is you're building this check for?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Lianecx
LianecxOP3y ago
Okay thank you :D Ill go through it and compare it to the old function
Lianecx
LianecxOP3y ago
Im pretty sure the order is like that (all roles = everyone)
Lianecx
LianecxOP3y ago
but needs testing couldnt find any docs anywhere
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
jack
jack2y ago
@lianecx did you use this in anything? I think I need to use something like this too
Lianecx
LianecxOP2y ago
Discord has made some changes to permissions including a flowchart that should make it easy to implement something like this https://discord.com/channels/222078108977594368/992166350640386090/1042878335304347758
jack
jack2y ago
Yeah i saw the flowchart still a lot of work 😵‍💫
Lianecx
LianecxOP2y ago
I can send you my updated code once its done Its not released to every server yet so i havent changed it
jack
jack2y ago
ooh please do that'd be greatly appreciated
Lianecx
LianecxOP2y ago
👍 Feel free to ping me if I forget to post it
jack
jack2y ago
alr @lianecx hey, did you end up making this?
Lianecx
LianecxOP2y ago
I believe discord still has their new app permission system in beta. I also dont know if spoon feeding my code is welcome here 😅
monbrey
monbrey2y ago
Am I missing something here? That referenced post was from last year, definitely not a beta anymore
Lianecx
LianecxOP2y ago
It was opt-in for servers like a month ago idk if it still is I think its released they were planning to release it in late february I actually stopped support for my prefix commands so this wasnt needed anymore, with the flowchart that discord attached it should be pretty easy to implement this though as the discord.js objects and functions mostly resemble the discord api itself
jack
jack2y ago
Yeah I may have to have a stab at implementing the user/roles bit of it for my bot. Sorry for bothering you
Lianecx
LianecxOP2y ago
No worries, lmk if you need more help 😄
Lianecx
LianecxOP2y ago
If you still need this, a friend just implemented it for his bot, here it is:
jack
jack2y ago
I'll check this out at home, thanks for sharing
Lianecx
LianecxOP2y ago
No problem!
jack
jack2y ago
obviously it's meant to do nothing while false trol makes me worry for when I open it up to look at I was hoping at the time it was in some sapphire library, it's not that I can't write it it's that it's annoying to write 🫠
Want results from more Discord servers?
Add your server