Reputation: 80
I’m trying to code a simple music bot for discord in python. I tried coding a queue command so that I can queue a certain song (searching for songs and playing them etc. all work). This is my code for the queue command:
@commands.command()
async def checkqueue(self, ctx):
if len(self.song_queue[ctx.guild.id]) == 0:
return await ctx.send("Queue is empty")
else:
embed = discord.Embed(title="Song Queue", description="", colour=discord.colour.dark_gold())
i = 1
for url in self.song_queue[ctx.guild.id]:
embed.description += f"{i}) {url}\n"
i += 1
await ctx.send(embed=embed)
When the queue is empty, the bot sends a message in discord saying "Queue is empty”. When I use the play command, it adds a song to the queue. However, when I try to use the checkqueue command when there’s at least one song in the queue, the bot doesn’t send the embed. Not sure if this is a problem with the code in the queue command or outside the queue command, so here’s the cut-down version of the rest of my code in my commands Cog.
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] = []
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
@commands.command()
async def stop(self, ctx):
if ctx.voice_client is not None:
return await ctx.voice_client.disconnect()
return await ctx.send("Disconnected")
else:
return await ctx.send("I am not connected to a voice channel")
@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")
else:
channel = ctx.author.voice.channel
await channel.connect()
await ctx.send(f"Connected to voice channel: '{channel}'")
@commands.command()
async def play(self, ctx, *, song=None):
if song is None:
return await ctx.send("You must include a song to play.")
if ctx.voice_client is None:
return await ctx.send("I must be in a voice channel to play a song.")
if not ("youtube.com/watch?" in song or "https://youtu.be/" in song):
await ctx.send("Searching for a song, this may take a few seconds...")
result = await self.search_song(1, song, get_url=True)
if result is None:
return await ctx.send("Sorry, I couldn't find the song you asked for. Try using my search command to find the song you want.")
song = result[0]
if ctx.voice_client.source is not None:
queue_len = len(self.song_queue[ctx.guild.id])
if queue_len < 10:
self.song_queue[ctx.guild.id].append(song)
return await ctx.send(f"Song added to the queue at position {queue_len+1}")
else:
return await ctx.send("Maximum queue limit has been reached, please wait for the current song to end to add more songs to the queue")
await self.play_song(ctx, song)
await ctx.send(f"Now playing: {song}")
@commands.command()
async def search(self, ctx, *, song=None):
if song is None:
return await ctx.send("Please include a song to search for")
await ctx.send("Searching for song, this may take a few seconds...")
info = await self.search_song(5, song)
embed = discord.Embed(title=f"Results for '{song}':", description="You can use these URL's to play the song\n", colour=discord.Colour.blue())
amount = 0
for entry in info["entries"]:
embed.description += f"[{entry['title']}]({entry['webpage_url']})\n"
amount += 1
embed.set_footer(text=f"Displaying the first {amount} results.")
await ctx.send(embed=embed)
@commands.command()
async def checkqueue(self, ctx):
if len(self.song_queue[ctx.guild.id]) == 0:
return await ctx.send("Queue is empty")
else:
embed = discord.Embed(title="Song Queue", description="", colour=discord.colour.blue())
i = 1
for url in self.song_queue[ctx.guild.id]:
embed.description += f"{i}) {url}\n"
i += 1
await ctx.send(embed=embed)
@commands.command()
async def queue(self, ctx, *, song=None):
if song is None:
return await ctx.send("You must include a song to queue.")
if not ("youtube.com/watch?" in song or "https://youtu.be/" in song):
await ctx.send("Searching for a song, this may take a few seconds...")
result = await self.search_song(1, song, get_url=True)
if result is None:
return await ctx.send("Sorry, I couldn't find the song you asked for. Try using my search command to find the song you want.")
song = result[0]
if ctx.voice_client.source is not None:
queue_len = len(self.song_queue[ctx.guild.id])
if queue_len < 10:
self.song_queue[ctx.guild.id].append(song)
return await ctx.send(f"Song added to the queue at position {queue_len+1}")
else:
return await ctx.send("Maximum queue limit has been reached, please wait for the current song to end to add more songs to the queue")
Upvotes: 1
Views: 1618
Reputation: 1318
The issue that I was having with your code was the color of the Embed. Everything else went smoothly when I ran your code. When you referenced the Colour, you didn't properly access the function.
What you did:
embed = discord.Embed(title="Song Queue",
description="",
colour=discord.colour.dark_gold())
What you should do:
embed = discord.Embed(title="Song Queue",
description="",
colour=discord.Colour.dark_gold())
Upvotes: 1