Middleware is a function that runs before the command is executed. It can be used to check that the user has the correct privileges, if the command is being used in the correct channel, or if the user has the the required role. Middleware can be used to check anything before the command is executed. There's almost no limit to what you can do with middleware. In this guide I'll show you how to create your own middleware and use it in your Discord.js commands.
As an example, let's create a middleware function that checks whether the user's user ID is in a predefined array of user IDs. If the user ID is in the array, the command is executed. If the user ID is not in the in the array, the command is not executed.
const AuthUtil = require("../utils/auth.util.js");
const ErrorRepository = require("../repositories/error.repository.js");
class RequireVerifiedTester {
/**
* **Middleware function to require VerifiedTester permission.**
* @param {import("discord.js").ChatInputCommandInteraction} interaction
* @returns {void} Void.
* @throws {Object} Throws a middleware error, if the user is not a verified tester.
*/
static requireVerifiedTester(interaction) {
try {
if (!AuthUtil.isVerifiedTester(interaction.user.id)) {
throw ErrorRepository.testersOnlyCommand;
}
} catch (err) {
if (err === ErrorRepository.testersOnlyCommand) {
throw err;
} else {
console.error(err);
throw ErrorRepository.generalMiddlewareError;
}
}
}
}
module.exports = RequireVerifiedTester.requireVerifiedTester;
In this example, we have created a middleware function called requireVerifiedTester
. This
function checks if the user's user ID is in the array of verified tester user IDs. If the user ID is in
the array, the function does nothing. If the user ID is not in the array, the function throws an error.
Now that we have created our middleware function, let's see how we can use it in our Discord.js command.
const { SlashCommandBuilder, InteractionContextType } = require("discord.js");
const mw = require("../middleware/middleware.js");
module.exports = {
data: new SlashCommandBuilder()
.setName("name")
.setDescription("description")
.setContexts(InteractionContextType.BotDM, InteractionContextType.PrivateChannel, InteractionContextType.Guild),
ephemeral: false,
public: true,
cooldown: 5,
// Add the middleware function
middleware: [mw.requireVerifiedTester],
/**
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async execute(interaction) {
// Your command code here...
},
};
In this example, we have added the middleware function requireVerifiedTester
to our command.
The middleware function is added to the middleware
array in the command object. This means
that the middleware function can be executed before the command is executed.
That's it! You have now successfully implemented your own custom middleware into your Discord.js commands. You can create as many middleware functions as you need and add them to your commands as needed.
Finally, we need to execute the middleware function. To do this, we need to call the middleware function before the command is executed.
We can do this by adding the following code to the interaction
listener function.
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName);
for (const middleware of command.middleware || []) {
try {
middleware(interaction);
} catch (middlewareError) {
console.log(middlewareError);
return await interaction.reply(middlewareError);
}
}
// Execute the command...
});
In this example, we have added a loop that iterates over the middleware functions in the command object.
The loop calls each middleware function with the interaction
object as an argument. If the
middleware function throws an error, the error is caught and a message is sent to the user.
That's it! You have now successfully implemented your own custom middleware into your Discord.js commands. You can create as many middleware functions as you need and add them to your commands as needed.
Keep in mind that middleware functions can be used for a wide variety of purposes. This was a very basic example, you can improve it as you see fit.