#TypeError [INVALID_TYPE] Supplied permissions is not an Array of ApplicationCommandPermissionData.
1 messages · Page 1 of 1 (latest)
okay
firstly, what's this doing? what is this?
AppCommands?.create(slashCommand.structure).then((command) => {
it makes a single command?
Yes.
okay that's a problem, you're looping through and registering one by one
which is bad, too many api requests
there is a bulk-update function for registering commands
first let's fix that
then we can bulk update permissions as well
also @idle cedar i highly recommend you ditch this system and go with using the recommended system in the guide
https://discordjs.guide/interactions/slash-commands.html#registering-slash-commands
so what do you want? work with this or convert to the guide first?
I think there is no difference, bc the problem will remain in any case.
not at all, there's a massive difference, a lot of people get rate limited and ask for help in #djs-help-v14 and there's nothing they can really do
what your system does is that it tries to update commands every time the bot's on regardless of whether or not there has been a change see
and that is sending needless api requests which could potentially get your bot rate limited
my suggestion is, fix it before it's too late, avoid api spam and discard terrible practices
in the end all those rate limited people can do is just wait for the rate limit to be over and theen fix their code to avoid rate limits
which is just dumb, avoid it from the start and don't let it be a pain
Okay, I will follow the guide and will mention you if it gives an error in permissions.
Okay?
permissions come in later, we'll setup a neat little system after you fix your registering, we can go at it step by step since the guide doesn't mention it
I understood how much my knowledge of English allows me, good 😄
well if there's something you don't get, show the specific line, we can help with that, that's the easy part
easier than the code 😔
let commands = []
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
let fs = require('fs')
const {clientId, token} = require("./config.json")
async function CreateCommands(guildId){
const slashCommandsDir = fs.readdirSync("./slash")
const commands = []
for(const slashCommandFileName of slashCommandsDir){
slashCommand = require(`./slash/${slashCommandFileName}`)
commands.push(slashCommand.structure);
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
}
module.exports.CreateCommands = CreateCommands
Did I do everything right?
hmm i'll be right back
make it a seperate script entirely
follow the guide completely
This is a separate file, if you are talking about it.
no like this should be completely detached from your entire bot functionality
you use like node index.js or something right? that entire process should not touch this file
you'll run this when you need to using node deploy-commands.js
Perhaps this would make sense if I were making a bot for multiple servers.
Okay, I'll do it.
you can copy paste the entire guide's code too, after you understand what's going, which if you don't, ask
okay back, @idle cedar show your file, i had to go get breakfast ðŸ¤
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
let fs = require('fs')
let {clientId, token} = require("./config.json")
let guildId = '821411139316613182';
clientId = clientId + ''
const slashCommandsDir = fs.readdirSync("./slash")
const commands = []
for(const slashCommandFileName of slashCommandsDir){
slashCommand = require(`./slash/${slashCommandFileName}`)
commands.push(slashCommand.structure);
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
Right now my code looks like this (it works)
okay do you have like a command class? any like dedicated structure for commands?
well either way, i want you to add a permissions property to it
is your bot just for one server?
yes
okay then we won't have an issue
ApplicationCommandPermissionData
Data for setting the permissions of an application command.
i want you to take a look at this object structure
so if you know how permissions work currently, it's like a switch, you mention a role or a user and you mention whether or not you want said role or user to be able to use it
const Discord = require("discord.js")
const {warns} = require("../DataBase.js")
const {createEmbed} = require("../EmbedGenerator.js")
module.exports.execute = async function execute(bot, interaction) {
. . .
}
module.exports.structure = {
name: 'dewarn',
description: "Выдаёт варны",
options: [
. . .
],
defaultPermission: false
}
module.exports.permissions = [
{
id: '464464090157416448',
type: 'ROLE',
permission: false,
},
];
yee and i see you already have permissions, nice
so now
we'll just work with making this add command permissions
you see this line here?
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
make this a variable
call it something like registeredCommands
let registeredCommands = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
like that?
yes! exactly
now this needs a bit of modification
const commands = []
for(const slashCommandFileName of slashCommandsDir){
slashCommand = require(`./slash/${slashCommandFileName}`)
commands.push(slashCommand.structure);
}
```hmm, perhaps instead of pushing `.structure`, you can push just `slashCommand`
since we need the entire command, we need structure, and permissions
and here js await rest.put( Routes.applicationGuildCommands(clientId, guildId), { body: commands }, ); you can use commands.map((cmd) => cmd.structure)
in order to just use structure in the body
I did everything, how can I register permissions now?
show me your upadted code first @idle cedar
for(const slashCommandFileName of slashCommandsDir){
slashCommand = require(`./slash/${slashCommandFileName}`)
commands.push(slashCommand);
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
let registeredCommands = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands.map((cmd) => cmd.structure) },
);
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
okay that's great, that's great
so we need to add another request
it might be applicationGuildCommandPermissions
let me go make sure first
Routes.guildApplicationCommandsPermissions @idle cedar create another rest.put and this time, use Routes.guildApplicationCommandsPermissions
it also takes two parameters, clientId and guildId
As far as I understand, this sets permission for all commands. Can this be done for one specific one?
we want to do it all at once, doing one by one is unnecessary
But if everyone can use one command, and only specific people can use the other?
no no you are changing all of them at once, they all have different overwrites
const fullPermissions = [
{
id: 'FirstCommandId',
permissions: [{
id: '224617799434108928',
type: 'USER',
permission: false,
}],
},
{
id: 'SecondCommandId',
permissions: [{
id: '464464090157416448',
type: 'ROLE',
permission: true,
}],
},
];
await rest.put(
Routes.guildApplicationCommandsPermissions(clientId, guildId),
{ body: fullPermissions },
)
Like that?
yes but you need the id
Yes, and I'm a little confused as to where I can get this from.
remember our variable registeredCommands?
use this ```const fullPermissions = commands.filter((cmd) => cmd.permissions).map(cmd => {
let command = registeredCommands.find(c => c.name === cmd.structure.name)
return {id: command.id, permissions: cmd.permissions}
})``` @idle cedar
basically filter those that even include permissions and then find it's id and create the fullPermissions array
Thank you very much, everything works!
sure @idle cedar could you send the entire code once more just for a check?
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
let fs = require('fs')
let {clientId, token} = require("./config.json")
let guildId = '821411139316613182';
clientId = clientId + ''
const slashCommandsDir = fs.readdirSync("./slash")
const commands = []
for(const slashCommandFileName of slashCommandsDir){
slashCommand = require(`./slash/${slashCommandFileName}`)
commands.push(slashCommand);
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
let registeredCommands = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands.map((cmd) => cmd.structure) },
);
const fullPermissions = commands.filter((cmd) => cmd.permissions).map(cmd => {
let command = registeredCommands.find(c => c.name === cmd.structure.name)
return {id: command.id, permissions: cmd.permissions}
})
await rest.put(
Routes.guildApplicationCommandsPermissions(clientId, guildId),
{ body: fullPermissions },
)
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
Permissions:
module.exports.permissions = [
{
id: '942019210589139004',
type: 1,
permission: true,
},
{
id: '941396687006605352',
type: 1,
permission: false,
}
];
There is just not a big problem.
defaultPermission: false doesn't work
yep looks great 🥳
and i believe it should be default_permission then
Understood. Thank you so much again!
@hollow flax guess what day it is, tommorow, and that's how you implement permissions on the split up script
WAIT AYO 😳
wdym @blazing cloud 😳
the guide i told you to follow yesterday, this is how you implement permissions on that
oh right
lmao alr
wait
then @blazing cloud when do I actually run the script? When I make a new command or...
whenever you have a change that you want to actually push
Hello, I followed this thread, you explained it well, can I ask you something? 😄 Can I use it like this and have module.exports.permissions in the command? Thanks
command
const { SlashCommandBuilder } = require("@discordjs/builders");
const { MessageEmbed } = require("discord.js");
module.exports = {
data: new SlashCommandBuilder()
.setName('idpanel')
.setDescription('Odešle panel pro vytvořenà identity')
.setDefaultPermission(false),
async execute(interaction) {
}
}
module.exports.permissions = [
{
id: '556478969755467778',
type: USER,
permission: true,
}
]```
deploy.js
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { token } = require('./config.json');
const fs = require('fs');
const commands = [];
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
// Place your client and guild ids here
const clientId = '967415499065528390';
const guildId = '967084493229932554';
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
let registeredCommands = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
const fullPermissions = commands.filter((cmd) => cmd.permissions).map(cmd => {
let command = registeredCommands.find(c => c.name === cmd.structure.name)
return {id: command.id, permissions: cmd.permissions}
})
await rest.put(
Routes.guildApplicationCommandsPermissions(clientId, guildId),
{ body: fullPermissions },
)
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
no, for you ```js
for (const file of commandFiles) {
const command = require(./commands/${file});
commands.push(command.data.toJSON());
}
here's what you should do
push just command, leave out the .data.toJSON()
let registeredCommands = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
```over here, map commands to use data.toJSON()
`body: commands.map(cmd => cmd.data.toJSON())`
and this would be ```js
let command = registeredCommands.find(c => c.name === cmd.structure.name)
It's working, thank you so much 
why? I added this for myself
{
id: '556478969755467778',
type: 1,
permission: true,
}
how did you even
is that on phone?
yes
Now I tried it on computer and still isn't working
they don't appear disabled/greyed out for you?
Nope, I can click on it, other users can't
yes
yes
then i have no idea, do you have a role that it was disabled for?
nope, I don't
hmm, could you try restarting your discord? could be a case of discord being whacky woo hoo
Tried, doesn't helped
well then i have absolutely no idea