I am trying to create a function for adding and removing a role from a user given the username (not user ID).
So far I have code that works with user ID. My question is how can I modify this code to work given the username?
const addDiscord = async (discord_username) => {
const guild = client.guilds.cache.get('<guild-id>'); // copy the id of the server your bot is in and paste it in place of guild-ID.
const role = guild.roles.cache.get('<role-id>'); // here we are getting the role object using the id of that role.
const member = await guild.members.fetch('user-id'); // here we are getting the member object using the id of that member. This is the member we will add the role to.
await member.roles.add(role); // here we just added the role to the member we got.
}
Here is my function that will handle checking for new user to add/remove
const checkNew = async () => {
if(toUpdate.length > 0) { // Check if there are any new users to update
toUpdate.forEach(element => {
addDiscord(element.new)
// Remove element.old from Discord role
// Add element.new to Discord role
})
toUpdate = []
}
}
And here I am connecting to bot and calling the checkNew() function every 10 seconds
client.once('ready', () => {
console.log('Ready!');
setInterval(checkNew, 10000)
});
Update:
I tried using client.users.cache.find() but it returns undefined
const addDiscord = async (discord_username) => {
const guild = client.guilds.cache.get('<guild-id>'); // copy the id of the server your bot is in and paste it in place of guild-ID.
const role = guild.roles.cache.get('<role-id>'); // here we are getting the role object using the id of that role.
console.log(discord_username)
const id = client.users.cache.find(u => u.tag === discord_username)
console.log(id)
}
Update 2: Attempted to implement the code from Miqhtie's answer
const addDiscord = async (discord_username) => {
const guild = client.guilds.cache.get('<server-id>'); // copy the id of the server your bot is in and paste it in place of guild-ID.
const role = guild.roles.cache.get('<role-id>'); // here we are getting the role object using the id of that role.
const members = await guild.members.fetch()
const member = members.find((m) => m.username === '<discord-username>')
console.log(member)
}
Error:
const member = members.find((m) => m.username === '<discord-username>')
^
TypeError: members.find is not a function
There is no specific method to fetch a GuildMember by username so what you would have to do is fetch all the members from a guild
<guild>.members.fetch()
and then filter it for a member whos username property is equal to the username you want.
An example implementation of this would be
const username = "Super Cool Username";
const members = await guild.members.fetch();
const member = members.find((m) => m.username === username);
member.roles.cache.add(role);
Related
I am trying to create a bot in discord that allows 2 captains two alternate picking teams until there are teams of 4 on each side. (1 captain, and 3 others). The captain would be picked randomly once 8 members signify; they are ready.
`
class MessageCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.cache.get(data.channel_id);
if (channel) {
const existing = channel.messages.cache.get(data.id);
if (existing) return { message: existing };
const message = channel.messages.add(data);
const user = message.author;
let member = message.member;
channel.lastMessageID = data.id;
if (user) {
user.lastMessageID = data.id;
user.lastMessageChannelID = channel.id;
}
if (member) {
member.lastMessageID = data.id;
member.lastMessageChannelID = channel.id;
}
/**
* Emitted whenever a message is created.
* #event Client#message
* #param {Message} message The created message
*/
client.emit(Events.MESSAGE_CREATE, message);
return { message };
}
return {};
}
}
`
You first need to fetch the guild where the channel is in, after that you can get the channel and message.
You can also see this post made by another user with the same error has you https://stackoverflow.com/a/66873076/15256312
you need to use ASYNCHRONOUS (async) to use await
const client = this.client;
const guild = client.guilds.cache.fetch(data.guild_id);
const channel = guild.channels.cache.get(data.channel_id);
if (channel) {
const existing = await channel.messages.fetch(data.id);
//...
}
Is there any way how to count messages of specified user in specified Discord channel in discord.js? When I use:
const countMyMessages = async (channel, member) => {
const messages = await channel.messages.fetch()
const myMessages = message.filter(m => m.author.id === member.id)
console.log(myMessages.size)
}
Only 50 messages are fetched, so I can't count all messages of user. And option limit can have max value 100. /guilds/guild_id/messages/search API on the other hand is not available for bots.
You will need to use a storage system to keep this kind of statistics on Discord.
I recommend you to use SQLite at first (like Enmap npm package).
I can quickly draw a structure for you based on this one.
const Enmap = require("enmap");
client.messages = new Enmap("messages");
client.on("message", message => {
if (message.author.bot) return;
if (message.guild) {
const key = `${message.guild.id}-${message.author.id}`;
client.messages.ensure(key, {
user: message.author.id,
guild: message.guild.id,
messages: 0
});
client.messages.inc(key, "messages");
// Do your stuff here.
console.log(client.messages.get(key, "messages"))
}
});
I want to know is it possible to know if any member is connected to a any voice channel in discord.js v12.2.0. Please let me know if you have any clues on it.
Use VoiceChannel.members
const vc = <message>.guild.channels.cache.get('VC Id')
const members = vc.members //COLLECTION
To check if a member is in vc, use GuildMember.voice
const vc = <member>.voice.channel //VOICE CHANNEL
//if you want, you can check the vc name, id, etc with vc.name, vc.id, etc
EDIT
Here is an example for what you said in the comments
//MAKE SURE IT IS ASYNC CALLBACK
await client.guilds.fetch();
const VCs = [];
client.guilds.cache.forEach(async guild => {
await guild.channels.fetch();
let VCs = guild.channels.cache.filter(c => c.type === 'voice');
VCs.forEach(vc => {
if(vc.members) {
VCs.push(vc)
}
})
})
I hope this is what you wanted (VCs is an array with all VCs with members)
My member counter didn't work
Why always my channel have name "online 0" 0 errors, console log working I don't know why
This is my code
const guild = client.guilds.cache.get('693805106906398722');
setInterval(() =>{
const memberCount = guild.memberCount;
const channel = guild.channels.cache.get('824050164376666182');
channel.setName(`Użytkownicy ${memberCount.toLocaleString()}`);
console.log('Member Status: Updating...');
}, 1200000);
setInterval(() =>{
const memberCollection = guild.members.cache;
const online = memberCollection.filter(member => {
member.presence.status === 'online'
}).size;
const channel1 = guild.channels.cache.get('824050194177720391');
channel1.setName(`Online ${online}`);
console.log('Member online Status: Updating...');
}, 1200);
} ```
Do you have Intents Enabled in your bot? If you do not: Then please do it in the Discord Developers Portal for your Application. You need to enable Guild Members intent. Also please do not forget to update your stuff in the Client Constructor (aka const client = new Discord.Client()) so that you can access the guild Member information!
There's a mistake in the code
const online = memberCollection.filter(member => {
member.presence.status === 'online'
}).size;
Please make it
const online = memberCollection.filter(member => {
return member.presence.status === 'online'
}).size;
Since for the filter to work, you need to have a function which returns a boolean and you're not returning anything from your filter function, it is getting a bit messed up.
When a user joins the server, the bot sends a welcome message, i want to take that welcome message's ID and make the bot delete it if the users leaves after he joins. I tried to save the message's id in a variable and make the bot delete the message when the user leaves but without success. I already took a look at the docs, but I really can't understand how to make it.
Define an object to hold the welcome messages by guild and user. You may want to use a JSON file or database (I'd highly recommend the latter) to store them more reliably.
When a user joins a guild...
Send your welcome message.
Pair the the message's ID with the user within the guild inside of the object.
When a member leaves the guild...
Fetch their welcome message.
Delete the message from Discord and the object.
Example setup:
const welcomeMessages = {};
client.on('guildMemberAdd', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.send(`Welcome, ${member}.`);
if (!welcomeMessages[member.guild.id]) welcomeMessages[member.guild.id] = {};
welcomeMessages[member.guild.id][member.id] = message.id;
} catch(err) {
console.error('Error while sending welcome message...\n', err);
}
});
client.on('guildMemberRemove', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.fetchMessage(welcomeMessages[member.guild.id][member.id]);
if (!message) return;
await message.delete();
delete welcomeMessages[member.guild.id][member.id];
} catch(err) {
console.error('Error while deleting existing welcome message...\n', err);
}
});
To do this you would have to store the id of the welcome message and the user that it is tied to (ideally put this in an object). And when the user leaves you would use those values to delete that message.
Example code:
const Discord = require('discord.js');
const client = new Discord.Client();
const welcomeChannel = client.channels.find("name","welcome"); // Welcome is just an example
let welcomes = [];
client.on('message', (message) => {
if(message.channel.name === 'welcome') {
const welcomeObj = { id: message.id, user: message.mentions.users.first().username };
welcomes.push(welcomeObj);
}
});
client.on('guildMemberRemove', (member) => {
welcomes.forEach(welcome, () => {
if(welcome.user === member.user.username) {
welcomeChannel.fetchMessage(welcome.id).delete();
}
});
});
This only works if the welcome message includes a mention to the user so make sure that's in the welcome message.
Also I can't test this code myself at the moment so let me know if you encounter any problems.