Discord Bot Delay after giving 1 command


@client.command()
async def work(ctx):
    await open_account(ctx.author)
    user = ctx.author
    users = await get_bank_data()
    earnings = random.randrange(269)

    await ctx.send(f'{ctx.author.mention} Got {earnings} Coins!!')

    users[str(user.id)]["wallet"] += earnings

    with open("mainbank.json",'w') as f:
        json.dump(users,f)

I am making an Economy bot for my discord server in which I have added a work command that'll give user some random amount of money after typing $work , but I want that people won't spam that command to earn easy money , I want my bot to send a message like 'Take a break , try again after 15 sec' and only after 15 seconds , user will be able to use that command again

2 answers

  • answered 2021-09-11 18:22 FLAK-ZOSO

    You can use a global variable for the delay, and also a global dictionary declared in this scope.
    Like this:

    @Bot.command()
    @commands.has_permissions(send_messages=True)
    async def work(ctx):
        worker = ctx.message.author.nick # I use nick so that you can store the data in a .json file
        # You can also use user.id
        if worker in delays.keys():
            if delays[worker] == 0:
                # Work
                delays[worker] = 15 # Seconds
                for i in reversed(range(delays[worker])):
                    await asyncio.sleep(1)
                    delays[worker] = i
                delays[worker] = 0
        else:
            # Let this poor man work
            delays[worker] = 0
    

    Then, I suggest to store the datas into the .json file only when the bot is stopped.
    Otherwise it will take lot of time for each time to open the file, store the datas, and then close it.

  • answered 2021-09-11 20:57 OneLoneTurnip

    While FLAK-ZOSO's answer works, there's a better way to do it

    In fact, discord.py (or Nextcord) has builtin support for it (btw in order to use commands.anything, you have to do from [discord/nextcord].ext import commands at the top):

    @client.command()
    @commands.cooldown([cooldown in seconds], [how many times you can run the command before hitting the cooldown], type=commands.BucketType.user)
    async def work(ctx):
        await open_account(ctx.author)
        user = ctx.author
        users = await get_bank_data()
        earnings = random.randrange(269)
    
        await ctx.send(f'{ctx.author.mention} Got {earnings} Coins!!')
    
        users[str(user.id)]["wallet"] += earnings
    
        with open("mainbank.json",'w') as f:
            json.dump(users,f)
    

    Also, if you want a channel specific, server specific, role specific, etc. cooldown instead of a user specific one, change the BucketType to one of the following options:

    • commands.BucketType.default for a global cooldown (across servers)
    • commands.BucketType.guild for a server specific cooldown
    • commands.BucketType.channel for a channel specific cooldown
    • commands.BucketType.member for a member specific cooldown (this is different than commands.BucketType.user because per user is global, so even if the user moves to a different server they'll still have the same cooldown whereas BucketType.member is server-specific, so if the user switches servers and runs the command again, there will be 2 seperate cooldowns)
    • commands.BucketType.category for a category specific cooldown
    • commands.BucketType.role for a role specific cooldown

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum