I just finished my bot and wanted to invite it to another server to test it out.
However, when I typed / no commands showed up.
When I invited the bot I enabled application.commands so I can use the slashcommands but it still did not work. My bot also has a global slashcommand handler so it should normally work right?
I don't know if the handler code is needed but I'll still add it here in case you do need it:
const { Perms } = require('../Validation/Permissions');
const { Client } = require('discord.js');
/**
* #param {Client} client
*/
module.exports = async (client, PG, Ascii) => {
const Table = new Ascii("Command Loaded");
CommandsArray = [];
(await PG(`${process.cwd()}/Commands/*/*.js`)).map(async (file) => {
const command = require(file);
if(!command.name)
return Table.addRow(file.split("/")[7], "⛔ FAILED", "Missing a name.")
if(command.type !== "USER" && !command.description)
return Table.addRow(command.name, "⛔ FAILED", "Missing a description.")
if(command.permission){
if(Perms.includes(command.permission))
command.defaultPermission = false;
else
return Table.addRow(command.name, "⛔ FAILED", "Permission is invalid.")
}
client.commands.set(command.name, command);
CommandsArray.push(command);
await Table.addRow(command.name, "✅ SUCCESSFUL");
});
console.log(Table.toString());
// PERMISSIONS CHECK //
client.on("ready", async () =>{
client.guilds.cache.forEach((g) => {
g.commands.set(CommandsArray).then(async (command) =>{
const Roles = (commandName) => {
const cmdPerms = CommandsArray.find((c) => c.name === commandName).permission;
if(!cmdPerms) return null;
return g.roles.cache.filter((r) => r.permissions.has(cmdPerms) && !r.managed).first(10);
}
const fullPermissions = command.reduce((accumulator, r) =>{
const roles = Roles(r.name);
if(!roles) return accumulator;
const permissions = roles.reduce((a, r) =>{
return [...a, {id: r.id, type: "ROLE", permission:true}]
}, []);
return [...accumulator, {id: r.id, permissions}]
}, []);
await g.commands.permissions.set({ fullPermissions });
});
})
});
}
You have to register the command first, which is essentially creating the command within Discord. Follow the guide to get it set up. And to clarify, you only register the command once, if that isn't obvious.
You can use Postman to create/edit the commands if you are comfortable with it.
Related
This question already has answers here:
What are the rules for JavaScript's automatic semicolon insertion (ASI)?
(7 answers)
Closed last year.
I am making a Discord bot command handler, and I keep getting this error:
(await PG(`${process.cwd()}/Commands/*/*js`)).map(async (file) => {
^
TypeError: [] is not a function
Here is my code:
const { Perms } = require('../Validation/Permissions');
const { Client } = require('discord.js')
const { promisify } = require("util")
const { glob } = require('glob');
const PG = promisify(glob)
const Ascii = require('ascii-table')
/**
* #param {Client} client
*/
module.exports = async (client) => {
const Table = new Ascii('Command Loaded')
CommandsArray = []
(await PG(`${process.cwd()}/Commands/*/*js`)).map(async (file) => {
const command = require(file);
if (!command.name)
return Table.addRow(file.split("/")[7], 'FAILED', 'Missing a name.')
if (!command.description)
return Table.addRow(command.name, 'FAILED', 'Missing the description.')
if (command.permission) {
if (Perms.includes(command.permission))
command.defaultPermission = false;
else
return Table.addRow(command.name,'FAILED','Permission is invalid')
}
client.commands.set(command.name, command);
CommandsArray.push(command);
await Table.addRow(command.name, 'SUCCESSFUL');
})
console.log(Table.toString())
// Permissions check //
client.on('ready', async() => {
const MainGuild = await client.guilds.cache.get('940180806696058910');
MainGuild.commands.set(CommandsArray).then(async (command) => {
const Roles = (commandName) => {
const cmdPerms = CommandsArray.find((c) => c.name === commandName).permission
if (!cmdPerms) return null;
return MainGuild.roles.cache.filter((r) => r.permissions.has(cmdPerms))
}
const fullPermissions = command.reduce((accumulator, r) => {
const roles = Roles(r.name);
if (!roles) return accumulator;
const permissions = roles.reduce((a, r) => {
return [...a,{id: r.id, type: 'ROLE', permission: true}]
}, [])
return [...accumulator, {id: r.id, permissions}]
}, [])
await MainGuild.commands.permissions.set({ fullPermissions });
})
})
}
I've done some googling, but I was unable to find anything related to just [], type error usually appears when there is a spelling mistake in your code. I have gone through my code numerous times and have been completely unable to find any mistakes, I just cannot figure this out.
I would really appreciate some help, thank you!
Please use semi-colons!
Add ; onto the line above the PG where you define an empty array, JS sees the array and also brackets right after and this thinks you are executing a function because JS when compiled does not look at lines or spacing.
CommandsArray = [];
(await PG(`${process.cwd()}/Commands/*/*js`)).map(async (file) => {
This is my setuplogger.js file, and the bottom part is the code I have in my index.js. This code is supposed to create a webhook for the channel set as the logschannel, this webhook will send logs for every ban that happens in the guild. But the problem is that I keep getting the .createWebhook is not a function, I couldn't figure out how to fix this error so I just came here.
if (!message.member.hasPermission("ADMINISTRATOR")) {
return message.channel.send(`***Error:*** *You do not have* ***[ADMINISTRATOR]*** *permission.*`);
}
const logEnableDisable = args[0];
const logChannel = message.mentions.channels.first();
if (!logEnableDisable) {
return message.channel.send(`***Error:*** *${prefix}setuplogger <enable/disable> <channel>*`)
}
if (!logChannel) {
return message.channel.send(`***Error:*** *${prefix}setuplogger <enable/disable> <channel>*`)
}
if (logEnableDisable === 'enable') {
db.set(`${message.guild.id}_logChannel`, logChannel.id)
message.channel.send(`*Succesfully enabled logs to* ***${logChannel}.***`)
}
if (logEnableDisable === 'disable') {
const findLogchannel = db.get(`${message.guild.id}_logChannel`);
if (!findLogchannel) {
message.channel.send(`***Error:*** *Log channel has not been setup yet, use \`${prefix}setuplogger enable <channel>\`.*`)
} else {
db.delete(`${message.guild.id}_logChannel`, true)
message.channel.send(`*Succesfully removed logs from* ***${logChannel}.***`)
}
}
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client.on("guildBanAdd", async (guild, user) => {
const channel = db.get(`${guild.id}_logChannel`);
const fetchedLogs = await guild.fetchAuditLogs({
limit: 1,
type: "MEMBER_BAN_ADD",
});
const banLog = fetchedLogs.entries.first();
if(!banLog) return console.log("It doesn't work.")
const { executor, target } = banLog;
if (target.id === user.id) {
const embed = new Discord.MessageEmbed()
.setTitle('Ban')
.setDescription(`**User Banned**\fModerator: ${executor}\fUser: ${target.tag}`)
.setTimestamp()
.setColor(color);
channel.createWebhook('Logger', { avatar: 'https://cdn2.iconfinder.com/data/icons/basic-ui-elements-circle/512/notepad_note_wrrte_pencil-512.png' }).then(webhook => { webhook.send(embed) });
}
});
It seems you're saving the channel's ID in the database (logChannel.id) and later, you're trying to call the createWebhook method on a string, not the channel. If you call a non-existing method on a string you'll receive an error; "channel.createWebhook is not a function":
const channel = '86924931458913231434'
const webhook = channel.createWebhook('Logger')
To solve this, you need to fetch the channel first so you can use the createWebhook method:
client.on('guildBanAdd', async (guild, user) => {
const channelID = db.get(`${guild.id}_logChannel`);
if (!channelID) return console.log('No channel ID');
try {
const channel = await client.channels.fetch(channelID);
const fetchedLogs = await guild.fetchAuditLogs({
limit: 1,
type: 'MEMBER_BAN_ADD',
});
const banLog = fetchedLogs.entries.first();
if (!banLog) return console.log("It doesn't work.");
const { executor, target } = banLog;
if (target.id === user.id) {
const embed = new Discord.MessageEmbed()
.setTitle('Ban')
.setDescription(
`**User Banned**\fModerator: ${executor}\fUser: ${target.tag}`,
)
.setTimestamp()
.setColor(color);
const webhook = await channel.createWebhook('Logger', {
avatar:
'https://cdn2.iconfinder.com/data/icons/basic-ui-elements-circle/512/notepad_note_wrrte_pencil-512.png',
});
webhook.send(embed);
}
} catch (error) {
console.log(error);
}
});
Well, I would create a discord bot that will stock given data in a database, .then I began to learn js
Until now i haven't any problem and found a lot of help in the web, before to create the database i tried to show detected data on the console but now I'm blocked and can't understand by myself where is the problem.
here is my code
const Discord = require('discord.js')
const client = new Discord.Client();
const { promisify } = require('util')
const sleep = promisify(setTimeout)
require('dotenv').config();
const BOT_TOKEN = '******'
client.on('ready', async () => {
console.log(`The bot is now working !\n\n`);
});
client.on('message', async (receivedMessage) => {
// Prevent bot from responding to its own messages
if (receivedMessage.author == client.user) {
return;
}
const { author, content, channel } = receivedMessage;
const { id } = author;
const trimmedContent = content.trim();
if (trimmedContent.startsWith('!ins')) {
console.log('Inside ins');
module.exports = {
prefix: "!ins",
fn: (msg) => {
let application = {}
let filter = (msg) => !msg.author.bot;
let options = {
max: 1,
time: 15000
};
msg.member.send("nom ?")
.then(dm => {
// After each question, we'll setup a collector on the DM channel
return dm.channel.awaitMessages(filter, options)
})
.then(collected => {
// Convert the collection to an array & get the content from the first element
application.name = collected.array()[0].content;
// Ask the next question
return msg.member.send("Parfait, maintenant votre mail ?")
})
.then(dm => {
return dm.channel.awaitMessages(filter, options)
})
.then(collected => {
application.emailAddress = collected.array()[0].content;
return msg.member.send("Excellent. Enfin, quel est votre âge ?")
})
.then(dm => {
return dm.channel.awaitMessages(filter, options)
})
.then(collected => {
application.pitch = collected.array()[0].content;
console.log(application)
})
}
}
}
});
// client.login logs the bot in and sets it up for use. You'll enter your token here.
client.login(' ');
The problem is that bot doesn't react to !ins command and on the console I only have the console.log 2 and 3
if you need any more info, feel free to ask them and thanks for taken time
I do think that you should code your main structure like mine because yours is a bit messy.
const Discord = require('discord.js');
const client = new Discord.Client();
const BOT_TOKEN = '...';
client.on('ready', async () => {
console.log(`The bot is now working !\n\n`);
});
client.on('message', async (receivedMessage) => {
// Prevent bot from responding to its own messages
if (receivedMessage.author == client.user) {
return;
}
const { author, content, channel } = receivedMessage;
const { id } = author;
// Removes whitespace from both ends of a string, "I personally do like this"
const trimmedContent = content.trim();
if (trimmedContent.startsWith('!ins')) {
console.log('Inside ins');
}
});
client.login(BOT_TOKEN);
process.on('exit', () => {
client.destroy();
console.log(`The bot is now disconnected !\n\n`);
});
I am trying to move all of my currency/shop commands/ Sequelize database into the command handler from index.js (works perfectly in index.js file) but I am running into issues transferring data from the index.js file into the individual command files. Any help on how to properly integrate the index.js commands into the command handler would be greatly appreciated. I realize this is a lot to go through but it would really mean a lot to me if anyone was able to help me out
index.js:
Reflect.defineProperty(currency, 'add', {
value: async function add(id, amount) {
const user = currency.get(id);
if (user) {
user.balance += Number(amount);
return user.save();
}
const newUser = await Users.create({ user_id: id, balance: amount });
currency.set(id, newUser);
return newUser;
},
});
Reflect.defineProperty(currency, 'getBalance', {
value: function getBalance(id) {
const user = currency.get(id);
return user ? user.balance : 0;
},
});
client.once('ready', async () => {
const storedBalances = await Users.findAll();
storedBalances.forEach(b => currency.set(b.user_id, b));
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', async message => {
if (message.author.bot) return;
currency.add(message.author.id, 1);
if (!message.content.startsWith(prefix)) return;
const input = message.content.slice(prefix.length).trim();
if (!input.length) return;
const [, command, commandArgs] = input.match(/(\w+)\s*([\s\S]*)/);
if (command === 'balance') {
const target = message.mentions.users.first() || message.author;
return message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}💰`);
} else if (command === 'buy') {
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);
} else if (command === 'shop') {
const items = await CurrencyShop.findAll();
return message.channel.send(items.map(i => `${i.name}: ${i.cost}💰`).join('\n'), { code: true });
} else if (command === 'leaderboard') {
return message.channel.send(
currency.sort((a, b) => b.balance - a.balance)
.filter(user => client.users.cache.has(user.user_id))
.first(10)
.map((user, position) => `(${position + 1}) ${(client.users.cache.get(user.user_id).tag)}: ${user.balance}💰`)
.join('\n'),
{ code: true }
);
}
});
converting balance command to balance.js
balance.js:
const { currency, getBalance, id, tag } = require('../index.js');
module.exports = {
name: "balance",
description: "checks balance",
execute(message) {
const target = message.mentions.users.first() || message.author;
message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}💰`);
},
};
error:
TypeError: Cannot read property 'getBalance' of undefined
Command Handler
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName)
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type !== 'text') {
return message.reply('I can\'t execute that command inside DMs!');
}
if (command.args && !args.length) {
let reply = `You didn't provide any arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
return message.channel.send(reply);
}
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 || 3) * 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.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
});
the bot sends an error from the command handler as seen above
EDIT: Cherryblossom's post seems to work. i have 1 more issue with immigrating the buy command though I dont know how to make the async work as async doesnt work in command handler. here is what i tried
const { currency, CurrencyShop} = require('../index.js');
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);```
What's happening is that in balance.js, currency is undefined. You need to export currency from index.js:
module.exports = { currency }
Also, in balance.js, you don't need to (and actually can't) import/require properties of other objects (getBalance, tag, id). Sorry if that doesn't make sense but basically you only need to require currency:
const { currency } = require('../index.js')
Edit
await can only be used in an async function. Edit the execute function so it is like this:
async execute(message) {
// your code here
}
When calling execute, use await. You'll need to make the message handler async as well:
client.on('message', async message => {
// code...
try {
await command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
}
making a discord bot in javascript with visual studio code but for some reason getting an error. I'll show you the code that is relevant first.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
classes I'm working with
Here is the index.js:
const { Client, Collection } = require("discord.js");
const { config } = require("dotenv");
const fs = require("fs");
const client = new Client({
disableEveryone: true
});
client.commands = new Collection();
client.aliases = new Collection();
client.categories = fs.readdirSync("./commands/");
config({
path: __dirname + "/.env"
});
["command"].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
client.user.setPresence({
status: "online",
game: {
name: "you get boosted❤️",
type: "Watching"
}
});
});
client.on("message", async message => {
const prefix = "!";
if (message.author.bot) return;
if (!message.guild) return;
if (!message.content.startsWith(prefix)) return;
if (!message.member) message.member = await message.guild.fetchMember(message);
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
if (command)
command.run(client, message, args);
});
client.login(process.env.TOKEN);
Here is tempmute:
bot.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'mute':
var person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!person) return message.reply("I CANT FIND THE USER " + person)
let mainrole = message.guild.roles.find(role => role.name === "Newbie");
let role = message.guild.roles.find(role => role.name === "mute");
if(!role) return message.reply("Couldn't find the mute role.")
let time = args[2];
if(!time){
return message.reply("You didnt specify a time!");
}
person.removeRole(mainrole.id)
person.addRole(role.id);
message.channel.send(`#${person.user.tag} has now been muted for ${ms(ms(time))}`)
setTimeout(function(){
person.addRole(mainrole.id)
person.removeRole(role.id);
console.log(role.id)
message.channel.send(`#${person.user.tag} has been unmuted.`)
}, ms(time));
break;
}
});
Here is the help.js which lists all commands
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
module.exports = {
name: "help",
aliases: ["h"],
category: "info",
description: "Returns all commands, or one specific command info",
usage: "[command | alias]",
run: async (client, message, args) => {
if (args[0]) {
return getCMD(client, message, args[0]);
} else {
return getAll(client, message);
}
}
}
function getAll(client, message) {
const embed = new RichEmbed()
.setColor("RANDOM")
const commands = (category) => {
return client.commands
.filter(cmd => cmd.category === category)
.map(cmd => `- \`${cmd.name}\``)
.join("\n");
}
const info = client.categories
.map(cat => stripIndents`**${cat[0].toUpperCase() + cat.slice(1)}** \n${commands(cat)}`)
.reduce((string, category) => string + "\n" + category);
return message.channel.send(embed.setDescription(info));
}
function getCMD(client, message, input) {
const embed = new RichEmbed()
const cmd = client.commands.get(input.toLowerCase()) || client.commands.get(client.aliases.get(input.toLowerCase()));
let info = `No information found for command **${input.toLowerCase()}**`;
if (!cmd) {
return message.channel.send(embed.setColor("RED").setDescription(info));
}
if (cmd.name) info = `**Command name**: ${cmd.name}`;
if (cmd.aliases) info += `\n**Aliases**: ${cmd.aliases.map(a => `\`${a}\``).join(", ")}`;
if (cmd.description) info += `\n**Description**: ${cmd.description}`;
if (cmd.usage) {
info += `\n**Usage**: ${cmd.usage}`;
embed.setFooter(`Syntax: <> = required, [] = optional`);
}
return message.channel.send(embed.setColor("GREEN").setDescription(info));
}
ERROR:
Error message, bot not defined.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
I think the tempmute simply doesn't work because you use bot.on() instead of client.on(), which was defined in the index.js. I can't help you for the rest but everything is maybe related to this.