I have a command that sends a DM to user and the user is defined like this:
let user;
if (message.mentions.users.first()) {
user = message.mentions.users.first();
} else if (args[0]) {
user = message.guild.members.cache.get(args[0]).user;
}
But if I ping a user that is not in this server or write something that is not #user, it sends an error "user is not defined". I tried making if (user == "undefined"), but it just aborts before it reaches it or if I put it above it can't work.
Instead of looking for the members with message.guild.members and then get the user from there, you could get the client.users and check if a user with the args[0] ID exists. If it doesn't exist, you can simply check if (!user) you don't have to check if it's undefined.
const user = message.mentions.users.first() || message.client.users.cache.get(args[0]);
if (!user)
return message.channel.send('There is no user mentioned');
message.channel.send(`You mentioned ${user}`);
You can also use fetch() to get the user instead of relying on cache:
let user;
try {
user = message.mentions.users.first() || (await message.client.users.fetch(args[0]));
} catch (error) { console.log(error); }
if (!user)
return message.channel.send('There is no user mentioned');
message.channel.send(`You mentioned ${user}`);
You are currently checking if you have written user as "undefined" when actually you want to see if the user is undefined.
Another issue with your code is that args[0] will return the command name when you want the next argument over from that, args[1].
Full example:
let user;
if (message.mentions.users.first()) {
user = message.mentions.users.first();
} else if (args[0]) {
user = message.guild.members.fetch(args[1]).user;
} else {
return message.channel.send("Please provide a user"); //Sends if the message author did not provide a user
}
if (user == undefined) return message.chanel.send("I could not find the user you are looking for"); //Sends if the user is not in the current guild or doesn't exist
For each variable in javascript you can take its type and obviously if its type is === 'undefined' then it is undefined.
if(typeof comment === 'undefined') {
alert('Variable "comment" is undefined.');
}
Related
On my server, we have a channel for just one word, "Oi".
If someone sends something other than the word "Oi", it gets deleted. But now I need a code that deletes the message if someone sends it twice in a row. They have to wait for someone else to send if they want to send.
This is my current code if you want to check it out for some reason:
if (message.channel.id === "ChannelIdWhichImNotGonnaTell") {
if (message.content === "Oi") {
let log = client.channels.cache.get("ChannelIdWhichImNotGonnaTell")
log.send(`New Oi By ${message.author.tag}`)
} else {
message.delete()
}
}
You can fetch() the last two messages by using the limit option and the last() in the returned collection will be the second last message in the channel (the one before the last one triggered your code).
Then you can compare the author's IDs; if they are the same, you can delete the message:
if (message.channel.id === oiChannelID) {
if (message.content === 'Oi') {
// fetch the last two messages
// this includes this one and the previous one too
let lastMessages = await message.channel.messages.fetch({ limit: 2 });
// this is the message sent before the one triggered this command
let previousMessage = lastMessages.last();
if (previousMessage.author.id === message.author.id) {
console.log('No two Ois, mate');
message.delete();
// don't execute the rest of the code
return;
}
let log = client.channels.cache.get(logChannelID);
log.send(`New Oi By ${message.author.tag}`);
} else {
message.delete();
}
}
There's some several work around for this. But I found this is the efficient way to do that.
As you said 'They have to wait for someone else to send oi' then you should fetch the "old message" before "the new message" that sent. and try to get the User ID. Then compare it with the new message one.
Here is the Example code :
if (message.content === 'Oi') {
message.channel.messages.fetch({limit: 2})
.then(map => {
let messages = Array.from(map.values());
let msg = messages[1];
if (msg.author.id === message.author.id){
message.delete();
// do something
} else {
let log = client.channels.cache.get("ChannelID")
log.send(`New Oi By ${message.author.tag}`)
}}).catch(error => console.log("Error fetching messages in channel"));
}
It will compare the "old messages" author UserID with the "new messages" author UserID. If it's match. Then it will be deleted.
I have this unban command and I want it to DM the user that got DMd but I cant get it working. send keeps being undefined.
if(command === "unban") {
const user = message.mentions.users.first() || client.users.cache.get(args[0])
if (!message.member.hasPermission("BAN_MEMBERS")) return message.channel.send("You need permissions!")
if (!message.guild.me.hasPermission("BAN_MEMBERS")) return message.channel.send("Bot need permissions!")
const reason = args[1] || "There was no reason!";
message.guild.members.unban(user, reason)
message.channel.send(`${user} has been unbanned from the server!`);
user.send("You've been unbanned!")
}
I think the error says "Cannot read property 'send' of undefined". It doesn't mean send is undefined, it means user is.
The problem is that you don't check if someone is mentioned in the message and try to send a DM anyway. Make sure you're checking if there's a user and send an error message if there isn't any.
It's also a good idea to only send a message once the user is unbanned. You can use .then() or async/await:
if (command === 'unban') {
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user)
return message.channel.send('You need to mention someone to unban');
if (!message.member.hasPermission('BAN_MEMBERS'))
return message.channel.send('You need permissions!');
if (!message.guild.me.hasPermission('BAN_MEMBERS'))
return message.channel.send('Bot need permissions!');
const reason = args[1] || 'There was no reason!';
message.guild.members
.unban(user, reason)
.then(() => {
message.channel.send(`${user} has been unbanned from the server!`);
user.send("You've been unbanned!");
})
.catch(console.log);
}
I'm trying to make a command that gives you on the command, !role {pronoun}. If the pronoun exists then it will give you the existing role, but if it doesn't exist it will give you the role already made. Each time I run the command though I get an error that says "Type Error: fn.bind is not a function". I have no clue why, if y'all could help me out that would be amazing.
client.on('message', async message => {
var input = (message.content.substr(12))
var roleName = (message.content.substr(12));
var role = message.guild.roles.cache.find(r => r.name == roleName);
if(!role){
if (message.member.roles.cache.find("name", "Member")){
message.channel.sendMessage('Sorry you already have a pronoun');
return;
}
else if (input === ""){
message.channel.sendMessage('Please Enter a Valid Pronoun Name');
return;
}
else{
var pronounName = message.guild.roles.find(role => role.name === "Member");
message.member.guild.createRole({
name: message.content.substr(12),
}).then(function(role)
{
message.member.addRole(role);
message.member.addRole(pronounName);
message.channel.sendMessage('You have created the pronoun: ' + role);
});
}
}else{
message.channel.sendMessage('That Pronoun Already Exists!');
return;
}
})
It's caused by message.member.roles.cache.find("name", "Member"). The .find() method accepts a function as its first argument (you provided a string) and the value to use as this as its second argument (you provided another string).
You could find a role by checking if the name property is equal to "Member":
message.member.roles.cache.find((role) => role.name === 'Member')
PS: Chances are there are other errors in your code but TypeError: fn.bind is not a function can be solved by this.
I want to create a command to send DM to users who reacted (all reactions) to a message from ID. I want to filter the bots and don't send two messages for one user if they reacted twice.
if (command === 'gopv') {
message.channel.messages.fetch("806866144597770280").then((reactionMessage) => {
console.log(
reactionMessage.reactions.cache
.each(async(reaction) => await reaction.users.fetch())
.map((reaction) => reaction.users.cache.filter((user) => !user.bot))
.flat()
);
});
}
I would probably create a dmSent object with the user IDs as keys, so I could easily check if a DM was already sent to them. When you loop over the users reacted to the message, you can check if the ID already exists or if the user is a bot. If the user is not found in the dmSent object, you can send a message and add the user ID to the object.
I've just checked it, the following sends only one message to each user who reacted at least to the message:
if (command === 'gopv') {
const dmSent = {};
try {
const { reactions } = await message.channel.messages.fetch('806866144597770280');
reactions.cache.each(async (reaction) => {
const usersReacted = await reaction.users.fetch();
usersReacted.each((user) => {
if (dmSent[user.id] || user.bot) return;
dmSent[user.id] = true;
user.send('You sent at least one reaction, so here is a DM.');
});
});
} catch (err) {
console.log(err);
}
}
I'm making a ban command and trying to check if the input is an invalid user. Then, I'm trying to check if that user is valid, and if so, check if the user is not banned.
Here's my code involved with the check:
const user = message.mentions.users.first() || await client.users.fetch(args[0]).catch(error => {
return message.channel.send('Please enter a valid user.');
});
const checkBan = await message.guild.fetchBan(user.id).catch(error => {
return null;
});
if (checkBan == null) {
return message.channel.send('This user is already banned.');
}
if (!user) {
return message.channel.send('Please specify a user.');
}
//output > "Please enter a valid user." & "This user is not banned."
If your input is not a valid user, it sends both error messages, and if the user is valid and is banned it does work correctly.
So my question is, why are both error messages sent if the user is invalid, and how do I fix the issue?