Search code examples
python-3.xdiscordtwitchtwitch-api

How to loop a task in discord.py


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?


Solution

  • 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: