Discord bot leave and play again something error - discord

I have a problem. This discord bot can join, play music, pause resune and leave. When i run the bot it can play songs but when i tell him to leave, join again and play something i get this error: discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ClientException: Not connected to voice.
music = DiscordUtils.Music()
#client.command(pass_context = True)
async def play(ctx,*,url):
player = music.get_player(guild_id = ctx.guild.id)
if not player:
player = music.create_player(ctx, ffmpeg_error_betterfix = True)
if not ctx.voice_client.is_playing():
await player.queue(url, search = True)
song = await player.play()
else:
song = await player.queue(url, search = True)
#client.command(pass_context = True)
async def pause(ctx):
player = music.get_player(guild_id = ctx.guild.id)
song = await player.pause()
#client.command(pass_context = True)
async def join(ctx):
channel = ctx.message.author.voice.channel
voice = await channel.connect()
#client.command(pass_context = True)
async def resume(ctx):
player = music.get_player(guild_id = ctx.guild.id)
song = await player.resume()
#client.command(pass_context = True)
async def queue(ctx):
player = music.get_player(guild_id = ctx.guild.id)
#client.command(pass_context = True)
async def leave(ctx):
await ctx.voice_client.disconnect()

Related

Bot won't play next song automatically, when the last one ends

I created a simple Music Bot, but there is one problem. When I run the "?play" Command, the Youtube Link is actually playing. Also, if I run the "?play" Command a second time, the link has been safed in the array. So when I run the "?skip" Command, the next YouTube Link has been shown, but if I do the same thing, just without the "?skip" Command, the Bot won't play the new Link automatically, after the first Link ended. Can someone help me please?
import discord
import asyncio
from discord.ext import commands
import youtube_dl
client = commands.Bot(intents=discord.Intents.all(), command_prefix="?", help_command=None)
voice_clients = {}
yt_dl_opts = {'format': 'bestaudio/best'}
ytdl = youtube_dl.YoutubeDL(yt_dl_opts)
ffmpeg_options = {'options': "-vn"}
queue = []
async def play_next(guild_id):
try:
url = queue[0]
loop = asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=False))
song = data['url']
player = discord.FFmpegPCMAudio(song, **ffmpeg_options)
voice_clients[guild_id].play(player)
asyncio.ensure_future(play_next(guild_id))
except Exception as err:
print(err)
#client.command()
async def play(ctx, url: str = None):
print(queue)
if url == None:
await ctx.send("Ich brauche schon irgend ein Link")
return
try:
voice_client = await ctx.author.voice.channel.connect()
voice_clients[voice_client.guild.id] = voice_client
except:
print("Bot ist schon im Voice")
url = url
queue.append(url)
if len(queue) == 1:
await play_next(ctx.guild.id)
else:
await ctx.send("Dein Link wurde erfolgreich in die Warteschlange hinzugefügt!")
print(queue)
#client.command()
async def skip(ctx):
try:
voice_clients[ctx.guild.id].stop()
except Exception as err:
print(err)
queue.pop(0)
if len(queue) >= 1:
await play_next(ctx.guild.id)
else:
await ctx.reply("Es gibt nix abzuspielen")

(CLOSED) Bot doesnt send anything, and doesnt give an error

I have this code:
#rob
#client.command()
#commands.cooldown(1,10800,commands.BucketType.user)
async def rob(ctx,member:discord.User = None):
if member == None:
em = discord.Embed(title='ERROR:', description='Please specify a member you want to rob!', color=0xff0000)
await ctx.send(embed = em)
return
await open_account(ctx.author)
await open_account(member)
bal = await update_bank(member)
if bal[0]<50:
em = discord.Embed(title='ERROR:', description="The member you try to rob doesn't have that much money!", color=0xff0000)
await ctx.send(embed = em)
return
if amount<0:
em = discord.Embed(title='ERROR:', description="Amount must be positive!", color=0xff0000)
await ctx.send(embed = em)
return
earnings = random.randrange(0, bal[100])
fine = random.randrange(0, bal[100])
em1 = discord.Embed(title='Succesfully robbed!', description=f"You robbed {earnings} coins!", color=0x00ff00)
em2 = discord.Embed(title='Caught!', description=f"You got caught! You paid a {fine} coins fine! ", color=0x00ff00)
yesorno = random.randrange(0, 1)
if yesorno == 1:
await ctx.send(embed = em1)
await update_bank(ctx.author,earnings)
await update_bank(member,-1*earnings)
else:
await ctx.send(embed = em2)
await update_bank(ctx.author,-1*fine)
This function's goal is to rob someone and take their money or give them a fine, but it doesn't work. It doesn't send em1 or em2, I don't know how to fix it. I tried many things, but it doesn't give an error!
What fixed it for me was changing the yesorno function. Changed it to:
yesorno = random.randrange(0, 2)
if yesorno == 1:
await ctx.send(embed = em1)
await update_bank(ctx.author,1*earnings)
await update_bank(member,-1*earnings)
else:
await ctx.send(embed = em2)
await update_bank(ctx.author,-1*fine)
await update_bank(member,1*fine)

Discord.py snipe command is sniping messages from other channels

I recently made a snipe command for my discord bot but I have one problem. Snipe command snipes a message from other channels when I for example want to snipe a message in general. Here is my code:
#bot.event
async def on_message_delete(message):
if message.attachments:
bob = message.attachments[0]
bot.sniped_messages[message.guild.id] = (bob.proxy_url, message.content, message.author, message.channel.name, message.created_at)
else:
bot.sniped_messages[message.guild.id] = (message.content,message.author, message.channel.name, message.created_at)
#bot.command(aliases=['s'])
async def snipe(ctx):
try:
bob_proxy_url, contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
except:
contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
try:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_image(url=bob_proxy_url)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
except:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
snipe_message_author = {}
snipe_message_content = {}
#client.event
async def on_message_delete(message):
snipe_message_author[message.channel.id] = message.author
snipe_message_content[message.channel.id] = message.content
#client.command(name = 'snipe')
async def snipe(ctx):
channel = ctx.channel
try:
em = discord.Embed(description = f"`{snipe_message_content[channel.id]}`\nMessage sent by {snipe_message_author[channel.id]}!", color = 0x00c230)
em.set_author(name = f"Last deleted message in #{channel.name}")
em.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
em.set_footer(text = f"Snipe requested by {ctx.message.author}")
await ctx.send(embed = em)
except:
embed = discord.Embed(colour = 0x00c230)
embed.set_author(name=f"There are no deleted messages in #{ctx.channel}!")
embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
embed.set_footer(text=f"Snipe requested by {ctx.message.author}")
await ctx.channel.send(embed=embed)
Thats what I use and it works properly.
Since I added [message.channel.id] to the variables it only checks for snipes in that channel. This is how it looks like in Discord

When I use the play command on my discord bot nothing happens

I am new to using discord.py but have experience using python. I am currently working on a discord music bot using discord.py and when I use the command "*play (song name)" nothing happens even though the bot is in the VC. I want the bot to be able to search youtube for the user's request and play it like any other music bot on discord like Rythum or Groovy. Any other suggestions you have for the code would be greatly appreciated as well. Thanks!
here is my code:
import discord
from discord.ext import commands, tasks
import youtube_dl
import asyncio
from random import choice
client = commands.Bot(command_prefix='*')
queue=[]
status = '18 Naked Cowboys'
#client.event
async def on_ready():
print("Rancher is online!")
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching,name=status))
#client.command(name='ping',help='This command will show that my ping is superior than yours!')
async def ping(ctx):
await ctx.send(f'**Pong!** Latency: {round(client.latency * 1000)}ms')
#client.command(name='hello',help='This command returns a random the welcome message!')
async def hello(ctx):
responses = ['***grumble*** Why you wake me up?!','Penis']
await ctx.send(choice(responses))
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
#client.command(name='join', help='This command makes the bot join the voice channel')
async def join(ctx):
if not ctx.message.author.voice:
await ctx.send("You are not connected to a voice channel")
return
else:
channel = ctx.message.author.voice.channel
await channel.connect()
#client.command(name='queue', help='This command adds a song to the queue')
async def queue_(ctx, url):
global queue
queue.append(url)
await ctx.send(f'`{url}` added to queue!')
#client.command(name='remove', help='This command removes an item from the list')
async def remove(ctx, number):
global queue
try:
del(queue[int(number)])
await ctx.send(f'Your queue is now `{queue}!`')
except:
await ctx.send('Your queue is either **empty** or the index is **out of range**')
#client.command(name='play', help='This command plays songs')
async def play(ctx):
global queue
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(queue[0], loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('**Now playing:** {}'.format(player.title))
del(queue[0])
#client.command(name='pause', help='This command pauses the song')
async def pause(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.pause()
#client.command(name='resume', help='This command resumes the song!')
async def resume(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.resume()
#client.command(name='view', help='This command shows the queue')
async def view(ctx):
await ctx.send(f'Your queue is now `{queue}!`')
#client.command(name='leave', help='This command stops makes the bot leave the voice channel')
async def leave(ctx):
voice_client = ctx.message.guild.voice_client
await voice_client.disconnect()
#client.command(name='stop', help='This command stops the song!')
async def stop(ctx):
server = ctx.message.guild
voice_channel = server.voice_client
voice_channel.stop()
client.run('')
You haven't assign anything to queue list. So you might need to modify play function a bit and append the url from user input to your queue. Here is an example of what the user will input *play https://youtube.com/watch?v=abcdefghij. And here's the code:
#client.command(name='play', help='This command plays songs')
async def play(ctx, *, search_url):
global queue
queue.append(search_url)
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(queue[0], loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('**Now playing:** {}'.format(player.title))
del(queue[0])

Poll question which adds the correct amount of reactions. (d.py)

I am trying to make a poll command which adds the correct amount of reactions such as A B C D E etc.
I have already tried this but it was a simple yes or no poll command.
elif message.content.startswith('m/qpoll'):
question = message[8:]
await message.delete()
message = await message.channel.send(f"**New poll:** {question}")
await message.add_reaction('❌')
await message.add_reaction('✔️')
What i am trying to achieve is a command which adds A B C reactions if there is three possible answers and A B C D E if there is five possible answers etc.
The command the user has to use is preferred to be in this format:
m/poll "question" "answer 1" "answer 2" "answer 3"
The command needs to be under a on_message statement as the command package does not work as well for my bot.
A simple way to do it, without using discord.ext.commands :
elif message.content.startswith('m/qpoll'):
content = message.content[8:]
items = content.split(" ")
question = items[0]
answers = '\n'.join(items[1:])
await message.delete()
message = await message.channel.send(f"**New poll:** {question}\n{answers}")
reactions = ['A', 'B', 'C', 'D', 'E'] #replace the letters with your reactions
for i in range(len(items[1:]))
await message.add_reaction(reactions[i])
Here's the poll command I made for my bot
#commands.command()
async def poll(self, ctx):
"""
Conduct a poll (interactive)
?poll
"""
member = ctx.author
member: Member
maker = []
await ctx.send("```What is the Question ❓```")
em = ["🧪", "🧬", "🚀", "🖌️", "🧨"]
def mcheck(m):
return m.author == member
try:
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
maker.append(msg.content)
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
await ctx.send("```How many options do you want?```")
try:
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
i = int(msg.content)
if i > 5:
return await ctx.send("```A maximum of 5 options for polls```")
await ctx.send("```Enter your options ✔```")
for i in range(i):
try:
await ctx.send(f"```{i + 1}) ```")
msg = await self.bot.wait_for('message', timeout=20.0, check=mcheck)
maker.append(msg.content)
await msg.add_reaction("✅")
except TimeoutError:
return await ctx.send("```Poll timed out ⏳```")
poller = Embed(color=0x5EE34)
poller.title = maker[0]
des = ''
for j in range(1, len(maker)):
des += f"```{em[j - 1]} {maker[j]}```\n"
poller.description = des
pr = await ctx.send(embed=poller)
for j in range(i + 1):
await pr.add_reaction(em[j])
def reac_check(r, u):
return pr.id == r.message.id and r.emoji in em
eopt = {e: 0 for e in em}
while True:
try:
reaction, user = await self.bot.wait_for('reaction_add', timeout=20.0, check=reac_check)
e = str(reaction.emoji)
except TimeoutError:
await ctx.send("```Poll Finished ✅```")
break
if e in eopt.keys() and user != self.bot.user:
eopt[e] += 1
eopt = {k: v for k, v in sorted(eopt.items(), key=lambda item: item[1], reverse=True)}
most = next(iter(eopt))
loc = em.index(most)
poller.title = "Results 🏆"
poller.description = f"```Folks chose 📜\n{maker[loc + 1]}```"
return await ctx.send(embed=poller)
As a rule of thumb avoid using on_message to create commands. You can read about commands.Bot() in the docs.
That said you should be able adapt the above example to suit your needs.

Resources