Cannot read property 'first' of null - javascript

So I'm currently making a discord bot so whenever someone types !true #USER [Location] it will DM the #USER a message, add a role and then nickname the user to [Location] with the following code :
const mention = message.mentions.members.first();
msg = message.content.toLowerCase();
if (msg.startsWith(prefix)){
if(message.channel.id === '12345'){
if (msg.startsWith (prefix + "true")){
if(!message.member.hasPermission("MANAGE_NICKNAMES")) return message.reply("You have no permission!");
if (mention == null) { return; }
let args = message.content.split(" ").slice(2);
if ((mention.displayName + " " + args.join(" ")).length > 32) return message.channel.send("The nickname exceeds 32 characters")
if(mention.roles.cache.has('1234567890')){
message.reply("User is already accepted.")
} else {
mention.roles.add('1234567890').then(() => mention.setNickname(mention.displayName+" "+args.join(' ')))
.catch((e) => {
console.log('handle error here: ', e.message)
})
}
}}}
However, most of the time it will return with Cannot read property 'first' of null and it won't change the user's nickname (only roles and DM). Is there anything wrong with my code? Thanks.

const mention = message.mentions.members.first();
In the above code, message.mentions.members is null so you can't access a property (here first) in a null object.
The culprit is probably somewhere you set members property, not the code you provided here. do some debugging and console.log and you'll fix the issue.

You got error because you can`t get first of null. Better check mention in a command, like this.
if (msg.startsWith(prefix)) {
if (message.channel.id === '12345') {
if (msg.startsWith(prefix + 'true')) {
if (args.length < 0) return message.reply('PLS mention a member or write his ID');
const mention = message.mentions.members.first() || message.guild.members.cache.get(args[0]);
if (!mention) return message.reply('Can`t find a member');
msg = message.content.toLowerCase();
if (!message.member.hasPermission('MANAGE_NICKNAMES')) return message.reply('You have no permission!');
if (mention == null) {
return;
}
let args = message.content.split(' ').slice(2);
if ((mention.displayName + ' ' + args.join(' ')).length > 32) return message.channel.send('The nickname exceeds 32 characters');
if (mention.roles.cache.has('1234567890')) {
message.reply('User is already accepted.');
} else {
mention.roles
.add('1234567890')
.then(() => mention.setNickname(mention.displayName + ' ' + args.join(' ')))
.catch(e => {
console.log('handle error here: ', e.message);
});
}
}
}
}

Related

TypeError: mention.send is not a function - discord.js

I have been trying to code this discord bot to send a message to a certain person through DMs. The way it is supposed to work is:
tb!send #usernamehere Hi
Then this should send a DM message to #usernamehere saying, "Hi". But instead, I get an error saying TypeError: mention.send is not a function. Here is my code:
client.on('message', (message) => {
var msg = message.content.toLowerCase();
if (message.author.bot) return;
let mention = message.mentions.users.first().id;
if (msg.startsWith(prefix + 'send')) {
console.log('ok');
if (mention == null) return;
message.delete();
var mentionMessage = message.content.slice(8);
mention.send(mentionMessage);
message.channel.send('done!');
}
});
Change
let mention = message.mentions.users.first().id;
to
let mention = message.mentions.users.first();
You can choose between using the id or mention
ID
let mention = message.mentions.users.first().id;
if (msg.startsWith(prefix + 'send')) {
console.log('ok');
if (mention == null) {
return;
}
message.delete();
mentionMessage = message.content.split(' ').slice(1);
client.users.cache.get(mention).send(mentionMessage);
message.channel.send('done!');
}
Or mention
let mention = message.mentions.users.first();
if (msg.startsWith(prefix + 'send')) {
console.log('ok');
if (mention == null) {
return;
}
message.delete();
mentionMessage = message.content.split(' ').slice(1);
mention.send(mentionMessage);
message.channel.send('done!');
}
Also I changed message.content.slice(8) to message.content.split(' ').slice(1) so it will work with all prefix that doesn't have a space.

Creating a BulkDelete command | Discord.JS

As you read by the title I'm trying to make a clear command for my Discord bot, but I can't get it to work.
Here's a snippet:
client.on('message', message => {
if (message.content = "clear") {
let args = message.content.substring(prefix.length).split(" ");
var deleteCount = message.guild.members.cache.get(args[1]);
if (message.member.hasPermission("MANAGE_MESSAGES")) {
const deleteCount = args[2];
const fetched = ({
limit: deleteCount
});
message.delete(fetched)
try {
} catch (error) {
}(error => message.reply(`Couldn't delete messages because of: ${error}`));
if (!deleteCount || deleteCount < 2 || deleteCount > 100)
return message.reply("Please provide a number between 2 and 100 for the number of messages to delete");
message.channel.send('Successfully deleted ' + `${deleteCount}` + 'messages!');
}
}
});
Also, don't ask me what I'm doing and why I copied some stuff from other people trying to make it but the code was outdated.
Can someone help me?
client.on("message", message => {
if (message.content.indexOf(prefix) !== 0) {return false};
const arguments = message.content.slice(prefix.length).trim().split(/ +/g);
const command = arguments.shift().toLowerCase();
if (command == "clear") {
if (!message.member.hasPermission("MANAGE_MESSAGES")) return message.channel.send("You are not allowed to use this command.");
if (!arguments[0]) return message.channel.send("Please provide a number between 2 and 100.")
if (arguments[0] < 2 || arguments[0] > 100) return message.channel.send("Please provide a number between 2 and 100.")
message.channel.bulkDelete(arguments[0]).then(messages => {
message.channel.send(`Deleted ${messages.size} messages.`);
}).catch(e => console.log(e));
};
});

Why Discord.js API dont see message.channel.id?

I have just created a simple bot with that code:
client.on('message', async message => {
if (!message.author.bot) {
if (!getClub(message) && (message.channel.id == channel_bot || message.channel.type != "dm")) { //
getRadio(message);
}
} else if (message.channel.id = channel_dev && message.author.bot) {
getDevCommands(message);
}
});
and I check bot command with
function getClub(msg) {
const args = msg.content.slice(msg.content.includes(config.prefix) ? config.prefix.length : 0).trim().split(/ +/g);
let isClub = false;
club_commands.forEach(function (element) {
if (element.id == "club" && element.commands.includes(args[0])) {
isClub = true;
}
});
if (!isClub) {
return false;
}
club_commands.forEach(function (element) {
// element is parsed object from JSON: {"id":"join", "commands":"join,attach,invite..."}
if (element.commands.includes(args[1])) {
switch (element.id) {
case "stats":
clubStats(msg);
return true;
case "join":
clubParticipation(msg, 1);
return true;
case "leave":
clubParticipation(msg, 0);
return true;
default:
// do nothing
break;
}
}
});
return false;
}
So in clubPartisipation() im getting in msg.channel.id - actual channel id but only "true" for the all next messages
function clubParticipation(msg, status) {
const args = msg.content.trim().split(/ +/g).splice(2, 2).join("");
if (args.length <= 3) {
msg.channel.send("test0");
} else {
let member = guild.members.get(msg.author.id);
if (status == "1") {
msg.channel.send("test1").catch(console.log);
} else {
msg.channel.send("test3").catch(console.log);
}
getHTTPResponce(config.server_url + 'add/club/participation?channel_id=' + msg.channel.id + '&status=' + status + '&user_id=' + member.id + '&club_id=' + Base64.encode(Base64.encode(args)) + '&token=' + config.server_token, msg)
.catch(console.log);
}
}
Error code is
{ DiscordAPIError: Invalid Form Body
channel_id: Value "true" is not snowflake.
at item.request.gen.end (/root/curatortojps/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js:85:15
)
at then (/root/curatortojps/node_modules/snekfetch/src/index.js:215:21)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
name: 'DiscordAPIError',
message: 'Invalid Form Body\nchannel_id: Value "true" is not snowflake.',
path: '/api/v7/channels/true/messages',
code: 50035,
method: 'POST' }
In your first block of code, you have:
(message.channel.id = channel_dev && message.author.bot)
= is an assignment operator. This means that you're setting message.channel.id to the value of channel_dev && message.author.bot, a boolean (true or false).
You should use an equality operator like == or === to compare the value of message.channel.id. For the difference between the two, check out this answer.
(message.channel.id === channel_dev && message.author.bot)

If statement firing when it shouldn't

Line 14 should fire if there are no commands with the guild id,
Line 15 should fire if the user has no commands in that guild,
but
!commands #Rusty#2746 returns No commands in this guild. in the server Go away. (I have a command in this server)
!commands #Rusty#2746 returns No commands in this guild. AND the actual command in the server SurgicalGoblin. ( I have a command in this server)
let user = message.mentions.users.first();
if (args.length !== 1) return message.reply("Incorrect arguments, " + args.length + " given, 1 required.");
if (message.mentions.users.size !== 1) return message.reply("You must mention a user to view the commands of.");
fs.readFile(path.join(__dirname, "../jsonFiles") + "/customCommands.json", "utf-8", function(err, data) {
if (err) throw err;
var arrayOfObjects = JSON.parse(data);
if (arrayOfObjects.commands.length === 0) return message.reply("No custom commands found.");
for (let i = 0; i < arrayOfObjects.commands.length; i++) {
console.log(message.guild.id) // matches the guild_id in json file
if (message.guild.id !== arrayOfObjects.commands[i].guild_id) return message.reply("No commands in guild.");
if (message.guild.id !== arrayOfObjects.commands[i].guild_id && user.id !== arrayOfObjects.commands[i].user_id) return message.reply(user.username + " has no commands in this guild.");
fs.writeFile(path.join(__dirname, "../jsonFiles") + "/customCommands.json", JSON.stringify(arrayOfObjects, null, 2), "utf-8", function(err) {
if (err) throw err;
const embed = new Discord.RichEmbed()
.setColor(0x08F258)
.setAuthor("Custom Commands for " + user.username, message.author.avatarURL)
.addField(arrayOfObjects.commands[i].command_name, arrayOfObjects.commands[i].command_reply)
return message.channel.sendEmbed(embed);
});
}
});
JSON: https://hastebin.com/zucogajita.json
In case the solution is helpful to anyone else, I discussed this with the OP in chat and discovered that the issue occurred because the OP wanted to compare the current message's guild with the corresponding guild in the JSON data. Therefore, I suggested taking out the for loop completely and instead finding the guild first (using find()) and then doing a comparison:
let user = message.mentions.users.first();
if (args.length !== 1) return message.reply("Incorrect arguments, " + args.length + " given, 1 required.");
if (message.mentions.users.size !== 1) return message.reply("You must mention a user to view the commands of.");
fs.readFile(path.join(__dirname, "../jsonFiles") + "/customCommands.json", "utf-8", function(err, data) {
if (err) throw err;
var arrayOfObjects = JSON.parse(data);
if (arrayOfObjects.commands.length === 0) return message.reply("No custom commands found.");
var guild = arrayOfObjects.commands.find(function(obj) { return obj.guild_id == message.guild.id; });
if (message.guild.id !== guild.guild_id) return message.reply("No commands in guild.");
if (message.guild.id !== guild.guild_id && user.id !== guild.user_id) return message.reply(user.username + " has no commands in this guild.");
fs.writeFile(path.join(__dirname, "../jsonFiles") + "/customCommands.json", JSON.stringify(arrayOfObjects, null, 2), "utf-8", function(err) {
if (err) throw err;
const embed = new Discord.RichEmbed()
.setColor(0x08F258)
.setAuthor("Custom Commands for " + user.username, message.author.avatarURL)
.addField(guild.command_name, guild.command_reply)
return message.channel.sendEmbed(embed);
});
});

Prohibition of the use of emojireact-role in third-party channels

how to make sure that the role when pressing the bell is give only in a certain channel? The code is below. Can also make that only administrators have the right to issue reactions with a bell that will issue a role. Help, pls.
var emojiname = ["🔔"];
var rolename=["🔔 Notifications"];
client.on('message', msg => {
if(msg.content.startsWith("reaction" && message.channel.name.toLowerCase() === 'information')){
if(!msg.channel.guild) return;
for(let n in emojiname){
var emoji =[msg.guild.emojis.find(r => r.name == emojiname[n])];
for(let i in emoji){
msg.react(emoji[i]);
}
}
}
});
client.on("messageReactionAdd",(reaction,user)=>{
if(!user) return;
if(user.bot)return;
if(!reaction.message.channel.guild) return;
for(let n in emojiname){
if(reaction.emoji.name == emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).addRole(role).catch(console.error);
}
}
});
client.on("messageReactionRemove",(reaction,user)=>{
if(!user) return;
if(user.bot)return;
if(!reaction.message.channel.guild) return;
for(let n in emojiname){
if(reaction.emoji.name == emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).removeRole(role).catch(console.error);
}
}
});
Here it is.
First, be aware that there is 2 types of discord emojis. The unicode one, common emoji, like âž¡. And the guild emoji, that you add to a server.
The first one are represented only by the unicode name, while the second have an id and others difference (see Emoji and Message Reaction)
That being said, I used the name of the emoji in the emojiname array. I then changed a little bit the code to accept both unicode and guild emojis.
The rest of the code was good. Just be sure to use === instead of == except if you realy want to accept "falsy" term.
demo gif
// âž¡ is an ascii emoji
// lina is a guild emoji
var emojiname = ['âž¡', 'lina'];
var rolename=["âž¡ Notifications", "lina supporter"];
client.on('message', msg => {
if(msg.content.startsWith('reaction') && (msg.channel.name.toLowerCase() === 'information')) {
for (let n in emojiname){
let emoji = msg.guild.emojis.find(r => r.name === emojiname[n]);
if (emoji === null) {
emoji = emojiname[n];
}
msg.react(emoji);
}
}
});
client.on("messageReactionAdd",(reaction,user)=>{
if (!user) { return; }
if (user.bot) { return; }
if (reaction.message.channel.name.toLowerCase() !== 'information') { return; }
for(let n in emojiname){
if(reaction.emoji.name === emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name === rolename[n]);
reaction.message.guild.member(user).addRole(role).catch(console.error);
}
}
});
client.on("messageReactionRemove",(reaction,user)=>{
if(!user) { return; }
if(user.bot) { return; }
if (reaction.message.channel.name.toLowerCase() !== 'information') { return; }
for(let n in emojiname){
if(reaction.emoji.name === emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).removeRole(role).catch(console.error);
}
}
});

Categories