This interaction failed - Discord.js - javascript

I'm making a discord slash command nowplaying with save button in it and sent the current music playing in user's dm. i manage to create the buttons working but my problem is after clicking the button "Save Song" it says "This interaction failed" tho the buttons works it sent a embed of the current music playing. Can someone help me why it saying that error?
Node: v17.7.2
Discord: ^13.2.0
my InteractionCreate events for the button "Save Song"
const client = require("../index");
const { MessageEmbed } = require('discord.js');
const ee = require('../config.json');
client.on("interactionCreate", async (interaction) => {
// Slash Command Handling
if (interaction.isCommand()) {
await interaction.deferReply({ ephemeral: false }).catch(() => {});
const cmd = client.slashCommands.get(interaction.commandName);
if (!cmd)
return interaction.followUp({ content: "An error has occured " });
const args = [];
for (let option of interaction.options.data) {
if (option.type === "SUB_COMMAND") {
if (option.name) args.push(option.name);
option.options?.forEach((x) => {
if (x.value) args.push(x.value);
});
} else if (option.value) args.push(option.value);
}
interaction.member = interaction.guild.members.cache.get(interaction.user.id);
cmd.run(client, interaction, args);
}
// Context Menu Handling
if (interaction.isContextMenu()) {
await interaction.deferReply({ ephemeral: false });
const command = client.slashCommands.get(interaction.commandName);
if (command) command.run(client, interaction);
}
//Save Song button function
if (interaction.isButton()){
const queue = client.distube.getQueue(interaction.guildId);
switch (interaction.customId) {
case 'saveTrack': {
if (!queue || !queue.playing){
return interaction.followUp({ content: `No music currently playing. āŒ`, ephemeral: true, components: [] });
} else {
const song = queue.songs[0];
const but_save = new MessageEmbed()
.setColor(ee.color)
.setTitle(client.user.username + " - Save Track")
.setThumbnail(client.user.displayAvatarURL())
.addField(`šŸŽ¶ Track`, `\`${song.name}\``)
.addField(`ā³ Duration`, `\`${song.formattedDuration}\``, true)
.addField(`šŸ”— URL`, `${song.url}`)
.addField(`抗 Saved Server`, `\`${interaction.guild.name}\``)
.addField(`āž” Requested By`, `${song.user}`, true)
.setTimestamp()
.setFooter({ text: 'H_M Save Music!', iconURL: interaction.user.displayAvatarURL({ dynamic: true }) });
interaction.user.send({ embeds: [but_save ] }).then(() => {
interaction.followUp({ content: `āœ… | I sent the name of the music via private message.`, ephemeral: true }).catch(e => { })
}).catch(error => {
interaction.followUp({ content: `āŒ | Unable to send you private message.`, ephemeral: true }).catch(e => { })
});
}
}
}
}
});
and here is my nowplaying.js
const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js');
const ee = require('../../config.json');
const Format = Intl.NumberFormat();
const status = queue =>
`Volume: \`${queue.volume}%\` | Filters: \`${queue.filters.join(', ') || 'Off'}\` | Loop: \`${
queue.repeatMode ? (queue.repeatMode === 2 ? 'Playlist' : 'Song') : 'Off'
}\` | Autoplay: \`${queue.autoplay ? 'On' : 'Off'}\``
module.exports = {
name: "nowplaying",
description: "Shows the current song playing",
usage: "nowplaying",
run: async (client, interaction, args) => {
const queue = client.distube.getQueue(interaction);
const song = queue.songs[0];
const embed = new MessageEmbed()
.setColor(ee.color)
.setAuthor({name: 'Now playing...', iconURL: 'https://i.imgur.com/81ig9jl.jpg'})
.setDescription(`[${song.name}](${song.url})`)
.setThumbnail(song.thumbnail)
.addField("šŸŒ­ | Status", `${status(queue).toString()}`, false)
.addField('šŸ‘€ | Listens', `${Format.format(song.views)}`, true)
.addField('šŸ‘ | Prefer', `${Format.format(song.likes)}`, true)
.addField('āŒ› | Played', `${queue.formattedCurrentTime} / ${song.formattedDuration}`, true)
.addField('šŸ“© | Download link', `[Click here](${song.streamURL})`, true)
.addField("šŸ‘Œ | Requested by",` ${song.user}`, true)
const saveButton = new MessageButton();
saveButton.setLabel('Save Song');
saveButton.setCustomId('saveTrack');
saveButton.setStyle('SUCCESS');
const row = new MessageActionRow().addComponents(saveButton);
interaction.followUp({embeds: [embed], components: [row] });
}
}

After you switched case to your id, you need to defer your interaction with await interaction.deferReply() also if you want it an ephemeral message there's option as await interaction.deferReply({ ephemeral: true }). This line should be awaited.

Related

I cannot have ".add(role)" and ".remove(role)" at the same line of code || Discord.js V.14

So, here is my command:
const {GuildMember, Embed, InteractionCollector, CommandInteraction} = require("discord.js");
module.exports = {
name: "interactionCreate",
execute(interaction, client) {
if (interaction.isChatInputCommand()) {
const command = client.commands.get(interaction.commandName);
if (!command) {
interaction.reply({ content: "This command does NOT exist any more!", ephemeral: true });
}
command.execute(interaction, client);
} else if (interaction.isButton()) {
const { customId } = interaction;
if(customId == "verify") {
const role = interaction.guild.roles.cache.get("1060524965427953684"); //Community Role ID
const role_remove = interaction.guild.roles.cache.get('1065321229625606215'); //Unverified Role ID
return interaction.member.roles
.remove(role_remove)
.add(role)
.then((member) =>
interaction.reply({
content: `${role} has been assigned to you!`,
ephemeral: true,
})
)
}
} else {
return;
}
},
};
I want it just like that: When someone clicks the Verify Button: 1)First give the Verified Role and 2)Remove the Unverified Role. But when I click the "Verification" Button it sends me an error saying:
TypeError: interaction.reply(...).add is not a function.
If there is anyone that can help me, please, reply. Thanks!
Thanks to #user19513069, The correct answer (Line of code) is:
const {GuildMember, Embed, InteractionCollector, CommandInteraction} = require("discord.js");
module.exports = {
name: "interactionCreate",
execute(interaction, client) {
if (interaction.isChatInputCommand()) {
const command = client.commands.get(interaction.commandName);
if (!command) {
interaction.reply({ content: "This command does NOT exist any more!", ephemeral: true });
}
command.execute(interaction, client);
} else if (interaction.isButton()) {
const { customId } = interaction;
if(customId == "verify") {
const role = interaction.guild.roles.cache.get("1060524965427953684"); //Community Role ID
const role_remove = interaction.guild.roles.cache.get('1065321229625606215'); //Unverified Role ID
**interaction.member.roles
.remove(role_remove)
.then((member) =>
member.roles
.add(role)
.then((member2) =>
interaction.reply({
content: `${role} has been assigned to you!`,
ephemeral: true,
})));**
}
} else {
return;
}
},
};

Combined Error(2). How do I fix it? The bot is expecting undefined or null and string primitive returns

I was creating a music bot that supports slash commands. It does fine when I embed an url to a single song. But when I tried putting a link to a playlist it returns two errors.
CombinedError (2)
Received one or more errors
1 ValidationError > s.nullish
| Expected undefined or null
|
| Received:
| | Thumbnail {
| | id: null,
| | width: 336,
| | height: 188,
| | url:
| | 'https://i.ytimg.com/vi/U7L-3VXAkSA/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLADvf4gOVhdVe-L0E8w-HsOCrvOfA' }
2 ValidationError > s.string
| Expected a string primitive
|
| Received:
| | Thumbnail {
| | id: null,
| | width: 336,
| | height: 188,
| | url:
| | 'https://i.ytimg.com/vi/U7L-3VXAkSA/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLADvf4gOVhdVe-L0E8w-HsOCrvOfA' }
at UnionValidator.handle (C:\Users\someone\Desktop\NewMusic\node_modules\#sapphire\shapeshift\dist\index.js:1088:23)
at UnionValidator.parse (C:\Users\someone\Desktop\NewMusic\node_modules\#sapphire\shapeshift\dist\index.js:201:88)
at EmbedBuilder.setThumbnail (C:\Users\someone\Desktop\NewMusic\node_modules\#discordjs\builders\dist\index.js:257:23)
at Object.execute (C:\Users\someone\Desktop\NewMusic\commands\play.js:80:18)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Client.<anonymous> (C:\Users\someone\Desktop\NewMusic\index.js:72:9)type here
This is my play.js that plays music
const { SlashCommandBuilder } = require("#discordjs/builders")
const { EmbedBuilder } = require("discord.js")
const { QueryType } = require("discord-player")
module.exports = {
data: new SlashCommandBuilder()
.setName("play")
.setDescription("play a song from YouTube.")
.addSubcommand(subcommand =>
subcommand
.setName("search")
.setDescription("Searches for a song and plays it")
.addStringOption(option =>
option.setName("searchterms").setDescription("search keywords").setRequired(true)
)
)
.addSubcommand(subcommand =>
subcommand
.setName("playlist")
.setDescription("Plays a playlist from YT")
.addStringOption(option => option.setName("url").setDescription("the playlist's url").setRequired(true))
)
.addSubcommand(subcommand =>
subcommand
.setName("song")
.setDescription("Plays a single song from YT")
.addStringOption(option => option.setName("url").setDescription("the song's url").setRequired(true))
),
execute: async ({ client, interaction }) => {
// Make sure the user is inside a voice channel
if (!interaction.member.voice.channel) return interaction.reply("You need to be in a Voice Channel to play a song.");
// Create a play queue for the server
const queue = await client.player.createQueue(interaction.guild);
// Wait until you are connected to the channel
if (!queue.connection) await queue.connect(interaction.member.voice.channel)
let embed = new EmbedBuilder()
if (interaction.options.getSubcommand() === "song") {
let url = interaction.options.getString("url")
// Search for the song using the discord-player
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.YOUTUBE_VIDEO
})
// finish if no tracks were found
if (result.tracks.length === 0)
return interaction.reply("No results")
// Add the track to the queue
const song = result.tracks[0]
await queue.addTrack(song)
embed
.setDescription(`**[${song.title}](${song.url})** has been added to the Queue`)
.setThumbnail(song.thumbnail)
.setFooter({ text: `Duration: ${song.duration}`})
}
else if (interaction.options.getSubcommand() === "playlist") {
// Search for the playlist using the discord-player
let url = interaction.options.getString("url")
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.YOUTUBE_PLAYLIST
})
if (result.tracks.length === 0)
return interaction.reply(`No playlists found with ${url}`)
// Add the tracks to the queue
const playlist = result.playlist
await queue.addTracks(result.tracks)
embed
.setDescription(`**${result.tracks.length} songs from [${playlist.title}](${playlist.url})** have been added to the Queue`)
.setThumbnail(playlist.thumbnail)
}
else if (interaction.options.getSubcommand() === "search") {
// Search for the song using the discord-player
let url = interaction.options.getString("searchterms")
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.AUTO
})
// finish if no tracks were found
if (result.tracks.length === 0)
return interaction.editReply("No results")
// Add the track to the queue
const song = result.tracks[0]
await queue.addTrack(song)
embed
.setDescription(`**[${song.title}](${song.url})** has been added to the Queue`)
.setThumbnail(song.thumbnail)
.setFooter({ text: `Duration: ${song.duration}`})
}
// Play the song
if (!queue.playing) await queue.play()
// Respond with the embed containing information about the player
await interaction.reply({
embeds: [embed]
})
},
}
This is the index.js
require('dotenv').config();
const {REST} = require('#discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { Client, GatewayIntentBits, Collection } = require("discord.js");
const { Player } = require("discord-player")
const fs = require('fs');
const path = require('path');
const client = new Client({
intents: [
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildScheduledEvents,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildVoiceStates,
],
});
// List of all commands
const commands = [];
client.commands = new Collection();
const commandsPath = path.join(__dirname, "commands"); // E:\yt\discord bot\js\intro\commands
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for(const file of commandFiles)
{
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.commands.set(command.data.name, command);
commands.push(command.data.toJSON());
}
// Add the player on the client
client.player = new Player(client, {
ytdlOptions: {
quality: "highestaudio",
highWaterMark: 1 << 25
}
})
client.on("ready", () => {
// Get all ids of the servers
const guild_ids = client.guilds.cache.map(guild => guild.id);
const rest = new REST({version: '9'}).setToken(process.env.TOKEN);
for (const guildId of guild_ids)
{
rest.put(Routes.applicationGuildCommands(process.env.CLIENT_ID, guildId),
{body: commands})
.then(() => console.log('Successfully updated commands for guild ' + guildId))
.catch(console.error);
}
});
client.on("interactionCreate", async interaction => {
if(!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
if(!command) return;
try
{
await command.execute({client, interaction});
}
catch(error)
{
console.error(error);
await interaction.reply({content: "There was an error executing this command"});
}
});
client.login(process.env.TOKEN);
I have no idea how to fix this. Can somebody help? I am using node.js v19 and discord.js v14
.setThumbnail(playlist.thumbnail) should be .setThumbnail(playlist.thumbnail.url) as playlist.thumbnail is an object and setThumbnail accepts a string as the URL.

Force the bot to wait and send all this embed at the same message

messageDelete.js
const Discord = require('discord.js')
module.exports = {
name: 'messageDelete',
async execute(client, message, messageDelete) {
if (message.channel.type === 'DM') return;
if (message.author == client) return;
if (!message.author) return;
if(message.embeds[0]) return;
if(message.attachments.size) return;
let Channel = client.channels.cache.get("CHANNEL-ID")
if (!Channel){
return;
} else if (Channel.type !== 'GUILD_TEXT') {
return;
} else if (!data.Mod.Logs.isEnabled){
return;
} else if(!Channel.guild.me.permissions.has("EMBED_LINKS", "VIEW_CHANNEL", "READ_MESSAGE_HISTORY", "VIEW_AUDIT_LOG", "SEND_MESSAGES")) {
return;
} else {
// Do nothing..
};
const timestamp = Math.floor(Date.now() / 1000)
const Msg = message.toString().substr(0, 500);
const DeletedLog = new Discord.MessageEmbed()
.setAuthor({ name: message.author.username, iconURL: message.author.displayAvatarURL({dynamic: true, size: 2048}) })
.setTitle(`<a:Down:853495989796470815> Deleted Message`)
.setDescription(`<a:iNFO:853495450111967253> **Member**: \`${message.author.tag}\` (${message.author.id})\n<:pp198:853494893439352842> **In**: ${message.channel}\nā€¢ **At**: <t:${timestamp}>\n\n<a:Right:877975111846731847> **Content**: \`\`\`\n${Msg || 'āŒ | Unkown message!'}\n\`\`\``)
.setColor('RED')
.setFooter({ text: message.guild.name, iconURL: message.guild.iconURL({dynamic: true}) })
.setTimestamp()
.setThumbnail(message.author.displayAvatarURL({dynamic: true}))
const botname = client.user.username;
const webhooks = await Channel.fetchWebhooks()
setTimeout(async function(){
let webhook = webhooks.filter((w)=>w.type === "Incoming" && w.token).first();
if(!webhook){
webhook = await Channel.createWebhook(botname, {avatar: client.user.displayAvatarURL({ format: 'png', dynamic: true, size: 128 })})
} else if(webhooks.size <= 10) {
}
webhook.send({embeds: [DeletedLog]})
.catch(() => {});
}, 5000);
// add more functions on ready event callback function...
return;
}
}
That's how my messageDelete event sends the embed
How can i force the bot to wait for a certain time and if the messageDelete event excuted like 5 times at this time the bot sends all the 5 embed at the same message?

TypeError: Cannot read property 'highest' of undefined - Mute Command

So hey Stackoverflow community, Im here kinda confused on why this stopped working all of the sudden, and I get the error that is stated in the title.
Basically it would check to see if the user who was attempting to mute a user had a higher role than the other user, and if they did.. it would mute them, and if they didn't it would throw an error.
But now all it does is just throw the error stated in the title once again and I cannot find a fix on the docs?
Also when i remove the highest.position from the check, it allows anyone with the right perms to mute anyone above or below them.
So here I am, asking nicely for some help/understanding on why this method of muting users has stopped working unexpectedly.
const { MessageEmbed } = require("discord.js");
const db = require("quick.db");
const ms = require("ms");
const modSchema = require("../../models/modLogs");
module.exports = {
name: "mute",
description: "Mutes a user in a server",
usage: "[name | nickname | mention | ID] (reason)",
run: async (client, message, args) => {
try {
if (!message.member.permissions.has('MANAGE_ROLES')) return message.reply('You do not have perms to mute users. - `[MANAGE_ROLES]`')
if (!message.guild.me.permissions.has('MANAGE_ROLES')) return message.reply('I do not have perms to mute users. - `[MANAGE_ROLES]`');
if (!args[0]) return message.reply("```Usage: c!mute <user>```");
var mutedMember = message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.guild.members.cache.find(r => r.user.username.toLowerCase() === args[0].toLocaleLowerCase()) || message.guild.members.cache.find(ro => ro.displayName.toLowerCase() === args[0].toLocaleLowerCase());
if (!mutedMember) return message.reply("Please provide a valid user to mute.");
if (mutedMember === message.member) return message.reply("I'm afraid you cannot mute yourself, Captain.");
if (message.author.roles.highest.position <= mutedMember.roles.highest.position) return message.reply("<a:CL_No:909440866622517318> You cannot mute that user because they have the same or higher role than you.");
let reason = args.slice(1).join(" ");
if (mutedMember.user.bot) return message.reply("<a:CL_No:909440866622517318> I am unable to mute other bots.");
const userRoles = mutedMember.roles.cache.filter(role => role.id !== message.guild.id).map(role => role.id);
let muterole;
let dbmute = await db.fetch(`muterole_${message.guild.id}`);
let muteerole = message.guild.roles.cache.find(role => role.name === "Muted");
if (!message.guild.roles.cache.has(dbmute)) {
muterole = muteerole;
} else {
muterole = message.guild.roles.cache.get(dbmute);
}
if (!muterole) {
try {
message.reply("<a:CL_No:909440866622517318> I was unable to find the `Muted` role, attempting to create one now...");
muterole = await message.guild.roles.create({
name: "Muted",
color: "#010101",
permissions: []
});
message.guild.channels.cache.forEach(async channel => {
await channel.permissionOverwrites.create(muterole, {
SEND_MESSAGES: false,
ADD_REACTIONS: false,
SPEAK: false,
CONNECT: false
});
});
message.reply("<a:CL_CheckMark:858853559940808724> Successfully created the \`Muted\` role.");
} catch (err) {
message.reply(`\`${err}\``)
}
}
if (mutedMember.roles.cache.has(muterole.id)) return message.reply(`\`${mutedMember.user.tag}\` is already muted.`);
db.set(`muteeid_${message.guild.id}_${mutedMember.id}`, userRoles);
try {
mutedMember.roles.set([muterole.id]).then(() => {
const muteEmbed1 = new MessageEmbed()
.setColor("RED")
.setAuthor({ name: message.guild.name, iconURL: message.guild.iconURL() })
.setDescription(`${mutedMember.user.tag}, You were muted in \`${message.guild.name}\``)
.addField("Reason:", `${reason || "No Reason Specified."}`)
.setTimestamp()
.setFooter({ text: `Moderator: ${message.author.tag}` });
mutedMember.send({ embeds: [muteEmbed1] });
});
} catch {
mutedMember.roles.set([muterole.id]);
}
if (reason) {
const muteEmbed2 = new MessageEmbed()
.setColor("RED")
.setAuthor({ name: message.guild.name, iconURL: message.guild.iconURL() })
.setDescription(`\`${mutedMember.user.tag}\` has been muted.`)
.addField("User Roles:", "<a:CL_CheckMark:858853559940808724> | Removed all user roles.")
.setTimestamp();
message.reply({ embeds: [muteEmbed2] });
} else {
const muteEmbed3 = new MessageEmbed()
.setColor("RED")
.setAuthor({ name: message.guild.name, iconURL: message.guild.iconURL() })
.setDescription(`\`${mutedMember.user.tag}\` has been muted.`)
.addField("User Roles:", "<a:CL_CheckMark:858853559940808724> | Removed all user roles.")
.setTimestamp();
message.reply({ embeds: [muteEmbed3] });
}
modSchema.findOne({ Guild: message.guild.id }, async (err, data) => {
if (!data) return;
const logschannel = message.guild.channels.cache.get(data.Channel);
if (logschannel) {
const muteMemberEmbed = new MessageEmbed()
.setTitle('User Muted')
.addField('User', `${mutedMember.user.username} (${mutedMember.user.id})`)
.addField('Moderator', `${message.author.tag}`)
.addField('Reason', `${reason || 'No Reason Specified'}`)
.addField('Muted', `<t:${Math.floor(Date.now() / 1000)}:R>`)
.setColor('ORANGE')
.setThumbnail(mutedMember.user.displayAvatarURL({ dynamic: true }))
logschannel.send({ embeds: [muteMemberEmbed] });
}
});
} catch (err) {
return message.reply(`\`\`\`${err}\`\`\``);
}
}
};
The problem is that message.author returns a User and Users don't have roles; only GuildMembers have. While a User is a global user on Discord, a GuildMember is a user on a specific server and this member has roles on that server.
So, instead of message.author you should use message.member that returns a GuildMember:
if (message.member.roles.highest.position <= mutedMember.roles.highest.position)
return message.reply(
"<a:CL_No:909440866622517318> You cannot mute that user because they have the same or higher role than you."
);

Unknown Interaction on All interactions - Discord.js v13

All of a sudden I keep on getting this error on most interactions and my bot just sends `"Bot is thinking...".
[UnhandledRejection] DiscordAPIError: Unknown interaction
at RequestHandler.execute (/Users/main/Desktop/Discordbots/gamerscavern/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (/Users/main/Desktop/Discordbots/gamerscavern/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
at async SelectMenuInteraction.reply (/Users/main/Desktop/Discordbots/gamerscavern/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:98:5)
Example this help command. Which returns Unknown interaction on the interaction.update() part in the collector AND in the filter when another user interacts with it. I have no clue why this is happening. And as mentioned, it worked fine just a few hours ago.
Here is my code:
Help command:
const {
Client,
Message,
MessageEmbed,
MessageActionRow,
MessageSelectMenu,
} = require('discord.js');
module.exports = {
name: 'help',
description: 'List all of my commands or info about a specific command.',
aliases: ['commands'],
usage: '[command name]',
category: 'info',
cooldown: 3,
/**
*
* #param {Client} client
* #param {Message} message
* #param {String[]} args
*/
execute: async (client, message, args, prefix) => {
if (message.author.bot) return;
const data = [];
const { commands } = message.client;
const emojis = {
config: 'āš™ļø',
info: 'ā„¹ļø',
moderation: 'šŸ”Ø',
owner: 'šŸ”',
utility: 'šŸ› ',
voice: 'šŸ—£',
welcoming: 'šŸ‘‹',
};
if (!args[0]) {
const directories = [
...new Set(client.commands.map((cmd) => cmd.category)),
].filter((e) => e !== 'secrets' && e !== undefined);
const formatString = (str) =>
`${str[0].toUpperCase()}${str.slice(1).toLowerCase()}`;
const categories = directories.map((dir) => {
const getCommands = client.commands
.filter((cmd) => cmd.category === dir)
.map((cmd) => {
return {
name: cmd.name || 'There is no name',
description:
cmd.description ||
'There is no description for this command',
};
});
return {
directory: formatString(dir),
commands: getCommands,
};
});
const initialEmbed = new MessageEmbed()
.setTitle('Developer: Kev#1880')
.setDescription(
'~~ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”~~\n** Links āž¼ ** [Invite](https://discord.com/api/oauth2/authorize?client_id=711371556504207423&permissions=8&scope=bot) |Ā [Server](https://discord.gg/XkCTA88) | [Upvote](https://top.gg/bot/711371556504207423/vote) \n~~ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”~~\n\n**Please choose a category in the dropdown menu**'
)
.setColor('#5787E8')
.setThumbnail(client.user.displayAvatarURL({ format: 'png' }))
.setFooter(
`Requested by: ${message.author.tag}`,
message.author.displayAvatarURL({ format: 'png' })
)
.setTimestamp();
const components = (state) => [
new MessageActionRow().addComponents(
new MessageSelectMenu()
.setCustomId('help-menu')
.setPlaceholder('Please select a category')
.setDisabled(state)
.addOptions(
categories.map((cmd) => {
return {
label: cmd.directory,
value: cmd.directory.toLowerCase(),
description: `Commands from ${cmd.directory} category`,
emoji:
emojis[cmd.directory.toLowerCase()] ||
null,
};
})
)
),
];
const initialMessage = await message.channel.send({
embeds: [initialEmbed],
components: components(false),
});
const filter = async (interaction) => {
if (interaction.user.id === message.author.id) {
return true;
}
interaction.reply({
content: `This is not your help menu, create your own with >help!`,
ephemeral: true,
});
return false;
};
const collector = initialMessage.createMessageComponentCollector({
filter,
componentType: 'SELECT_MENU',
time: 600000,
});
collector.on('collect', (interaction) => {
console.log(interaction);
const [directory] = interaction.values;
const category = categories.find(
(x) => x.directory.toLowerCase() === directory
);
const categoryEmbed = new MessageEmbed()
.setTitle(`${formatString(directory)} commands`)
.setDescription(
'~~ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”~~\n** Links āž¼ ** [Invite](https://discord.com/api/oauth2/authorize?client_id=711371556504207423&permissions=8&scope=bot) |Ā [Server](https://discord.gg/XkCTA88) | [Upvote](https://top.gg/bot/711371556504207423/vote) \n~~ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”ā€”~~\n\n**Here are the list of commands**'
)
.setColor('#5787E8')
.addFields(
category.commands.map((cmd) => {
return {
name: `\`${cmd.name}\``,
value: cmd.description,
inline: true,
};
})
)
.setThumbnail(
client.user.displayAvatarURL({ format: 'png' })
)
.setFooter(
`Requested by: ${message.author.tag}`,
message.author.displayAvatarURL({ format: 'png' })
)
.setTimestamp();
interaction.update({
embeds: [categoryEmbed],
});
});
collector.on('end', () => {
const ranOut = new MessageEmbed()
.setColor('RED')
.setTitle('Oops!')
.setDescription(
'Interaction ran out of time! Please create a new help menu!'
)
.setThumbnail(
client.user.displayAvatarURL({ format: 'png' })
)
.setFooter(
`Requested by: ${message.author.tag}`,
message.author.displayAvatarURL({ format: 'png' })
)
.setTimestamp();
initialMessage.edit({
embeds: [ranOut],
components: components(true),
});
});
}
if (args[0]) {
const name = args[0].toLowerCase();
const command =
commands.get(name) ||
commands.find((c) => c.aliases && c.aliases.includes(name));
if (!command) {
return message.reply({
content: "that's not a valid command!",
});
}
// data.push(`**Name:** ${command.name}`);
if (command.aliases)
data.push(`**Aliases:** ${command.aliases.join(', ')}`);
if (command.description)
data.push(`**Description:** ${command.description}`);
if (command.nb) data.push(`**NB:** ${command.nb}`);
if (command.userPermissions)
data.push(
`**User Permissions:** \`${command.userPermissions.join(
', '
)}\``
);
if (command.botPermissions)
data.push(
`**Bot Permissions:** ${command.botPermissions
.map((perm) => {
return `\`${perm}\``;
})
.join(', ')}`
);
if (command.usage)
data.push(
`**Usage:** \`${prefix}${command.name} ${command.usage}\``
);
if (command.examples)
data.push(`**Examples:**
${command.examples
.map((example) => {
return `\`${prefix}${command.name} ${example}\``;
})
.join('\n')}
`);
data.push(`**Cooldown:** ${command.cooldown || 3} second(s)`);
const commandHelp = new MessageEmbed()
.setTitle(`Command: **${command.name}**`)
.setColor('#5787E8')
.setDescription(`${data.join('\n')}`)
.setFooter(
`Requested by: ${message.author.tag}`,
message.author.displayAvatarURL({ format: 'png' })
);
return message.reply({ embeds: [commandHelp] });
}
},
};
interactionCreate event:
const blacklist = require('../../models/blacklists.js');
const guildBlacklist = require('../../models/guildBlacklist.js');
const reactionRoles = require('../../models/reactionRoles.js');
module.exports = async (Discord, client, interaction) => {
//Slash Command Handling
if (interaction.isCommand()) {
// await interaction.deferReply();
//blacklists
const bl = await blacklist.findOne({ Client: client.user.id });
if (bl) {
if (bl.Users) {
if (bl.Users.includes(interaction.user.id)) return;
}
}
const gbl = await guildBlacklist.findOne({
Guild: interaction.guild.id,
});
if (gbl) {
if (gbl.Users) {
if (gbl.Users.includes(interaction.user.id)) return;
}
}
const cmd = client.slashCommands.get(interaction.commandName);
if (!cmd) return interaction.reply({ content: 'An error has occured' });
const args = [];
for (let option of interaction.options.data) {
if (option.type === 'SUB_COMMAND') {
if (option.name) args.push(option.name);
option.options?.forEach((x) => {
if (x.value) args.push(x.value);
});
} else if (option.value) args.push(option.value);
}
interaction.member = interaction.guild.members.cache.get(
interaction.user.id
);
if (!interaction.member.permissions.has(cmd.userPermissions || []))
return interaction.reply({
content: 'You do not have the permissions to use this command!',
ephemeral: true,
});
cmd.execute(client, interaction, args);
}
//Context Menu Handling
if (interaction.isContextMenu()) {
await interaction.deferReply();
const command = client.slashCommands.get(interaction.commandName);
if (command) command.execute(client, interaction);
}
//Reaction Roles Handling
if (interaction.isSelectMenu()) {
await interaction.deferReply();
const reactionPanel = await reactionRoles.findOne({
guildId: interaction.guildId,
'reactionPanels.customId': `${interaction.customId}`,
});
if (reactionPanel) {
//if (interaction.customId !== 'reaction-roles') return;
const roleId = interaction.values[0];
const role = interaction.guild.roles.cache.get(roleId);
if (!role) return;
const memberRoles = interaction.member.roles;
const hasRole = memberRoles.cache.has(roleId);
if (hasRole) {
memberRoles.remove(roleId);
interaction.followUp({
content: `${role.name} has been removed from you`,
ephemeral: true,
});
} else {
memberRoles.add(roleId);
interaction.followUp({
content: `${role.name} has been added to you`,
ephemeral: true,
});
}
}
}
};
What happened
If you do not reply or acknowledge the interaction in 3 seconds. There's a cooldown!
The user will see interaction failed and the reply gate is closed.
Solution
However, if you defer the reply and edit later, the gate will open until you update the defer or edit the reply.
Here's how to do it, and here's the documentation about it.
interaction.deferReply();
// Do some stuff that takes time right here...
interaction.editReply({ content: "replied" });
To answer your other question about the bot sending Bot is thinking...,
It happens when you defer without editing the reply after. It will stay like that until you do something.

Categories

Resources