Python discord bot leave voice channel - python

I've made bot to join my voice server like below
if message.content.startswith("?join"):
channel = message.author.voice.channel
await channel.connect()
await message.channel.send('bot joined')
but i can't make bot to leave the channel.. how can i code to do it??
and what is the difference between
#bot.event
async def on_message(message):
if message.content.startswith('~'):
and
#bot.command()
async def ~(ctx):

You can do both of these commands (the join and leave channel commands) in two ways, one is by using on_message, and the other is by using #bot.commands. It's is best to use bot.command instead of on_message for commands as bot.commands has more features plus I think it's fast after all it was built for commands. So I'll rewrite both of your commands using bot.command and also put using on_message there incase you don't want to use bot.command.
According to your message, I'm assuming ? is your prefix
Using on_message
#bot.event
async def on_message(message):
if (message.content.startswith('?join')):
if (message.author.voice): # If the person is in a channel
channel = message.author.voice.channel
await channel.connect()
await message.channel.send('Bot joined')
else: #But is (s)he isn't in a voice channel
await message.channel.send("You must be in a voice channel first so I can join it.")
elif message.content.startswith('?~'): # Saying ?~ will make bot leave channel
if (message.guild.voice_client): # If the bot is in a voice channel
await message.guild.voice_client.disconnect() # Leave the channel
await message.channel.send('Bot left')
else: # But if it isn't
await message.channel.send("I'm not in a voice channel, use the join command to make me join")
await bot.process_commands(message) # Always put this at the bottom of on_message to make commands work properly
Using bot.command
#bot.command()
async def join(ctx):
if (ctx.author.voice): # If the person is in a channel
channel = ctx.author.voice.channel
await channel.connect()
await ctx.send('Bot joined')
else: #But is (s)he isn't in a voice channel
await ctx.send("You must be in a voice channel first so I can join it.")
#bot.command(name = ["~"])
async def leave(ctx): # Note: ?leave won't work, only ?~ will work unless you change `name = ["~"]` to `aliases = ["~"]` so both can work.
if (ctx.voice_client): # If the bot is in a voice channel
await ctx.guild.voice_client.disconnect() # Leave the channel
await ctx.send('Bot left')
else: # But if it isn't
await ctx.send("I'm not in a voice channel, use the join command to make me join")

Save the channel connection, so you can disconnect later.
voice = None
...
if message.content.startswith("?join"):
channel = message.author.voice.channel
global voice = await channel.connect()
await message.channel.send('bot joined')
elif message.content.startswith("?join"):
await self.voice.disconnect()
Anyways, try using the discord.ext.commands extension. It makes everything involving commands easier. I'd also recommend using cogs (example), as you can just have a class with everything voice-related, and you don't need global variables.

Related

discord.py bot - Nuke command not working

I am having issues with my nuke command which is supposed to delete the current channel and clone it, clearing all the messages. The problem is that it doesn't work at all and doesn't give any errors!
Code
#client.command()
#commands.has_permissions(administrator=True)
async def nuke(ctx):
embed = discord.Embed(
colour=discord.Colour.blue,
title=f":boom: Channel ({ctx.channel.name}) has been nuked :boom:",
description=f"Nuked by: {ctx.author.name}#{ctx.author.discriminator}"
)
nuke_ch = discord.utils.get(ctx.guild.channels, name=ctx.channel.name)
new_ch = await nuke_ch.clone(reason="Being nuked and remade!")
await nuke_ch.delete()
sendem = new_ch.send(embed=embed)
await asyncio.sleep(3)
sendem.delete()
If you have a solution, please answer this question. Thanks in advance.
Remember to also request nuke_ch as an argument in your command. You just work with ctx, nothing more.
Here is a nuke command that I used to work with:
#client.command()
#commands.has_permissions(administrator=True)
async def nuke(ctx, channel_name):
channel_id = int(''.join(i for i in channel_name if i.isdigit()))
existing_channel = client.get_channel(channel_id) # Get channel ID
if existing_channel:
await ctx.send("**This channel will be nuked in X seconds.**")
await asyncio.sleep(YourValue) # Can be removed
await existing_channel.delete() # Deletes the old channel
existing = await existing_channel.clone() # Clones the channel again
await existing.send("**This channel was nuked/re-created!**")
else:
await ctx.send(f'**No channel named `{channel_name}` was found.**')
What did we do?
Get the channel by ID or name
Check if the channel exists and then nuke it
Built in an error handler if the channel was not found

discord.py member join voice channel

How can I create a channel that if someone joins it, bot will create a text channel. Here is my code:
#client.event
async def on_voice_state_update(member):
guild = member.guild
role = discord.utils.get(guild.roles, name="#everyone")
chan = await member.guild.create_text_channel(f"ticket - {member}")
await chan.set_permissions(role, send_messages=False, read_messages=False, add_reactions=False, embed_links=False, attach_files=False, read_message_history=False, external_emojis=False)
await chan.set_permissions(member, send_messages=True, read_messages=True, add_reactions=True, embed_links=True, attach_files=True, read_message_history=True, external_emojis=True)
I also want to make bot create this channel only if user join specific channel. Another thing I have to fix is making this script works only if member join voice channel, not leave, edit etc. Thanks
You can do it with
voice_channel = client.get(CHANNEL_ID)
try:
while True:
voice_channel.members[0]
await asyncio.sleep(0.1)
...
except:
...
But be careful!! This is a loop which will always run (with only a pause of 0.1 seconds) and will check the voice channel for members!

Discord.py Not recognising members

My Discord bot doesn't recognise members in a voice channel before the have switched to at least 1 other voice channel after the bot has started (after joining the channel, a user has to manually change to a different channel, then return, for the bot to recognise the member and be able to move them to the desired channel). This is a bit counterintuative, and defeats the purpose of my bot.
from discord.ext import commands
class Mute(commands.Cog):
# Commands
#commands.command()
async def mute(self, ctx):
vc = ctx.author.voice.channel
for member in vc.members:
await member.edit(mute=True)
await ctx.channel.purge()
#commands.command()
async def unmute(self, ctx):
vc = ctx.author.voice.channel
for member in vc.members:
await member.edit(mute=False)
await ctx.channel.purge()
#commands.command()
async def start(self, ctx):
vc = ctx.author.voice.channel
await ctx.channel.send("A new game has started!")
await ctx.channel.send("Users will now be moved. Game has started!")
await ctx.channel.purge()
channel = discord.utils.get(ctx.guild.channels, name="AU voice")
for member in vc.members:
await member.move_to(channel)
def setup(client):
client.add_cog(Mute(client))
Update your discord.py to latest version and follow this tutorial on discord.py official docs:
A Primer to Gateway Intents

Discord.py bot won't join voice

I'm trying to make a discord bot. It works fine for responding to certain messages, which is part of what I wanted it to do. I now want it to be able to join the voice channel, but it wont:
import discord
import youtube_dl
from discord.ext import commands
from discord.utils import get
TOKEN = 'token string here
BOT_PREFIX = '/'
bot = commands.Bot(command_prefix=BOT_PREFIX)
players = {}
#bot.event
async def on_ready():
print(bot.user.name + ' is now online.\n')
and then after my message handling #bot.event,
#bot.command(pass_context=True)
async def join(ctx):
print('Join executed')
global voice
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
print (f"The bot has joined {channel}\n")
#bot.command(pass_context=True)
async def leave(ctx):
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.disconnect()
print(f"The bot has left {channel}")
else:
print("Bot was asked to leave, but was not in one.")
I'm very new, so it could be (or probably is) a very simple, stupid fix.
The join command isn't even being processed, as that print statement isn't showing up in console when I call it in the discord chat.
I was following this video tutorial to a T, and his clearly works fine.
I think you just got on_message event. If you do, check this docs page.
Also i have no idea why you passed pass_context they removed it at version 1.0, and it doesn't even exist now.
Check below. This will work with the latest version of discord.py.
#bot.command(name='join', invoke_without_subcommand=True)
async def join(ctx):
destination = ctx.author.voice.channel
if ctx.voice_state.voice:
await ctx.voice_state.voice.move_to(destination)
return
ctx.voice_state.voice = await destination.connect()
await ctx.send(f"Joined {ctx.author.voice.channel} Voice Channel")

Join + Leave with a Discord bot in Python

I've made these two commands, one for leaving the channel that the bot is currently connected to, and one for joining the command sender's channel.
The problem is that neither of them are working. How can I fix this?
#bot.command(pass_context=True)
async def leave(ctx):
server = ctx.message.guild.voice_client
await server.disconnect()
#bot.command(pass_context = True)
async def join(ctx):
channel = ctx.message.author.voice.voice_channel
await bot.join_voice_channel(channel)
It looks as though you're using old documentation or tutorials, along with some new documentation.
Some changes from 0.16.x to rewrite:
You should use VoiceChannel.join() instead of Client.join_voice_channel()
Shortcuts are available when using Context. In your case, ctx.guild instead of ctx.message.guild.
All voice changes
Context is automatically passed - there isn't any need for pass_context=True
Rewriting your code - with some conditions to check if the author is in a voice channel:
#bot.command()
async def leave(ctx):
if ctx.guild.voice_client.is_connected(): # Checking that they're in a vc
await ctx.guild.voice_client.disconnect()
else:
await ctx.send("Sorry, I'm not connected to a voice channel at the moment.")
#bot.command()
async def join(ctx):
if ctx.author.voice:
await ctx.author.voice.channel.connect() # This will error if the bot doesn't have sufficient permissions
else:
await ctx.send("You're not connected to a channel at the moment.")
References:
New documentation
VoiceClient.is_connected()
VoiceClient.disconnect()
Context.send()
Member.voice
VoiceState.channel
VoiceChannel.connect()

Categories

Resources