Guide discord.js
Fonctionnalités supplémentaires

Délais d'Attente

Le spam est quelque chose que vous généralement voulez éviter, surtout si l'une de vos commandes nécessite des appels à d'autres API ou prend un peu de temps pour construire/envoyer.

Cette section suppose que vous avez suivi la partie Gestion des commandes du guide.

D'abord, ajoutez une propriété de délai d'attente à votre commande. Cela déterminera combien de temps l'utilisateur devra attendre (en secondes) avant d'utiliser à nouveau la commande.

commands/utility/ping.js
const { SlashCommandBuilder } = require('discord.js');

module.exports = {
	cooldown: 5, 
	data: new SlashCommandBuilder().setName('ping').setDescription('Replies with Pong!'),
	async execute(interaction) {
		// ...
	},
};

Dans votre fichier principal, initialisez une Collection pour stocker les délais d'attente des commandes :

client.cooldowns = new Collection();

La clé sera les noms des commandes, et les valeurs seront des Collections associant l'id de l'utilisateur (clé) à la dernière fois (valeur) que cet utilisateur a utilisé cette commande. En général, le chemin logique pour obtenir la dernière utilisation d'une commande par un utilisateur sera cooldowns > command > user > timestamp.

Dans votre gestionnaire d'événement InteractionCreate, ajoutez le code suivant :

index.js / interactionCreate.js (if you followed the event handler section)
// ...
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) * 1_000;

if (timestamps.has(interaction.user.id)) {
	// ...
}

Vous vérifiez si la Collection cooldowns a déjà une entrée pour la commande utilisée. Si ce n'est pas le cas, vous pouvez ajouter une nouvelle entrée, où la valeur est initialisée comme une Collection vide. Ensuite, créez les variables suivantes :

  1. now : L'horodatage actuel.
  2. timestamps : Une référence à la Collection des identifiants d'utilisateur et des paires clé-valeur d'horodatage pour la commande déclenchée.
  3. cooldownAmount : Le délai d'attente spécifié pour la commande, converti en millisecondes pour un calcul simple. S'il n'est pas spécifié, cela correspond par défaut à trois secondes.

Si l'utilisateur a déjà utilisé cette commande dans cette session, obtenez l'horodatage, calculez l'heure d'expiration et informez l'utilisateur du temps qu'il doit attendre avant d'utiliser à nouveau cette commande. Notez l'utilisation de la déclaration return ici, ce qui fait que le code ci-dessous s'exécute uniquement si l'utilisateur n'a pas utilisé cette commande dans cette session ou si le délai d'attente a déjà expiré.

En continuant avec votre configuration actuelle, voici la déclaration if complète :

index.js / interactionCreate.js (if you followed the event handler section)
const defaultCooldownDuration = 3;
const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1_000;

if (timestamps.has(interaction.user.id)) {
	// ...
	const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount;

	if (now < expirationTime) {
		const expiredTimestamp = Math.round(expirationTime / 1_000);
		return interaction.reply({
			content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again <t:${expiredTimestamp}:R>.`,
			flags: MessageFlags.Ephemeral,
		});
	}
}

Puisque la Collection timestamps a l'id de l'utilisateur comme clé, vous pouvez utiliser la méthode get() sur celle-ci pour obtenir la valeur et l'ajouter à la variable cooldownAmount pour obtenir l'horodatage d'expiration correct et vérifier davantage si elle a expiré ou non.

La vérification précédente de l'utilisateur sert de précaution au cas où l'utilisateur quitterait la guilde. Vous pouvez maintenant utiliser la méthode setTimeout, qui vous permettra d'exécuter une fonction après un laps de temps spécifié et de supprimer le délai d'attente.

if (timestamps.has(interaction.user.id)) {
	const expiredTimestamp = Math.round(expirationTime / 1_000);
	return interaction.reply({
		content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again <t:${expiredTimestamp}:R>.`,
		flags: MessageFlags.Ephemeral,
	});
} 

timestamps.set(interaction.user.id, now);
setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);

Cette ligne provoque la suppression de l'entrée de l'utilisateur sous la commande spécifiée après l'expiration du délai d'attente de la commande.