How to loop a task in discord.py

Viewed 39484

I am experimenting with making my own little discord bot that can get information from Twitch, but I'm stumped on how to make the bot loop and check for a condition.

I want the bot to loop a section of code every few seconds that checks if the specified twitch channel is live.


Code

import discord
from discord.ext import commands, tasks
from twitch import TwitchClient
from pprint import pformat


client = TwitchClient(client_id='<twitch token>')

bot = commands.Bot(command_prefix='$')

@bot.event
async def on_ready():
    print('We have logged in as {0.user}'.format(bot))

@bot.command()
async def info(ctx, username):
    response = await ctx.send("Querying twitch database...")
    try:
        users = client.users.translate_usernames_to_ids(username)
        for user in users:
            print(user.id)
            userid = user.id
        twitchinfo = client.users.get_by_id(userid)
        status = client.streams.get_stream_by_user(userid)
        if status == None:
            print("Not live")
            livestat = twitchinfo.display_name + "is not live"
        else:
            livestat = twitchinfo.display_name + " is " + status.stream_type
        responsemsg = pformat(twitchinfo) + "\n" + livestat
        await response.edit(content=responsemsg)
    except:
        await response.edit(content="Invalid username")

bot.run("<discord token>")

I want the bot to run the following code every 10 seconds, for example:

status = client.streams.get_stream_by_user(<channel id>)
if status == None:
     print("Not live")
     livestat = twitchinfo.display_name + "is not live"
else:
     livestat = twitchinfo.display_name + " is " + status.stream_type

I've tried using @tasks.loop(seconds=10) to try and make a custom async def repeat every 10 seconds but it didn't seem to work.

Any ideas?

3 Answers

The newer version of discord.py doesn't support client.command()

To achieve the same I used the following snippet

import discord
from discord.ext import tasks
client = discord.Client()
@tasks.loop(seconds = 10) # repeat after every 10 seconds
async def myLoop():
    # work


myLoop.start()

client.run('<your token>')

This can be done like so:

async def my_task(ctx, username):
    while True:
        # do something
        await asyncio.sleep(10)

@client.command()
async def info(ctx, username):
    client.loop.create_task(my_task(ctx, username))

References:

This is the most proper way to implement background tasks.

from discord.ext import commands, tasks

bot = commands.Bot(...)

@bot.listen()
async def on_ready():
    task_loop.start() # important to start the loop

@tasks.loop(seconds=10)
async def task_loop():
    ... # this code will be executed every 10 seconds after the bot is ready

Check this for more info

Related