I am getting a Cannot read the property 'inviter' of undefined error, and I'm not quite sure why. Here is my code:
Client.on('guildMemberAdd', async (member) => {
const cachedInvites = GuildInvites.get(member.guild.id);
const nweInvites = await member.guild.fetchInvites();
GuildInvites.set(member.guild.id, nweInvites);
try {
const usedInvites = nweInvites.find(
(inv) => cachedInvites.get(inv.code) < inv.uses
);
const embed = new Discord.MessageEmbed()
.setDescription(
`${member.user.tag} is the ${member.guild.memberCount}th member. \nInvited by ${usedInvites.inviter.username} \nNumber of uses: ${usedInvites.uses}`
)
.setTimestamp()
.setColor('YELLOW');
const WelcomeChannel = member.guild.channels.cache.find(
(channel) => channel.id === '704908658068422698'
);
WelcomeChannel.send(embed).catch((err) => {
console.log(err);
});
} catch (err) {
console.log(err);
}
});
Client.login();
I'm trying to create an invite manager bot. Any help would be appreciated, thanks!
What you can do is manage that situation by protecting your code.
try {
const usedInvites = nweInvites.find(
(inv) => cachedInvites.get(inv.code) < inv.uses
);
if (!usedInvites) {
return;
}
const embed = new Discord.MessageEmbed()
.setDescription(
`${member.user.tag} is the ${member.guild.memberCount}th member. \nInvited by ${usedInvites.inviter.username} \nNumber of uses: ${usedInvites.uses}`
)
.setTimestamp()
.setColor('YELLOW');
const WelcomeChannel = member.guild.channels.cache.find(
(channel) => channel.id === '704908658068422698'
);
WelcomeChannel.send(embed).catch((err) => {
console.log(err);
});
}
I added: if (!usedInvites) return; but you can do whatever action you need.
Related
I am getting the following error using discord.js V14 :
TypeError: Cannot read properties of undefined (reading 'send')
Thank you to anyone who can help me.
const { Client, Message, MessageEmbed } = require("discord.js");
const {SlashCommandBuilder} = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('test')
.setDescription('this is a test thing'),
/**
* #parom {Client} client
* #parom {Message} message
* #parom {String[]} args
*/
async execute(client, message, args, interaction) {
const questions = [
"test",
"test1?"
];
let collectCounter = 0;
let endCounter = 0;
const filter = (m) => m.author.id === message.author.id;
const author = message.author;
const appStart = await author.send(questions[collectCounter++]);
const channel = appStart.channel;
const collector = channel.createMessageCollector(filter);
message.delete({timeout: 100})
collector.on("collect", () => {
if (collectCounter < questions.length) {
channel.send(questions[collectCounter++]);
} else {
channel.send("submited!");
collector.stop("fulfilled");
}
});
const appsChannel = client.channels.cache.get("976110575547482152");
collector.on("end", (collected, reason) =>{
if (reason === "fulfilled") {
let index = 1;
const mappedResponses = collected
.map((msg) => {
return `${index++}) ${questions[endCounter++]}\n-> ${msg.content}`;
})
.join("\n\n");
appsChannel.send(
new MessageEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true}))
.setTitle("!New Report!")
.setDescription(mappedResponses)
.setColor(`RANDOM`)
.setTimestamp()
);
appsChannel.send(`<#1057374161846145076>`);
}
});
},
};
Note I was using this before and once I updated to V14 I started getting this error.
it should message the user the set questions then post the answers in a channel.
EDIT: I am getting the error on this line
const appStart = await author.send(questions[collectCounter++]);
My interactions.js file
module.exports = {
name: "interactionCreate",
async execute(interaction, client) {
if (interaction.isChatInputCommand()) {
const {commands} = client;
const {commandName} = interaction;
const command = commands.get(commandName);
if (!command) return;
try {
await command.execute(interaction, client);
} catch (error) {
console.error(error);
await interaction.reply({
content: `Something went wrong while executing this command...`,
ephemeral: true,
});
}
} else if (interaction.isButton()) {
const {buttons} = client;
const {customId} = interaction;
const button = buttons.get(customId);
if (!button) return new Error('This Button Does not exist');
try{
await button.execute(interaction, client);
} catch (err) {
console.error(err);
}
}
},
};
You're calling the execute method of your /test command file with (interaction, client) but the method expects (client, message, args, interaction).
A possible solution would be to change the /test command file to
// Optimized imports
const { Client, MessageEmbed, BaseInteraction,
SlashCommandBuilder } = require("discord.js");
module.exports = {
data: new SlashCommandBuilder()
.setName('test')
.setDescription('this is a test thing'),
// Fixed typo in #param
/**
* #param {Client} client
* #param {BaseInteraction} interaction
*/
async execute(interaction, client) {
const questions = [
"test",
"test1?"
];
let collectCounter = 0;
let endCounter = 0;
// Get "Author" from interaction
const author = interaction.user;
const filter = (m) => m.author.id === author.id;
const appStart = await author.send(questions[collectCounter++]);
const channel = appStart.channel;
const collector = channel.createMessageCollector(filter);
// Removed message.delete() because interactions aren't messages and cant be deleted.
collector.on("collect", () => {
if (collectCounter < questions.length) {
channel.send(questions[collectCounter++]);
} else {
channel.send("submited!");
collector.stop("fulfilled");
}
});
const appsChannel = client.channels.cache.get("976110575547482152");
collector.on("end", (collected, reason) => {
if (reason === "fulfilled") {
let index = 1;
const mappedResponses = collected
.map((msg) => {
return `${index++}) ${questions[endCounter++]}\n-> ${msg.content}`;
})
.join("\n\n");
appsChannel.send(
new MessageEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
.setTitle("!New Report!")
.setDescription(mappedResponses)
.setColor(`RANDOM`)
.setTimestamp()
);
appsChannel.send(`<#1057374161846145076>`);
}
});
},
};
So I was trying to fix this thing for a few hours now, and I have no idea what I'm doing wrong.
This thing should execute itself when member joins the guild
const { Discord, MessageEmbed } = require("discord.js")
module.exports = {
name: "guildMemberAdd",
run: async ({bot, member}) => {
const welcome = new MessageEmbed()
.setDescription(`
<:nezuko_peek:974066160108732517> — New friend just showed up: <#${member.user.id}>
Welcome fellow adventurer in **Jasmine Dragon**! What brings you in these sides? <:girl_love:973968823449436190> Here, go to <#972618593294512128> to introduce yourself and talk with us in <#971800237507248158>!
`)
.setImage("https://64.media.tumblr.com/01a9f72f062feaafa60cdbf80f9ba729/tumblr_inline_orgoyznIM51sd5e91_500.gif")
.setColor("#F7DF79")
.setFooter({ text: "Thank you for joining and enjoy your stay!" })
member.guild.channels.cache.get("971800237507248158").send({ content: `<#&974343947105206382>`, embeds: [welcome] })
}
}
Here's my event handler
const { getFiles } = require("../util/functions")
module.exports = (bot, reload) => {
const {client} = bot
let events = getFiles("./events/", ".js")
if (events.length === 0){
console.log("No events to load")
}
events.forEach((f, i) => {
if (reload)
delete require.cache[require.resolve(`../events/${f}`)]
const event = require(`../events/${f}`)
client.events.set(event.name, event)
if (!reload)
console.log (`${i + 1}. ${f} loaded`)
})
if (!reload)
initEvents(bot)
}
function triggerEventHandler(bot, event, ...args){
const {client} = bot
try {
if (client.events.has(event))
client.events.get(event).run(bot, ...args)
else
throw new Error(`Event ${event} does not exist`)
}
catch(err){
console.error(err)
}
}
function initEvents(bot) {
const {client} = bot
client.on("ready", () => {
triggerEventHandler(bot, "ready")
})
client.on("messageCreate", (message) => {
triggerEventHandler(bot, "messageCreate", message)
})
client.on("guildMemberAdd", () => {
triggerEventHandler(bot, "guildMemberAdd")
})
}
And here's my index.js
const Discord = require("discord.js")
require("dotenv").config()
const { MessageEmbed, MessageActionRow, MessageSelectMenu } = require("discord.js")
const slashcommands = require("./handlers/slashcommands")
const client = new Discord.Client({
intents: [
"GUILDS",
"GUILD_MESSAGES",
"GUILD_MEMBERS"
]
})
// Bot config
let bot = {
client,
prefix: "i?",
owners: ["511889215672287242"]
}
// Handlers
client.commands = new Discord.Collection()
client.events = new Discord.Collection()
client.slashcommands = new Discord.Collection()
client.loadEvents = (bot, reload) => require("./handlers/events")(bot, reload)
client.loadCommands = (bot, reload) => require("./handlers/commands")(bot, reload)
client.loadSlashCommands = (bot, reload) => require("./handlers/slashcommands")(bot, reload)
client.loadEvents(bot, false)
client.loadCommands(bot, false)
client.loadSlashCommands(bot, false)
// Slash commands handler
client.on("interactionCreate", (interaction) => {
if (!interaction.isCommand()) return
if (!interaction.inGuild()) return interaction.reply("This command can only be used in a server")
const slashcmd = client.slashcommands.get(interaction.commandName)
if (!slashcmd) return interaction.reply("Invalid slash command")
if (slashcmd.perm && !interaction.member.permissions.has(slashcmd.perm))
return interaction.reply("You don not have permission for this command")
slashcmd.run(client, interaction)
})
module.exports = bot
client.login(process.env.TOKEN)
Other events like "ready" and "messageCreate" are working just fine so I'm not sure why it's not working.
Recently I decided to update my Discord Bot from V12 to V13 and I encountered a problem with my Reaction Roles.
It only works if the bot doesn't restart. It worked perfectly on discord.js 12.5.3 and now I'm using discord.js 13.5.0. Could you guys help me with the problem?
Here is my code:
const { MessageEmbed } = require("discord.js");
const Discord = require('discord.js');
const { Client } = require('discord.js');
const client = new Client({
intents: 32767,
partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
});
const config2 = require("../config2");
module.exports = async (client, message, args) => {
client.on('messageCreate', async message => {
if (message.content.startsWith("22ar")) {
const embed = new MessageEmbed()
.setColor('#FFA500')
.setTitle(`Pick the roles`)
.setDescription(`🔓 **- You unlock yourself.**
✅ **- You get access to the server.**
💜 **- You get notified for X things.**
[🔓, ✅] - obligatory.
[💜] - optional.
\`Wait at least 30 seconds and try again if you don't get the roles.\``)
const msg = await message.channel.send({ embeds: [ embed ] })
msg.react('🔓')
msg.react('✅')
msg.react('💜')
}
})
const CHANNEL = config2.ROLECHANNEL;
const UROLE = config2.UNLOCKROLE;
const MROLE = config2.MEMBERROLE;
const NROLE = config2.NOTIFYROLE;
const unlockEmoji = '🔓';
const checkEmoji = '✅';
const notifyEmoji = '💜';
client.on('messageReactionAdd', async (reaction, user) => {
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
console.error('Fetching message failed: ', error);
return;
}
}
if (!user.bot) {
if(reaction.message.channel.id === CHANNEL) {
if (reaction.emoji.name == checkEmoji) {
const memberRole = reaction.message.guild.roles.cache.find(r => r.id === MROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.add(MROLE);
}
if (reaction.emoji.name == unlockEmoji) {
const unlockRole = reaction.message.guild.roles.cache.find(r => r.id === UROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.remove(UROLE)
}
if (reaction.emoji.name == notifyEmoji) {
const notifyRole = reaction.message.guild.roles.cache.find(r => r.id === NROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.add(NROLE)
}
}
client.on('messageReactionRemove', async (reaction, user) => {
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
console.error('Fetching message failed: ', error);
return;
}
}
if (!user.bot) {
if(reaction.message.channel.id === CHANNEL) {
if (reaction.emoji.name == checkEmoji) {
const memberRole = reaction.message.guild.roles.cache.find(r => r.id === MROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.remove(memberRole);
}
if (reaction.emoji.name == unlockEmoji) {
const unlockRole = reaction.message.guild.roles.cache.find(r => r.id === UROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.remove(unlockRole)
}
if (reaction.emoji.name == notifyEmoji) {
const notifyRole = reaction.message.guild.roles.cache.find(r => r.id === NROLE);
const { guild } = reaction.message
const member = guild.members.cache.find(member => member.id === user.id);
member.roles.remove(notifyRole)
}
}
}
})
}
})
}
I am not getting any error in the console and the bot continues to work as usual.
Thank you for your attention.
Messages sent before your bot started are uncached unless you fetch them first. By default, the library does not emit client events if the data received and cached is not sufficient to build fully functional objects. Since version 12, you can change this behavior by activating partials.
Official guide about this here (Listening for reactions on old messages).
I started making a music bot for my discord server when i input command for playing song it returns that execute is not defined i tried to fix but i had no success. That's why I am asking here.
Note: I made event and command handler but that is not the problem since it was also not working before implementing it.
Here is my code from event that happens on message aka starting command:
module.exports = (client, Discord, message)=>{
const prefix = '-';
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split('/ +/');
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
//const ChannelName = message.channel.name;
try{
command.execute(args, cmd, client, Discord, message);
} catch(err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
And here is my code for play command:
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const queue = new Map();
module.exports = {
name: 'play',
aliases: ['skip', 'stop'],
cooldown: 0,
description: 'Advanced music bot',
async execute(args, cmd, client, Discord, message){
const voice_channel = message.member.voice.channel;
if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command!');
const permissions = voice_channel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) return message.channel.send('You dont have the correct permissins');
if (!permissions.has('SPEAK')) return message.channel.send('You dont have the correct permissins');
const server_queue = queue.get(message.guild.id);
if (cmd === 'play'){
if (!args.length) return message.channel.send('You need to send the second argument!');
let song = {};
if (ytdl.validateURL(args[0])) {
const song_info = await ytdl.getInfo(args[0]);
song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url }
} else {
const video_finder = async (query) =>{
const video_result = await ytSearch(query);
return (video_result.videos.length > 1) ? video_result.videos[0] : null;
}
const video = await video_finder(args.join(' '));
if (video){
song = { title: video.title, url: video.url }
} else {
message.channel.send('Error finding video.');
}
}
if (!server_queue){
const queue_constructor = {
voice_channel: voice_channel,
text_channel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
try {
const connection = await voice_channel.join();
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('There was an error connecting!');
throw err;
}
} else{
server_queue.songs.push(song);
return message.channel.send(`👍 **${song.title}** added to queue!`);
}
}
else if(cmd === 'skip') skip_song(message, server_queue);
else if(cmd === 'stop') stop_song(message, server_queue);
}
}
const video_player = async (guild, song) => {
const song_queue = queue.get(guild.id);
if (!song) {
song_queue.voice_channel.leave();
queue.delete(guild.id);
return;
}
const stream = ytdl(song.url, { filter: 'audioonly' });
song_queue.connection.play(stream, { seek: 0, volume: 0.5 })
.on('finish', () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
await song_queue.text_channel.send(`🎶 Now playing **${song.title}**`)
}
const skip_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
if(!server_queue){
return message.channel.send(`There are no songs in queue 😔`);
}
server_queue.connection.dispatcher.end();
}
const stop_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
server_queue.songs = [];
server_queue.connection.dispatcher.end();
}
I think that problem is in main part of code but I cant seem to find problem.
Here is code for command handling
const fs = require('fs');
module.exports = (client, Discord) =>{
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for (const file of commandFiles){
const command = require(`../commands/${file}`);
if(command.name){
client.commands.set(command.name, command);
} else{
continue;
}
}
}
And here is my main file of the bot with commands collection
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
client.user.setStatus('online')
console.log('Bot is online!');
client.user.setActivity('Youtube',{
type:"LISTENING"
})
console.log('Servers:')
client.guilds.cache.forEach((guild) => {
console.log('-' + guild.name)
})
});
const fs = require('fs');
const message = require('./events/guild/message');
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
['command_handler', 'event_handler'].forEach(handler =>{
require(`./handlers/${handler}`)(client, Discord);
})
I am trying to create a command that kicks people, unfortunately, it doesn't work and no errors in the console, when I type -kick without mentioning anyone, the expected message comes, but when I mention someone it doesn't kick them.
Here is my code in my command handler:
module.exports = {
name: 'kick',
decription: 'Kick command',
execute(message, args) {
if (!message.guild) return;
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
if (member) {
member
.kick()
.then(() => {
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member');
console.error(err);
});
} else {
message.reply("That user isn't in this guild!");
}
} else {
message.reply("You didn't mention the user to kick!");
};
}
}
EDIT: here is my main file code:
const Discord = require("discord.js");
const keepAlive = require("./server");
const client = new Discord.Client();
const prefix = ('-');
const fs = require('fs');
client.on("ready", () => {
console.log(`logged in as ${client.user.tag}`);
});
client.commands = new Discord.Collection();
const commandFiles = fs
.readdirSync('./commands/')
.filter((file) => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.on('message', (message) => {
if(!message.content.startsWith(prefix) || message.author.bot)
return;
const args = message.content.slice(prefix.length).split("/ +/");
const command = args.shift().toLowerCase();
if (command === 'help') {
client.commands.get('help').execute(message, args);
} else if (command === 'clear') {
client.commands.get('clear').help(message,args);
} else if(command === 'ban') {
client.commands.get('ban').execute(message, args);
} else if(command === 'kick') {
client.commands.get('kick').execute(message);
} else if(command === 'mute') {
client.commands.get('mute').execute(message,args);
}
});
keepAlive();
client
.login("TOKEN")
.catch(console.error);
TypeScript has a feature that tells you if you declared an unnecessary variable (you never used the variable). You could remove it, or ignore it. Your code will work either way.
For example, using this code, TypeScript will tell you b is declared but its value is never read
const a = 1
const b = 2
console.log(a)
//b is not used anywhere except for the declaration
Why is your code not working?
You are using Guild.member. This relies on cache and is deprecated. Use message.mentions.members.first() instead to directly retrieve the member
const member = message.mentions.members.first();
args is not defined
This just means that the parameter args to your execute function is unnecessary here and you could remove it.
guild.member() does not exist, use guild.members.resolve(user.id) instead.
Also if you're just accessing a member of a guild, you should use message.mentions.members instead.
So in the end it would look something like this:
module.exports = {
name: 'kick',
decription: 'Kick command',
execute(message) {
if (!message.guild) return;
const member = message.mentions.members.first();
if (member) {
member
.kick()
.then(() => {
message.reply(`Successfully kicked ${member.user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member');
console.error(err);
});
} else {
message.reply("You didn't mention a member to kick!");
};
}
}
I have solved this problem by editing my code a bit. I also moved the code from my command handler to my main file. Here is the code for anyone who needs it.
else if(message.content.startsWith("-kick")) {
message.content.split("-kick ")[1]
if (!message.guild) return;
const member = message.mentions.members.first();
if (member) {
member
.kick()
.then(() => {
message.reply(`Successfully kicked ${member.user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member');
console.error(err);
});
} else {
message.reply("You didn't mention a member to kick!");
};
}
I only added the following piece of code:
message.content.split("-kick ")[1]
EDIT: I figured out what was wrong
const args = message.content.slice(prefix.length).split("/ +/");
I needed to remove the quotation marks at the end, so it is basically like this:
const args = message.content.slice(prefix.length).split(/ +/);