2

i have a work command for my discord.py bot with a hour cooldown. So if i do >work and then someone else does >work, it tells them they must wait for an hour. How can i get the cooldown to only apply to one user when the do >work? Thx

this is the code that i have for the cooldown and command,

class Economy(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.last_work_time = None

    def on_work_waiting():
      time.sleep(3600)
      last_work_time = None

    def on_work_typed():
      if last_work_time is None:
        last_work_time = datetime.datetime.now()
        threading.Thread(target: on_work_waiting).start()
  
    else:
        time_left = datetime.datetime.now() - last_work_time
        minutes_left, _ = divmod(time_left.total_seconds(), 60)

        await ctx.send(f'{ctx.author.mention}, Wait {minutes_left} minutes until you can work again!')


    @commands.cooldown(1, 3600, commands.BucketType.user)

    @commands.command()
    async def work(self, ctx):
      database.load()
      randomjobtitle = ["Construction Worker", "Teacher", "Twitch Streamer", "911 Dispatcher", "Librarian", "Cookie Giver", "Fast Food Worker"]
      job = random.choice(randomjobtitle)
      author = ctx.author
      money = random.randint(10,50)
      balance = database[str(ctx.message.author.id)]
      total = database[str(ctx.message.author.id)] = balance + money
      embed=discord.Embed(title=f"{ctx.author.name} decided to work!", description="You're going to work!", color=0x00FFFF)
      embed.add_field(name="Amount Earned", value=f"**{money}** Ulti Coins", inline=True)
      embed.add_field(name="Job Title (random)", value=f"**{job}**", inline=True)
      embed.add_field(name="Balance Before Work", value=f"**{total}** Ulti Coins", inline=True)
      embed.set_thumbnail(url=author.avatar_url)
      embed.set_footer(text="Your total amount is saved across all servers that I'm in! >balance to see your balance")
      await ctx.send(embed=embed)
      try:
        balance = database[str(ctx.message.author.id)]
      except:
        balance = 0
      database[str(ctx.message.author.id)] = balance + money
  • You can do this with a global variable or with a property inside a class. Every time a person types `work`, check if this variable is already set (e.g. initialize it with None and check if it's not None). If it is, tell the person to wait. If it's not, set the variable to some value (it can be `datetime.datetime.now()`), create a new Thread and sleep inside it for one hour. When it wakes up, set the variable to None again. The sleep inside Thread can be replaced with [something else](https://stackoverflow.com/q/510348/9997212) if you want. – enzo May 18 '21 at 14:15
  • @Enzo Thank you for helping, may i ask for you to maybe post an answer with the new code? – Coleman Ethington May 18 '21 at 14:16
  • Sure, I'll post it asap – enzo May 18 '21 at 14:17

1 Answers1

1

Your command cooldown, @commands.cooldown(1, 3600, commands.BucketType.user), should already be working this way. You are using the user BucketType which applies a cooldown on a per-user basis. Based on how your bot is being used, the person who still has that cooldown could be doing the command in another server. In that case, you could use the member BucketType.

StarbuckBarista
  • 1,298
  • 1
  • 8
  • 20