Discord.js button reaction role - javascript

I've been trying to make a reaction role in my bot but I keep getting this error
interaction.guild.roles.fetch(mustard).then(role => member.roles.add(role)).catch(console.error())
^
TypeError: Cannot read properties of undefined (reading 'guild')
This is the full code:
const {
Client,
Message,
MessageEmbed,
MessageActionRow,
MessageButton,
} = require('discord.js');
const cooldown = new Set();
module.exports = {
name: "quickroles",
aliases: ["roles"],
permissions: ["ADMINISTRATOR"],
/**
* #param {Client} client
* #param {Message} message
* #param {String[]} args
*/
run: async (client, message, args, interaction) => {
if(cooldown.has(message.author.id)) {
message.reply(`Please wait! You're on a default cooldown of 5 seconds!`)
} else {
const row = new MessageActionRow().addComponents(
new MessageButton()
.setCustomId("pin")
.setLabel("Pink")
.setEmoji('πŸŸ₯')
.setStyle("SECONDARY"),
new MessageButton()
.setCustomId("mus")
.setLabel("Mustard")
.setEmoji('🟨')
.setStyle("SECONDARY"),
new MessageButton()
.setCustomId("ski")
.setLabel("Sky")
.setEmoji('🟦')
.setStyle("SECONDARY")
)
let pink = '927403952348221449'
let mustard = '927403952427921412'
let sky = '927403952411140137'
let iuser = message.mentions.users.first() || message.author
let embed = new MessageEmbed()
.setTitle(`Color Roles`)
.setDescription('πŸŸ₯ | Pink\n🟨 | Mustard\n🟦 | Sky')
.setURL("https://www.youtube.com/watch?v=rzVhR7ioqL4")
.setColor('#ffdb58')
const m = await message.channel.send({ embeds: [embed], components: [row] })
const filter = (interaction) => {
if(interaction.user.id === iuser.id) return true;
return interaction.reply({content: "This isn't for u", ephemeral: true})
}
const collector = message.channel.createMessageComponentCollector({
filter,
max: 1,
});
collector.on("end", (ButtonInteraction) => {
const id = ButtonInteraction.first().customId;
let pp = new MessageEmbed()
.setDescription(`You now have the <#&927403952348221449> role`)
.setColor('#ffc0cb')
m.edit(pp)
let mm = new MessageEmbed()
.setDescription(`You now have the <#&927403952427921412> role`)
.setColor('#ffdb58')
m.edit(mm)
let ss = new MessageEmbed()
.setDescription(`You now have the <#&927403952411140137> role`)
.setColor('#ffdb58')
m.edit(ss)
if(id === "pin") {
interaction.guild.roles.fetch(pink).then(role => member.roles.add(role)).catch(console.error())
return ButtonInteraction.first().reply({embeds: [pp]})
}else if(id === "mus") {
interaction.guild.roles.fetch(mustard).then(role => member.roles.add(role)).catch(console.error())
return ButtonInteraction.first().reply({embeds: [pp]})
}else if(id === "ski") {
interaction.guild.roles.fetch(sky).then(role => member.roles.add(role)).catch(console.error())
return ButtonInteraction.first().reply({embeds: [pp]})
}
})
} cooldown.add(message.author.id);
setTimeout(() => {
cooldown.delete(message.author.id)
}, 5000)}
};
I'm pretty much new in coding so hopefully, you could help me figure out the problem and make the code work fully πŸ˜„

I think you didn't define "guild",
try instead of
const {
Client,
Message,
MessageEmbed,
MessageActionRow,
MessageButton,
} = require('discord.js');
with the following:
const {
Client,
Guild,
guild
Message,
MessageEmbed,
MessageActionRow,
MessageButton,
} = require('discord.js');

Related

timeout.js discord.js v13 command not working

I got this problem, when i wanna use a message embed in my timeout command, that i get a error message! I sended all of the command / files down there! i appreciate the help!
Here the Error Message:
TypeError: command.run is not a function
at module.exports (/home/runner/Bolt-Utilities/events/guild/command.js:132:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Here the Timeout.js command:
const MessageEmbed = require("discord.js");
module.exports = {
name: 'timeout',
aliases: ["tmute", "tm"],
utilisation: '{prefix}timeout',
async execute(client, message, args) {
const fetch = require('node-fetch');
const ms = require('ms');
if (!message.member.permissions.has('TIMEOUT_MEMBERS')) {
message.delete()
} else {
const user = message.mentions.users.first();
const embed1 = new MessageEmbed()
.setDescription("Please provide the user.")
.setColor("RED");
const embed2 = new MessageEmbed()
.setDescription("Please specify the time.")
.setColor("RED");
const embed3 = new MessageEmbed()
.setDescription("Please specify the time between **10 seconds** (10s) and **28 days** (28d).")
.setColor("RED");
if(!user) return message.reply({ embeds: [embed1] });
const time = args.slice(1).join(' ');
if(!time) return message.reply({ embeds: [embed2] });
const milliseconds = ms(time);
if(!milliseconds || milliseconds < 10000 || milliseconds > 2419200000) return message.reply({ embeds: [embed3] });
const iosTime = new Date(Date.now() + milliseconds).toISOString();
await fetch(`https://discord.com/api/guilds/${message.guild.id}/members/${user.id}`, {
method: 'PATCH',
body: JSON.stringify({ communication_disabled_until: iosTime }),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bot ${client.token}`,
},
});
const embed4 = new MessageEmbed()
.setDescription(`${user} has been **Timeout.** | \`${user.id}\``)
.setColor("YELLOW");
message.channel.send({ embeds: [embed4] })
}
},
};
and here the command.js file:
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 1) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
`please wait ${timeLeft.toFixed(
1
)} more second(s) before reusing the \`${command.name}\` command.`
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.run(client, message, args, p, cooldowns);
} catch (error) {
console.error(error);
let embed2000 = new MessageEmbed()
.setDescription("There was an error executing that command.")
.setColor("BLUE");
message.channel.send({ embeds: [embed2000] }).catch(console.error);
}
};
That are all files! i hope someone can help me i dont know what is wrong there!
Typo: you don't actually have a command.run function in your command file, instead you have execute. Change either one to be the same as the other will solve the problem.
Note: if you change the async execute to async run, change like the following:
async run(client, message, args) => {

discord.js / ytdl-core play command

this is my second question today. I'm using discord.js v13. Earlier I looked into finding out how to make audio play from the bot, and now I am attempting to make a queue work for my discord.js bot. My problem is getting the queue defined from index.js correctly. I will provide the error log along with my code.
error logs: https://i.imgur.com/ScDcJHK.jpg
index.js
const fs = require('fs');
const { Collection, Client, Intents } = require('discord.js');
const Levels = require('discord-xp');
require('dotenv').config();
const client = new Client({
presence: {
status: 'idle',
afk: false,
activities: [{
name: 'The Official Xontavs',
type: 'WATCHING'
}],
},
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILD_PRESENCES, Intents.FLAGS.GUILD_MEMBERS]
});
client.queue = new Map();
const mongoose = require('./database/mongoose.js');
Levels.setURL(`mongodb+srv://discordbot:${process.env.PASS}#bot.z8ki0.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
['aliases', 'commands'].forEach(x => client[x] = new Collection());
['command', 'event'].forEach(x => require(`./handlers/${x}`)(client));
mongoose.init();
client.login(process.env.CLIENT_TOKEN); // SECRET TOKEN
play.js
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const { getVoiceConnection, joinVoiceChannel, AudioPlayerStatus, createAudioResource, getNextResource, createAudioPlayer, NoSubscriberBehavior } = require('#discordjs/voice');
const { createReadStream} = require('fs');
module.exports = {
name: "play",
category: "music",
description: "plays a song",
usage: "<id | mention>",
run: async (client, message, args, queue) => {
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send('You are not in a voice channel.');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT', 'SPEAK')) return message.channel.send('You do not have the correct permissions');
if(!args.length) return message.channel.send('You need to send the second argument');
const server_queue = queue.get(message.guild.id);
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 videoResult = await ytSearch(query);
return (videoResult.videos.length > 1) ? videoResult.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: voiceChannel,
text_channel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
try {
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
});
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('Error connecting');
throw err;
}
} else {
server_queue.songs.push(song);
return message.channel.send(`**${song.title}** added to queue.`);
}
//audioPlayer.play(createAudioResource(stream, {seek: 0, volume: 1}))
//audioPlayer.on(AudioPlayerStatus.Idle, () => {
//audioPlayer.stop();
//connection.destroy();
//message.channel.send('Leaving VC');
//});
}
}
const video_player = async (guild, song, queue) => {
const song_queue = queue.get(guild.id);
if(!song) {
connection.destroy();
queue.delete(guild.id);
return;
}
const audioPlayer = createAudioPlayer();
song_queue.connection.subscribe(audioPlayer);
const stream = ytdl(song.url, { filter: 'audioonly' });
audioPlayer.play(createAudioResource(stream, {seek: 0, volume: 1}))
audioPlayer.on(AudioPlayerStatus.Idle, () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
song_queue.text_channel.send(`Now playing **${song.title}**`)
}
messageCreate.js (if needed)
const del = require('../../functions.js');
const Levels = require('discord-xp');
require('dotenv').config();
const prefix = process.env.PREFIX;
const queue = new Map();
module.exports = async (Discord, client, message) => {
if (message.author.bot || !message.guild) return;
const randomXP = Math.floor(Math.random() * 14) + 1; //1-15
const hasLeveledUP = await Levels.appendXp(message.author.id, message.guild.id, randomXP);
if (hasLeveledUP) {
const user = await Levels.fetch(message.author.id, message.guild.id);
message.channel.send(`${message.member} is now level ${user.level}.`);
}
//const args = message.content.startsWith(prefix) ? message.content.slice(prefix.length).trim().split(/ +/g) : message.content.replace(/[^\s]*/, '').trim().split(/ +/g);
const args = message.content.slice(prefix.length).trim().split(" ");
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd) || client.commands.find(c => c.aliases?.includes(cmd));
if (command) {
command.run(client, message, args, queue);
}
}
Any help is appreciated because I'm really not smart and I'm still trying to learn how all this stuff works, especially with discord.js v13
In
video_player(message.guild, queue_constructor.songs[0]);
You only put two parameters and as you said in the comments, you only had to change it to this to fix your problem
video_player(message.guild, queue_constructor.songs[0], queue, audioPlayer)

Startup TypeError: Cannot read property 'Collection' of undefined

So I've had multiple problems one after another. The first being;
TypeError [CLIENT_MISSING_INTENTS]: Valid intents must be provided for the Client
Which I solved by changing up my code from:
const Discord = require("discord.js");
const bot = new Discord.Client();
To:
const { Client, Intents, Discord } = require("discord.js");
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
But now I am running into a seperate issue. Where I keep getting this error;
Startup TypeError: Cannot read property 'Collection' of undefined
This is really frustrated because I've been at this problem for a couple of hours. Any help would be massively appreciated!
All essential code:
const { Client, Intents } = require("discord.js");
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const { prefix, token, mongoPath } = require("./jsonFiles/config.json");
const mongoose = require("mongoose");
const mongo = require("./utility/mongo.js");
const fs = require("fs");
const Levels = require("discord-xp");
bot.login(token);
bot.commands = new Discord.Collection();
bot.cooldowns = new Discord.Collection();
const commandFolders = fs.readdirSync("./commands");
for (const folder of commandFolders) {
//Finds the name of the command
const commandFiles = fs
.readdirSync(`./commands/${folder}`)
.filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(`./commands/${folder}/${file}`);
bot.commands.set(command.name, command);
}
}
bot.on("ready", async () => {
console.log("Connect as " + bot.user.tag);
//levels(bot);
await mongo().then(() => {
try {
console.log("Connected to mongo!");
} finally {
mongoose.connection.close();
}
});
bot.user.setActivity(".help", {
type: "WATCHING",
});
});
bot.on("message", async (message) => {
try {
await mongo().then(async (mongoose) => {
Levels.setURL(mongoPath);
if (!message.guild) return;
if (message.author.bot) return;
const randomAmountOfXp = Math.floor(Math.random() * 20) + 1; // Min 1, Max 30
const hasLeveledUp = await Levels.appendXp(
message.author.id,
message.guild.id,
randomAmountOfXp
);
if (hasLeveledUp) {
const user = await Levels.fetch(message.author.id, message.guild.id);
message.channel.send(
`${message.author}, congratulations! You have leveled up to **${user.level}** in \`${message.guild.name}\` :sunglasses:`
);
}
});
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command =
bot.commands.get(commandName) ||
bot.commands.find((cmd) => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type === "dm")
return message.reply("I can't execute that command inside DMs!");
if (command.permissions) {
const authorPerms = message.channel.permissionsFor(message.author);
if (!authorPerms || !authorPerms.has(command.permissions)) {
if (message.author.id !== "344834268742156298") {
return message.reply("YOU DO NOT HAVE PERMISSION (git gud scrub)");
}
}
}
if (command.creator === true && message.author.id !== "344834268742156298")
return message.reply("Wait what, you are not creator man, you cannot use the command!!!!!");
if (command.args === true && !args.length) {
let reply = `You didn't provide a valid arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
message.delete({
timeout: 25 * 1000,
});
return message.channel.send(reply).then((message) => {
message.delete({
timeout: 25 * 1000,
});
});
}
const { cooldowns } = bot;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown ?? 1.5) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${
command.name
}\` command.`
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
const maxArguments = command.maxArgs || null;
if (
args.length < command.minArgs ||
(maxArguments !== null && command.args === "true" && args.length > command.maxArgs)
) {
let reply = `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
return message.channel.send(reply);
}
try {
command.execute(message, args, message.guild);
} catch (err) {
console.log(err);
}
} catch (err) {
console.log(err);
}
});
At the top you never defined Discord properly. You are trying to access the non-existant Discord property of the discord.js module with object destructuring. There are 2 quick fixes for this, the first one will be faster however.
//at the top change the declaration of Client
const Discord = {
Client,
Intents
} = require('discord.js')
//Discord is module discord.js
Or you can do
const {
Collection,
Client,
Intents
} = require('discord.js')
//use new Collection() instead of new Discord.Collection()
Try instead of:
const { Client, Intents } = require("discord.js");
Try:
const Discord = require("discord.js"), { Client, Intents } = Discord;
Or you can also import Collection from discord:
const { Client, Intents, Collection } = require("discord.js");
and replace:
new Discord.Collection() with new Collection()

Application System

So i make a application system for a discord server and when testing it the bot worked fine till the questiosn for the application finished and it said application has been sent but it didnt send the application and i got a error saying
(node:11408) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'send' of undefined
Here is my code The error is on appsChannel.send(applicationembed);
const { Client, Message, MessageEmbed } = require('discord.js')
module.exports = {
name: "apply",
/**
* #param {Client} client
* #param {Message} message
* #param {string[]} args
*/
run: async (client, message, args) => {
const questions = [
"What is your IGN currently?",
"What is your discord Name and Tag?",
"Why do you want to join the guild?",
"What games stats are you applying with?",
"Is there anything else you want to tell us?"
];
let collectCounter = 0;
let endCounter = 0;
const filter = (m) => m.author.id === message.author.id;
const appStart = await message.author.send(questions[collectCounter++])
const channel = appStart.channel;
const collector = channel.createMessageCollector(filter);
collector.on("collect", () => {
if(collectCounter < questions.length) {
channel.send(questions[collectCounter++])
} else {
channel.send("You application has been sent!")
collector.stop("fulfilled")
}
})
const appsChannel = client.channels.cache.get('820355472635985991')
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');
const applicationembed = new MessageEmbed()
.setAuthor(
message.author.tag,
message.author.displayAvatarURL({ dynamic: ture })
)
.setTitle('New Application!')
.setDescription(mappedResponses)
.setColor('RANDOM')
.setTimestamp()
appsChannel.send(applicationembed);
}
})
},
}
It's possible that the channel you're trying to get is not in the cache. It's always best to fetch rather than rely on the cache.
Change your appsChannel definition to this.
const appsChannel = await client.channels.cache.fetch('820355472635985991');
Can you try using await here?
const appsChannel = await client.channels.cache.get('820355472635985991')
Edit:
const applicationembed = await new MessageEmbed()
.setAuthor(
message.author.tag,
message.author.displayAvatarURL({ dynamic: ture })
)
.setTitle('New Application!')
.setDescription(mappedResponses)
.setColor('RANDOM')
.setTimestamp()
await appsChannel.send(applicationembed);
For your async to work:
collector.on('end', async (collected, reason) => {

Whenever I react to an embed, It sends double messages. [DiscordAPIError: Unknown Message]

I have a waifu command where it gets an image and a name and puts it in a embed, it also then reacts with the πŸ’– emoji. I wanted to make it so the first person who clicked the emoji would claim the waifu.
const { Client, MessageEmbed, ReactionCollector} = require('discord.js');
const {
prefix
} = require('../../config');
const superagent = require('superagent');
const {
urlencoded
} = require('body-parser');
module.exports = {
name: 'waifu',
category: 'waifu',
description: 'Random Waifu',
usage: `${prefix}waifu`,
perms: 'Send Messages',
cooldown: 5,
run: async (bot, message, args) => {
const rating1 = 10
const rating2 = Math.floor(Math.random() * rating1)
var rating = rating2
const decimals1 = 100
const decimals2 = Math.floor(Math.random() * decimals1)
var decimals = decimals2
const compatibility1 = 100
const compatibility2 = Math.floor(Math.random() * compatibility1)
var compatibility = compatibility2
const {
waifuID
} = require("../../Database/WaifuNameDB.json")
let randW = Math.floor(Math.random() * Object.keys(waifuID).length)
let randomWaifu = waifuID[randW]
let embed2 = new MessageEmbed()
.setTitle(`πŸŽ€${randomWaifu.names}πŸŽ€`)
.addField("Claims:", `${randomWaifu.claims}`)
.addField("Rating:", `${rating}.${decimals}/10 ⭐`)
.setImage(`${randomWaifu.img_url}`, innerHeight = '500', innerWidth = '500')
.setColor('#f095d1')
.setFooter(`| Powered by: #TwintailsπŸŽ€ API `, `https://64.media.tumblr.com/1a1c3bcc08b5a048b90139a56fe7f415/tumblr_o9ku1rVS8z1vnqjx7o2_250.png`)
var mg = await message.channel.send(embed2);
mg.react('πŸ’–')
message.delete()
bot.on('messageReactionAdd', async (reaction, user) => {
if (reaction.mg) await reaction.mg.fetch();
if (reaction) await reaction.fetch()
if (user.bot) return;
if (reaction.emoji.name == "πŸ’–") {
message.channel.send(`${randomWaifu.names} was claimed!`)
mg.delete()
if(user = message.author) return;
}
})
}
}
It works, but if for example I do /waifu, it sends the embed and says (waifuname) was claimed, but whenever I do /waifu again, everything is the same, but when I click the react button, it says that the previous and the current waifu was claimed.
https://aws1.discourse-cdn.com/business6/uploads/glitch/original/2X/9/98363d9496747899fe23698cb0f98846b1e7136c.jpeg
(Umaru Doma was the previous waifu I rolled)
It also gives an error:
(node:9964) UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Message
Please help if you can!
I have figured out a way to fix this everyone!
bot.on('messageReactionAdd', (messageReaction, user) => {
if(user.bot) return;
const {
message,
emoji
} = messageReaction;
if (emoji.name === "πŸ’–") {
if (!message.id === mg.id) return;
if (message.id === mg.id) {
mg.delete()
message.channel.send(`${randomWaifu.names} was claimed!`)
}
}
});

Categories

Resources