How do I make a lockdown command for a specified role? - discord.py

You may have seen my previous question (How do I make a lockdown command?), where I asked about how to lockdown specified channel. But that command only locked down the # everyone role. My server has millions of roles and channels made for other roles, so I want to know how to change ctx.guild.default_role to something where you specify the role and the channel locks down for that role. Current command:
#commands.command()
#commands.has_permissions(manage_channels=True)
async def lockdown(self, ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=False)
await ctx.send(ctx.channel.mention + " ***is now in lockdown.***")

You can simply pass the role as an argument
async def lockdown(self, ctx, role: discord.Role): # `RoleConverter` will automatically convert it to a `discord.Role` instance
await ctx.channel.set_permissions(role, send_messages=False)
await ctx.send(ctx.channel.mention + " ***is now in lockdown.***")
You can invoke it by mentioning the role, by putting the role ID or simply by passing the name of the role

Related

Reset nickname on role removal

I'm currently using this code to assign prefix to nickname if users has specific role:
#client.event
async def on_member_update(before, after):
role = discord.utils.get(before.guild.roles, name="FK")
if after.nick is not None and after.nick.startswith("F |"):
return
if after in role.members:
await after.edit(nick="FK | " + after.display_name, reason=None)
How can i remove (or reset the nickname) if the the role has been removed from the user?
I tried using if after not in role.members but it's not working, so i guess i'm not doing the right thing.

How do you send a private message on_ready aka on a #client.event. Discord.py

I had multiple attempts.
# One of the attempts
ch = client.get_user(USERID)
await ch.send("IDK")
#Another
client = discord.Client()
#client.event
async def on_ready():
user = "#name"
user = discord.Member
await user.send(user, "here")
#Another
client = discord.Client()
#client.event
async def on_ready():
user = discord.utils.get(client.get_all_members(), id='USERID')
if user is not None:
await client.send(user, "A message for you")
else:
await client.send(user, "A message for you")
#Another
#client.event
async def on_ready():
ch = client.get_all_members()
await ch.send("Hello")
# Another
ch = client.start_private_message(USERID)
await ch.send("IDK")
As you can see I messed with the variables because I noticed that you can send a message by channel like this
channel = client.get_channel(CHANNELID)
await channel.send("Something)
But that doesn't work with get_user. Thanks in advance also sorry how bad my post/code is.
Allow me to inform you on what is wrong with the pieces of code you have provided.
await client.send(user, "A message for you") is older syntax, and has not been used since the v1.0 migration.
client.get_all_members() shouldn't be used in this case, as you are only getting all the members the bot shares a server with rather than a single user.
client.start_private_message(USERID) does not exist as far as I have read, and therefore we can assume that this wouldn't work.
My recommendation would be to use one of the two methods I will detail.
The first method would be to use client.fetch_user(), which sends a request to the Discord API instead of its internal cache (as the second method will). The only problem you will face with this method is if you retrieve too many users in a small amount of time, which will get you ratelimited. Other than that, I recommend this method.
The second method is to get a server through client.get_guild() and getting your user through there via guild.get_member(). This method will require the user to be in its cache, however, so this shouldn't be your go-to method in my opinion.
Do view both of these methods in the code below.
#client.event
async def on_ready():
# Method 1: Using fetch
user = await client.fetch_user(USER_ID)
await user.send("A message!")
# Method 2: Using 'get'
guild = client.get_guild(GUILD_ID)
user = guild.get_member(USER_ID)
await user.send("A message!")
Other Links:
Send DM to specific User ID - Stackoverflow
DM a specific user - Stackoverflow
Sending DM through python console (Fetch user) - Stackoverflow
DPY v1.0 Migration - Discord.py Documentation

How can I stop a specific role from talking in discord using discord.py

So, what I want to do is stop a specific role from speaking in a channel on discord using discord.py.
Here's what I have so far.
import discord
import os
from keep_alive import keep_alive
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
countingBotGuildSave = ['test']
if any(word in message.content for word in countingBotGuildSave):
await message.channel.set_permissions(discord.utils.get(message.guild.members, name='Foo'), send_messages=False)
await message.channel.send('**An admin/moderator has locked this channel. Please wait for an admin to unlock this channel with `+unlock`.**')
print(f'{message.author} locked channel {message.channel}')
keep_alive()
client.run(os.getenv('TOKEN'))
This doesn't cause any errors when I run the bot, but when I say test in discord it says: target parameter must be either Member or Role. I don't understand because I made a role named Foo.
Can you pls help?
Tysm.
The error itself tells you what went wrong. Your await function does not make any sense in that case. You are looking for guild.members with the name Foo but what you want is the role.
Have a look at the following code:
#client.event
async def on_message(message):
countingBotGuildSave = ['test']
if any(word in message.content for word in countingBotGuildSave):
await message.channel.set_permissions(discord.utils.get(message.guild.roles, name='Foo'), send_messages=False) # Get the role
await message.channel.send('**An admin/moderator has locked this channel. Please wait for an admin to unlock this channel with `+unlock`.**')
print(f'{message.author} locked channel {message.channel}')
Here we are looking for a role in the guild named Foo. You can also just use the ID to change the name to whatever you want to without editing the code (id=RoleID).
The output:

Prisoner Role, Discord.py 1.5.0a

I'm trying to do a bot that picks up all roles from user, send a message that mention all roles in a channel, so the bot need remove all roles and add a 'Prisoner' role and send a reason for the prison. How do I do this?
I'm trying to do this command for 3 days, but nobody could help me.
You can try this for deleting all roles and adding prisoner role:
#client.command()
async def prison(ctx, member: discord.Member):
member_roles = []
for role in member.roles:
member_roles.append(role)
await member.remove_roles(role)
member_roles = ', '.join(member_roles)
await ctx.send(f'{member.mention} is in prison. His {member_roles} roles are deleted.')
prisoner = discord.utils.get(ctx.guild.roles, name='Prisoner')
await member.add_roles(prisoner)
After you create the Prisoner role, change the permissions of this role for all the channels except for Prison channel in Discord.
Note: There could be syntax problems in my code because I'm on mobile right now. If any problem raises, just comment.

Set username as argument

Earlier, I asked a question which was fixing some broken code. But the code specified changed the role of the author.
async def ruleBreak(ctx, arg):
member = await ctx.message.author
role = discord.utils.get(member.guild.roles, name="RuleBreakers")
await discord.Member.add_roles(member, role)
However, I want to set a specified user to get the role, not the author. I've thought about removing the send part on line 2.
Please help.
Thanks in advance!
Your second line is saying that the member who should get the role is the member who invokes the command. For this you can use add_roles() which takes the role you want to give as an arguments. You can specify a recipient and role like so !addrole #someperson #thisrole
#client.command()
async def addrole(ctx, user: discord.Member, role: discord.Role):
await user.add_roles(role)
await ctx.send(f"I gave {user.name} the role {role.name}")

Resources