I have a code where if someone joins the bot gives a Privat message and a Role but when a user joins, the bot does not give the message and the Role.
TypeError: memb.guild.roles.find
const AUTOROLEID = "689098211536666624"
client.on('guildMemberAdd', (memb) => {
var role = memb.guild.roles.find(r => r.id == "689098211536666624")
if (role) {
memb.addRole(role).then(() => {
memb.send('', new Discord.MessageEmbed().setColor(0x18FFFF).setDescription(`Willkommen aufm Discord deine aktuelle rolle ist ${role.name}!`))
})
}
})
As Discord.js v12 docs you need to access the property cache after <GuildMember>.guild.roles which is a collection of all roles in the guild so you can try this:
var role = memb.guild.roles.cache.find(r => r.id == "689098211536666624")
From the given code, I assume you are using discord.js v11 which got deprecated. So update to v12. v12 introduced the concept of managers/cache. In v11 you were able to use collection methods like get() and find()on collection structures, but now you need to ask for cache on a manager before trying to use collection methods.
Eg:
var role = memb.guild.roles.cache.find(r => r.id == "689098211536666624") //find requires a function
var var role = memb.guild.roles.cache.get("689098211536666624"); //get requires an ID as string.
and <GuildMember>.addRole() method got deprecated. You need to pass through the managers(GuildMemberRoleManager) and then call then .add() method.
Eg:
var role = memb.guild.roles.cache.find(r => r.id == "689098211536666624")
if(role){
memb.roles.add(role).then(()=>{
//do things.
}
}
Related
I'm trying to create a modmail system and whenever I try to make it, it says "channel.send is not a function, here is my code."
const Discord = require("discord.js")
const client = new Discord.Client()
const db = require('quick.db')
// ...
client.on('message', message => {
if(db.fetch(`ticket-${message.author.id}`)){
if(message.channel.type == "dm"){
const channel = client.channels.cache.get(id => id.name == `ticket-${message.author.id}`)
channel.send(message.content)
}
}
})
// ...
client.login("MYTOKEN")
I'm trying this with version 12.0.0
EDIT:
I found my issue, for some reason the saved ID is the bots ID, not my ID
As MrMythical said, you should use the find function instead of get. I believe the issue is that you're grabbing a non-text channel, since channel is defined, you just can't send anything to it.
You could fix this by adding an additional catch to ensure you are getting a text channel, and not a category or voice channel. I would also return (or do an error message of sorts) if channel is undefined.
Discord.js v12:
const channel = client.channels.cache.find(c => c.name === `ticket-${message.author.id}` && c.type === 'text');
Discord.js v13:
const channel = client.channels.cache.find(c => c.name === `ticket-${message.author.id}` && c.type === 'GUILD_TEXT');
Edit:
You can tell channel is defined because if it weren't it would say something along the lines of: Cannot read property 'send' of undefined.
You are trying to find it with a function. Use .find for that instead:
const channel = client.channels.cache.find(id => id.name == `ticket-${message.author.id}`)
I want to run a command on my discord bot and add a secondary role to all members which have the predefined role.
Its gonna be like this. All members have the X role are gonna be assigned to the Y role.
I tried to write to code but I failed so I am writing my code as pseudo-code below any help will be great.
const userID = "1234"; //this is my userid so only I will be able to use this command
let roleID1 = "xxxx";
let roleID2 = "yyyy";
client.on("message", function (message) {
if (message.author.id === userID) {
if (message.content === "!setrole") {
// Code for taking the list of all members with role xxxx.
// Code for assigning all those people to the role yyyy.
message.channel.send("Roles assigned");
}
}
});
Try this:
// iterate a function through all members of the guild
message.guild.members.cache.forEach((member) => {
if (member.roles.cache.has(roleID1) // if member has x role
member.roles.add(roleID2); // give y role
});
You could also use Array.prototype.filter(); although there's no difference in execution, it might be faster (but I really have no idea):
message.guild.members
.filter((member) => member.roles.cache.has(roleID1))
.forEach((member) => member.roles.add(roleID2))
So I wrote the following code that is supposed to mute all the members in a given channel:
client.on('message', message => {
if (message.content == 'sh!') {
let channel = message.member.voice.channel
for (let member of channel.members) {
member[1].setMute(true)
}
}
})
But it does not work and I cannot find out why because I do not really know how the setMute() function works.
EDIT: I am not sure about how I can access every member and mute it
The 'setMute' function is part of the member's voice state object. You're using it directly from the GuildMember object itself. As you may already know, the voice state object is the property 'voice' of the GuildMember object. So here's the solution:
// change this
member[1].setMute(true);
// to this
member[1].voice.setMute(true);
The property Members of a VoiceChannel is a Discord Collection (which extends from Javascript Map), I would iterate using a forEach loop so I could avoid Downlevel Iteration.
This should work:
client.on('message', message => {
if (message.content == 'sh!') {
const members = message.member.voice.channel.members;
members.forEach(member => {
member.voice.setMute(true);
});
}
});
Here's some useful links:
TextChannel#members | discord.js
Collection | discord.js
Map - JavaScript | MDN
I want the bots status to show the amount of people that currently are online. I have been trying with this code but it keeps saying:
TypeError: client.guilds.get is not a function
//Checks if the bot is online
client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
//Activity
var guild = client.guilds.get('id here');
var onlineCount = guild.membersCount.filter(m => m.presence.status === 'online').size
client.user.setActivity('games with ' + onlineCount + ' people' , { type: 'PLAYING' });
});
Since discord.js v12 you now need to use the cache property to access guilds collection, so you need to replace var guild = client.guilds.get('id here'); with var guild = client.guilds.cache.get('id here');
Unrelated to the question:
You are getting the guild's memberCount and filtering it to get the number of online users in that guild, the problem with that is that memberCount returns a number not a collection of GuildMembers, what you need to use is the members property instead, which to access that collection, you need to use cache again:
var onlineCount = guild.members.cache.filter(m => m.presence.status === 'online').size
So I have been utterly frustrated these past few days because I have not been able to find a single resource online which properly documents how to find emojis when writing a discord bot in javascript. I have been referring to this guide whose documentation about emojis seems to be either wrong, or outdated:
https://anidiots.guide/coding-guides/using-emojis
What I need is simple; to just be able to reference an emoji using the .find() function and store it in a variable. Here is my current code:
const Discord = require("discord.js");
const config = require("./config.json");
const fs = require("fs");
const client = new Discord.Client();
const guild = new Discord.Guild();
const bean = client.emojis.find("name", "bean");
client.on("message", (message) => {
if (bean) {
if (!message.content.startsWith("#")){
if (message.channel.name == "bean" || message.channel.id == "478206289961418756") {
if (message.content.startsWith("<:bean:" + bean.id + ">")) {
message.react(bean.id);
}
}
}
}
else {
console.error("Error: Unable to find bean emoji");
}
});
p.s. the whole bean thing is just a test
But every time I run this code it just returns this error and dies:
(node:3084) DeprecationWarning: Collection#find: pass a function instead
Is there anything I missed? I am so stumped...
I never used discord.js so I may be completely wrong
from the warning I'd say you need to do something like
client.emojis.find(emoji => emoji.name === "bean")
Plus after looking at the Discord.js Doc it seems to be the way to go. BUT the docs never say anything about client.emojis.find("name", "bean") being wrong
I've made changes to your code.
I hope it'll help you!
const Discord = require("discord.js");
const client = new Discord.Client();
client.on('ready', () => {
console.log('ready');
});
client.on('message', message => {
var bean = message.guild.emojis.find(emoji => emoji.name == 'bean');
// By guild id
if(message.guild.id == 'your guild id') {
if(bean) {
if(message.content.startsWith("<:bean:" + bean.id + ">")) {
message.react(bean.id);
}
}
}
});
Please check out the switching to v12 discord.js guide
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.
In this specific situation, you need to add the cache object to your expression:
var bean = message.guild.emojis.cache?.find(emoji => emoji.name == 'bean');
In case anyone like me finds this while looking for an answer, in v12 you will have to add cache in, making it look like this:
var bean = message.guild.emojis.cache.find(emoji => emoji.name == 'bean');
rather than:
var bean = message.guild.emojis.find(emoji => emoji.name == 'bean');