So, I am making a discord bot and recently I updated my ubuntu server. When I later tried to host the discord bot in my ubuntu server the code is returning "RuntimeWarning: coroutine 'setup' was never awaited" and I can't figure out why the code wont work after the system update. When I created the discord bot I wrote it on my windows machine and transported it over to linux and mixed some things up so that it would match linux, example the os.system("cls") on windows => os.system("clear") on linux. I can run the code on windows but not on linux. The bot gets online but doesn't responde to commands.
Some strings/comments may be in Swedish since I am Swedish and the bot too :)
ERROR MESSAGE:
Bot is starting...
/home/johan/discord/abdi/bot.py:32: RuntimeWarning: coroutine 'setup' was never awaited
cogs[i].setup(bot)
Object allocated at (most recent call last):
File "/home/johan/discord/abdi/bot.py", lineno 32
cogs[i].setup(bot)
Bot logged in as: mybotstagishere
Bot is online and ready
Logging:
|
I am using multiple code files so it can be organized;
MAIN CODE:
#Import
import discord
import tracemalloc
from discord.ext import commands
import os
from datetime import date
#Cog import
import music
import normalcommands
import events
import economy
import asyncio
#Setup
os.system("clear")
print("Bot is starting...")
intents = discord.Intents.default()
#intents = discord.Intents.all()
intents.members = True
intents.reactions = True
#case_insensitive=True sätt den i bot =>
PREFIX = "!"
TOKEN = "blablaiamnotgoingtogiveyoumytokenheheheblabla"
client = discord.Client(intents=intents)
bot = commands.Bot(command_prefix=PREFIX, intents=intents, )
cogs = [music, normalcommands, events, economy]
tracemalloc.start()
for i in range(len(cogs)):
cogs[i].setup(bot)
#Startup prints
#bot.event
async def on_ready():
print("Bot logged in as: {0.user}".format(bot))
print("Bot is online and ready")
print("Logging:")
print()
print("|")
#Logs
#bot.event
async def on_message(message):
username = str(message.author).split("#")[0]
user_message = str(message.content)
#channel = str(message.channel.name)
#Logging
if message.author == bot.user:
return
else:
fullstring = user_message
substring = PREFIX
if fullstring.find(substring) != -1:
date.today()
print(date.today())
print(f"{username}: {user_message}")
print("|")
else:
pass
await bot.process_commands(message)
#Info
#bot.command(aliases=["om", "hjälp"])
async def info(ctx):
await ctx.send(f"Vanliga kommandon:**!ping, !random (min) (max), !rickroll, !blötfis, !hogrida, !beinis (personen).** **Musik kommandon: !play (url/namn), !loop, !join, !leave, !queue, !clearqueue, !stop, !pause, !resume, !skip. På vissa av musik kommandona kan man bara ta första bokstaven, exempel !j som är !join. Ekonomi system kommer senare!**")
#Startup
bot.run(TOKEN)
MUSIC CODE:
#Import
import discord
from discord.ext import commands
import requests
from youtube_dl import YoutubeDL
from discord import FFmpegPCMAudio
import asyncio
#Inställningar
YDL_OPTIONS = {
'format': 'bestaudio/best',
'noplaylist': True,
'prostprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '256',
}]
}
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
#Variablar
#Funktioner
def search(query):
with YoutubeDL(YDL_OPTIONS) as ydl:
try:
requests.get(query)
except:
info = ydl.extract_info(f"ytsearch:{query}", download=False)['entries'][0]
else:
info = ydl.extract_info(query, download=False)
return (info, info['formats'][0]['url'])
def play_next(self,ctx):
vc = ctx.voice_client
song_queue = self.song_queue
if len(song_queue) >= 1:
query = song_queue[0]
video, source = search(query)
del song_queue[0]
vc.play(discord.FFmpegPCMAudio(source=source, **FFMPEG_OPTIONS), after=lambda e: after_song(self, ctx))
asyncio.run_coroutine_threadsafe(ctx.send(f"Nu spelas: **{video['title']}**"), self.bot.loop)
vc.is_playing()
#asyncio.run_coroutine_threadsafe(self.bot.loop)
else:
pass
def after_song(self,ctx):
if self.loop_activate == False:
try:
del self.current_song[:]
except:
pass
play_next(self,ctx)
elif self.loop_activate == True:
song_queue = self.song_queue
del song_queue[:]
query = self.current_song
video, source = search(query)
vc = ctx.voice_client
vc.play(discord.FFmpegPCMAudio(source=source, **FFMPEG_OPTIONS), after=lambda e: after_song(self,ctx))
vc.is_playing()
#Program
class music(commands.Cog):
def __init__(self, bot):
self.bot = bot
##commands.Cog.listener() / #bot.event():
##commands.command() / #bot.command():
#---------------------------------------------------
#Spel listor
song_queue = []
current_song = []
loop_activate = False
#Spela
#commands.command(aliases=["p", "spela"])
async def play(self,ctx,*,query):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
member_voice = ctx.author.voice
if member_voice and member_voice.channel:
if ctx.voice_client:
pass
else:
try:
await member_voice.channel.connect()
except:
await ctx.send("Lyckades inte joina vc! Kan ha med perms på röst kanalen.")
vc = ctx.voice_client
video, source = search(query)
self.current_song.append(video['title'])
if not vc.is_playing():
#Uppspelning
vc.play(discord.FFmpegPCMAudio(source=source, **FFMPEG_OPTIONS), after=lambda e: after_song(self,ctx))
vc.is_playing()
await ctx.send(f"Nu spelas: **{video['title']}**")
else:
self.song_queue.append(video['title'])
await ctx.send(f"**{video['title']}** har lagts till i kön!")
#Repeat
#commands.command(aliases=["upprepa", "repeat"])
async def loop(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
song_queue = self.song_queue
del song_queue[:]
if self.loop_activate == True:
self.loop_activate = False
await ctx.send("Upprepning är avstängt!")
else:
self.loop_activate = True
await ctx.send(f"Upprepning är på!")
#Join
#commands.command(aliases=["j", "joina", "gåmed"])
async def join(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
member_voice = ctx.author.voice
if member_voice and member_voice.channel:
if ctx.voice_client:
pass
else:
try:
await member_voice.channel.connect()
except:
await ctx.send("Kunde inte gå med i samtalet:cry:, kan bero på att det är privat eller att du inte sitter i något samtal! Om jag redan sitter i ett samtal så måste du dra mig till ditt samtal.")
#Visa kön
#commands.command(aliases=["kö", "visakö"])
async def queue(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
song_queue = self.song_queue
song_queue_length = len(song_queue)
song_queue_str = str(song_queue)
song_queue_str1 = song_queue_str.replace("[", "")
song_queue_str2 = song_queue_str1.replace("]", "")
song_queue_str3 = song_queue_str2.replace("'", "")
song_queue_show = song_queue_str3
if song_queue == []:
await ctx.send(f"Finns inget på kö!")
else:
await ctx.send(f"Det är {song_queue_length} låt/ar på kö! Kön ser ut såhär: **{song_queue_show}**")
#Töm kön
#commands.command(aliases=["clearqueue", "töm", "tömkön"])
async def clear(self,ctx):
song_queue = self.song_queue
del song_queue[:]
#Stoppa
#commands.command(aliases=["stop", "restart"])
async def stopp(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
self.current_song = []
self.loop_activate = False
song_queue = self.song_queue
del song_queue[:]
vc = ctx.voice_client
vc.stop()
#Lämna samtal
#commands.command(aliases=["leave", "l"])
async def lämna(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
member_voice = ctx.author.voice
if member_voice and member_voice.channel:
if ctx.voice_client:
if member_voice.channel == ctx.voice_client.channel:
try:
await ctx.voice_client.disconnect()
except:
await ctx.send("Kunde inte lämna!")
else:
await ctx.send("Du måste vara i samma samtal som mig!")
else:
pass
#Pausa
#commands.command(aliases=["pausa"])
async def pause(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
vc = ctx.voice_client
try:
vc.pause()
except:
await ctx.send("Lyckades inte pausa!")
#Fortsätt spela
#commands.command(aliases=["continue", "r", "fortsätt"])
async def resume(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
vc = ctx.voice_client
try:
vc.resume()
except:
await ctx.send("Lyckades inte fortsätta spela upp!")
#Skippa
#commands.command(aliases=["s", "hoppa", "skip"])
async def skippa(self,ctx):
emoji = '\N{THUMBS UP SIGN}'
await ctx.message.add_reaction(emoji)
vc = ctx.voice_client
try:
vc.stop()
except:
await ctx.send("Kunde inte skippa!")
#Add cog
async def setup(bot):
await bot.add_cog(music(bot))
Your setup function in your separate modules like music is an async function, and if you notice in line 32 cogs[i].setup(bot) is not awaited where you're calling it in the loop. In order to await in the iteration, you may use a wait wrapper around a list of tasks containing your setup calls.
def init_configs(bot):
loop = asyncio.get_event_loop()
tasks = [config.setup(bot) for config in cogs]
loop.run_until_complete(asyncio.wait(tasks))
init_configs(bot)
# ...
Or if you want to use async/await:
import asyncio
async def init_configs(bot):
tasks = [config.setup(bot) for config in cogs]
await asyncio.wait(tasks)
import asyncio
# ...
async def main():
await init_configs(bot)
# All the bot codes like:
#bot.event
async def on_message(message):
# ...
asyncio.run(main())
Related
I making discord music bot and use wavelink library.
I write this code:
#commands.Cog.listener()
async def on_wavelink_track_end(player: wavelink.Player, track: wavelink.Track):
ctx = player.ctx
vc: player = ctx.voice_client
if vc.loop:
return await vc.play(track)
next_song = vc.queue.get()
await vc.play(next_song)
await ctx.send(f"Сейчас играет {next_song.title}")
#commands.command()
async def play(self,ctx: commands.Context, *, search: wavelink.YouTubeTrack):
if not ctx.author.voice:
return await ctx.send("Ты не в голосовом канале!", delete_after = 10)
if not ctx.voice_client:
vc: wavelink.Player = await ctx.author.voice.channel.connect(cls = wavelink.Player)
else:
vc: wavelink.Player = ctx.voice_client
if vc.queue.is_empty and vc.is_playing:
await vc.play(search)
m = search.duration/60
await ctx.send(f"Сейчас играет `{search.title}` продолжительностью `{round(m, 2)}` минут")
else:
await vc.queue.put_wait(search)
await ctx.send(f"Добавлен {search.title} трек в очередь")
vc.ctx = ctx
setattr(vc, "loop", False)
And also I got this error
TypeError: Music.on_wavelink_track_end() got multiple values for argument 'track'
Another commands works properly, but play command do not append to wavelink queue and just play new song if we type play again.
Any ideas?
#commands.Cog.listener()
async def on_wavelink_track_end(player: wavelink.Player, track: wavelink.Track):
#You need to pass in `self` to here ⤴
So your code will look like this
#commands.Cog.listener()
async def on_wavelink_track_end(self, player: wavelink.Player, track: wavelink.Track):
ctx = player.ctx
vc: player = ctx.voice_client
if vc.loop:
return await vc.play(track)
next_song = vc.queue.get()
await vc.play(next_song)
await ctx.send(f"Сейчас играет {next_song.title}")
#commands.command()
async def play(self,ctx: commands.Context, *, search: wavelink.YouTubeTrack):
if not ctx.author.voice:
return await ctx.send("Ты не в голосовом канале!", delete_after = 10)
if not ctx.voice_client:
vc: wavelink.Player = await ctx.author.voice.channel.connect(cls = wavelink.Player)
else:
vc: wavelink.Player = ctx.voice_client
if vc.queue.is_empty and vc.is_playing:
await vc.play(search)
m = search.duration/60
await ctx.send(f"Сейчас играет `{search.title}` продолжительностью `{round(m, 2)}` минут")
else:
await vc.queue.put_wait(search)
await ctx.send(f"Добавлен {search.title} трек в очередь")
vc.ctx = ctx
setattr(vc, "loop", False)
This is probably it.
• Sxviaat
simply add self
async def on_wavelink_track_end(self , player: wavelink.Player, track: wavelink.Track)
#client.command()
async def play(ctx, *, url = None):
if ctx.author.voice is None:
msg = await ctx.send("You are not in a voice channel.")
await msg.delete(delay = 3)
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)
search_keyword = url
if not ("youtube.com/watch?" in search_keyword):
search_keyword = search_keyword.replace(" ", "+")
html = urllib.request.urlopen(f"https://www.youtube.com/results?search_query={search_keyword}")
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
url = str(f"https://www.youtube.com/watch?v={video_ids[0]}")
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
title = info.get('title', None)
length = info['duration']
url2 = info["formats"][0]["url"]
source = await discord. FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
vc.play(source)
embed = discord.Embed(title = "Currently Playing", colour = discord.Colour.blue())
embed.add_field(name = "Song", value = title, inline = False)
embed.add_field(name = "Length", value = str(datetime.timedelta(seconds = length)), inline = False)
embed.add_field(name = "Link", value = url, inline = False)
msg = await ctx.send(embed=embed)
await msg.add_reaction("\u23F8")
await msg.add_reaction("\u25B6")
await msg.add_reaction("\u23F9")
while True:
try:
reaction, user = await client.wait_for("reaction_add", check=lambda reaction, user: user.id == ctx.author.id and reaction.message.id == msg.id and reaction.emoji in ["\u23F8", "\u25B6", "\u23F9"], timeout = length)
except asyncio.TimeoutError:
return await msg.clear_reactions()
async def process():
if reaction.emoji == "\u23F8":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.pause()
elif reaction.emoji == "\u25B6":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.resume()
elif reaction.emoji == "\u23F9":
await msg.remove_reaction(reaction.emoji, ctx.author)
ctx.voice_client.stop()
asyncio.create_task(process())
Here's the code for my play command. Right now if the command is invoked while a song is playing, then that song stops and the newly requested one begins, this is because of the ctx.voice_client.stop() before the song is downloaded. However, I'm trying to implement a queue system where if the command is invoked while another song is playing it will be added to queue, and songs in the queue will be played right after the current song ends. Currently my idea of how to do this would be to replace the ctx.voice_client.stop() with an if statement that checks the status of the bot, if it is currently playing or not, and either appends it it to a global list variable containing the current queue or plays the song. But I am clueless on how to make it play the queue one after another and implement a skip command. Another complicated part would be to implement the skip command into a reaction similar to how I've implemented the pause and play commands. I don't now if my idea will work, so any input is appreciated.
first you need to creat a empty queue outside your command
queues = {}
and a funtion to check if there's a song in queues it will play that song
#check queue
queues = {}
def check_queue(ctx, id):
if queues[id] !={}:
voice = ctx.guild.voice_client
source = queues[id].pop(0)
voice.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))
and inside play command create a funtion to add the next song to queue if a song is already being played and add the check queue funtion
if voice.is_playing():
guild_id = ctx.message.guild.id
if guild_id in queues:
queues[guild_id].append(source)
else:
queues[guild_id] = [source]
else:
vc.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))
You can check out my code here if u need more help Need help Discord bot queue
I was just adding some extra code to my discord bot to play youtube music, but then i go to run the bot and it starts as normal and works, but then when i go to test the new commands nothing works, no errors or anything, then i try the basic commands like /hello that was working fine before and that also is not doing anything. The bot as Administration role.
Ive double checked Iam not spelling commands wrong, but even if I was the on_command_error function should call. Also i did a print debug statement at the start of the /play command and not even that gets called, and I havent changed anything major. Anyone have any ideas?
from discord.ext import commands
from dotenv import load_dotenv
from lxml import html
import youtube_dl
import requests
import random
import discord
import requests
import shutil,os
# Load .env file
load_dotenv()
PREFIX = "/"
bot = commands.Bot(command_prefix=PREFIX)
# EVENTS #
#bot.event
async def on_ready():
await bot.get_channel(888736019590053898).send(f"We back online! All thanks to *sploosh* :D")
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
replies = ["Err is that even a command?", "Can you type bro?", "Yeah... thats not a command buddy.", "Sorry forgot you can't spell"]
await ctx.send(random.choice(replies))
#bot.event
async def on_message(message):
if str(message.channel) == "images-videos" and message.content != "":
await message.channel.purge(limit=1)
# COMMANDS #
#bot.command()
async def hello(ctx):
# Get a random fact
url = 'http://randomfactgenerator.net/'
page = requests.get(url)
tree = html.fromstring(page.content)
hr = str(tree.xpath('/html/body/div/div[4]/div[2]/text()'))
await ctx.reply("**Hello Bozo!**\n" + "*Random Fact : *" + hr[:-9]+"]")
#bot.command()
async def randomNum(ctx, start:int = None, end:int = None):
if(start == None or end == None):
await ctx.reply("*Check your arguments!*\n```/randomNum START_NUMBER END_NUMBER```")
else:
randNum = random.randint(start, end)
await ctx.reply(f"*{randNum}*")
#bot.command()
#commands.is_owner()
async def kick(ctx, member:discord.Member = None, *, reason="You smell bozo."):
if(member == None):
await ctx.reply("*Check your arguments!*\n```/kick #MEMBER REASON(optional)```")
elif ctx.author.id in (member.id, bot.user.id):
await ctx.reply("*You cant kick yourself/me you silly.*")
else:
await member.kick(reason=reason)
#bot.command()
#commands.is_owner()
async def ban(ctx, member:discord.Member = None, *, reason="Bye Bye! :D."):
if(member == None):
await ctx.reply("*Check your arguments!*\n```/kick #MEMBER REASON(optional)```")
elif ctx.author.id in (member.id, bot.user.id):
await ctx.reply("*You cant ban yourself/me you silly.*")
else:
await member.ban(reason=reason)
#bot.command()
#commands.is_owner()
async def close_bot(ctx):
replies = ["Well bye!", "Guess I go now?", "Please let me stay..."]
await ctx.send(random.choice(replies))
await bot.close()
# YOUTUBE AUDIO PLAYER
#bot.command()
async def play(ctx, url : str):
print("WORKING")
if(url == None):
await ctx.reply("*Check your arguments!*\n```/play VIDEO_URL```")
else:
song = os.path.isfile("songs/song.mp3")
try: # Check if song exists if so remove it
if(song):
os.remove("songs/song.mp3")
except PermissionError:
await ctx.reply("*Wait for current song to end, or use 'stop' command*")
return
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name="Lounge")
await voiceChannel.connect()
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
ytdl_opts = { # Some options you need to pass in
'format': 'bestaudio/best',
'postprocessors':[{
'key':'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192'
}],
}
with youtube_dl.YoutubeDL(ytdl_opts) as ydl:
ydl.download(url) # Download the vid
for file in os.listdir("./"): # Change the name and move to songs folder
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
shutil.move("song.mp3", "songs")
voice.play(discord.FFmpegPCMAudio(source="songs/song.mp3")) # Play the song
#bot.command()
async def leave(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_connected()):
voice.disconnect()
else:
await ctx.reply("*How can I leave a voice channel if I'am not connected?*")
#bot.command()
async def pause(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_playing()):
voice.pause()
else:
await ctx.reply("*Can't pause buddy, nothings playing...*")
#bot.command()
async def resume(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_paused()):
voice.resume()
else:
await ctx.reply("*Can't resume buddy, audio is already playing*")
#bot.command()
async def stop(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
voice.stop()
if __name__ == "__main__":
bot.run(os.getenv("BOT_TOKEN"))
You need to have bot.process_commands(message) inside your custom on_message events,
#bot.event
async def on_message(message):
if str(message.channel) == "images-videos" and message.content != "":
await message.delete()
await bot.process_commands(message)
I've also changed message.channel.purge(limit=1) to message.delete() because it's the proper way of deleting a message
For more info as to why this is required, see the faq
I kinda made this working music bot code, it join vc and play the song. But when its in voice it wont play another one, i need to disconnect him. I want that he play next song even if he is joined. How to do it?
code(part where i want the thing):
#bot.command()
async def hraj(ctx, url):
if not ctx.message.author.voice:
await ctx.send("Musíš být ve voicu ty pepego!")
return
else:
channel = ctx.message.author.voice.channel
await channel.connect()
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(url, loop=bot.loop)
voice_channel.play(player, after=lambda e: print("Error. %s" %e if e else None))
e = discord.Embed(title="Právě hraje:", description=f"[{player.title}]({url})", color=0x0091ff)
e.set_footer(text="Lets go jdem vibovat <333")
await ctx.send(embed=e)
You could use
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice == None:
channel = ctx.message.author.voice.channel
This works because discord.utils.get(client.voice_clients, guild=ctx.guild) returns None if your bot isn't in a voice channel.
So your code would be:
#bot.command()
async def hraj(ctx, url):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice == None:
channel = ctx.message.author.voice.channel
else:
await ctx.send('Musíš být ve voicu' ty pepego)
await channel.connect()
server = ctx.message.guild
voice_channel = server.voice_client
async with ctx.typing():
player = await YTDLSource.from_url(url, loop=bot.loop)
voice_channel.play(player, after=lambda e: print("Error. %s" %e if e else None))
e = discord.Embed(title="Právě hraje:", description=f"[{player.title}]({url})", color=0x0091ff)
e.set_footer(text="Lets go jdem vibovat <333")
await ctx.send(embed=e)
Your question wasn't very clear btw.
I have this as my music class to make my bot play music
class Music(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.bot.music = lavalink.Client(self.bot.user.id)
self.bot.music.add_node("localhost", 7000, 'server-utils', 'eu', 'music-node')
self.bot.add_listener(self.bot.music.voice_update_handler, 'on_socket_response')
self.bot.music.add_event_hook(self.track_hook)
#commands.command(name="music")
async def music(self, ctx, opt, *, arg=None):
if opt == "join":
print(f"music join command worked")
member = discord.utils.find(lambda m: m.id == ctx.author.id, ctx.guild.members)
if member is not None and member.voice is not None:
vc = member.voice.channel
player = self.bot.music.player_manager.create(ctx.guild.id, endpoint=str(ctx.guild.region))
if not player.is_connected:
player.store('channel', ctx.guild.id)
await self.connect_to(ctx.guild.id, str(vc.id))
if opt == "play" and arg is not None:
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
query = f'ytsearch:{arg}'
results = await player.node.get_tracks(query)
tracks = results['tracks'][0:10]
i = 0
query_result = ''
for track in tracks:
i = i + 1
query_result = query_result + f'{i}) {track["info"]["title"]}\n'
embed = discord.Embed()
embed.description = query_result
await ctx.channel.send(embed=embed)
def check(m):
return m.author.id == ctx.author.id
reponse = await self.bot.wait_for('message', check=check)
track = tracks[int(reponse.content)-1]
player.add(requester=ctx.author.id, track=track)
if not player.is_playing:
await player.play()
except Exception as error:
print(error)
if opt == "stop":
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
except Exception as error:
print(error)
if opt == "leave":
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
await self.disconnect_from(ctx.guild.id)
async def track_hook(self, event):
if isinstance(event, lavalink.events.QueueEndEvent):
guild_id = int(event.player.guild_id)
await self.connect_to(guild_id, None)
async def connect_to(self, guild_id: int, channel_id: int):
ws = self.bot._connection._get_websocket(guild_id)
await ws.voice_state(str(guild_id), channel_id)
async def disconnect_from(self, guild_id: int):
ws = self.bot._connection.voice_clients
print(ws)
def setup(bot):
bot.add_cog(Music(bot))
Everythink works fine except the part to disconnect from the channel he is connected to... I've tried lots of things and can't figure out how to make it disconnect..
Ps: Here the command doesn't do anything but to print a list where I hoped there would be the bot connect, but it had nothing there
I believe it's because you're passing the guild id as opposed to the voice channels id, for example.
You're in the guild; Hello World with an ID of 12345
You're in the guilds voice channel of; Hello World voice channel which has an id of 6789.
so you're trying to use the guild.id as opposed to the voice channel id. Does this make sense?
Can't you do await ctx.voice_client.disconnect()
if opt == "leave":
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
await ctx.voice_client.disconnect()
I did a disconnect command on my Discord bot using VoiceClient.disconnect(). I got some trouble with it in my first approach because the connect command generated the VoiceClient object, but disconnect command could not use it since it was a local variable on the other command, so i just made it global and it works
#commands.command()
async def enter(self, ctx):
try:
canal = ctx.author.voice.channel
global voice_client
voice_client = await canal.connect()
except AttributeError:
await ctx.send("Você precisa estar conectado a um canal de voz")
except discord.errors.ClientException:
await ctx.send("Eu já estou conectado ao seu canal de voz")
#commands.command()
async def leave(self, ctx):
try:
await voice_client.disconnect()
except NameError:
await ctx.send("Eu não estou conectado a nenhum canal de voz :worried:")
The full music cog that I coded:
https://github.com/Voz-bonita/Discord-Bot/blob/master/Music%20extension.py