How to create Categories in Discord.JS V14

2/4/2023, 11:00:37 PM

This is the third (of four) parts of the Discord.JS V14 tutorial that I've published. You can read the here. You can also read the full version of this tutorial on Medium if you prefer.

As mentioned in the previous lessons, Categories are the parents of some Channels. Not all Channels belong to a Category (the ones that don't, are referred as "stray Channels").

Categories exist for primarily two reasons: Organizing Channels within a certain topic and quickly syncing the permissions of all Channels within it. They also are very simple to create, even simpler than Voice Channels or Text Channels, since the number of configuration options for them is limited.

Let's modify the Text Channel file a bit and then talk about the differences between them and Categories:

// ... // initial code unchanged // ... .addStringOption((option) => option .setName("categoryname") // option names need to always be lowercase and have no spaces .setDescription("Choose the name to give to the category") .setMinLength(1) // A Category needs to be named .setMaxLength(25) // Discord will cut-off names past the ~27 characters (for Categories), // so that's a good hard limit to set. You can manually increase this if you wish .setRequired(true) ); // ... // code in between unchanged // ... const chosenCategoryName = interaction.options.getString("categoryname"); // ... // code in between unchanged // ... await interaction.guild.channels.create({ name: chosenCategoryName, // The name given to the Channel by the user type: ChannelType.GuildCategory, // The type of the Channel created. }); // ... // rest of the code unchanged // ...
View/Download file

You might have noticed if you went through the Create a Text Channel with Dynamic Names lesson that very little was changed. We have renamed our variable, updated the command and the option name, and changed the type of Channel being created to GuildCategory. Simple, right? But there is not much use in having empty Categories, so let's populate our newly created Category with some Channels now.

Creating a Category that nests other types of channels

We have seen how to create Text and Voice Channels that can be nested in their existing parent Categories (when there is one), but now we are going to create a Category and immediately nest newly created Text Channels and Voice Channels within. As you can probably guess, we won't need to change a lot of our existing code, but we gonna reuse code from a few of our files to accomplish this.

// ... // initial code unchanged // ... // Text Channel name .addStringOption((option) => option .setName("textchannelname") // option names need to always be lowercase and have no spaces .setDescription("Choose the name to give to the text channel") .setMinLength(1) // A Text Channel needs to be named .setMaxLength(25) // Discord will cut-off names past the 25 characters, // so that's a good hard limit to set. You can manually increase this if you wish .setRequired(true) ); // Voice Channel name .addStringOption((option) => option .setName("voicechannelname") // option names need to always be lowercase and have no spaces .setDescription("Choose the name to give to the voice channel") .setMinLength(1) // A Voice Channel needs to be named .setMaxLength(25) // Discord will cut-off names past the 25 characters, // so that's a good hard limit to set. You can manually increase this if you wish .setRequired(true) ); // ... // code in between unchanged // ... const chosenTextChannelName = interaction.options.getString("textchannelname"); const chosenVoiceChannelName = interaction.options.getString( "voicechannelname", ); // ... // code in between unchanged // ... // Now create the Category in the server. const newlyCreatedCategory = await interaction.guild.channels.create({ name: chosenCategoryName, // The name given to the Channel by the user type: ChannelType.GuildCategory, // The type of the Channel created. }); // Now we create the Text Channel within the Category we just created await newlyCreatedCategory.children.create({ name: chosenTextChannelName, // The name given to the Channel by the user type: ChannelType.GuildText, // The type of the Channel created. // Since "text" is the default Channel created, this could be ommitted }); // Lastly we create the Voice Channel within the same Category await newlyCreatedCategory.children.create({ name: chosenVoiceChannelName, // The name given to the Channel by the user type: ChannelType.GuildVoice, // The type of the Channel created. }); // ... // rest of the code unchanged // ...
View/Download file

You should be fairly familiar with what's happening here by this point if you have been following along. We are requiring the user to provide us a name for the Text Channel and the Voice Channel, we are then fetching that input and using it to create them nested within the Category we created. There are only two points that I think it's important to go through in more detail:

const newlyCreatedCategory = await interaction.guild.channels.create({ (line 65)

We are now fetching the Category and storing it to a constant, so it can be used to nest the newly created Text and Voice Channels.

await newlyCreatedCategory.children.create({ (lines 74 and 81)

Since we now have a Category, we don't need to transverse through the interaction, then the guild, and then the guild channels to create our Channels, we can just use the Category's children and nest our Channels inside that.

Next post: .

Written with 💞 by TheYuriG