From a03497b05e58623dac8248f5aeb6a2b2c6e08249 Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 17:39:27 -0500 Subject: [PATCH 1/7] Made additional features more consistent with the guide's previous code implementations in event handling for clarity. --- .../cooldowns/events/interactionCreate.js | 67 +++++++++++++++ .../cooldowns/events/ready.js | 9 ++ .../additional-features/cooldowns/index.js | 86 +++++++------------ .../events/interactionCreate.js | 67 +++++++++++++++ .../reloading-commands/events/ready.js | 9 ++ .../reloading-commands/index.js | 86 +++++++------------ 6 files changed, 216 insertions(+), 108 deletions(-) create mode 100644 code-samples/additional-features/cooldowns/events/interactionCreate.js create mode 100644 code-samples/additional-features/cooldowns/events/ready.js create mode 100644 code-samples/additional-features/reloading-commands/events/interactionCreate.js create mode 100644 code-samples/additional-features/reloading-commands/events/ready.js diff --git a/code-samples/additional-features/cooldowns/events/interactionCreate.js b/code-samples/additional-features/cooldowns/events/interactionCreate.js new file mode 100644 index 000000000..bb6d0506e --- /dev/null +++ b/code-samples/additional-features/cooldowns/events/interactionCreate.js @@ -0,0 +1,67 @@ +const { Events, Collection, MessageFlags } = require("discord.js"); + +module.exports = { + name: Events.InteractionCreate, + async execute(interaction) { + if (!interaction.isChatInputCommand()) return; + + const command = interaction.client.commands.get( + interaction.commandName + ); + + if (!command) { + console.error( + `No command matching ${interaction.commandName} was found.` + ); + return; + } + + const { cooldowns } = interaction.client; + + if (!cooldowns.has(command.data.name)) { + cooldowns.set(command.data.name, new Collection()); + } + + const now = Date.now(); + const timestamps = cooldowns.get(command.data.name); + const defaultCooldownDuration = 3; + const cooldownAmount = + (command.cooldown ?? defaultCooldownDuration) * 1000; + + if (timestamps.has(interaction.user.id)) { + const expirationTime = + timestamps.get(interaction.user.id) + cooldownAmount; + + if (now < expirationTime) { + const expiredTimestamp = Math.round(expirationTime / 1000); + return interaction.reply({ + content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, + flags: MessageFlags.Ephemeral, + }); + } + } + + timestamps.set(interaction.user.id, now); + setTimeout( + () => timestamps.delete(interaction.user.id), + cooldownAmount + ); + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + if (interaction.replied || interaction.deferred) { + await interaction.followUp({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } else { + await interaction.reply({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } + } + }, +}; diff --git a/code-samples/additional-features/cooldowns/events/ready.js b/code-samples/additional-features/cooldowns/events/ready.js new file mode 100644 index 000000000..4cb90c77c --- /dev/null +++ b/code-samples/additional-features/cooldowns/events/ready.js @@ -0,0 +1,9 @@ +const { Events } = require("discord.js"); + +module.exports = { + name: Events.ClientReady, + once: true, + execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); + }, +}; diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index 101d8037d..54f45fe74 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -1,75 +1,53 @@ -const fs = require('node:fs'); -const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); -const { token } = require('./config.json'); +const fs = require("node:fs"); +const path = require("node:path"); +const { + Client, + Collection, + Events, + GatewayIntentBits, + MessageFlags, +} = require("discord.js"); +const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, 'commands'); + +const foldersPath = path.join(__dirname, "commands"); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + const commandFiles = fs + .readdirSync(commandsPath) + .filter((file) => file.endsWith(".js")); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ('data' in command && 'execute' in command) { + if ("data" in command && "execute" in command) { client.commands.set(command.data.name, command); } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + console.log( + `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` + ); } } } -client.once(Events.ClientReady, readyClient => { - console.log(`Ready! Logged in as ${readyClient.user.tag}`); -}); - -client.on(Events.InteractionCreate, async interaction => { - if (!interaction.isChatInputCommand()) return; - const command = client.commands.get(interaction.commandName); - - if (!command) { - console.error(`No command matching ${interaction.commandName} was found.`); - return; +const eventsPath = path.join(__dirname, "events"); +const eventFiles = fs + .readdirSync(eventsPath) + .filter((file) => file.endsWith(".js")); + +for (const file of eventFiles) { + const filePath = path.join(eventsPath, file); + const event = require(filePath); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); } - - const { cooldowns } = interaction.client; - - if (!cooldowns.has(command.data.name)) { - cooldowns.set(command.data.name, new Collection()); - } - - const now = Date.now(); - const timestamps = cooldowns.get(command.data.name); - const defaultCooldownDuration = 3; - const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; - - if (timestamps.has(interaction.user.id)) { - const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; - - if (now < expirationTime) { - const expiredTimestamp = Math.round(expirationTime / 1000); - return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral }); - } - } - - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } else { - await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } - } -}); +} client.login(token); diff --git a/code-samples/additional-features/reloading-commands/events/interactionCreate.js b/code-samples/additional-features/reloading-commands/events/interactionCreate.js new file mode 100644 index 000000000..bb6d0506e --- /dev/null +++ b/code-samples/additional-features/reloading-commands/events/interactionCreate.js @@ -0,0 +1,67 @@ +const { Events, Collection, MessageFlags } = require("discord.js"); + +module.exports = { + name: Events.InteractionCreate, + async execute(interaction) { + if (!interaction.isChatInputCommand()) return; + + const command = interaction.client.commands.get( + interaction.commandName + ); + + if (!command) { + console.error( + `No command matching ${interaction.commandName} was found.` + ); + return; + } + + const { cooldowns } = interaction.client; + + if (!cooldowns.has(command.data.name)) { + cooldowns.set(command.data.name, new Collection()); + } + + const now = Date.now(); + const timestamps = cooldowns.get(command.data.name); + const defaultCooldownDuration = 3; + const cooldownAmount = + (command.cooldown ?? defaultCooldownDuration) * 1000; + + if (timestamps.has(interaction.user.id)) { + const expirationTime = + timestamps.get(interaction.user.id) + cooldownAmount; + + if (now < expirationTime) { + const expiredTimestamp = Math.round(expirationTime / 1000); + return interaction.reply({ + content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, + flags: MessageFlags.Ephemeral, + }); + } + } + + timestamps.set(interaction.user.id, now); + setTimeout( + () => timestamps.delete(interaction.user.id), + cooldownAmount + ); + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + if (interaction.replied || interaction.deferred) { + await interaction.followUp({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } else { + await interaction.reply({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } + } + }, +}; diff --git a/code-samples/additional-features/reloading-commands/events/ready.js b/code-samples/additional-features/reloading-commands/events/ready.js new file mode 100644 index 000000000..4cb90c77c --- /dev/null +++ b/code-samples/additional-features/reloading-commands/events/ready.js @@ -0,0 +1,9 @@ +const { Events } = require("discord.js"); + +module.exports = { + name: Events.ClientReady, + once: true, + execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); + }, +}; diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index a2ab97353..54f45fe74 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -1,75 +1,53 @@ -const fs = require('node:fs'); -const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); -const { token } = require('./config.json'); +const fs = require("node:fs"); +const path = require("node:path"); +const { + Client, + Collection, + Events, + GatewayIntentBits, + MessageFlags, +} = require("discord.js"); +const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, 'commands'); + +const foldersPath = path.join(__dirname, "commands"); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + const commandFiles = fs + .readdirSync(commandsPath) + .filter((file) => file.endsWith(".js")); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ('data' in command && 'execute' in command) { + if ("data" in command && "execute" in command) { client.commands.set(command.data.name, command); } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + console.log( + `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` + ); } } } -client.once(Events.ClientReady, c => { - console.log(`Ready! Logged in as ${c.user.tag}`); -}); - -client.on(Events.InteractionCreate, async interaction => { - if (!interaction.isChatInputCommand()) return; - const command = client.commands.get(interaction.commandName); - - if (!command) { - console.error(`No command matching ${interaction.commandName} was found.`); - return; +const eventsPath = path.join(__dirname, "events"); +const eventFiles = fs + .readdirSync(eventsPath) + .filter((file) => file.endsWith(".js")); + +for (const file of eventFiles) { + const filePath = path.join(eventsPath, file); + const event = require(filePath); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); } - - const { cooldowns } = interaction.client; - - if (!cooldowns.has(command.data.name)) { - cooldowns.set(command.data.name, new Collection()); - } - - const now = Date.now(); - const timestamps = cooldowns.get(command.data.name); - const defaultCooldownDuration = 3; - const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; - - if (timestamps.has(interaction.user.id)) { - const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; - - if (now < expirationTime) { - const expiredTimestamp = Math.round(expirationTime / 1000); - return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral }); - } - } - - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } else { - await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } - } -}); +} client.login(token); From 0990e5dd031d786c5798761d31916a547cb632bd Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 17:39:27 -0500 Subject: [PATCH 2/7] Made additional features more consistent with the guide's previous code implementations in event handling for clarity. --- .../cooldowns/events/interactionCreate.js | 67 +++++++++++++++ .../cooldowns/events/ready.js | 9 ++ .../additional-features/cooldowns/index.js | 86 +++++++------------ .../events/interactionCreate.js | 67 +++++++++++++++ .../reloading-commands/events/ready.js | 9 ++ .../reloading-commands/index.js | 86 +++++++------------ 6 files changed, 216 insertions(+), 108 deletions(-) create mode 100644 code-samples/additional-features/cooldowns/events/interactionCreate.js create mode 100644 code-samples/additional-features/cooldowns/events/ready.js create mode 100644 code-samples/additional-features/reloading-commands/events/interactionCreate.js create mode 100644 code-samples/additional-features/reloading-commands/events/ready.js diff --git a/code-samples/additional-features/cooldowns/events/interactionCreate.js b/code-samples/additional-features/cooldowns/events/interactionCreate.js new file mode 100644 index 000000000..bb6d0506e --- /dev/null +++ b/code-samples/additional-features/cooldowns/events/interactionCreate.js @@ -0,0 +1,67 @@ +const { Events, Collection, MessageFlags } = require("discord.js"); + +module.exports = { + name: Events.InteractionCreate, + async execute(interaction) { + if (!interaction.isChatInputCommand()) return; + + const command = interaction.client.commands.get( + interaction.commandName + ); + + if (!command) { + console.error( + `No command matching ${interaction.commandName} was found.` + ); + return; + } + + const { cooldowns } = interaction.client; + + if (!cooldowns.has(command.data.name)) { + cooldowns.set(command.data.name, new Collection()); + } + + const now = Date.now(); + const timestamps = cooldowns.get(command.data.name); + const defaultCooldownDuration = 3; + const cooldownAmount = + (command.cooldown ?? defaultCooldownDuration) * 1000; + + if (timestamps.has(interaction.user.id)) { + const expirationTime = + timestamps.get(interaction.user.id) + cooldownAmount; + + if (now < expirationTime) { + const expiredTimestamp = Math.round(expirationTime / 1000); + return interaction.reply({ + content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, + flags: MessageFlags.Ephemeral, + }); + } + } + + timestamps.set(interaction.user.id, now); + setTimeout( + () => timestamps.delete(interaction.user.id), + cooldownAmount + ); + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + if (interaction.replied || interaction.deferred) { + await interaction.followUp({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } else { + await interaction.reply({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } + } + }, +}; diff --git a/code-samples/additional-features/cooldowns/events/ready.js b/code-samples/additional-features/cooldowns/events/ready.js new file mode 100644 index 000000000..4cb90c77c --- /dev/null +++ b/code-samples/additional-features/cooldowns/events/ready.js @@ -0,0 +1,9 @@ +const { Events } = require("discord.js"); + +module.exports = { + name: Events.ClientReady, + once: true, + execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); + }, +}; diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index 101d8037d..54f45fe74 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -1,75 +1,53 @@ -const fs = require('node:fs'); -const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); -const { token } = require('./config.json'); +const fs = require("node:fs"); +const path = require("node:path"); +const { + Client, + Collection, + Events, + GatewayIntentBits, + MessageFlags, +} = require("discord.js"); +const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, 'commands'); + +const foldersPath = path.join(__dirname, "commands"); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + const commandFiles = fs + .readdirSync(commandsPath) + .filter((file) => file.endsWith(".js")); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ('data' in command && 'execute' in command) { + if ("data" in command && "execute" in command) { client.commands.set(command.data.name, command); } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + console.log( + `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` + ); } } } -client.once(Events.ClientReady, readyClient => { - console.log(`Ready! Logged in as ${readyClient.user.tag}`); -}); - -client.on(Events.InteractionCreate, async interaction => { - if (!interaction.isChatInputCommand()) return; - const command = client.commands.get(interaction.commandName); - - if (!command) { - console.error(`No command matching ${interaction.commandName} was found.`); - return; +const eventsPath = path.join(__dirname, "events"); +const eventFiles = fs + .readdirSync(eventsPath) + .filter((file) => file.endsWith(".js")); + +for (const file of eventFiles) { + const filePath = path.join(eventsPath, file); + const event = require(filePath); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); } - - const { cooldowns } = interaction.client; - - if (!cooldowns.has(command.data.name)) { - cooldowns.set(command.data.name, new Collection()); - } - - const now = Date.now(); - const timestamps = cooldowns.get(command.data.name); - const defaultCooldownDuration = 3; - const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; - - if (timestamps.has(interaction.user.id)) { - const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; - - if (now < expirationTime) { - const expiredTimestamp = Math.round(expirationTime / 1000); - return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral }); - } - } - - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } else { - await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } - } -}); +} client.login(token); diff --git a/code-samples/additional-features/reloading-commands/events/interactionCreate.js b/code-samples/additional-features/reloading-commands/events/interactionCreate.js new file mode 100644 index 000000000..bb6d0506e --- /dev/null +++ b/code-samples/additional-features/reloading-commands/events/interactionCreate.js @@ -0,0 +1,67 @@ +const { Events, Collection, MessageFlags } = require("discord.js"); + +module.exports = { + name: Events.InteractionCreate, + async execute(interaction) { + if (!interaction.isChatInputCommand()) return; + + const command = interaction.client.commands.get( + interaction.commandName + ); + + if (!command) { + console.error( + `No command matching ${interaction.commandName} was found.` + ); + return; + } + + const { cooldowns } = interaction.client; + + if (!cooldowns.has(command.data.name)) { + cooldowns.set(command.data.name, new Collection()); + } + + const now = Date.now(); + const timestamps = cooldowns.get(command.data.name); + const defaultCooldownDuration = 3; + const cooldownAmount = + (command.cooldown ?? defaultCooldownDuration) * 1000; + + if (timestamps.has(interaction.user.id)) { + const expirationTime = + timestamps.get(interaction.user.id) + cooldownAmount; + + if (now < expirationTime) { + const expiredTimestamp = Math.round(expirationTime / 1000); + return interaction.reply({ + content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, + flags: MessageFlags.Ephemeral, + }); + } + } + + timestamps.set(interaction.user.id, now); + setTimeout( + () => timestamps.delete(interaction.user.id), + cooldownAmount + ); + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + if (interaction.replied || interaction.deferred) { + await interaction.followUp({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } else { + await interaction.reply({ + content: "There was an error while executing this command!", + flags: MessageFlags.Ephemeral, + }); + } + } + }, +}; diff --git a/code-samples/additional-features/reloading-commands/events/ready.js b/code-samples/additional-features/reloading-commands/events/ready.js new file mode 100644 index 000000000..4cb90c77c --- /dev/null +++ b/code-samples/additional-features/reloading-commands/events/ready.js @@ -0,0 +1,9 @@ +const { Events } = require("discord.js"); + +module.exports = { + name: Events.ClientReady, + once: true, + execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); + }, +}; diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index a2ab97353..54f45fe74 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -1,75 +1,53 @@ -const fs = require('node:fs'); -const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); -const { token } = require('./config.json'); +const fs = require("node:fs"); +const path = require("node:path"); +const { + Client, + Collection, + Events, + GatewayIntentBits, + MessageFlags, +} = require("discord.js"); +const { token } = require("./config.json"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, 'commands'); + +const foldersPath = path.join(__dirname, "commands"); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + const commandFiles = fs + .readdirSync(commandsPath) + .filter((file) => file.endsWith(".js")); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ('data' in command && 'execute' in command) { + if ("data" in command && "execute" in command) { client.commands.set(command.data.name, command); } else { - console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + console.log( + `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` + ); } } } -client.once(Events.ClientReady, c => { - console.log(`Ready! Logged in as ${c.user.tag}`); -}); - -client.on(Events.InteractionCreate, async interaction => { - if (!interaction.isChatInputCommand()) return; - const command = client.commands.get(interaction.commandName); - - if (!command) { - console.error(`No command matching ${interaction.commandName} was found.`); - return; +const eventsPath = path.join(__dirname, "events"); +const eventFiles = fs + .readdirSync(eventsPath) + .filter((file) => file.endsWith(".js")); + +for (const file of eventFiles) { + const filePath = path.join(eventsPath, file); + const event = require(filePath); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); } - - const { cooldowns } = interaction.client; - - if (!cooldowns.has(command.data.name)) { - cooldowns.set(command.data.name, new Collection()); - } - - const now = Date.now(); - const timestamps = cooldowns.get(command.data.name); - const defaultCooldownDuration = 3; - const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; - - if (timestamps.has(interaction.user.id)) { - const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; - - if (now < expirationTime) { - const expiredTimestamp = Math.round(expirationTime / 1000); - return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral }); - } - } - - timestamps.set(interaction.user.id, now); - setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); - - try { - await command.execute(interaction); - } catch (error) { - console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } else { - await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } - } -}); +} client.login(token); From eea2f58028f6c92656c45b96994b46c4cc3e7af4 Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 18:03:05 -0500 Subject: [PATCH 3/7] Updated style and added pull request information --- .github/PULL_REQUEST_TEMPLATE.md | 5 ++++ .../cooldowns/events/interactionCreate.js | 6 ++--- .../additional-features/cooldowns/index.js | 24 +++++++------------ .../events/interactionCreate.js | 6 ++--- .../reloading-commands/events/ready.js | 2 +- .../reloading-commands/index.js | 24 +++++++------------ 6 files changed, 30 insertions(+), 37 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a0d7a9f45..0ba15ed97 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1 +1,6 @@ **Please describe the changes this PR makes and why it should be merged:** + +This pull request updates the `additional-features` code samples to include the individual event +files that were added in previous steps of the guide. This change makes reading the reference code +more consistent, clearer, and easier for the user who has followed the previous steps in case they +wanted to cross-reference their own work. \ No newline at end of file diff --git a/code-samples/additional-features/cooldowns/events/interactionCreate.js b/code-samples/additional-features/cooldowns/events/interactionCreate.js index bb6d0506e..74db8ac6f 100644 --- a/code-samples/additional-features/cooldowns/events/interactionCreate.js +++ b/code-samples/additional-features/cooldowns/events/interactionCreate.js @@ -1,4 +1,4 @@ -const { Events, Collection, MessageFlags } = require("discord.js"); +const { Events, Collection, MessageFlags } = require('discord.js'); module.exports = { name: Events.InteractionCreate, @@ -53,12 +53,12 @@ module.exports = { console.error(error); if (interaction.replied || interaction.deferred) { await interaction.followUp({ - content: "There was an error while executing this command!", + content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral, }); } else { await interaction.reply({ - content: "There was an error while executing this command!", + content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral, }); } diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index 54f45fe74..991081716 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -1,31 +1,25 @@ -const fs = require("node:fs"); -const path = require("node:path"); -const { - Client, - Collection, - Events, - GatewayIntentBits, - MessageFlags, -} = require("discord.js"); -const { token } = require("./config.json"); +const fs = require('node:fs'); +const path = require('node:path'); +const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); +const { token } = require('./config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, "commands"); +const foldersPath = path.join(__dirname, 'commands'); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); const commandFiles = fs .readdirSync(commandsPath) - .filter((file) => file.endsWith(".js")); + .filter((file) => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ("data" in command && "execute" in command) { + if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log( @@ -35,10 +29,10 @@ for (const folder of commandFolders) { } } -const eventsPath = path.join(__dirname, "events"); +const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs .readdirSync(eventsPath) - .filter((file) => file.endsWith(".js")); + .filter((file) => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); diff --git a/code-samples/additional-features/reloading-commands/events/interactionCreate.js b/code-samples/additional-features/reloading-commands/events/interactionCreate.js index bb6d0506e..74db8ac6f 100644 --- a/code-samples/additional-features/reloading-commands/events/interactionCreate.js +++ b/code-samples/additional-features/reloading-commands/events/interactionCreate.js @@ -1,4 +1,4 @@ -const { Events, Collection, MessageFlags } = require("discord.js"); +const { Events, Collection, MessageFlags } = require('discord.js'); module.exports = { name: Events.InteractionCreate, @@ -53,12 +53,12 @@ module.exports = { console.error(error); if (interaction.replied || interaction.deferred) { await interaction.followUp({ - content: "There was an error while executing this command!", + content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral, }); } else { await interaction.reply({ - content: "There was an error while executing this command!", + content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral, }); } diff --git a/code-samples/additional-features/reloading-commands/events/ready.js b/code-samples/additional-features/reloading-commands/events/ready.js index 4cb90c77c..e59e552a9 100644 --- a/code-samples/additional-features/reloading-commands/events/ready.js +++ b/code-samples/additional-features/reloading-commands/events/ready.js @@ -1,4 +1,4 @@ -const { Events } = require("discord.js"); +const { Events } = require('discord.js'); module.exports = { name: Events.ClientReady, diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index 54f45fe74..991081716 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -1,31 +1,25 @@ -const fs = require("node:fs"); -const path = require("node:path"); -const { - Client, - Collection, - Events, - GatewayIntentBits, - MessageFlags, -} = require("discord.js"); -const { token } = require("./config.json"); +const fs = require('node:fs'); +const path = require('node:path'); +const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); +const { token } = require('./config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.cooldowns = new Collection(); client.commands = new Collection(); -const foldersPath = path.join(__dirname, "commands"); +const foldersPath = path.join(__dirname, 'commands'); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); const commandFiles = fs .readdirSync(commandsPath) - .filter((file) => file.endsWith(".js")); + .filter((file) => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); - if ("data" in command && "execute" in command) { + if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log( @@ -35,10 +29,10 @@ for (const folder of commandFolders) { } } -const eventsPath = path.join(__dirname, "events"); +const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs .readdirSync(eventsPath) - .filter((file) => file.endsWith(".js")); + .filter((file) => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); From 4021baa5359b7f62a8e8feb3dab15b54716e9dcd Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 18:04:01 -0500 Subject: [PATCH 4/7] Updated style --- code-samples/additional-features/cooldowns/events/ready.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code-samples/additional-features/cooldowns/events/ready.js b/code-samples/additional-features/cooldowns/events/ready.js index 4cb90c77c..e59e552a9 100644 --- a/code-samples/additional-features/cooldowns/events/ready.js +++ b/code-samples/additional-features/cooldowns/events/ready.js @@ -1,4 +1,4 @@ -const { Events } = require("discord.js"); +const { Events } = require('discord.js'); module.exports = { name: Events.ClientReady, From a91f05121c295d6b85fd4cf5e94412a4e4b00767 Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 18:05:43 -0500 Subject: [PATCH 5/7] Updated format --- code-samples/additional-features/cooldowns/index.js | 8 ++------ .../additional-features/reloading-commands/index.js | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index 991081716..2e8463f2b 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -13,18 +13,14 @@ const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs - .readdirSync(commandsPath) - .filter((file) => file.endsWith('.js')); + const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { - console.log( - `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` - ); + console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); } } } diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index 991081716..2e8463f2b 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -13,18 +13,14 @@ const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs - .readdirSync(commandsPath) - .filter((file) => file.endsWith('.js')); + const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { - console.log( - `[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.` - ); + console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); } } } From 843d4a4c7db0cd2da4673cdf8ce81bd456f5c39e Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 18:07:04 -0500 Subject: [PATCH 6/7] Updated format --- code-samples/additional-features/cooldowns/index.js | 2 +- code-samples/additional-features/reloading-commands/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index 2e8463f2b..c48e4d680 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -13,7 +13,7 @@ const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js')); + const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index 2e8463f2b..c48e4d680 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -13,7 +13,7 @@ const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js')); + const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); From dc1e82b56616e4526f76ad9fe0dcb78aa0ae9389 Mon Sep 17 00:00:00 2001 From: Pogoretskiy777 Date: Tue, 7 Jan 2025 18:17:57 -0500 Subject: [PATCH 7/7] Fixed lint errors and warnings --- .../cooldowns/events/interactionCreate.js | 29 +++++-------------- .../additional-features/cooldowns/index.js | 4 +-- .../events/interactionCreate.js | 29 +++++-------------- .../reloading-commands/index.js | 4 +-- 4 files changed, 18 insertions(+), 48 deletions(-) diff --git a/code-samples/additional-features/cooldowns/events/interactionCreate.js b/code-samples/additional-features/cooldowns/events/interactionCreate.js index 74db8ac6f..eb9c79182 100644 --- a/code-samples/additional-features/cooldowns/events/interactionCreate.js +++ b/code-samples/additional-features/cooldowns/events/interactionCreate.js @@ -5,14 +5,10 @@ module.exports = { async execute(interaction) { if (!interaction.isChatInputCommand()) return; - const command = interaction.client.commands.get( - interaction.commandName - ); + const command = interaction.client.commands.get(interaction.commandName); if (!command) { - console.error( - `No command matching ${interaction.commandName} was found.` - ); + console.error(`No command matching ${interaction.commandName} was found.`); return; } @@ -25,12 +21,10 @@ module.exports = { const now = Date.now(); const timestamps = cooldowns.get(command.data.name); const defaultCooldownDuration = 3; - const cooldownAmount = - (command.cooldown ?? defaultCooldownDuration) * 1000; + const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; if (timestamps.has(interaction.user.id)) { - const expirationTime = - timestamps.get(interaction.user.id) + cooldownAmount; + const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; if (now < expirationTime) { const expiredTimestamp = Math.round(expirationTime / 1000); @@ -42,25 +36,16 @@ module.exports = { } timestamps.set(interaction.user.id, now); - setTimeout( - () => timestamps.delete(interaction.user.id), - cooldownAmount - ); + setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); try { await command.execute(interaction); } catch (error) { console.error(error); if (interaction.replied || interaction.deferred) { - await interaction.followUp({ - content: 'There was an error while executing this command!', - flags: MessageFlags.Ephemeral, - }); + await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); } else { - await interaction.reply({ - content: 'There was an error while executing this command!', - flags: MessageFlags.Ephemeral, - }); + await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); } } }, diff --git a/code-samples/additional-features/cooldowns/index.js b/code-samples/additional-features/cooldowns/index.js index c48e4d680..7cca2ff26 100644 --- a/code-samples/additional-features/cooldowns/index.js +++ b/code-samples/additional-features/cooldowns/index.js @@ -1,6 +1,6 @@ const fs = require('node:fs'); const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); +const { Client, Collection, GatewayIntentBits } = require('discord.js'); const { token } = require('./config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); @@ -28,7 +28,7 @@ for (const folder of commandFolders) { const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs .readdirSync(eventsPath) - .filter((file) => file.endsWith('.js')); + .filter(file => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); diff --git a/code-samples/additional-features/reloading-commands/events/interactionCreate.js b/code-samples/additional-features/reloading-commands/events/interactionCreate.js index 74db8ac6f..eb9c79182 100644 --- a/code-samples/additional-features/reloading-commands/events/interactionCreate.js +++ b/code-samples/additional-features/reloading-commands/events/interactionCreate.js @@ -5,14 +5,10 @@ module.exports = { async execute(interaction) { if (!interaction.isChatInputCommand()) return; - const command = interaction.client.commands.get( - interaction.commandName - ); + const command = interaction.client.commands.get(interaction.commandName); if (!command) { - console.error( - `No command matching ${interaction.commandName} was found.` - ); + console.error(`No command matching ${interaction.commandName} was found.`); return; } @@ -25,12 +21,10 @@ module.exports = { const now = Date.now(); const timestamps = cooldowns.get(command.data.name); const defaultCooldownDuration = 3; - const cooldownAmount = - (command.cooldown ?? defaultCooldownDuration) * 1000; + const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; if (timestamps.has(interaction.user.id)) { - const expirationTime = - timestamps.get(interaction.user.id) + cooldownAmount; + const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; if (now < expirationTime) { const expiredTimestamp = Math.round(expirationTime / 1000); @@ -42,25 +36,16 @@ module.exports = { } timestamps.set(interaction.user.id, now); - setTimeout( - () => timestamps.delete(interaction.user.id), - cooldownAmount - ); + setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount); try { await command.execute(interaction); } catch (error) { console.error(error); if (interaction.replied || interaction.deferred) { - await interaction.followUp({ - content: 'There was an error while executing this command!', - flags: MessageFlags.Ephemeral, - }); + await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); } else { - await interaction.reply({ - content: 'There was an error while executing this command!', - flags: MessageFlags.Ephemeral, - }); + await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); } } }, diff --git a/code-samples/additional-features/reloading-commands/index.js b/code-samples/additional-features/reloading-commands/index.js index c48e4d680..7cca2ff26 100644 --- a/code-samples/additional-features/reloading-commands/index.js +++ b/code-samples/additional-features/reloading-commands/index.js @@ -1,6 +1,6 @@ const fs = require('node:fs'); const path = require('node:path'); -const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); +const { Client, Collection, GatewayIntentBits } = require('discord.js'); const { token } = require('./config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); @@ -28,7 +28,7 @@ for (const folder of commandFolders) { const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs .readdirSync(eventsPath) - .filter((file) => file.endsWith('.js')); + .filter(file => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file);