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!
Related
I am making a tempmute command that logs in to another channel, I have it so that when there is no channel called "modlog" it creates one but so far I have it so everyone cant type in it including me. How do I make it so a role called "Member" cant type in it only?
Code:
`except:
await ctx.send("No channel called 'modlog', creating one. (Note: Setup the permissions to allow
everyone to see the channel but cannot type in it")
await asyncio.sleep(3)
await ctx.send(":white_check_mark: Channel Created! :thumbsup:")
perms = ctx.channel.overwrites_for(ctx.guild.default_role)
perms.send_messages=False
await ctx.guild.create_text_channel(name='modlog', permissions=perms)
logs = discord.utils.get(guild.text_channels, name="modlog")
await logs.set_permissions(ctx.guild.default_role, send_messages=False)
guild = ctx.guild
modlog = discord.utils.get(guild.text_channels, name="modlog")
await modlog.send(embed=kickEmbed)
await modlog.send(embed=unmutelog)
await ctx.send(embed=embed)`
By doing that
modlog = discord.utils.get(guild.text_channels, name="modlog")
logs = discord.utils.get(guild.text_channels, name="modlog")
await logs.set_permissions(modlog , send_messages=False)
So firstly you got the role and then update the channel perms. ctx.guild.default_role belong to everyone.
Lemme know if that doesn't work for you.
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
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")
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()
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.