I am creating a bot command so that when you type !setup it sets up the whole server (creating channels and roles, etc). I have already set it to create the roles and channels but there are some channels that only specific roles can type in, whereas, other roles can only read the channel. I don't know how to set up permission overwrites for certain roles.
I have already looked on the Discord.js documentation and it doesn't help much. I receive an error that supplied parameter was neither a user nor a role, but I don't know how to gain the role ID.
message.guild.createRole({
name: 'Admin',
color: '#2494ad',
permissions: ['ADMINISTRATOR', 'VIEW_AUDIT_LOG', 'MANAGE_GUILD', 'MANAGE_CHANNELS', 'SEND_TTS_MESSAGES', 'CREATE_INSTANT_INVITE', 'KICK_MEMBERS', 'BAN_MEMBERS', 'ADD_REACTIONS', 'PRIORITY_SPEAKER', 'READ_MESSAGES', 'SEND_MESSAGES', 'MANAGE_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY', 'MENTION_EVERYONE', 'USE_EXTERNAL_EMOJIS', 'CONNECT', 'SPEAK', 'MUTE_MEMBERS', 'DEAFEN_MEMBERS', 'MOVE_MEMBERS', 'USE_VAD', 'CHANGE_NICKNAME', 'MANAGE_NICKNAMES', 'MANAGE_ROLES', 'MANAGE_WEBHOOKS', 'MANAGE_EMOJIS']
});
message.guild.createRole({
name: 'Requesting Role',
color: '#1bb738',
permissions: ['READ_MESSAGES', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY',]
});
//Categories and Channels
message.guild.createChannel('clan-communications', {
type: 'category',
permissionOverwrites: [{
id:'25311096',
deny: ['SEND_MESSAGES']
}]
});
//Permissions
message.channel.overwritePermissions('25311096', {
SEND_MESSAGES: false
});
break;
I would like roles to have base permissions for the whole server. But certain roles have overwrites for different channels. Instead it says the supplied parameter was neither a user nor a role.
First and foremost, welcome to Stack Overflow. Hopefully we can be of help to you.
Let's walk through a solution step by step to achieve your desired result.
When you create your roles, you should declare a variable to store them. That way, you can use what the client just created later on. Since Guild.createRole() returns a promise, we can save the fulfilled result into a variable.
Note that the keyword await must be placed in async context (within an async function).
const vip = await message.guild.createRole('VIP', { ... });
Then, when you need to use that role, you can refer to the variable.
await message.guild.createChannel('VIPs Only', {
type: 'category',
permissionOverwrites: [
{
id: vip.id,
allow: ['READ_MESSAGES']
}, {
id: message.guild.defaultRole.id, // #everyone role
deny: ['READ_MESSAGES']
}
]
});
If the role already exists, you can retrieve it from the Collection of roles returned by Guild.roles.
const testRole = message.guild.roles.get('IDhere');
const adminRole = message.guild.roles.find(r => r.name === 'Admin');
Other simple improvements.
In your code snippet, I don't see any error handling. The methods you're using return promises. If an error occurs in any, the promise state will become rejected. Any rejected promises that aren't caught will throw errors. To fix this, attach catch() methods to each promise (better for individual handling) or wrap async code in a try...catch statement.
When creating your Admin role, know that the ADMINISTRATOR permission automatically grants all other permissions (and allows users to bypass channel-specific permissions). Therefore, there's no need to list any other permission, or change the role's permission overwrites in any channels.
Your IDs in your code don't appear to be valid. Discord IDs are snowflakes, represented by strings of 18 digits. You can access them through Developer Mode in Discord. However, you shouldn't have to hard-code them with this solution, unless they already exist.
In the permissions array for your Requesting Role role, you have an extra comma.
Related
Let say I want to make a lock command (making only admins be able to say something in a channel) and I want a specific role to be overwrite (not #everyone). How could I do that?
To simply it. How can I disable SEND_MESSAGE for a specific role? /
You will be able to achieve this via GuildChannel.permissionOverwrites which returns the PermissionOverwriteManager class. Within that class, you will be able to use the .edit() method which edits permission overwrites for a user or role in this channel, or creates an entry if not already present.
In the first parameter of the .edit() method, you can input the role ID as a string, and in the options, you can input the property, or as known as the permission, with a value of true to enable or value false to disable.
An example of this is the following: (code according to the documentation from https://discord.js.org/#/docs/discord.js/stable/class/PermissionOverwriteManager)
// Edit or Create permission overwrites for a message author
message.channel.permissionOverwrites.edit(message.author, {
SEND_MESSAGES: false
})
.then(channel => console.log(channel.permissionOverwrites.cache.get(message.author.id)))
.catch(console.error);
You can use GuildChannel.permissionOverwrites.edit to set permission overwrite.
The code would be:
message.channel.permissionOverwrites.edit('replace with role id', {
SEND_MESSAGE: false
})
Slash command version:
interaction.channel.permissionOverwrites.edit('replace with role id', {
SEND_MESSAGES: false
})
I know how to get all members from a guild but I need to do the opposite operation : Getting all the guilds (IDs) where a specified member is registered in.
When fetching user like this client.users.cache.get(memberID); I don't see anything in the result that can allow me to see all the member's guilds :
User {
id: '706498754712807398',
system: null,
locale: null,
flags: UserFlags { bitfield: 0 },
username: 'johndoe',
bot: false,
discriminator: '1023',
avatar: null,
lastMessageID: null,
lastMessageChannelID: null
}
Any suggestion ?
You can do this by using the following code:
const userID = '3383083830389'; // the ID of the user
const guilds = client.guilds.cache.filter((guild) => guild.members.cache.has(userID));
and guilds is a Collection of guilds where the user is in. This has two limitations :
you can only get the guilds where the bot is in too
this won't work if the member is not cached (this can be resolved by trying to fetch the member in each guild)
You cannot view servers that a user is in that you do not have access to the account. This is a Discord limitation and falls under the privacy category, you don't want to do this anyways as it can be used maliciously.
The only way you can access the guilds a user is in if you are logged in as that account, otherwise without logging into that account, you cannot see what kind of servers they are in.
But if you want to check what kind of servers your bot is in, the code is quiet simple.
const allGuilds = (client.guilds.cache)
console.log(allGuilds)
I have not tested this myself, but it should point you in the right direction.
I want to make a command so i can give all the users in my discord server a role.
Problem is now with the code i have, that he gives not all the members the specified role because it are to much members and it will spam the discord api.
How can i make it so that after i do the command, the bot will give all the members the specified role, but not directly to prevent spamming the API, but for example every 10 min he gives 5 members the role until all the members got the role.
Hope some one could helpe me
this is what i have now :
module.exports = {
name: "give-roles",
aliases: ["gr"],
category: "roles",
description: "Give's all members the Verified-Member role",
usage: `${prefix}give-roles`,
run: async (Client, message) => {
message.guild.members.fetch()
.then(console.log)
.catch(console.error);
let role = message.guild.roles.cache.find(r => r.name === 'Verified-Member')
if (!role) return message.channel.send(`**${message.author.username}**, role not found`)
message.guild.members.cache.filter(m => !m.user.bot).forEach(member => member.roles.add(role))
message.channel.send(`**${message.author.username}**, role **${role.name}** was added to all members`)
},
}```
A way to get round this is to add a role when a member joins instead of all at once (which will never work since not all members will be cached)
<client>.on('guildMemberAdd', member => {
var memberRole = member.guild.roles.cache.find(role => role.name === "<role name here>");
member.roles.add(memberRole); //auto assign role on join
});
change the code in <> to fit your needs
The reason you cannot add a role to all members is due to the v12 addition of cache.
Managers/Cache
v12 introduces the concept of managers, you will no longer be able to directly use collection methods such as Collection#get on data structures like Client#users. You will now have to directly ask for cache on a manager before trying to use collection methods. Any method that is called directly on a manager will call the API, such as GuildMemberManager#fetch and MessageManager#delete.
I would recommend that you read the docs to further understanding of how bots work here
Developing a discord moderation bot with Discord.js
Facing error "DiscordAPIError: Missing Access"
My bot user, which has all server permissions except "Administrator", and highest.rawPosition is 18 (highest of all roles) :
user: ClientUser {
id: 'XXXXXXXXX',
bot: true,
username: 'Bot',
discriminator: '1863',
avatar: '2e8af5cccdc5cf15a0f88818dbb044e6',
lastMessageID: null,
lastMessageChannelID: null,
verified: true,
mfaEnabled: true,
_typing: Map {}
},
is trying to add this role (rawPosition is 2) :
Role {
id: 'XXXXXXXXX',
name: 'Mod',
color: 0,
hoist: false,
rawPosition: 2,
permissions: Permissions { bitfield: 37211712 },
managed: false,
mentionable: false,
deleted: false
}
as an overwrite permission to this channel :
CategoryChannel {
type: 'category',
deleted: false,
id: 'XXXXXXXXX',
name: 'Section Job',
rawPosition: 6,
parentID: null,
}
using this code :
await channel.createOverwrite(role, {
VIEW_CHANNEL: true,
READ_MESSAGES: true,
SEND_MESSAGES: true,
CONNECT: true
});
Here is the error I get :
[2020/10/06 00:52:56:427] DiscordAPIError: Missing Access
I performed a search before posting this.
Discord gives many possible explanations about this specific error, and none would fit with my issue : https://discordjs.guide/popular-topics/permissions-extended.html#missing-permissions
Your bot is missing the needed permission to execute this action in it's calculated base or final permissions (requirement changes based on the type of action you are trying to execute).
--> My bot has all permissions except "Administrator"
You provided an invalid permission number while trying to create overwrites. (The calculator on the apps page returns decimal values while the developer documentation lists the flags in hex. Make sure you are not mixing the two and don't use the hex prefix 0x where not applicable)
--> I give the exact same permissions, formatted exactly the same as another group, and it works
It is trying to execute an action on a guild member with a role higher than or equal to your bots highest role.
--> Not executing an action on a user, but on a group
It is trying to modify or assign a role that is higher than or equal to its highest role.
--> Bot highest role is 18, and added role rawPosition is 2
It is trying to add a managed role to a member.
--> As you can see it is not "managed"
It is trying to remove a managed role from a member.
--> Not trying to remove a role
It is trying to execute a forbidden action on the server owner.
--> Not editing a user, but a channel (and server owwner does not have this role)
It is trying to execute an action based on another unfulfilled factor (for example reserved for partnered guilds).
--> I don't understand this one but it couldn't be that
It is trying to execute an action on a voice channel without the VIEW_CHANNEL permission.
--> Not executing an action on a voice channel, but on a Category channel, and it has VIEW_CHANNEL permission
More information :
1/ The same command in the exact same context works with some other groups, like this one :
Role {
id: 'XXXXXXXXX',
name: 'Job',
color: 0,
hoist: false,
rawPosition: 1,
permissions: Permissions { bitfield: 37211712 },
managed: false,
mentionable: false,
deleted: false
}
2/ The same command works with "Administrator" permission assigned to the bot
3/ Of course, adding "Administrator" permission to the bot is not an option
Thanks for any help !
Ok then I found the solution thanks to discord Js community
I forgot to give my bot read permissions on that specific channel, so the bot couldn't give permissions to a channel he didn't have access to...
I just added
permissionOverwrites: [
{
id: guild.me.roles.highest,
allow: ['VIEW_CHANNEL', 'MANAGE_CHANNELS', 'MANAGE_ROLES']
}
]
to my channel creation, and it works.
I would like to make an application in React Native that allows to work in two modes, parent and child. The initial stage is registration with Firebase, then after adding additional information about the role (parent / child), registering both the child and parent, and after logging in both of them, the child will share location and parent will receive it.
I would like to add additional fields such as role (parent / child) in my application in React Native + Firebase, to later create other functionalities of the application based on the role.
Registration:
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(userCredentials => {
return userCredentials
.user.updateProfile({
displayName: name,
})
.additionalUserInfo.profile = {
role: role,
}
})
Homescreen
const { displayName } = firebase.auth().currentUser;
const { role } = firebase.additionalUserInfo.profile;
this.setState({displayName, role});
and role returns undefined.
The properties that you can store on a user profile are defined by Firebase Authentication. You can't just add additional properties to it as you see fit. At best Firebase will simply ignore those, but likely it will also explicitly reject them (throwing an error).
If you want to store additional information about a user, you have two main options:
Store the additional information as custom claims in the user's authentication token.
Store the additional information in an external database, such as the Firestore and Realtime Database that are part of Firebase.
While storing the data as custom claims is pretty close to what you want to accomplish, you'll need to keep a few things in mind:
Custom claims are used for authorization purposes, and for that reason can only be set from a trusted environment (such as your development machine, a server you control, or Cloud Functions). So you can't simply set the role from within the app, and will need a separate process to add that claim.
After setting a custom claim on a user profile it may take up to an hour before that change is visible in the client. If you need it sooner, you can force the user to sign in again, or refresh their ID token.
Custom claims are sent with every request you make to Firebase resources, and for that reason are very limited in size. There's a maximum size of 1000 bytes for custom claims for a user. While your current role will easily fit into that, it may limit what you can add later.
If instead you store user data in an external database, you'll typically combine it with other information about that user into a users node/collection. In here you'd store a document/node for each user based on that user's UID, and then their profile information.
So something like:
users: {
uidOfAleksandra: {
username: "Aleksandra",
displayName: "Aleksandra Lastname",
role: "parent",
registrationDate: "2020-02-01"
},
uidOfPuf: {
username: "puf",
displayName: "Frank van Puffelen",
role: "child",
registrationDate: "2015-03-07"
},
}
Having this list of user profiles does not only allow you to store the additional information for each user, but would also allow you to query that list of users from within your app, something that the Authentication API doesn't allow from within application code.