editing roles with edit_role discord.py - python-3.x

I have the following line in my script:
await client.edit_role(server='547874634978789398', role='' ,colour=0x008000)
However I do not understand what parameter discord.py is expecting for role=. Can anyone point me in the right direction to better understand this parameter?

First, you should use Server class not server's id. There is get_server() function that returns Server object with the given server's id.
server = client.get_server('547874634978789398')
Then, you can access to all roles belonging to the server by server.roles. It is list of Role object. So if you have a name of role and want to edit one's role into that, try it.
for role in server.roles:
if role.name == 'role_name':
# What you want to do.
await client.edit_role(server=server, role=role, colour=0x0080000)
break
Also there is server.role_hierarchy property which returns roles in order of the hierarchy. It contains same elements with server.roles but it is the sorted version.

role = discord.utils.get(ctx.guild.roles, name="Name")
# This will get the role you want to edit
await role.edit(color=0x008000, reason="The reason")
# This will edit the role with the desired color
For more information on this please see the docs: discord.Role.edit | discord.utils.get

Related

Discord.js - Command to Remove All Users Containing Role

I know that you can remove certain roles from users, and remove all roles from a user, but I was thinking of doing the reverse. I looked at this guide, which provides a way to retrieve all of the people who have a specific role. It seems like you could manipulate the collection/map to go through each member and remove the role. However, I cannot seem to achieve this.
I've hard-coded the one specific role that I am targeting as well as the message that should trigger the command.
Current code that I've been trying out (only seems to be working if there's just one person assigned the role):
if (msg.startsWith('!new round')) {
//check for everyone and remove the role
//roleID is just the roleID number string; I've stated it outside the if loop, for other command use cases as well
let membersWithRole = message.guild.roles.cache.get(roleID).members;
console.log(membersWithRole);
for (let member of membersWithRole) {
let mem = member[1]
mem.roles.remove(role).catch(console.error);
message.reply("Everyone with the jail role is now back in the game!");
}
}
Bottom line: Given a collection of the list of "guild" members that have the specified role (provided in the guide), could I iterate through a list* in order to remove the role from each member?
*I haven't found said list containing the members, but it's probably the objects themselves, so the whole collection
you need to learn documentation of discord.js
and yes you can do it by looping through all members.
if(msg.startsWith('!new round')){
console.log('command used by '+msg.author);
let role =msg.guild.roles.cache.get(roleId);
role.members.each(member=>{
member.roles.remove(role);
});
console.log('removed role from all members');
}
and also if you want to remove role from all members, so why you are not just deleting the role?
delete role:
msg.guild.roles.cache.get(roleId).delete();

Get highest role of a member with mentions

How can I get the highest role name of a mentioned member? I tried something like this but it doesn't work. Thanks! :) btw this is a ban command and I need this bc my bot is crashing when someone is trying to ban a user with a higher rank than bot.
if(message.member.hasPermission('BAN_MEMBERS')){
const user = message.mentions.users.first()
console.log(user.roles.highest.name)
if(!user) return console.log("test1")
if(!args[2]) return console.log("test2")
const ddays = args[1]
What you could do is:
Getting a user's highest role:
Get the UserId from the Mention inside of the Message
Get the Cache from the RoleManager of the Guild in which the Message was sent in
(I don't know if the roles in RoleCache are sorted by position, so sort if needed)
Iterate through the roles in RoleCache and check if the UserId is contained inside a specific role
Get the position of the role
Getting the bot's highest role:
Repeat steps 2-5 for your bot (or integrate them within the previous iteration of the RoleCache)
Then compare both numbers and find out if the bot's "role number" is higher than the one of the user's.

How to get the bot to recognize when a role was mentioned, and then respond back?

I would like the bot to recognize when the #Community Manager, #Admin, #Moderator roles are tagged, either single, or multiple roles tagged in same message, then send a message to the channel mentioning the user name.
I can get the bot to recognize when it's been tagged using this code:
if client.user.mentioned_in(message) and message.mention_everyone is False:
await message.delete()
I cannot for the life of me figure out how to see if other roles were tagged.
I've tried
if message.role_mentions.name('Admin'):
#do stuff
but get this error:
AttributeError: 'list' object has no attribute 'name'
message.role_mentions gives back a list of Role.
And then you can fetch roles from the guild using message.guild.get_role(id) in order to compare against the list of roles you gotten from the message.
Should result in something along the lines of this:
# Create a list of roles to check against
rolesToCheckAgainst [
# Fetches the role from the guild which the message was sent from
message.guild.get_role("The ID of the role"),
message.guild.get_role("The ID of the second role")
#etc...
]
# 'rolesWerePinged' will be true if any of the roles were pinged
rolesWerePinged = any(item in rolesToCheckAgainst for item in message.role_mentions)
if rolesWerePinged:
# Do something, some of the roles was pinged.
Also, I used any() to check if any of the roles mentioned contained any of the roles that needed to be check against. You can use a double-loop instead if you need different actions to be done depending on the type of roles mentioned.

How do I check if member have role

How do I check if the message.author has admin role?
Or is there a way I can check if a member have a higher role than another?
You can use discord.utils.get to get a role if it exists in the list of a Members roles.
from discord.utils import get
if get(member.roles, name="admin"):
# has role
else:
# does not have role
To determine position in the hierarchy, you can compare the highest roles of the Members
if member1.top_role > member2.top_role:
# member 1 is higher than member 2
To get role(s) of user
You can either comparing with the role's name
message.member.roles is a collection. It mean you just look for the role directly in the collection. Like this:
if(message.member.roles.find(r => r.name === "Admin") || message.member.roles.find(r => rname === "AnotherRole"))
Or you can check directly if a member have certain role with the Map.has method. This will check for keys, not values, so you'll have to use the roles' ids instead.
message.member.roles.has(adminRole.id)
message.member.roles.has(modRole.id)
To compare a role to another
You can simply use this kind of code (has described in the official documentation)
if(role_of_author > role_of_user_to_be_banned)
But take care that one user can have multiple roles, so adapt this condition based on your use case.
You can refer to the documentation for more information.

How to protect properties for different roles using loopback

I was just wondering how you would restrict property access to the $owner role only. For instance in my case I have a Joke which has an Author. The Author has User as base. I would like other "Authers" / Users to see who created the Joke, but they should not be able to see the Authers email, only if the Author is the $owner of the Joke itself it should be OK to show their email, just for the sake of this case.
Looking at the built-in User model you can see that they use the hidden feature to hide the password, but using that for their email will also hide their email for the $owner, which is not what I wanted
Let me know if something is not clear.
Thanks in advance
Register beforeRemote hook and check if current user is the $owner.
Joke.boforeRemote('findById', function(context, joke, next) {
// 1. find current user by id, using context.req.accessToken.userId
// 2. check if he is owner or not, by Role.isOwner
// 3. remove email from returned joke instance if user is not $owner
})
Note: it can be a bit complicated to cover all endpoints that return Jokes. But is there another way to do it?
To modify the output/results, you can use the afterRemote hook, as per the docs. The output/results are stored in ctx.result.
'findById' hooks into your GET requests when the call is like GET http://myModel/id. Use 'find' if you are not including the id in your request e.g. GET http://myModel. Just notice that in case of 'find', the returned instance(s) (joke(s)) is usually not just one so it is in an array of objects.
Joke.afterRemote('findById', function(ctx, joke, next) {
//your code
});
Get the id of current logged-in user: var currentUser = context.req.accessToken.userId
Compare the user id of the current logged-in user with that of the joke owner. If both are not the same (i.e. if (!(currentUser == joke.userId))), then:
before calling next(), remove the email attribute from returned joke instance. Because sometimes some ways don't work, here are a few:
delete ctx.result.email;
ctx.result.email = '';
loop through the attributes and transferring them to a new var, except the email, then save that new var the result: ctx.result = newVar;
You can create your own role resolver. See https://github.com/strongloop/loopback-example-access-control/blob/master/server/boot/role-resolver.js for an example. Just add your own logic once you determine the user.

Resources