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
Related
When I run my kick/ban command, I want it to send an embed to the channel the command is executed in to announce who has been banned. I have it in the code, but it doesn't post when the user is kicked. How would I fix this?
#commands.has_permissions(kick_members=True)
async def kick(context, member : discord.Member, *, reason=None):
# Conditions
if reason == None:
await context.channel.send("**``Please provide a reason for why this member should be kicked!``**", delete_after=3)
else:
# Await Kick
await member.kick(reason=reason)
# Send Embed in Server
myEmbed = discord.Embed(title="CRYPTIC Moderation", color=0x000000)
myEmbed.add_field(description=f'{member.mention} has been successfully kicked for: **``{reason}``**!')
myEmbed.set_footer(icon_url=context.author.avatar_url, text=f'Invoked by {context.message.author}')
await context.message.channel.send(embed=myEmbed)
# DM Kicked User
if member.dm_channel == None:
await member.create_dm()
await member.dm_channel.send(
content=f"You have been kicked from **``{context.guild}``** by {context.message.author} for **``{reason}``**!"
) ```
The DM part works in both commands, but the embed doesn't work in either. Thank you.
The problem is, that instead of just adding a description to the embed, you add a field, but fields have name and value, and not description. So instead, set the description where you set the embed title:
##bot.command or something similar is missing here. Copy and paste error?
#commands.has_permissions(kick_members=True)
async def kick(context, member : discord.Member, *, reason=None):
# Conditions
if reason == None:
await context.channel.send("**``Please provide a reason for why this member should be kicked!``**", delete_after=3)
else:
# Await Kick
await member.kick(reason=reason)
# Send Embed in Server
myEmbed = discord.Embed(title="CRYPTIC Moderation", color=0x000000, description=f'{member.mention} has been successfully kicked for: **``{reason}``**!') #add the description where you add the title
myEmbed.set_footer(icon_url=context.author.avatar_url, text=f'Invoked by {context.message.author}')
await context.message.channel.send(embed=myEmbed)
# DM Kicked User
if member.dm_channel == None:
await member.create_dm()
await member.dm_channel.send(
content=f"You have been kicked from **``{context.guild}``** by {context.message.author} for **``{reason}``**!"
) ```
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.
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!
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.