So I'm creating a third-party to discord verification bot, and all of it works, except for when I try to access the guild member. The third-party sends all the data back to the bot, but for some reason, (and all the information is correct), it doesn't allow me to get the guild member, (via their discord id), and change their nickname.
Here's the code, and any help is appreciated!
let Mem = message.guild.members.cache.find(Member => Member.id === String(message.content.split(' ')[0]));
Mem.setNickname(message.content.split(' ')[1]);
I've tried (what I think) is all of the ways to access the guild member, but none of them work. The id is valid, which is why it's even more confusing. Thanks in advance!
You aren't allowed to access the whole server list by default. You need discord GUILD_MEMBERS intent, and also make sure to enable Server Members Intent in the website Discord Developer > Your Bot > Bot > Privileged Gateway Intents > Server Members Intent
Related
I'm trying to figure out how to check if my bot has permission to send messages and include embeds into a specific channel.
I have found the following code that returns a boolean if a specific member has a permission in a specific channel. but I'm unsure how to perform the same action for the bot itself.
message.member.permissionIn('channel_id').hasPermission('SEND_MESSAGES');
None of the other answers explain how the get the GuildMember object, so I'll try explaining it. All you need to do is get the GuildMember from your client. To do this, use client.guilds.cache.get(guild_id).members.me to your the bot's GuildMember, then from there you can use the same code. Try this:
client.guilds.cache.get(guild_id).members.me.permissionsIn(channel_id).has('SEND_MESSAGES')
where guild_id is the server ID and channel_id is the channel ID.
Alternatively, if you already have the Message object, then you can just the the Guild from there. Like this:
message.guild.members.me.permissionsIn(channel_id).has('SEND_MESSAGES')
You need to check if the GuildMember has permission.
[Guild].me.permissionsIn('channel_id').has('SEND_MESSAGES')
In Discord.JS v14, you can do the following:
const { PermissionFlagsBits } = require("discord.js");
// Check for permissions
if (!channel.permissionsFor(interaction.guild.members.me).has(PermissionFlagsBits.SendMessages)) {
// No permissions!
}
In which channel is your channel object
I know you can do it like this
bot.on('guildMemberAdd', member => {
member.guild.channels.get('channelID').send("Welcome"); });
But then you have to specify a channelID.
Welcome Channel
All members join through this link onto the welcome channel. Is there a way that discordjs sends a join message where ever the user got invited? Example: A join link for general so the welcome message is in general.
Thanks for the help :)
The guildMemberAdd event only returns a GuildMember object which doesn't seem to include a reference to the invite used. You can fetch all the generated invite links and guess which one was used, but I wouldn't recommend this option.
Here are three solutions I can think of:
Use the System Message Channel
This channel can be defined in the server settings without enabling the "Random welcome message". You can find it in Guild.systemChannelID.
https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=systemChannelID
With public bots, make this setting configurable by an admin
You can make your bot respond to a command that will allow an admin to select a channel, either by selecting the channel where the command was sent, or prompting a list of channels. This is not the most straightforward solution to implement, but this is the best in terms of UX for your users.
With private bots, hardcode the channel ID
This one will be the easiest to implement if your using your bot privately in one server or a limited number of servers.
Go into Discord settings
Appearance
Toggle "Developer mode" in the Avanced section
Then right click on the desired channel, and Copy ID
there is a event in the Client() class that called guildMemberAdd. It will return a GuildMember class that will store all informations about the newly joined member!
If you bot is private bot
then you can simple hard code your bot, by enable the developer mode and right-click on the specific channel that you want your bot send welcome messages to, chose get ID and then paste the copied ID to member.guild.channels.cache.get("THE_ID") and then simple send the message.
client.on('guildMemberAdd', member => {
const channel = member.guild.channels.cache.get("CHANNEL_ID"); // Getting the channel
if(channel){ // Checking if the channel exist
channel.send(`Welcome ${member} to ${member.guild.name}`); //Send the message
}
Else if your bot is public bot
Then you will need a setup command to helps others server owners setup their welcome message function with your bot.
You should need a database (google it, if you don't know) to store channel's IDs, then get the channel's ID and do the same thing that I mentioned before!
My code has been working just fine for weeks, but a few events and functions have randomly stopped working!
Firstly, my guildMemberAdd, guildMemberRemove, and guildMemberUpdate events simply stopped doing anything. No errors are appearing, and when I debugged my code, I realized the event wasn't even being emitted when the corresponding action took place.
// const client = new Discord.Client();
client.on('guildMemberAdd', (member) => // not triggering!
client.channels.cache.get('channel-id').send(`${member.tag} joined!`); // not sending!
Secondly, when trying to get a member from the GuildMemberManager cache, it always returns undefined:
const member = message.guild.members.cache.get(targetID); // undefined
When I then tried to display every member in that guild's member cache, it only showed me and my bot instead of the usual 100+ members.
Then I tried to fetch every member in my guild using GuildMemberManager.fetch():
const members = await message.guild.members.fetch();
But I got this error:
[GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
Again, I'm sure my syntax is correct, as it's been working perfectly for a while, and I haven't updated anything recently that would affect this code.
🤖 Discord is now enforcing privileged intents
What are intents?
Maintaining a stateful application can be difficult when it comes to the amount of data you're expected to process, especially at scale. Gateway Intents are a system to help you lower that computational burden.
Gateway intents allow you to pick and choose what events you choose to "subscribe" to so that you don't have to use up storage on events you're not using. This feature was introduced by Discord in 2020 and was supported by discord.js in v12.
What are privileged intents?
Some intents are defined as "Privileged" due to the sensitive nature of the data. Those intents are:
GUILD_PRESENCES
GUILD_MEMBERS
As of October 27th 2020, these intents have been turned off by default.
Some problems you might be facing because of this
GUILD_PRESENCES
member and user caches are empty (or very close to it) on startup
Guild.memberCount returns count as of ready
All events involving Presences do not trigger (presenceUpdate)
Some Presence data returns null or undefined
All GuildMembers appear to the bot as offline.
client.login() times out if you specified the fetchAllMembers option in your ClientOptions
GUILD_MEMBERS
member and user caches are empty (or very close to it) on startup
GuildMemberManager.fetch() and UserManager.fetch() methods time out
All events involving GuildMembers do not trigger (guildMemberAdd, guildMemberRemove, guildMemberUpdate, guildMemberSpeaking, and guildMembersChunk)
How do I enable intents?
Through the Discord Developer Portal:
Firstly, you must manually enable the intents from the Discord Developer site. Go to applications, select your app, and find the "bot" tab on the sidebar. Then you can scroll down until you see this:
As shown in the screenshot, your bot will require verification if in more than 75 guilds.
If your bot is verified:
Once your bot is verified, you won't be able to manually flip the intent switches in the Developer Portal. To request whitelisted access to an additional privileged gateway intent for a verified bot, please send our support team a ticket here!
Make sure to include your bot's ID, which intents you're requesting, a basic description of your use case for the requested intent, and screenshots or video of that use case in action (or code snippets, if not user facing!).
Through the discord.js module:
Once you have either/both intents checked off, you just have to enable them through discord.js. The discord.js intents guide thoroughly explains how to do this, but I will paraphrase it here.
You don't need to go through these steps if you want every intent. Discord enables all intents (except these two, obviously) by default. As long as you checked off both intents in the Developer Portal, you can stop here if you don't care about blocking any other intents. If you do, just remember intents are only supported by discord.js v12+, so you might have to upgrade.
One of the ClientOptions (ClientOptions is a typedef of potential options to pass when creating your client) is ws (yet another typedef of potential websocket options). In there, you'll find the intents property.
intents accepts a IntentsResolvable, which can be a string or an array of strings of an intent(s) (such as 'GUILD_PRESENCES'. All available intents), a bitfield (a number corresponding to an intent(s)), an instance of the Intents class.
Examples:
// using a string
const client = new Discord.Client({ ws: { intents: 'GUILD_PRESENCES' }});
// using an array
const client = new Discord.Client({ ws: { intents: ['GUILD_PRESENCES', 'GUILD_MEMBERS'] }});
// using a bitfield value
const client = new Discord.Client({ ws: { intents: 32509 }));
// using Intents class
const client = new Discord.Client({ ws: { intents: Discord.Intents.PRIVILEDGED }});
const client = new Discord.Client({ ws: { intents: new Discord.Intents(Discord.Intents.ALL) }});
Resources:
Discord.js Official Guide - Gateway Intents
Discord Developer Documentation - Gateway Intents
Gateway Update FAQ
Discord API Github - Issue 1363 - Privileged Intents
Discord Blog - The Future of Bots on Discord
TL;DR
To fix this issue, go to:
Discord Developer Portal > Applications > Your Application > Bot > Check both/either intent(s) (screenshot above)
So, I wanted to create a command like .getuser #role and the bot then tags every user with that role and after it says x people have this role..
The problem is that I couldn't find anywhere something that resembles this, I hope someone will help me cause I'm out of luck on this one!
You can use roles.get()
members = message.guild.roles.cache.find(role => role.name === 'role name').members.map(m=>m.user.tag);
Edit:
I've been received lots of messages claiming that the bot is inaccurately showing what members have what roles. This is because discord uses the cache to grab info about roles. To fix this do the following...
Navigate to your application at https://discord.com/developers/applications
Go to the bot section
Turn ON "Server Members Intent"
This will make it so that your discord bot doesn't grab from the cache for member data from the api.
let membersWithRole = guild.roles.resolve('role_ID').members.size
Basically we get a specific role from a guild trough its ID and then we see the size of the members collection of the role.
In a program, i want to know if the bot is connected or disconnected in any voice channel on a specific server. I see the Voice Statuses on the wiki but i dont know how to use it.
You should try read the documentation a little bit more.
So, from client you have all the guilds that client is: client.guilds. Then from that you can filter the guilds, client.guilds.get('thisID'). And according to the documentation, with a guild you can get the voiceConnection from that guild with: guild.voiceConnection.
It will return null if the client is not on any voiceChannel.