This is the Most Advance Explaination on slash commands in discord.js
Note that discord.js doesn't officially support using client.api, this is basically just a workaround until they release complete support. Do not ask for help with client.api in the discord.js server.
Note that slash commands won't show in a server unless that server has authorized it with the applications.commands
oauth2 scope (not just the bot
scope).
This does not require a discord.js update! It should work as long as you're using discord.js v12 it will work fine.
You only need to register a slash command once but if you are making a bot which is to be added in more then one server, it is recommanded to add it in the ready listener.
You can register a command either globally or for only a specific guild.
Global commands are displayed in all servers your bot has application.commands
permission and could take upto an hour to update in all for your servers.
client.api.applications(client.user.id).commands.post({
data: {
name: 'Hello',
description: 'Hello World!'
}
})
Specific guild commands can be instantly updated in the server and is prefered for testing of a slash command before making it global.
client.api.applications(client.user.id).guilds("guild_id").commands.post({
data: {
name: 'Hello',
description: 'Hello World!'
}
})
So after you register a command you need to make a receiving event so when the slash command is used, you can get it's data and reply to the command.
interaction
is an Interaction object.
client.ws.on('INTERACTION_CREATE', async interaction => {
// do all the work related to replying
})
This goes inside of the Receiving the Event block. Now we need to send an Interaction Response.
const command = interaction.data.name.toLowerCase() //this is the command name
const args = interaction.data.options; //all the options like roles, channels, etc.
if(command === "Hello"){
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: 'Hello World!'
}
}
})
}
So, when you define a slash command you can also define the options which could be selected by the user.
client.api.applications(client.user.id).guilds("guild_id").commands.post({
data: {
name: 'Channel',
description: 'Select a Channel',
options : [{
name : "channel", //name of the option,
description : "select a channel to console.log", //this is the description of your slash commands options.
type : 7, // 7 stands for channels you can get type of other things here -
// https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype
required : true //This will make it compulsory ypu can do it false to make it optional
}]
}
})
And you can get it in the Recieving Event by,
const command = interaction.data.name.toLowerCase() //this is the command name
const args = interaction.data.options; //all the options like roles, channels, etc.
if(command === "Hello"){
console.log(args[0]) //this will console.log the info of the channel the user selected
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: 'Hello World!'
}
}
})
}
As demonstrated above, you can also customize the options.
client.api.applications(client.user.id).guilds("guild_id").commands.post({
data: {
name: 'Channel',
description: 'Select a Channel',
options : [{
name : "channel", //name of the option,
description : "select a channel to console.log", //this is the description of your slash commands options.
type : 3, // 3 stands for string
required : true, //This will make it compulsory ise can do it false to make it optional
choices : [
{
name : "option 1", // name of the option
value : "option_one" // the value which will you get in the receiving event
},
{
name : "option 2", // name of the option
value : "option_two" // the value which will you get in the receiving event
}
]
}]
}
})
You can get it in the receiving event similar the normal options like Defining Options in Slash Commands.
First, add this outside of the Ready listener
async function createAPIMessage(interaction, content) {
const apiMessage = await Discord.APIMessage.create(client.channels.resolve(interaction.channel_id), content)
.resolveData()
.resolveFiles();
return { ...apiMessage.data, files: apiMessage.files };
}
After you add this outside of the Ready listener you can reply with embeds.
const command = interaction.data.name.toLowerCase() //this is the command name
const args = interaction.data.options; //all the options like roles, channels, etc.
if(command === "Hello") {
let embed = new Discord.MessageEmbed()
.setDescription(`Hello World.`)
client.api.interactions(interaction.id , interaction.token).callback.post({
data: {
type: 4,
data: await createAPIMessage(interaction, embed)
}
})
}
This will also go inside of the Receiving the Event block.
Also you can refer to the Webhook#send docs for more info about webhooks.
new Discord.WebhookClient(client.user.id, interaction.token).send('Hello World!')