Tengo un bot de discordia que estoy usando para aprender a usar la API y practicar mi conocimiento de Python. Estoy tratando de crear un sistema que elija aleatoriamente un estado y lo aplique, luego espere un corto tiempo, actualmente 10 minutos, luego continúe así infinitamente hasta que el bot se apague. Actualmente, tengo el bucle en mi función on_ready() pero el bot se apaga después de un corto tiempo (menos de 10 minutos, alrededor de 2-3) y no puedo entender por qué. El código actual es este:

@client.event
async def on_ready():
  print("We have logged in as {0.user}".format(client))
  infiniteTime = 1
  while infiniteTime != 20:
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))
    time.sleep(600)

watchingStatus y listeningStatus son matrices 1D con 11 cadenas. Se agradece cualquier ayuda / comentario ya que soy nuevo en la API. ¡Salud!

ETA: Probablemente debería aclarar que me he dado cuenta de que tener el código en la función on_ready() significa que nunca termina y, por lo tanto, no puede hacer nada más. Lo pregunto porque no sé por qué el bot se apaga en el extremo de Discord sin que yo detenga el código y no sé dónde más debería poner este bucle ya que soy nuevo en este sistema asíncrono / en espera y el forma en que funciona la API.

0
finalerock44 22 ene. 2021 a las 22:02

1 respuesta

La mejor respuesta

El lugar donde está tratando de cambiar el estado del bot es correcto, el problema es que la forma de intentar crear este bucle impide que su bot funcione, ya que time.sleep no es adecuado para una biblioteca asincrónica como discord .py. En su lugar, puede utilizar asyncio.sleep().

Podrías hacer algo como esto:

import asyncio

@client.event
async def on_ready():
  # ...
  # Here goes your code for on_ready()
  # ...
  while True:
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))
    asyncio.sleep(600)

Otra forma de hacer esto sería usando discord.ext.tasks, que son funciones definidas para ejecutar tareas en segundo plano como la que desea lograr.

from discord.ext import commands, tasks
import asyncio

# Your code here

@loop(seconds=600)
async def status_change():
    # ...
    # Some code to define playingStatus and watchingStatus arrays
    # ...
    statusType = random.randint(0, 1)
    if statusType == 0:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.playing, name=playingStatus[statusNum]))
    else:
      statusNum = random.randint(0, 10)
      await client.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.watching, name=watchingStatus[statusNum]))

status_change.before_loop(client.wait_until_ready())    
status_change.start()
client.run("TOKEN")

Referencias:

2
Shunya 22 ene. 2021 a las 19:28