I'm trying to make the status for a test discord bot change between two messages every ten seconds. I need the rest of the script to execute while the status message changes, but an error keeps popping up whenever I try to make it work. There's threading in my script, but I'm not entirely sure how to use it in this circumstance.
@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'))
The error message reads:
C:\Python\Python36-32\lib\threading.py:1182: RuntimeWarning: coroutine 'change_playing' was never awaited
self.function(*self.args, **self.kwargs)
Threading and asyncio don't play nice together unfortunately. You need to jump through extra hoops to await coroutines inside threads. The simplest solution is to just not use threading.
What you are trying to do is wait a duration and then run a coroutine. This can be done with a background task (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())
You cannot use time.sleep() as this will block the execution of the bot. asyncio.sleep() though is a coroutine like everything else and as such is non-blocking.
Lastly, the @client.event
decorator should only be used on functions the bot recognises as events. Such as on_ready and on_message.
discord.py version 1.1.0 introduced discord.ext.tasks
, which is designed to make background tasks like the one you describe easier, as well as handling the potentially complicated logic of reconnecting to discord if there is a connection issue.
Here's an example of your task using 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")
See this:
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 comes with a built in background task feature,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With