I’m trying to write a simple music bot using discord.py to play music using youtube_dl. I’m having problems with my 'join’ command. When I try to use it on discord it gives this error
Ignoring exception in command join:
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "/home/runner/Discord-Bot-2/commands.py", line 44, in join
await ctx.voice_client.connect(ctx.author.voice_channel)
AttributeError: 'NoneType' object has no attribute 'connect'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'connect'
This error happens when I’m in a voice channel. If I’m not, the bot follows the code that I wrote and sent a message in discord “You are not connected to a voice channel”. But when I am in a voice channel it gives the error.
The code for the join command is
@commands.command()
async def join(self, ctx):
if ctx.author.voice is None:
return await ctx.send("You are not connected to a voice channel")
if ctx.voice_client is not None:
await ctx.voice_client.disconnect()
await ctx.voice_client.connect(ctx.author.voice_channel)
await ctx.send(f"Connected to {ctx.author.voice_channel}")
I’m pretty sure that I set up everything correctly, but here’s all the code above the join command where I set up the cog for my commands
import discord
from discord.ext import commands
import youtube_dl
import pafy
import asyncio
class Commands(commands.Cog):
def __init__(self, client):
self.client = client
self.song_queue = {}
@commands.Cog.listener()
async def on_ready(self):
for guild in self.client.guilds:
self.song_queue[guild.id] = []
print("Cog 'commands' loaded")
async def check_queue(self, ctx):
if len(self.song_queue[ctx.guild.id]) > 0:
ctx.voice_client.stop()
await self.play_song(ctx, self.song_queue[ctx.guild.id][0])
self.song_queue[ctx.guild.id].pop(0)
async def search_song(self, amount, song, get_url=False):
info = await self.client.loop.run_in_executor(None, lambda: youtube_dl.YoutubeDL({"format": "bestaudio", "quiet" : True}).extract_info(f"ytsearch{amount}:{song}", download=False, ie_key="YoutubeSearch"))
if len(info["entries"]) == 0:
return None
return [entry["webpage_url"] for entry in info["entries"]] if get_url else info
async def play_song(self, ctx, song):
url = pafy.new(song).getbestaudio().url
ctx.voice_client.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(url)), after=lambda error: self.client.loop.create_task(self.check_queue(ctx)))
ctx.voice_client.source.volume = 0.5