I'm trying to write a simple discord bot in python. I want the bot to be able to join a voice channel, and constantly keep repeating an mp3 file. I firstly tried using a while loop in the on_ready() function, which had an understandably bad result. I have now tried using a thread to run the loop seperately from the main thread, but discord.py's functions use async/await, so I've had to improvise (badly).
import asyncio
import threading
import discord
from discord import app_commands
intents = discord.Intents.all()
client = discord.Client(intents=intents)
discord.Permissions.manage_nicknames = True
tree = app_commands.CommandTree(client)
def targeter():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(play_sounds())
loop.close()
async def play_sounds():
for channel in client.guilds[1].channels:
if str(channel.type) == "voice":
print("started")
player_channel = await channel.connect()
print("done")
@client.event
async def on_ready():
await tree.sync()
threading.Thread(target=targeter).start()
client.run("token")
When I run said thread, it gets to the line where I introduce the awaited discord.VoiceChannel.connect() function and hangs. The rest of the commands work fine, it's just that thread. The connect() command usually returns a VoiceClient within a few milliseconds when run normally. Is this something to do with me trying to run functions across threads? If so, is there a better solution I'm not seeing?
>>> started
Why use threads? Take a look at tasks
instead.
Create a task that runs every minute or so; have it join the VC if it's not in it (aka on first run) and then have it check that song is still running/playing.
Take a look here at creating a player
. Save that player object in the task, and then when the task loop runs you can do player.is_done()
to check if it's still playing or not - and then start playing the song again.