it-swarm.com.de

Alle 10 Sekunden wird ein Abspielstatus des Discord-Bot geändert

Ich versuche den Status für einen Testdiskont-Bot zwischen zwei Nachrichten alle zehn Sekunden zu ändern. Ich muss den Rest des Skripts ausführen, während sich die Statusmeldung ändert, aber es wird immer ein Fehler angezeigt, wenn ich versuche, dass es funktioniert. Es gibt ein Threading in meinem Skript, aber ich bin mir nicht ganz sicher, wie ich es unter diesen Umständen einsetzen sollte.

@test_bot.event
async def on_ready():
    print('Logged in as')
    print(test_bot.user.name)
    print(test_bot.user.id)
    print('------')
    await change_playing()


@test_bot.event
async def change_playing():
    threading.Timer(10, change_playing).start()
    await test_bot.change_presence(game=discord.Game(name='Currently on ' + str(len(test_bot.servers)) +
                                                          ' servers'))
    threading.Timer(10, change_playing).start()
    await test_bot.change_presence(game=discord.Game(name='Say test.help'))

Die Fehlermeldung lautet:

C:\Python\Python36-32\lib\threading.py:1182: RuntimeWarning: coroutine 'change_playing' was never awaited
  self.function(*self.args, **self.kwargs)
6
luigiisgreeny

Threading und Asyncio spielen leider nicht Nizza zusammen. Sie müssen durch zusätzliche Reifen springen, um Coroutinen in Threads zu erwarten. Die einfachste Lösung ist, kein Threading zu verwenden.

Was Sie zu tun versuchen, ist eine Weile zu warten und dann eine Coroutine auszuführen. Dies kann mit einer Hintergrundaufgabe erfolgen ( example )

async def status_task():
    while True:
        await test_bot.change_presence(...)
        await asyncio.sleep(10)
        await test_bot.change_presence(...)
        await asyncio.sleep(10)

@test_bot.event
async def on_ready():
    ...
    bot.loop.create_task(status_task())

Sie können time.sleep () nicht verwenden, da dies die Ausführung des Bots blockiert. asyncio.sleep () ist jedoch eine Coroutine wie alles andere und als solche nicht blockierend.

Schließlich sollte der @client.event-Dekorator nur für Funktionen verwendet werden, die der Bot als events erkennt. Wie zB on_ready und on_message.

7
Sam Rockett

Sieh dir das an:

https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py

import discord
import asyncio
client = discord.Client()
async def my_background_task():
    await client.wait_until_ready()
    counter = 0
    channel = discord.Object(id='channel_id_here')
    while not client.is_closed:
        counter += 1
        await client.send_message(channel, counter)
        await asyncio.sleep(60) # task runs every 60 seconds
@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')
client.loop.create_task(my_background_task())
client.run('token')

Discord.py verfügt über eine integrierte Hintergrundaufgabenfunktion.

0
ADug

discord.py Version 1.1.0 eingeführt discord.ext.tasks , das dazu dient, Hintergrundaufgaben wie die von Ihnen beschriebene zu vereinfachen und die möglicherweise komplizierte Logik des erneuten Verbindens mit Discord zu handhaben, wenn ein Verbindungsproblem vorliegt.

Hier ist ein Beispiel für Ihre Aufgabe mit tasks:

from discord.ext import commands, tasks
from commands import Bot
from tasks import loop
from asyncio import sleep

bot = Bot("!")

@loop(seconds=10)
async def name_change():
    await bot.change_presence(...)
    await sleep(10)
    await bot.change_presence(...)

name_change.before_loop(bot.wait_until_ready())    
name_change.start()
bot.run("TOKEN")
0
Patrick Haugh