Discord.py command to play audio in a VC and command to leave VC using interactions/slash commands. NOT ctx or 'discord.ext commands'
Question:
I am wanting to make my own personal/private bot join the voice channel I am in and play audio files. I have it able to join the VC but I can’t figure out how to make the bot leave or play music/audio using slash commands/interactions. Everywhere I look it’s just old & outdated examples. Even the discord.py github examples don’t help and rely on using ctx and discord.ext commands. (same for what I can find here on stackoverflow).
It’s something that should be SO simple but is so obfuscated with garbage examples and outdated material. Nothing with what I am wanting to do. Not cogs/classes, no ctx., nothing to do with "self". Just interactions/slash commands. "app_commands"
I also don’t need to know how to use slash commands or how to work with them. I think I have that down.
I am trying to use interaction.voice_client.play()
to play audio but I just get the following error. AttributeError: 'Interaction' object has no attribute 'voice_client'
I have spent all day trying to understand the discord.py documentation with no way of finding up to date examples that use slash commands/interactions. I am not even sure what to look for or where to even look in that mess of a documentation. Searching up the error just gives me no help with the search results being completely different errors, etc.
Here’s some code that I am using for the play command..I have nothing for the leave command:
(From an example in the discord.py github examples directory but edited slightly to try and allow me to use slash commands instead of just sending "!play" in the chat.)
@muise.tree.command()
@app_commands.describe(url='Youtube URL')
async def play(interaction: discord.Interaction, url: str):
"""Streams audio from a url"""
player = await YTDLSource.from_url(url, loop=muise.loop, stream=True)
#no idea if muise.loop will even work. used to be "self.bot.loop" But I am not in a cog or class.
interaction.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
embed = discord.Embed(title='Muise', colour=main_embed_color, timestamp=datetime.datetime.now(datetime.timezone.utc))
embed.add_field(name='Now Playing', value=f'{player.title}')
embed.set_footer(text=Config["author"], icon_url='https://cdn.discordapp.com/attachments/1019374213037035530/1040294855315836998/Ori_the_cutie-1.png')
await interaction.response.send_message(embed=embed)
The expected outcome should be audio being played in the VC.
My main issue is not having the proper knowledge of how to make this work..idk what to do, where to look. I am so tired and want this simple task to be over with. Any help would be very appreciated.
Feel free to ask questions and I’ll answer them to the best of my ability.
Answers:
Try doing
guild = interaction.guild
guild.voice_client.play
instead of
interaction.voice_client.play
you should use
voices = interaction.client.voice_clients
for i in voices:
if i.channel == interaction.user.voice.channel:
voice = i
break
else:
if interaction.user.voice is not None:
vc = interaction.user.voice.channel
voice = await vc.connect()
else:
await interaction.response.defer(ephemeral=True)
await interaction.followup.send("You are not in a voice channel.")
return
to find the voice client
I am wanting to make my own personal/private bot join the voice channel I am in and play audio files. I have it able to join the VC but I can’t figure out how to make the bot leave or play music/audio using slash commands/interactions. Everywhere I look it’s just old & outdated examples. Even the discord.py github examples don’t help and rely on using ctx and discord.ext commands. (same for what I can find here on stackoverflow).
It’s something that should be SO simple but is so obfuscated with garbage examples and outdated material. Nothing with what I am wanting to do. Not cogs/classes, no ctx., nothing to do with "self". Just interactions/slash commands. "app_commands"
I also don’t need to know how to use slash commands or how to work with them. I think I have that down.
I am trying to use interaction.voice_client.play()
to play audio but I just get the following error. AttributeError: 'Interaction' object has no attribute 'voice_client'
I have spent all day trying to understand the discord.py documentation with no way of finding up to date examples that use slash commands/interactions. I am not even sure what to look for or where to even look in that mess of a documentation. Searching up the error just gives me no help with the search results being completely different errors, etc.
Here’s some code that I am using for the play command..I have nothing for the leave command:
(From an example in the discord.py github examples directory but edited slightly to try and allow me to use slash commands instead of just sending "!play" in the chat.)
@muise.tree.command()
@app_commands.describe(url='Youtube URL')
async def play(interaction: discord.Interaction, url: str):
"""Streams audio from a url"""
player = await YTDLSource.from_url(url, loop=muise.loop, stream=True)
#no idea if muise.loop will even work. used to be "self.bot.loop" But I am not in a cog or class.
interaction.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
embed = discord.Embed(title='Muise', colour=main_embed_color, timestamp=datetime.datetime.now(datetime.timezone.utc))
embed.add_field(name='Now Playing', value=f'{player.title}')
embed.set_footer(text=Config["author"], icon_url='https://cdn.discordapp.com/attachments/1019374213037035530/1040294855315836998/Ori_the_cutie-1.png')
await interaction.response.send_message(embed=embed)
The expected outcome should be audio being played in the VC.
My main issue is not having the proper knowledge of how to make this work..idk what to do, where to look. I am so tired and want this simple task to be over with. Any help would be very appreciated.
Feel free to ask questions and I’ll answer them to the best of my ability.
Try doing
guild = interaction.guild
guild.voice_client.play
instead of
interaction.voice_client.play
you should use
voices = interaction.client.voice_clients
for i in voices:
if i.channel == interaction.user.voice.channel:
voice = i
break
else:
if interaction.user.voice is not None:
vc = interaction.user.voice.channel
voice = await vc.connect()
else:
await interaction.response.defer(ephemeral=True)
await interaction.followup.send("You are not in a voice channel.")
return
to find the voice client