I'm trying to make categories in my discord bot and I'm also trying to make categories help command, but It's not working well, so I need some help. Its not an error and there is nothing showing in my console of DiscordAPIErrors, Syntax Errors, or any error. It should display the chosen category and itβs commands in an embed message, but Itβs not. It only display the specific commands help, for example, when I type (prefix)help kick it shows the kick command help, but when I type (prefix)help utility it only says that the command provided is invalid. So it only reacts with commands not categories. here's my code:
Code:
const Discord = require('discord.js')
const fs = require('fs')
const { prefix, owner_id } = require('../../configs.json')
module.exports.run = async (message, args, client) => {
const data = [];
const allCategories = ['general','currency','premium','settings'];
const categoryName = {
"general": 'General Commands',
"currency": 'Currency Commands',
"settings": 'Settings Commands'
}
const user = await client.users.fetch('685079477629485093');
const colors = [
'WHITE','#add8e6','#e0ffff','#d3d3d3',
'#20b2aa','#5d8aa8','#f0f8ff','#f2f3f4',
'#b2beb5','#007fff','#f0ffff','#89cff0',
'#a1caf1','#21abcd','#848482','#bcd4e6',
'#f5f5dc','#318ce7','#ace5ee','#a2a2d0',
'#6699cc','#0d98ba','#0095b6','#e3dac9',
'#0070ff','#1dacd6','#08e8de','#e7feff'
]
const randomColor = colors[Math.round(Math.random()*colors.length)];
if (!args[0]) {
let firstHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.setDescription(`
Commands Usage: \`${prefix}(command)\`\nYou're asking for help,
**${message.author.username}**? I'm here to help!
`, { split: true })
.addFields(
{ name: `βοΈ General`, value: `${(client.generalCommands.map(command =>
`\`${command.help.name}\``).join(', ')) || '\`coming soon...\`'}`, inline: true },
{ name: `π° Currency`, value: `${(client.currencyCommands.map(command =>
`\`${command.help.name}\``).join(', ')) || '\`coming soon...\`'}`, inline: true },
)
.setFooter(`For more information about a specific command, ${prefix}help <command>`)
.setThumbnail(`${message.guild.iconURL({ dynamic: true })}`)
.setTitle(`E-Mod Command List`);
if (!message.guild.iconURL()) {
firstHelp.setThumbnail(`${client.user.displayAvatarURL({ dynamic: true })}`)
}
return message.channel.send(firstHelp)
}
const name = args[0].toLowerCase();
const command = client.generalCommands.get(name)
|| client.generalCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
|| client.currencyCommands.get(name)
|| client.currencyCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
|| client.premiumCommands.get(name)
|| client.premiumCommands.find(cmd => cmd.help.aliases && cmd.help.aliases.includes(name))
if (!command) {
const categorySelected = allCategories.map(category => category.startsWith(name));
if (name == categorySelected) {
let { categoryCommands } = message.client.get(name + 'Commands')
let categoryHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.addFields(
{ name: `${categoryName.map(category => category.startsWith(name))}`, value:
`${(categoryCommands.map(command => `\`${command.help.name}\``).join(', ')) || '\`coming
soon...\`'}`, inline: false },
)
.setFooter(`Premium commands can be used by specific users!`);
return message.channel.send(categoryHelp);
} else {
return message.reply(`it seems you\'ve supplied an invalid command.\nPlease use
\`${prefix}help\` to check out what commands do I support.`)
}
}
let commandHelp = new Discord.MessageEmbed()
.setColor(randomColor)
.addFields(
{ name: 'Description:', value: `${command.help.description}`, inline: false },
{ name: 'Triggers:', value: `${((command.help.aliases).join(', ')) || 'No triggers found'}`,
inline: true },
{ name: 'Usage:', value: `\`${command.help.usage}\``, inline: true },
)
.setFooter(`Premium commands can be used by specific users!`)
.setTitle(`Help | ${command.help.name}`);
return message.channel.send(commandHelp);
}
module.exports.help = {
name: 'help',
description: 'Get a list of all commands or info about a specific command.',
usage: `${prefix}help <command>`,
aliases: ['commands', 'cmds'],
cooldown: 3,
}
You can try making an array and make an object that you can push. If you use a command handler, it can be even easier to use. Heres an Example with the command handler:
const roleColor =
message.guild.me.displayHexColor === "#000000" ?
"#ffffff" :
message.guild.me.displayHexColor;
if (!args[0]) {
let categories = [];
//Use below for each category emoji, may pop up as Undefined
const dirEmojis = {
Category: 'πββοΈ'
}
const ignoredCategories = [`moderation`, `Other`, `suggest`, `Warn`, `Mute`, `ReactionRoles`, `Economy`, `Ticket`, `Welcome_Message`, `Welcome-Message`]
fs.readdirSync("./commands/").forEach((dir) => {
if (ignoredCategories.includes(dir)) return;
const editedName = `${dirEmojis[dir]} ${dir.toUpperCase()}`;
const commands = fs.readdirSync(`./commands/${dir}/`).filter((file) =>
file.endsWith(".js")
);
// If your handler does not use a folder for categories remove the dir, the dir is what the category name will be
const cmds = commands.filter((command) => {
let file = require(`../../commands/${dir}/${command}`);
return !file.hidden;
}).map((command) => {
let file = require(`../../commands/${dir}/${command}`);
if (!file.name) return "No command name.";
let name = file.name.replace(".js", "");
return `\`${name}\``;
});
let data = new Object();
data = {
name: editedName,
value: cmds.length === 0 ? "In progress." : cmds.join(" "),
};
categories.push(data);
});
const embed = new Discord.MessageEmbed()
.setTitle("Here Are My Commands:")
.addFields(categories)
.setDescription(
`Use \`${prefix}help\` followed by a command name to get more additional information on a command. For example: \`${prefix}help ban\`.`
)
.setFooter(
`Requested by ${message.author.tag}`,
message.author.displayAvatarURL({
dynamic: true
})
)
.setTimestamp()
.setColor(roleColor);
return message.channel.send(embed);
} else {
const command =
client.commands.get(args[0].toLowerCase()) ||
client.commands.find(
(c) => c.aliases && c.aliases.includes(args[0].toLowerCase())
);
if (!command) {
const embed = new Discord.MessageEmbed()
.setTitle(`Invalid command! Use \`${prefix}help\` for all of my commands!`)
.setColor("FF0000");
return message.channel.send(embed);
}
//This will show command info here
const embed = new Discord.MessageEmbed()
.setTitle("Command Details:")
.addField("PREFIX:", `\`${prefix}\``)
.addField(
"COMMAND:",
command.name ? `\`${command.name}\`` : "No name for this command."
)
.addField(
"ALIASES:",
command.aliases ?
`\`${command.aliases.join("` `")}\`` :
"No aliases for this command."
)
.addField(
"USAGE:",
command.usage ?
`\`${prefix}${command.name} ${command.usage}\`` :
`\`${prefix}${command.name}\``
)
.addField(
"DESCRIPTION:",
command.description ?
command.description :
"No description for this command."
)
.setFooter(
`Requested by ${message.author.tag}`,
message.author.displayAvatarURL({
dynamic: true
})
)
.setTimestamp()
.setColor(roleColor);
return message.channel.send(embed);
}
}
}
This was inspired by reconlx, but modified. github.com/reconlx
If you decide not to use the handler method, do what is shown below:
let category = []
let data = new Object()
data = {
name: category name/ category array
value: commands in the category
}
category.push(data)
let embed = new Discord.MessageEmbed()
.setTitle('Help')
.addFields(category)
Basic Command Handler Below (copy and paste into main file)
fs.readdirSync('./commands').forEach(dirs => {
const commands = fs.readdirSync(`./commands/${dirs}`).filter(files => files.endsWith('.js'));
for (const file of commands) {
const command = require(`./commands/${dirs}/${file}`);
console.log(`Loading command ${file}`);
if (command.name) {
client.commands.set(command.name.toLowerCase(), command);
} else {
continue;
}
}
});
Related
I'm still trying to place an order for the voice bot to enter. I want to make a music system using youtube-dl and I always get this error saying that it doesn't know what "Voice" means in the line "message.member.voiceChannel"
I'm already getting nervous about this problem, I tried to add permissions, but it doesn't work, I want to specify that it uses Discord.js#v12
below you have all the files that I use for the command, such as message event and command class.
Error Code:
2022-06-02 05:39:42 [info] [Command] "n!join" (join) ran by "GhostStru#1982" (780808189226123294) on guild "GhostStruπΏ's server" (939865905708552242) channel "#cmmds" (980923745768181831)
TypeError: Cannot read properties of undefined (reading 'voice')
at module.exports.run (C:\Users\Ghost\Desktop\NucleusNEW\commands\music\join.js:23:36)
at module.exports.runCommand (C:\Users\Ghost\Desktop\NucleusNEW\events\message\message.js:417:23)
at module.exports.run (C:\Users\Ghost\Desktop\NucleusNEW\events\message\message.js:391:20)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
This is my Join command
const { joinVoiceChannel } = require('#discordjs/voice');
const { MessageEmbed, Util } = require('discord.js');
const discord = require("discord.js")
const Command = require('../../structures/Command');
module.exports = class extends Command {
constructor(...args) {
super(...args, {
name: 'join',
aliases: ['add'],
usage: "",
category: "Music",
examples: ["join"],
description: "Join into you'r voice channel.",
cooldown: 5,
})
}
async run(client, message, args) {
const voiceChannel = message.member.voice.channel;
if (!message.member.voiceChannel) return message.channel.send({embeds: [new MessageEmbed().setColor(client.color.error).setDescription(`You must be a voice channel before using this command.`)]});
if (message.guild.me.voiceChannel && message.member.voiceChannel.id !== message.guild.me.voiceChannel.id) return message.channel.send({embeds: [new MessageEmbed().setColor(client.color.error).setDescription(`You are not in same voice channel.`)]});
try {
joinVoiceChannel({
channelId: message.member.voiceChannel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator,
});
await message.react('π').catch(() => { });
} catch {
return message.channel.send({embeds: [new MessageEmbed().setColor(client.color.error).setDescription(`An error occurred while joining the voice channel.`)]});
}
}
}
This is my message event
const Event = require('../../structures/Event');
const { Permissions, Collection } = require("discord.js");
const afk = require("../../models/afk");
const Statcord = require("statcord.js");
const moment = require('moment');
const discord = require("discord.js");
const config = require('./../../config.json');
const { MessageEmbed } = require('discord.js');
const logger = require('../../utils/logger');
const nsfwplease = require('../../assets/json/nfsw.json');
const mongoose = require('mongoose');
const Guild = require('../../database/schemas/Guild');
const User = require('../../database/schemas/User');
const Moderation = require('../../database/schemas/logging');
const Blacklist = require('../../database/schemas/blacklist');
const customCommand = require('../../database/schemas/customCommand');
const autoResponse = require('../../database/schemas/autoResponse');
const autoResponseCooldown = new Set();
const inviteFilter = require('../../filters/inviteFilter');
const linkFilter = require('../../filters/linkFilter');
const maintenanceCooldown = new Set();
const metrics = require('datadog-metrics');
const permissions = require('../../assets/json/permissions.json')
const Maintenance = require('../../database/schemas/maintenance')
require("moment-duration-format");
module.exports = class extends Event {
constructor(...args) {
super(...args);
this.impliedPermissions = new Permissions([
"VIEW_CHANNEL",
"SEND_MESSAGES",
"SEND_TTS_MESSAGES",
"EMBED_LINKS",
"ATTACH_FILES",
"READ_MESSAGE_HISTORY",
"MENTION_EVERYONE",
"USE_EXTERNAL_EMOJIS",
"ADD_REACTIONS"
]);
this.ratelimits = new Collection();
}
async run(message) {
try {
if (!message.guild) return;
if(config.datadogApiKey){
metrics.init({ apiKey: this.client.config.datadogApiKey, host: 'nucleus', prefix: 'nucleus.' });
}
const mentionRegex = RegExp(`^<#!?${this.client.user.id}>$`);
const mentionRegexPrefix = RegExp(`^<#!?${this.client.user.id}>`);
if (!message.guild || message.author.bot) return;
const settings = await Guild.findOne({
guildId: message.guild.id,
}, async (err, guild) => {
if (err) console.log(err)
if (!guild) {
const newGuild = await Guild.create({
guildId: message.guild.id,
prefix: config.prefix || 'p!',
language: "english"
});
}
});
//if (!settings) return message.channel.send('Oops, this server was not found in the database. Please try to run the command again now!');
if (message.content.match(mentionRegex)) {
const proofita = `\`\`\`css\n[ Prefix: ${settings.prefix || '!'} ]\`\`\``;
const proofitaa = `\`\`\`css\n[ Help: ${settings.prefix || '!'}help ]\`\`\``;
const embed = new MessageEmbed()
.setTitle('Hello, I\'m Nucleus. What\'s Up?')
.addField(`Prefix`,proofita, true)
.addField(`Usage`,proofitaa, true)
.setDescription(`\nIf you like Nucleus, Consider [voting](https://top.gg/bot/980373513691090974), or [inviting](https://discord.com/oauth2/authorize?client_id=980373513691090974&scope=bot&permissions=470150262) it to your server! Thank you for using Nucleus, we hope you enjoy it, as we always look forward to improve the bot`)
.setFooter('Thank you for using Nucleus!!')
.setColor('#FF2C98')
message.channel.send(embed);
}
if(config.datadogApiKey){
// Add increment after every darn message lmfao!
metrics.increment('messages_seen');
}
// Filters
if (settings && await inviteFilter(message)) return;
if (settings && await linkFilter(message)) return;
let mainPrefix = settings ? settings.prefix : '!';
const prefix = message.content.match(mentionRegexPrefix) ?
message.content.match(mentionRegexPrefix)[0] : mainPrefix
const guildDB = await Guild.findOne({
guildId: message.guild.id
});
const moderation = await Moderation.findOne({
guildId: message.guild.id
});
if(!moderation){
Moderation.create({
guildId: message.guild.id
})
}
// maintenance mode
const maintenance = await Maintenance.findOne({
maintenance: "maintenance"
})
const userBlacklistSettings = await Blacklist.findOne({ discordId: message.author.id,});
const guildBlacklistSettings = await Blacklist.findOne({ guildId: message.guild.id });
//autoResponse
const autoResponseSettings = await autoResponse.findOne({ guildId: message.guild.id, name: message.content.toLowerCase() });
if (autoResponseSettings && autoResponseSettings.name) {
if (userBlacklistSettings && userBlacklistSettings.isBlacklisted) return;
if(maintenance && maintenance.toggle == "true") return;
if(autoResponseCooldown.has(message.author.id)) return message.channel.send(`${message.client.emoji.fail} Slow Down - ${message.author}`)
message.channel.send(autoResponseSettings.content
.replace(/{user}/g, `${message.author}`)
.replace(/{user_tag}/g, `${message.author.tag}`)
.replace(/{user_name}/g, `${message.author.username}`)
.replace(/{user_ID}/g, `${message.author.id}`)
.replace(/{guild_name}/g, `${message.guild.name}`)
.replace(/{guild_ID}/g, `${message.guild.id}`)
.replace(/{memberCount}/g, `${message.guild.memberCount}`)
.replace(/{size}/g, `${message.guild.memberCount}`)
.replace(/{guild}/g, `${message.guild.name}`)
.replace(/{member_createdAtAgo}/g, `${moment(message.author.createdTimestamp).fromNow()}`)
.replace(/{member_createdAt}/g, `${moment(message.author.createdAt).format('MMMM Do YYYY, h:mm:ss a')}`))
autoResponseCooldown.add(message.author.id)
setTimeout(()=>{
autoResponseCooldown.delete(message.author.id)
}, 2000)
return;
}
//afk
let language = require(`../../data/language/english.json`)
if(guildDB) language = require(`../../data/language/${guildDB.language}.json`)
moment.suppressDeprecationWarnings = true;
if(message.mentions.members.first()){
if(maintenance && maintenance.toggle == "true") return;
const afklist = await afk.findOne({ userID: message.mentions.members.first().id, serverID: message.guild.id});
if(afklist){
await message.guild.members.fetch(afklist.userID).then(member => {
let user_tag = member.user.tag;
return message.channel.send(`**${afklist.oldNickname || user_tag || member.user.username}** ${language.afk6} ${afklist.reason} **- ${moment(afklist.time).fromNow()}**`).catch(() => {});
});
}
}
const afklis = await afk.findOne({ userID: message.author.id, serverID: message.guild.id});
if(afklis) {
if(maintenance && maintenance.toggle == "true") return;
let nickname = `${afklis.oldNickname}`;
message.member.setNickname(nickname).catch(() => {});
await afk.deleteOne({ userID: message.author.id });
return message.channel.send(new discord.MessageEmbed().setColor('GREEN').setDescription(`${language.afk7} ${afklis.reason}`)).then(m => {
setTimeout(() => {
m.delete().catch(() => {});
}, 10000);
});
};
if (!message.content.startsWith(prefix)) return;
// eslint-disable-next-line no-unused-vars
const [cmd, ...args] = message.content.slice(prefix.length).trim().split(/ +/g);
const command = this.client.commands.get(cmd.toLowerCase()) || this.client.commands.get(this.client.aliases.get(cmd.toLowerCase()));
// maintenance mode
if(!this.client.config.developers.includes(message.author.id)){
if(maintenance && maintenance.toggle == "true") {
if(maintenanceCooldown.has(message.author.id)) return;
message.channel.send(`Nucleus is currently undergoing maintenance which won't allow anyone to access Nucleus Commands. Feel free to try again later. For updates: https://discord.gg/FqdH4sfKBg`)
maintenanceCooldown.add(message.author.id);
setTimeout(() => {
maintenanceCooldown.delete(message.author.id)
}, 10000);
return;
}
}
// Custom Commands
const customCommandSettings = await customCommand.findOne({ guildId: message.guild.id, name: cmd.toLowerCase() });
const customCommandEmbed = await customCommand.findOne({ guildId: message.guild.id, name: cmd.toLowerCase() });
if (customCommandSettings && customCommandSettings.name && customCommandSettings.description) {
if (userBlacklistSettings && userBlacklistSettings.isBlacklisted) return;
let embed = new MessageEmbed()
.setTitle(customCommandEmbed.title)
.setDescription(customCommandEmbed.description)
.setFooter(``)
if( customCommandEmbed.image !== "none") embed.setImage(customCommandEmbed.image)
if( customCommandEmbed.thumbnail !== "none") embed.setThumbnail(customCommandEmbed.thumbnail)
if( customCommandEmbed.footer !== "none") embed.setFooter(customCommandEmbed.footer)
if( customCommandEmbed.timestamp !== "no") embed.setTimestamp()
if( customCommandEmbed.color == 'default') {
embed.setColor(message.guild.me.displayHexColor)
} else embed.setColor(`${customCommandEmbed.color}`)
return message.channel.send(embed)
}
if (customCommandSettings && customCommandSettings.name && !customCommandSettings.description && customCommandSettings.json == "false") {
if (userBlacklistSettings && userBlacklistSettings.isBlacklisted) return;
return message.channel.send(customCommandSettings.content
.replace(/{user}/g, `${message.author}`)
.replace(/{user_tag}/g, `${message.author.tag}`)
.replace(/{user_name}/g, `${message.author.username}`)
.replace(/{user_ID}/g, `${message.author.id}`)
.replace(/{guild_name}/g, `${message.guild.name}`)
.replace(/{guild_ID}/g, `${message.guild.id}`)
.replace(/{memberCount}/g, `${message.guild.memberCount}`)
.replace(/{size}/g, `${message.guild.memberCount}`)
.replace(/{guild}/g, `${message.guild.name}`)
.replace(/{member_createdAtAgo}/g, `${moment(message.author.createdTimestamp).fromNow()}`)
.replace(/{member_createdAt}/g, `${moment(message.author.createdAt).format('MMMM Do YYYY, h:mm:ss a')}`)
)
}
if (customCommandSettings && customCommandSettings.name && !customCommandSettings.description && customCommandSettings.json == "true") {
if (userBlacklistSettings && userBlacklistSettings.isBlacklisted) return;
const command = JSON.parse(customCommandSettings.content)
return message.channel.send(command).catch((e)=>{message.channel.send(`There was a problem sending your embed, which is probably a JSON error.\nRead more here --> https://nucleus.xyz/embeds\n\n__Error:__\n\`${e}\``)})
}
if (command) {
await User.findOne({
discordId: message.author.id
}, (err, user) => {
if (err) console.log(err)
if (!user) {
const newUser = new User({
discordId: message.author.id
})
newUser.save()
}
});
const disabledCommands = guildDB.disabledCommands;
if (typeof(disabledCommands) === 'string') disabledCommands = disabledCommands.split(' ');
const rateLimit = this.ratelimit(message, cmd);
if (!message.channel.permissionsFor(message.guild.me).has('SEND_MESSAGES')) return;
// Check if user is Blacklisted
if (userBlacklistSettings && userBlacklistSettings.isBlacklisted) {
logger.warn(`${message.author.tag} tried to use "${cmd}" command but the user is blacklisted`, { label: 'Commands' })
return message.channel.send(`${message.client.emoji.fail} You are blacklisted from the bot :(`);
}
// Check if server is Blacklisted
if (guildBlacklistSettings && guildBlacklistSettings.isBlacklisted) {
logger.warn(`${message.author.tag} tried to use "${cmd}" command but the guild is blacklisted`, { label: 'Commands' })
return message.channel.send(`${message.client.emoji.fail} This guild is Blacklisted :(`);
}
let number = Math.floor((Math.random() * 10) + 1);
if (typeof rateLimit === "string") return message.channel.send(` ${message.client.emoji.fail} Please wait **${rateLimit}** before running the **${cmd}** command again - ${message.author}\n\n${number === 1 ? "*Did You know that Nucleus has its own dashboard? `https://nucleus.xyz/dashboard`*" : ""}${number === 2 ? "*You can check our top.gg page at `https://vote.nucleus.xyz`*" : ""}`).then((s)=>{
message.delete().catch(()=>{});
s.delete({timeout: 4000}).catch(()=>{})
}).catch(()=>{})
if (command.botPermission) {
const missingPermissions =
message.channel.permissionsFor(message.guild.me).missing(command.botPermission).map(p => permissions[p]);
if (missingPermissions.length !== 0) {
const embed = new MessageEmbed()
.setAuthor(`${this.client.user.tag}`, message.client.user.displayAvatarURL({ dynamic: true }))
.setTitle(`<:wrong:822376943763980348> Missing Bot Permissions`)
.setDescription(`Command Name: **${command.name}**\nRequired Permission: **${missingPermissions.map(p => `${p}`).join(' - ')}**`)
.setTimestamp()
.setFooter('https://nucleus.xyz')
.setColor(message.guild.me.displayHexColor);
return message.channel.send(embed).catch(()=>{})
}
}
if (command.userPermission) {
const missingPermissions =
message.channel.permissionsFor(message.author).missing(command.userPermission).map(p => permissions[p]);
if (missingPermissions.length !== 0) {
const embed = new MessageEmbed()
.setAuthor(`${message.author.tag}`, message.author.displayAvatarURL({ dynamic: true }))
.setTitle(`<:wrong:822376943763980348> Missing User Permissions`)
.setDescription(`Command Name: **${command.name}**\nRequired Permission: **${missingPermissions.map(p => `${p}`).join('\n')}**`)
.setTimestamp()
.setFooter('https://nucleus.xyz')
.setColor(message.guild.me.displayHexColor);
return message.channel.send(embed).catch(()=>{})
}
}
if(disabledCommands.includes(command.name || command)) return;
if (command.ownerOnly) {
if (!this.client.config.developers.includes(message.author.id)) return
}
if(config.datadogApiKey){
metrics.increment('commands_served');
}
if (command.disabled) return message.channel.send(`The owner has disabled the following command for now. Try again Later!\n\nFor Updates: https://discord.gg/duBwdCvCwW`)
if (command.nsfwOnly && !message.channel.nsfw && message.guild) return message.channel.send(`${nsfwplease[Math.round(Math.random() * (nsfwplease.length - 1))]}`)
Statcord.ShardingClient.postCommand(cmd, message.author.id, this.client);
await this.runCommand(message, cmd, args)
.catch(error => {
if(config.datadogApiKey){
metrics.increment('command_error');
}
return this.client.emit("commandError", error, message, cmd);
})
}
} catch(error) {
if(config.datadogApiKey){
metrics.increment('command_error');
}
return this.client.emit("fatalError", error, message);
}
}
async runCommand(message, cmd, args) {
if (!message.channel.permissionsFor(message.guild.me) || !message.channel.permissionsFor(message.guild.me).has('EMBED_LINKS'))
return message.channel.send(`${message.client.emoji.fail} Missing bot Permissions - **Embeds Links**`)
const command = this.client.commands.get(cmd.toLowerCase()) || this.client.commands.get(this.client.aliases.get(cmd.toLowerCase()));
logger.info(`"${message.content}" (${command.name}) ran by "${message.author.tag}" (${message.author.id}) on guild "${message.guild.name}" (${message.guild.id}) channel "#${message.channel.name}" (${message.channel.id})`, { label: 'Command' })
await command.run(message, args)
}
ratelimit(message, cmd) {
try {
const command = this.client.commands.get(cmd.toLowerCase()) || this.client.commands.get(this.client.aliases.get(cmd.toLowerCase()));
if (message.author.permLevel > 4) return false;
const cooldown = command.cooldown * 1000
const ratelimits = this.ratelimits.get(message.author.id) || {}; // get the ENMAP first.
if (!ratelimits[command.name]) ratelimits[command.name] = Date.now() - cooldown; // see if the command has been run before if not, add the ratelimit
const difference = Date.now() - ratelimits[command.name]; // easier to see the difference
if (difference < cooldown) { // check the if the duration the command was run, is more than the cooldown
return moment.duration(cooldown - difference).format("D [days], H [hours], m [minutes], s [seconds]", 1); // returns a string to send to a channel
} else {
ratelimits[command.name] = Date.now(); // set the key to now, to mark the start of the cooldown
this.ratelimits.set(message.author.id, ratelimits); // set it
return true;
}
} catch(e) {
this.client.emit("fatalError", error, message);
}
}
}
And this is my Command class
module.exports = class Command {
constructor(client, name, options = {}) {
this.client = client;
this.name = options.name || name;
this.aliases = options.aliases || [];
this.description = options.description || "No description provided.";
this.category = options.category || "General";
this.usage = `${this.name} ${options.usage || ''}` || "No usage provided.";
this.examples = options.examples || [];
this.disabled = options.disabled || false;
this.cooldown = "cooldown" in options ? options.cooldown : 5 || 5;
this.ownerOnly = options.ownerOnly || false;
this.guildOnly = options.guildOnly || false;
this.nsfwOnly = options.nsfwOnly || false;
this.botPermission = options.botPermission || ['SEND_MESSAGES', 'EMBED_LINKS'];
this.userPermission = options.userPermission || null;
}
// eslint-disable-next-line no-unused-vars
async run(message, args) {
throw new Error(`The run method has not been implemented in ${this.name}`);
}
reload() {
return this.store.load(this.file.path);
}
}
In this "code cases" i put my personal codes, and i dont know where can i find the problem, or what can i modifiy in my code, thats all i can say..
Can someone tell me what can i do?...
Its a simple join command, and he cannot read voice.channel...
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.
So I made a discord selection menu ticket that when I select that category it makes a channel and send a message with a button. The button is supposed to delete the channel when pressed, but it doesn't seem to work. I think I have found the error but I don't know how to fix it. It is probably easy to fix but I'm stuck.
The code: (I think the error is located in the end here)
} else if (Discord.MessageButton.customId === 'del') {
const channel = message.guild.channel
channel.delete();
const Discord = require("discord.js");
const { MessageSelectMenu, MessageActionRow } = require("discord.js");
module.exports = {
name: "ticket",
author: "Falcone",
run: async(client, message, args) => {
if (!message.member.permissions.has("ADMINISTRATOR")) return message.reply('You Dont Have the `ADMINISTRATOR` permision');
message.delete();
let embed = new Discord.MessageEmbed()
.setColor("RANDOM")
.setDescription(`Test`)
.setThumbnail(message.guild.iconURL({ dynamic: true }))
.setAuthor(message.guild.name, message.guild.iconURL({ dynamic: true }));
let painel = new MessageActionRow().addComponents( new MessageSelectMenu()
.setCustomId('menu')
.setPlaceholder('Test') // Mensagem estampada
.addOptions([
{
label: 'Support',
description: '',
emoji: 'πββοΈ',
value: '1',
},
{
label: 'Test',
description: '',
emoji: 'β',
value: '2',
},
{
label: 'Test',
description: '',
emoji: 'π€',
value: '3',
}
])
);
message.channel.send({ embeds: [embed], components: [painel] }).then(msg => {
const filtro = (interaction) =>
interaction.isSelectMenu()
const coletor = msg.createMessageComponentCollector({
filtro
});
coletor.on('collect', async (collected) => {
let ticket = collected.values[0]
collected.deferUpdate()
if (ticket === "1") {
const embed = new Discord.MessageEmbed()
.setTitle('Ticket')
.setDescription('Hello there, \n The staff will be here as soon as possible mean while tell us about your issue!\nThank You!')
.setColor('GREEN')
.setTimestamp()
const del = new MessageActionRow()
.addComponents(
new Discord.MessageButton()
.setCustomId('del')
.setLabel('ποΈ Delete Ticket!')
.setStyle('DANGER'),
);
message.guild.channels.create(`${collected.user.id}`, {
type : 'GUILD_TEXT',
permissionOverwrites : [
{
id : message.guild.id,
deny : ['VIEW_CHANNEL']
},
{
id : collected.user.id,
allow : ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES']
}
]
}).then(async (msg) => {
msg.send({ embeds: [embed], components: [del] }).then(msg => msg.pin() );
})
} else if (Discord.MessageButton.customId === 'del') {
const channel = message.guild.channel
channel.delete();
}
})
});
}
}
MessageButton.customId is not a static property. That means it must be done on an instance, not the class. Something that you could try is this:
const msg = await message.channel.send({
content: "Which one?",
components: [
new Discord.MessageActionRow().addComponents([
new Discord.MessageButton().setLabel("Delete").setStyle("DANGER").setCustomId("DEL"), //delete button
new Discord.MessageButton().setLabel("Cancel").setStyle("DANGER").setCustomId("CAN") //cancel button
])
]
})
//Create button collector
const collector = msg.createMessageComponentCollector({
componentType: "BUTTON",
filter: (c) => c.member.id === msg.member.id,
max: 1
})
//Handle button click
collector.on("collect", i => {
if(i.customId === "CAN") return i.reply("Cancelled")
if(i.customId === "DEL") i.channel.delete() //or whatever channel you want to delete
})
Warning: I did not test this code. You can tell me any problems you have and I will try to modify this
let ticket = new Map()
module.exports = {
commands: ['ticket'],
description: "open a new ticket",
callback: (message, async, text) => {
const ticketChannel = message.guild.channels.cache.find(c => c.name.toLowerCase() === `${message.author.username}--ticket`.toLowerCase())
if(ticketChannel || ticket.get(message.author.id) === true) return message.channel.send("You already have a ticket currently open!")
const ticketCreated = await message.guild.channels.create(`${message.author.username}-ticket`, {
type: 'text',
permissionOverwrites: [
{
allow: 'VIEW_CHANNEL',
id: message.author.id
},
{
deny: 'VIEW_CHANNEL',
id: message.guild.id
}
]
})
ticket.set(message.author.id, true)
let embed1 = new Discord.MessageEmbed()
.setAuthor(message.member.displayName, message.member.user.displayAvatarURL())
.setTitle(`Your Ticket has been created!`)
.setTimestamp()
.setColor('RANDOM');
let embed3 = new Discord.MessageEmbed()
.setAuthor(message.member.displayName, message.member.user.displayAvatarURL())
.setTitle(`Why have you created this ticket?`)
.setDescription('Give a brief explanation on why you created this ticket.')
.addField('Staff will be here shortly', 'Please wait without pinging anyone.')
.setTimestamp()
.setColor('RANDOM');
ticketCreated.send(embed3)
message.channel.send(embed1)
}
}
i have this code and this is give me const ticketCreated = await message.guild.channels.create(${message.author.username}-ticket, {
error, what this is mean?
It's important to note that this is not my code, but I've made some changes to it for it to work, I'd love help
Does someone know how to get the startup time of his own discord bot? ( i don't mean the uptime) (i am looking for the startup time)
Something like that:
in a variable.
Start time
2020-12-31 12:12:12
You can use this event to detect when he's online:
let _date;
client.once("ready", () => {
_date = new Date();
console.log(_date);
});
const { CommandoClient, Client } = require('discord.js-commando');
const { Structures } = require('discord.js');
const discord = require('discord.js');
const path = require('path');
const { prefix, token, discord_owner_id } = require('./config.json');
const bot = new Client();
Structures.extend('Guild', function(Guild) {
class MusicGuild extends Guild {
constructor(client, data) {
super(client, data);
this.musicData = {
queue: [],
isPlaying: false,
nowPlaying: null,
songDispatcher: null,
volume: 1
};
this.triviaData = {
isTriviaRunning: false,
wasTriviaEndCalled: false,
triviaQueue: [],
triviaScore: new Map()
};
}
}
return MusicGuild;
});
const client = new CommandoClient({
commandPrefix: prefix,
owner: discord_owner_id // value comes from config.json
});
client.registry
.registerDefaultTypes()
.registerGroups([
['music', 'Music Command Group'],
['gifs', 'Gif Command Group'],
['other', 'random types of commands group'],
['guild', 'guild related commands']
])
.registerDefaultGroups()
.registerDefaultCommands({
eval: false,
prefix: false,
commandState: false
})
.registerCommandsIn(path.join(__dirname, 'commands'));
let _date;
client.on("ready", () =>{
_date = new Date();
console.log(_date)
console.log('Startet Up :) !')
client.user.setStatus('dnd')
client.user.setActivity('Simogus Livestream', {type: 'WATCHING'}, {url: 'www.twitch.tv/simogu'}).catch(console.error);
});
client.on('voiceStateUpdate', async (___, newState) => {
if (
newState.member.user.bot &&
!newState.channelID &&
newState.guild.musicData.songDispatcher &&
newState.member.user.id == client.user.id
) {
newState.guild.musicData.queue.length = 0;
newState.guild.musicData.songDispatcher.end();
return;
}
if (
newState.member.user.bot &&
newState.channelID &&
newState.member.user.id == client.user.id &&
!newState.selfDeaf
) {
newState.setSelfDeaf(true);
}
});
client.on('guildMemberAdd', member => {
const channel = member.guild.channels.cache.find(ch => ch.name === 'Allgemein'); // change this to the channel name you want to send the greeting to
if (!channel) return;
channel.send(`Willkommen ${member} auf den Server von den Kings π !`);
});
client.login(token);