Reputation: 79
Let's say I have two commands...
hi 1
that sends hi once to user and starts a cooldown of 500 secondshi 2
that sends hi twice to user and starts a cooldown of 1000 secondsNow when I type hi 1
it should not respond to me when I type hi 2
.
Something like a shared cooldown system!
How can I do that?
I am currently using this:
@commands.cooldown(1, 5, commands.BucketType.user)
Which allows me to use the multiple commands without stopping for cooldown on a previous command.
Upvotes: 1
Views: 1633
Reputation: 964
You could use a custom check to ensure that the commands aren't used while they're on cooldown.
./q63262849/cooldowns.py
import datetime
from discord.ext import commands
on_cooldown = {} # A dictionary mapping user IDs to cooldown ends
def cooldown(seconds):
def predicate(context):
if (cooldown_end := on_cooldown.get(context.author.id)) is None or cooldown_end < datetime.datetime.now(): # If there's no cooldown or it's over
if context.valid and context.invoked_with in (*context.command.aliases, context.command.name): # If the command is being run as itself (not by help, which runs checks and would end up creating more cooldowns if this didn't exist)
on_cooldown[context.author.id] = datetime.datetime.now() + datetime.timedelta(seconds=seconds) # Add the datetime of the cooldown's end to the dictionary
return True # And allow the command to run
else:
raise commands.CommandOnCooldown(commands.BucketType.user, (cooldown_end - datetime.datetime.now()).seconds) # Otherwise, raise the cooldown error to say the command is on cooldown
return commands.check(predicate)
This can then be imported
./main.py
from q63262849 import cooldowns
and used as a decorator for commands
./main.py
@bot.command()
@cooldowns.cooldown(10)
async def cooldown1(ctx):
await ctx.send("Ran cooldown 1")
@bot.command()
@cooldowns.cooldown(20)
async def cooldown2(ctx):
await ctx.send("Ran cooldown 2")
It is notable that this approach still has some issues, in particular if another later check fails this check will still put the command on cooldown, however these could be solved by putting this check such that it will run after all the other checks.
Upvotes: 2