threading.Timer alternative for coroutines

Viewed 106

Im creating a discord bot and I wanted to know if there is any third party libraries that do the same thing as threading.Timer but with coroutine support for Discord.client.send.

@client.command(aliases = ['Timer'])
async def timer(ctx, secs, *message):
    await ctx.send(f"Your timer {message} started, and it is gonna take {secs}secs to stop.")

    async def stop_timer():
        await ctx.send(f'Your timer: {message} is over, it took {secs} secs.')

    def timer_over():
        asyncio.run(stop_timer())
        
    simpleTimer = threading.Timer(int(secs), timer_over)
    simpleTimer.start()

My code up there, im looking for a function that takes some seconds and after those seconds the function returns a coroutine. Kinda like an alarm.

3 Answers

Check out tasks from discord.ext:

from discord.ext import tasks

@tasks.loop(seconds=30)
async def my_loop(messageable):
    await messageable.send("Here's some message!")

@bot.command()
async def startloop(ctx):
    my_loop.start(messageable=ctx)

This will send Here's some message! to whatever messageable object you give it every 30 seconds.


References:

Thanks @Diggy for mentioning asyncio.sleep

This is the code that fits what I want and works:

@client.command(aliases = ['Timer'])
async def timer(ctx, secs, *message):
    globalsecs = secs
    await ctx.send(f"The timer {message} started and it is going to take {secs} secs to be over.")
    await asyncio.sleep(int(secs))
    await send_message(message = f'Your timer:{message} is over, it took {secs}secs.', ctx = ctx)
    
async def send_message(ctx, message):
    await ctx.send(message)

Here's a pretty simple example (for your example with the timer):

@client.command(aliases = ['Timer'])
async def timer(ctx, secs, *message):
    if secs < 1:
        await ctx.send("You can't give seconds lower than 1!")
    else:
        timer = await ctx.send(f"Your timer {message} started, and it is gonna take {secs}secs to stop.")
        while True:
            if secs > 0:
                await asyncio.sleep(1)
                secs -= 1
                await timer.edit(content=f"Your timer {message} started, and it is gonna take {secs}secs to stop.")
            else:
                await ctx.send(f'Your timer: {message} is over, it took {secs} secs.')

Maybe this helps you..

Related