CodeFreak
CodeFreak

Reputation: 11

Make the same cooldown for multiple discord.py bot commands?

This is written in discord.py.

I have multiple commands similar to the following:

@bot.command(name ="hi")
async def hi(ctx):
    link = ["https://google.com", "https://youtube.com"]
    chosen = random.choice(link)
    url = chosen
    embed = discord.Embed(title="Your Link", description=f"[Click Here]({url})", color=0x00ff00)
    if ctx.message.guild == None:
        await ctx.author.send('You can not use this command in your DM!')
        pass
    else:
        await ctx.author.send(embed=embed)

If someone uses one of the commands, a cooldown should be enacted for all the commands (e.g. if !hi is used, a cooldown would be applied to both !hi AND !bye.

I know you can use @commands.cooldown(1, 600, commands.BucketType.user), but this only applies a cooldown to the current command.

Upvotes: 1

Views: 1367

Answers (1)

Patrick Haugh
Patrick Haugh

Reputation: 61063

This is how the cooldowns decorator is defined in the code:

def cooldown(rate, per, type=BucketType.default):
    def decorator(func):
        if isinstance(func, Command):
            func._buckets = CooldownMapping(Cooldown(rate, per, type))
        else:
            func.__commands_cooldown__ = Cooldown(rate, per, type)
        return func
    return decorator

We can modify this so that we only create one Cooldown object that gets shared between the commands:

def shared_cooldown(rate, per, type=BucketType.default):
    cooldown = Cooldown(rate, per, type=type)
    def decorator(func):
        if isinstance(func, Command):
            func._buckets = CooldownMapping(cooldown)
        else:
            func.__commands_cooldown__ = cooldown
        return func
    return decorator

We would use this by calling it to get the decorator that we then apply to the commands:

my_cooldown = shared_cooldown(1, 600, commands.BucketType.user)

@bot.command()
@my_cooldown
async def hi(ctx):
    await ctx.send("Hi")


@bot.command()
@my_cooldown
async def bye(ctx):
    await ctx.send("Bye")

Upvotes: 3

Related Questions