I have created a bot that will lock every channel when I type the command, however, I don't want it to lock the staff ones and the announcement ones.
Here is my code so far:
#bot.command(aliases=['r'])
#commands.has_permissions(manage_channels=True)
async def lockdown(ctx):
for guild in bot.guilds:
for channel in guild.text_channels:
channel = channel
overwrite = channel.overwrites_for(ctx.guild.default_role)
overwrite.send_messages = False
await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
await channel.send('Lockdown has started')
How can I do this?
You can exclude channels which you dont want to lock by name using a blocking statement. Like this:
#bot.command(aliases=['r'])
#commands.has_permissions(manage_channels=True)
async def lockdown(ctx):
for guild in bot.guilds:
for channel in guild.text_channels:
if channel.name in ['dont_lock_ch_name_1', 'dont_lock_ch_name_2']:
continue
overwrite = channel.overwrites_for(ctx.guild.default_role)
overwrite.send_messages = False
await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
await channel.send('Lockdown has started')
Related
I made a lock command but when fl.lock #general test is used in #general channel it isn't locking the general channel but when fl.lock #general test is used in #staff-chat channel it is locking the #general channel
So my bot isn't locking a channel when that channel is mentioned in the lock commmand and it is used in the same channel
The code
#commands.command(case_insensitive = True)
#commands.has_any_role(885434191783788564, 856071314740740096, 856061783722426378, 856465667296985108)
async def lock(self, ctx, channel: discord.TextChannel, *, reason=None):
channel = channel or ctx.channel
overwrite = channel.overwrites_for(ctx.guild.default_role)
if overwrite.send_messages == True:
overwrite.send_messages = False
await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
em_reason = discord.Embed(title="**Channel locked**", description=f":lock: {reason}",color=discord.Color.red())
embed = discord.Embed(description = f"<a:fl_check:874522235879186483> Locked channel <#{channel.id}>",color=discord.Color.green())
await ctx.send(embed=em_reason)
await ctx.send(embed=embed)
elif overwrite.send_messages == False:
em = discord.Embed(description="<a:fl_no:874522273984442420> That channel is already locked.", color=discord.Color.red())
await ctx.send(embed=em)```
I think channel = channel or ctx.channel is the issue here.
You should check directly if the channel argument is None and than use the ctx.channel.
#commands.command(case_insensitive = True)
#commands.has_any_role(885434191783788564, 856071314740740096, 856061783722426378, 856465667296985108)
async def lock(self, ctx, channel: discord.TextChannel=None, *, reason=None):
if channel is None:
channel = ctx.channel
overwrite = channel.overwrites_for(ctx.guild.default_role)
if overwrite.send_messages == True:
overwrite.send_messages = False
await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
em_reason = discord.Embed(title="**Channel locked**", description=f":lock: {reason}",color=discord.Color.red())
embed = discord.Embed(description = f"<a:fl_check:874522235879186483> Locked channel <#{channel.id}>",color=discord.Color.green())
await ctx.send(embed=em_reason)
await ctx.send(embed=embed)
elif overwrite.send_messages == False:
em = discord.Embed(description="<a:fl_no:874522273984442420> That channel is already locked.", color=discord.Color.red())
await ctx.send(embed=em)
I want to lock the voice channel so that nobody can join it after creating it. The voice channel is being used as a server clock. Here are the codes where the channel is being created:
for channel in saved_guild["guild"].channels:
#first_word = channel.name.split(" ")[0]
#if first_word == 'π (GMT-4)':
if 'π (GMT-4)' in channel.name:
await channel.delete()
#channel_exists = True
#await channel.edit(name=new_title)
#break
#create new channel
if not channel_exists:
await saved_guild["guild"].create_voice_channel(new_title)
And
channel_exists = False
for channel in context.guild.channels:
#first_word = channel.name.split(" ")[0]
#if first_word == 'Time/Hora':
if 'π (GMT-4)' in channel.name:
await channel.delete()
#channel_exists = True
#await channel.edit(name=new_title)
#break
#create new channel
if not channel_exists:
await context.guild.create_voice_channel(new_title)
If you want to lock the voice channel for EVERYBODY, you could so something like this:
for channel in ctx.guild.voice_channels:
#insert code here
for role, permissions in channel.overwrites:
permissions.connect = False
await channel.set_permissions(role, permissions)
This basically denies "connect" perms for every role in the voice channels permissions list
The suggestion made by yotam rec helped, this was the new code:
for channel in saved_guild["guild"].channels:
if 'π' in channel.name:
await channel.set_permissions(saved_guild["guild"].roles[0], connect=True)
await channel.delete()
and
if not channel_exists:
await saved_guild["guild"].create_voice_channel(new_title)
for channel in saved_guild["guild"].channels:
if 'π' in channel.name:
await channel.set_permissions(saved_guild["guild"].roles[0], connect=False)
Im currently trying to make the reaction in the bot response to turn off an moderation event which listens to messages being deleted. This will work as a filter so if the user dont want to log deleted messages they can turn it off by reacting. I've heard of the wait for and the dispatch function but i currently dont know how it works and couldnt find a tutorial. Any feedback would be amazing as i am a bit stuck and willing to listen to anyone.
Current Code;
import discord
from discord.ext import commands
import datetime
class log(commands.Cog):
def __init__(self,bot):
self.bot = bot
mess = False
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
channel = reaction.message.channel
guild = channel.guild
message = reaction.message
if user != self.bot.user:
if reaction.emoji == '1οΈβ£':
check = discord.utils.get(guild.categories, name="Chilly Logs") # Find the Category
if not check: # If category doesnt exist create the logs
cat = await channel.guild.create_category_channel('Chilly Logs')
await channel.guild.create_text_channel("Message Logs", category=cat) # Message Logs
await channel.guild.create_text_channel("Other Logs", category=cat) # Other Logs
await channel.send('**Log Channels Were Succesfully Added!**')
await message.remove_reaction('1οΈβ£', user)
return
else:
await channel.send('**Log Channel Already Exists**')
await message.remove_reaction('1οΈβ£', user)
if reaction.emoji == '2οΈβ£':
channel1 = discord.utils.get(guild.channels, name="other-logs") # Other Logs
channel2 = discord.utils.get(guild.channels, name="message-logs") # Message Logs
category = discord.utils.get(guild.categories, name="Chilly Logs") # Category/Parent
if category is not None: # Deletes All The Channels
await channel1.delete()
await channel2.delete()
await category.delete()
await channel.send('**Logging Channels Have Been Removed**')
await message.remove_reaction('2οΈβ£', user)
else:
await channel.send('**Channels Either Dont Exist Or Have Been Renamed**')
await message.remove_reaction('2οΈβ£', user)
if reaction.emoji == 'β':
#commands.command()
async def test(self, ctx):
embed = discord.Embed(title = "Chilly Logging", description = "Chilly Will Log Any Edited, Deleted Messages. More Features & Flexibility Coming Soon", colour = discord.Color.blurple())
embed.add_field(name="βββLogging Commands βββ", value="1οΈβ£ - Turn On Server Logging", inline=True)
embed.add_field(name="β β", value= "2οΈβ£ - Delete & Turn Off Logging", inline=False)
msg = await ctx.send(embed=embed)
emoji = ['1οΈβ£', '2οΈβ£', 'β']
response = 3
for i in range(response):
await msg.add_reaction(emoji[i])
#commands.Cog.listener()
async def on_message_delete(self, message):
if x == True:
if not message.author.bot: # Checks for bot message
channel = message.channel.name # Channel the deleted message is from
logchannel = discord.utils.get(message.guild.channels, name='message-logs') # Finds the log channel
embed = discord.Embed(title="Message Log", description="", color= discord.Color.red()) # Embeds
embed.add_field(name="Message sent by {} has been deleted in `{}`" .format(message.author.display_name, channel), value=message.content, inline=True,)
embed.set_footer(text='User ID: {} | Message ID: {}' .format(message.author.id, message.id))
await logchannel.send(embed=embed) # Finally sends the embed to log channel
#commands.Cog.listener()
async def on_message_edit(self, before, after):
if not after.author.bot:
if before.content != after.content:
channel = after.channel.name # Channel the edited message is from
logchannel = discord.utils.get(after.guild.channels, name='message-logs') # Finds the log channel
embed = discord.Embed(title="Message Log", description="Message edited in `{}` by {}" .format(channel, after.author.display_name), color= discord.Color.red()) # Embeds
embed.add_field(name="Before", value=before.content, inline=True,)
embed.add_field(name="After", value=after.content, inline=False,)
embed.set_footer(text='User ID: {} | Message ID: {}' .format(after.author.id, before.id))
await logchannel.send(embed=embed) # Finally sends the embed to log channel
def setup(bot):
bot.add_cog(log(bot))```
You could use a global variable. Simply:
Toggle = True
#bot.command()
async def toggle(ctx):
global Toggle
# Toggles the variable.
Toggle = !Toggle
# Example event
#bot.event
async def on_message(message):
if Toggle:
# Event's code
else:
await message.channel.send("Function disabled")
I'm trying to get my background task to send in different channels using random.choice(). When I turn the bot on, it will send in only one random channel and that channel only. Is there a way to send in a different channel each time it loops?
async def test_loop():
await client.wait_until_ready()
channels = ['550528972226', '5149003563352', '514900351233', '5799132312340']
channel = client.get_channel(random.choice(channels))
while not client.is_closed:
time = random.randint(1,5)+random.random()
monies = random.randint(100,250)
emojigrab = dollar
emojimsg = await client.send_message(channel, emojigrab)
await client.add_reaction(emojimsg, hand)
pay = await client.wait_for_reaction(emoji=hand, message=emojimsg, timeout=1800,
check=lambda reaction, user: user != client.user)
if pay:
await client.delete_message(emojimsg)
await client.send_message(channel, "{} collects {:,} dollars".format(pay.user.mention, monies))
add_dollars(pay.user, monies)
await asyncio.sleep(int(time))
Currently, channel = client.get_channel(random.choice(channels)) is outside of your while loop, meaning that variable channel never changes. Move it to inside your while loop to change it every time a new message is going to be sent.
async def test_loop():
await client.wait_until_ready()
channels = ['550528972226', '5149003563352', '514900351233', '5799132312340']
while not client.is_closed:
channel = client.get_channel(random.choice(channels))
time = random.randint(1,5)+random.random()
monies = random.randint(100,250)
emojigrab = 'π΅'
emojimsg = await client.send_message(channel, emojigrab)
await client.add_reaction(emojimsg, "π°")
pay = await client.wait_for_reaction(emoji="π°", message=emojimsg, timeout=1800,
check=lambda reaction, user: user != client.user)
if pay:
await client.delete_message(emojimsg)
await client.send_message(channel, "{} secures the bag for ${:,}".format(pay.user.mention, monies))
add_dollars(pay.user, monies)
await asyncio.sleep(int(time))
If user add reaction :HotS_Tank: in a special message, the bot will need to give this role to user, but I do not have any idea how to do it...
That's what I have tried:
async def role_background_task():
await client.wait_until_ready()
roleChannel = discord.Object(id='411270826374070293')
roleMSG1 = client.get_message(roleChannel, id='411657109860515840')
roleMSG2 = client.get_message(roleChannel, id='411657144488689674')
while not client.is_closed:
reac1 = await client.wait_for_reaction(emoji=':HotS_Tank:411445724287598592',message=roleMSG1)
if reac1.reaction.emoji == ':HotS_Tank:411445724287598592':
await client.add_roles(reac1.user, roleHOTS_Tank)
client.loop.create_task(role_background_task())
If you check the documentation, there's an event called on_reaction_add here. You can simply use that.
#client.event
async def on_reaction_add(reaction, user):
roleChannelId = '411270826374070293'
if reaction.message.channel.id != roleChannelId:
return #So it only happens in the specified channel
if str(reaction.emoji) == "<:HotS_Tank:411445724287598592>":
await client.add_roles(user, roleHOTS_Tank)