I am coding a discord bot that to use will require lots of commands, so it clogs up a channel pretty quickly. Here is some example code that in theory should work.
#commands.command()
async def play(self,ctx,url):
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -
reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format':"bestaudio"}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(url2,
**FFMPEG_OPTIONS)
vc.play(source)
await ctx.message.delete()
This example works, however this one sometimes works but sometimes doesn't and I have no idea why.
#commands.command()
async def join(self,ctx):
await ctx.message.delete()
if ctx.author.voice is None:
await ctx.send("You are not in a voice channel.")
voice_channel = ctx.author.voice.channel
if ctx.voice_client is None:
await voice_channel.connect()
else:
await ctx.voice_client.move_to(voice_channel)
I am really confused as to why it doesn't work, all I want it to do is delete the previous message so it doesn't block up channels.
Discord.Py has a delete_after kwarg that takes the amount of seconds to delete the sent message after, for example
await channel.send("this message will be deleted after 10 seconds", delete_after=10)
You can use this arg in any ctx.send message so it will auto delete after a specific amount of time.
Related
THIS QUESTION HAS BEEN SOLVED BY FURAS IN THE COMMENTS.
So I was following this tutorial on how to create a discord music bot like Rythm using discord.py. I had troubleshooted my code and fixed a few errors to do with coroutine.
EDIT: I have called the r function and now get this error upon running the code:
main.py:15: RuntimeWarning: coroutine 'r' was never awaited
r()
When I run the code everything boots up successfully until I try to use a command. If I put '#join' in the chat it should have joined the voice chat or said "You're not in a voice channel!". Instead I get this error:
2022-09-02 20:07:08 ERROR discord.ext.commands.bot Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "join" is not found
I have tried swapping out #commands.command for #client.command (whilst also defining client in music.py) but more of the same. Any help would be much appreciated.
I have two files, main.py and music.py.
MAIN.PY
import discord
from discord.ext import commands
import music
cogs = [music]
client = commands.Bot(command_prefix='#', intents=discord.Intents.all())
async def r():
for i in range(len(cogs)):
await cogs[i].setup(client)
r()
client.run(
"my token")
MUSIC.PY
import discord
from discord.ext import commands
import youtube_dl
class music(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
async def join(self, ctx):
if ctx.author.voice is None:
await ctx.send("You're not in a voice channel!")
voice_channel = ctx.author.voice.channel
if ctx.voice_client is None:
await voice_channel.connect()
else:
await ctx.voice_client.move_to(voice_channel)
#commands.command()
async def disconnect(self, ctx):
await ctx.voice_client.disconnect()
#commands.command()
async def play(self, ctx, url):
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -
reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format': "bestaudio"}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(
url2, **FFMPEG_OPTIONS)
vc.play(source)
#commands.command()
async def pause(self, ctx):
await ctx.voice_client.pause()
await ctx.send("Paused")
#commands.command()
async def resume(self, ctx):
await ctx.voice_client.resume()
await ctx.send("Resumed")
async def setup(client):
await client.add_cog(music(client))
When you define async function like async def r() then you would have to run it await r(). Problem is that you can't run await outside functions. You would have to run it in some async function - but it make the same problem with running this async function.
You may try to run it in event on_ready() which is async function.
#client.event
async def on_ready():
for item in cogs:
await item.setup(client)
I am trying to code a discord music bot but i am getting errors.
Discord.py library doesn't work for me.
The errors like "discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'stop'."
These type error for almost every attribute for voice_client. Can someone correct my code. Because i can't see my fault.
My Code is (in music.py);
import discord
from discord.ext import commands
import youtube_dl
import ffmpeg
class music(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
async def join(self, ctx):
if ctx.author.voice is None:
await ctx.send("Ses kanalına gir")
voice_channel = ctx.author.voice.channel
if ctx.voice_client is None:
await voice_channel.connect()
else:
await ctx.voice_client.move_to(voice_channel)
#commands.command()
async def disconnect(self, ctx):
await ctx.voice_client.disconnect()
#commands.command()
async def play(self, ctx, url):
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -
reconnect_delay_max 5',
'options': '-vn'}
YDL_OPTIONS = {'format': "bestaudio"}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
vc.play(source)
#commands.command()
async def pause(self, ctx):
await ctx.voice_client.pause()
await ctx.send("paused")
#commands.command()
async def resume(self, ctx):
await ctx.voice_client.resume()
await ctx.send("resumed")
def setup(client):
client.add_cog(music(client))
My code is (in main.py);
import discord
from discord.ext import commands
import music
cogs = [music]
client = commands.Bot(command_prefix='?', intents = discord.Intents.all())
for i in range(len(cogs)):
cogs[i].setup(client)
client.run("My_Token")
ctx.voice_client doesn't have the stop property.
Solutions:
Either CTX or ctx.voice_client is None
Or, voice_client doesn't have the stop() function.
I'm trying to code a simple music bot with discord.py following a tutorial. However when I use '<play' it shows me this error: AttributeError: 'NoneType' object has no attribute 'stop'. Please help, thank you.
async def play(self,ctx,url):
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format':"bestaudio"}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
vc.play(source)
ctx.voice_client can be None if the bot is not connected to any voice channel. In that case, you can't use stop(). You can prevent this by implementing a check.
#commands.command()
async def play(self, ctx, url):
if ctx.voice_client is None:
# bot is not connected to a voice channel
await ctx.author.voice.channel.connect()
else:
# bot is already connected to a voice channel
I would also implement a statement to check to see if the user is connected to any voice channel.
if ctx.author.voice is None:
await ctx.send("You are not connected to any voice channel!")
else:
# user is connected to a voice channel
My music bot built with hikari is unable to join. I have copied the code that I had used from discord.py. It worked properly on discord.py but wont work on hikari for some reason.
Here's the code:
#bot.command
#lightbulb.command('join', 'Makes bot join a voice channel')
#lightbulb.implements(lightbulb.PrefixCommand)
async def join(ctx):
try:
channel = ctx.message.author.voice.channel
await channel.connect()
await ctx.respond("I\'m in")
except:
await ctx.respond("You need to be connected to a voice channel in order for me to join")
#bot.command
#lightbulb.command('play', 'Plays track in connected voice channel')
#lightbulb.implements(lightbulb.PrefixCommand)
async def play(ctx, q: str):
YDL_OPTIONS = {'default_search': 'auto', 'format': 'bestaudio', 'noplaylist':'True'}
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
voice = ctx.message.guild.voice_client
with YoutubeDL(YDL_OPTIONS) as ydl:
try:
info = ydl.extract_info(q, download=False)
a = info['entries'][0]['formats'][0]['url']
queue.append(a)
if voice.is_playing():
await ctx.respond('I have queued the track')
else:
idk = queue[0]
queue.pop(0)
voice.play(FFmpegPCMAudio(idk, **FFMPEG_OPTIONS))
except:
info = ydl.extract_info(q, download=False)
a = info['url']
queue.append(a)
if voice.is_playing():
await ctx.respond('I have queued the track')
elif len(queue)==0:
idk = queue[0]
voice.play(FFmpegPCMAudio(idk, **FFMPEG_OPTIONS))
else:
idk = queue[0]
queue.pop(0)
voice.play(FFmpegPCMAudio(idk, **FFMPEG_OPTIONS))
Your command implementation is not the way that Lightbulb handles commands. Command arguments are not passed as arguments to the callback function, they are accessed via ctx.options.your_option_here.
Reference: The option decorator
Example command that accepts an argument:
#bot.command
#lightbulb.option("q", "The track to play.")
#lightbulb.command("play", "Plays track in connected voice channel.")
#lightbulb.implements(lightbulb.PrefixCommand)
async def play(ctx: lightbulb.Context) -> None:
await ctx.respond(f"The song you want to play is {ctx.options.q}!")
Many of the attributes/methods you are using like ctx.message.guild.voice_client, ctx.message.author.voice.channel, and await channel.connect() just do not exist in Hikari.
You can't transfer your discord.py code over 1:1.Hikari does implement the discord voice API, however you will need to read the documentation.
Connecting to a voice channel:
await bot.update_voice_state(ctx.guild_id, channel_id)
Disconnecting from a voice channel:
await bot.update_voice_state(ctx.guild_id, None)
I´m trying to connect my bot to a voice channel and tried every solution I could find online, nothing works though.
When I call await channel.connect() the program just hangs and doesn´t do anything
Code Snippet:
#commands.command()
async def join(self, ctx):
if not ctx.message.author.voice:
ctx.send("You are not in a voice channel")
else:
channel = ctx.message.author.voice.voice_channel
await channel.connect()
Firstly, you didn't await ctx.send, second of all discord.VoiceState has no attribute voice_channel, it's channel.
Here's the fixed code:
#commands.command()
async def join(self, ctx):
if not ctx.author.voice:
await ctx.send("You are not in a voice channel")
else:
channel = ctx.author.voice.channel
await channel.connect()
reference
According to this docs
I think you need to changes
ctx.message.author.voice.voice_channel into ctx.message.author.voice.channel