Reputation: 320
I'm working on a command right now that, after using a command (e.g. ?hello
), puts you in a set. If you use the command again, you would be greeted with a message (e.g. "Please wait 10 seconds before using this command again.") However, if you wait 10 seconds, you can use the command again.
The problem is, before the 10 seconds is up, each time I do ?hello
before the 10 seconds is up, the bot always says "Please wait 10 seconds before using this command again." This means that even if I have waited for, lets say 8 seconds, and used the command, the bot will still reply with "Please wait 10 seconds before using this command again." instead of "Please wait 2 seconds before using this command again."
I'm currently using setTimeout()
for this, but the bot isn't counting down. I've tried using setInterval()
and using a for()
loop for this but I can't figure out how to make this work using either of them.
My basic code right for the ?hello command
const helloSet = new Set();
bot.on('message', msg => {
let args = msg.content.substring(prefix.length).split(" ");
if(args[0] === 'hello'){
if(helloSet.has(msg.author.id)){
msg.channel.send(`Please wait 10 seconds before using this command again.`)
setTimeout(() => {
helloSet.delete(msg.author.id)
}, 10000)
} else {
msg.channel.send(`Hello!`)
helloSet.add(msg.author.id)
}
}
})
This does not have the timer/countdown thing in there, so this is what happens when I use the ?hello
command.
User: ?hello
Bot: Hello!
User right after using ?hello: ?hello
Bot: Please wait 10 seconds before using this command again
User 8 seconds later: ?hello
Bot: Please wait 10 seconds before using this command again
*Even after I wait for 8 seconds, the bot still says wait 10 more seconds although I really only need to wait 2 more seconds.*
User after a total 10 seconds later: ?hello
Bot: Hello!
Again, I'm not too sure how to use something like setInterval()
for a for()
loop to achieve this as I've tried it and it hasn't worked.
I would really appreciate any help on how I can achieve this. Thank you so much!
Upvotes: 0
Views: 11617
Reputation: 1
This is because you are telling your code to remove the cooldown after 10s of running the same command again, this will not make your remove cooldown on running command BUT after 10s of that command being run again. To improve this you can add setTimeout() to your else
block:
if(helloSet.has(message.author.id)) {
message.reply("Please wait 10s before running the command again!");
} else {
message.reply("Hello");
helloSet.add(message.author.id);
setTimeout(() => {
helloSet.delete(message.author.id);
}, 10000)
}
This will tell your bot to delete the user from cooldown instantly 10s after the command has been run once.
Upvotes: 0
Reputation: 53
From your description it seems that the bot is counting down correctly but it just isn't outputting the remaining time correcty.
This is because the message you print when someone calls the help function is static (Please wait 10 seconds before using this command again.
).
setTimeout doesn't have a method to retrieve the time left before it's execution so you have to manually take note of the time at which the command is first called and on later calls calculate the time left as the difference between the timeout and part already elapsed.
Declare a variable to keep track of the time:
var callTime = 0;
And when you call setTimeout take note of the current date/time:
callTime = (new Date()).getTime();
Finally change the message you print when on cooldown with:
Please wait ${10-((new Date()).getTime() - callTime )} seconds before using this command again.
Upvotes: 2
Reputation: 5174
That is because you literally told the bot to say 10 seconds, you need to set a variable instead:
if (helloSet.has(message.author.id)) {
const expirationTime = helloSet.get(message.author.id) + 10000; // 10000 is cooldown
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`please wait ${timeLeft.toFixed(1)} seconds before using this command again`);
}
}
Either way however, the timer won't ever expire because you need to run the setTimeout()
function as soon as you add the user to the Set()
:
} else {
msg.channel.send(`Hello!`)
helloSet.add(msg.author.id)
setTimeout(() => {
helloSet.delete(msg.author.id)
}, 10000)
}
Upvotes: 2