I followed a tutorial for making a discord bot and every time I type in a command I get the error message:
discord.ext.commands.errors.CommandNotFound: Command "play" is not found
It runs and shows to be online in my Discord server, I have given it every permission know to man, and checked through multiple times in my code to see if I find something wrong. But I don't see anything that can be changed or something that can fix it. I am in desperate need for help. Thanks alot in advance!!
This is my files and code:
main.py
import discord
from discord.ext import commands
import os
from help_cog import help_cog
from music_cog import music_cog
bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())
bot.remove_command("help")
bot.add_cog(help_cog(bot))
bot.add_cog(music_cog(bot))
bot.run(os.getenv("TOKEN"))
music_cog.py
import discord
from discord.ext import commands
from yt_dlp import YoutubeDL
import yt_dlp as youtube_dl
class music_cog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.is_playing = False
self.is_paused = False
self.music_queue = []
self.YDL_OPTIONS = {"format": "bestaudio", "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "192",}]}
self.FFMPEG_OPTIONS = {"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", "options": "-vn"}
self.vc = None
print("Success")
def search_yt(self, item):
with YoutubeDL(self.YDL_OPTIONS) as ydl:
try:
info = ydl.extract_info(f"ytsearch:{item}", download=False)["entries"][0]
except Exception:
return False
return {"source": info["url"], "title": info["title"]}
def play_next(self):
if len(self.music_queue) > 0:
self.is_playing = True
m_url = self.music_queue[0][0]["source"]
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
async def play_music(self, ctx):
if len(self.music_queue) > 0:
self.is_playing = True
m_url = self.music_queue[0][0]["source"]
if self.vc == None or not self.vc.is_connected():
self.vc = await self.music_queue[0][1].connect()
if self.vc == None:
await ctx.send("Could not connect to the voice channel")
return
else:
await self.vc.move_to(self.music_queue[0][1])
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
@commands.command(name="play", aliases=["p", "playing"], help="Play the selected song from YouTube")
async def play(self, ctx, *args):
query = " ".join(args)
voice_channel = ctx.author.voice.channel
if voice_channel is None:
await ctx.send("Connect to a voice channel!")
elif self.is_paused:
self.vc.resume()
else:
song = self.search_yt(query)
if type(song) == type(True):
await ctx.send("Could not download the song. Incorrect format, try a different keyword")
else:
await ctx.send("Song added to queue")
self.music_queue.append([song, voice_channel])
if self.is_playing == False:
await self.play_music(ctx)
@commands.command(name="pause", help="Pauses the current song being played")
async def pause(self, ctx, *args):
if self.is_playing:
self.is_playing = False
self.is_paused = True
self.vc.pause()
elif self.is_paused:
self.is_playing = True
self.is_paused = False
self.vc.resume()
@commands.command(name="resume", aliases=["r"], help="Resumes playing the current song")
async def resume(self, ctx, *args):
if self.is_paused:
self.is_playing = True
self.is_paused = False
self.vc.resume()
@commands.command(name="skip", aliases=["s"], help="Skips the currently played song")
async def skip(self, ctx, *args):
if self.vc != None and self.vc:
self.vc.stop()
await self.play_music(ctx)
@commands.command(name="queue", aliases=["q"], help="Displays all the songs currently in queue")
async def queue(self, ctx):
retval = ""
for i in range(0, len(self.music_queue)):
if i > 4: break
retval += self.music_queue[i][0]["title"] + "\n"
if retval != "":
await ctx.send(retval)
else:
await ctx.send("No music in the current queue")
@commands.command(name="clear", aliases=["c", "bin"], help="Stops the current song and clears the queue")
async def clear(self, ctx, *args):
if self.vc != None and self.is_playing:
self.vc.stop()
self.music_queue = []
await ctx.send("Music queue cleared")
@commands.command(name="leave", aliases=["disconnect", "l", "d"], help="Kick the bot from the voice channel")
async def leave(self, ctx):
self.is_playing = False
self.is_paused = False
await self.vc.disconnect()
help_cog.py
import discord
from discord.ext import commands
class help_cog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.help_message = """
Help message
"""
self.text_channel_text = []
@commands.Cog.listener()
async def on_ready(self):
for guild in self.bot.guilds:
for channel in guild.text_channels:
self.text_channel_text.append(channel)
await self.send_to_all(self.help_message)
async def send_to_all(self, msg):
for text_channel in self.text_channel_text:
await text_channel.send(msg)
@commands.command(name="help", help="Displays all the available commands")
async def help(self, ctx):
await ctx.send(self.help_message)
As an extension to the asyncio changes in discord.py v2.0, the loading and unloading of extensions and cogs is now asynchronous (read more).
This way you will need to load the cogs
in an async context as shown below:
import discord
from discord.ext import commands
import os
import asyncio
from help_cog import help_cog
from music_cog import music_cog
bot = commands.Bot(
command_prefix="?",
intents=discord.Intents.all(),
help_command=None
)
async def main():
async with bot:
await bot.add_cog(help_cog(bot))
await bot.add_cog(music_cog(bot))
await bot.start(os.getenv("TOKEN"))
asyncio.run(main())