In my Discord.JS bot, I have multiple commands setup (ping, beep, etc.) but Discord only recognizes "ping". I have tried multiple setups, and all are the same.
Here is my code:
const { Client, Intents } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName: command } = interaction;
if (command === 'ping') {
await interaction.reply('Pong!');
} else if (command === 'beep') {
await interaction.reply('Boop!');
} else if (command === 'server') {
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
} else if (command === 'user-info') {
await interaction.reply(`Your username: ${interaction.user.username}\nYour ID: ${interaction.user.id}`);
}
});
client.login(token);
And here is Discords command view when "/" is enter
As you can see, ping is the only thing being recognized by discord.
It is also worth noting the ‘ping’ command has a description which the original description I setup, so it seems like issue is that Discord is not updating the commands each time the script changes. But, I don’t know how to resolve that issue.
It seems like you only registered the ping command. You have to register each slash command individually.
I guess you registered the slashcommand some tile earlier, and have not removed it since. You are only responding in your code example to slashcommands, but you have to create them in the first hand.
Check here on how to do that.
it may take up to one hour to register a global command tho, so be patient. If you are fine, with slashcommands for one guild only, you can also only create guildCommands. These are up and running within a view minutes (under 10minutes max)
Here is a simple command, with which you can update the slashcommands (this is staright from the docs)
client.on('messageCreate', async message => {
if (!client.application?.owner) await client.application?.fetch();
if (message.content.toLowerCase() === '!deploy' && message.author.id === client.application?.owner.id) {
const data = [
{
name: 'ping',
description: 'Replies with Pong!',
},
{
name: 'pong',
description: 'Replies with Ping!',
},
];
const commands = await client.application?.commands.set(data);
console.log(commands);
}
});
NOTE: you have to be running the master branch of discord.js (aka Discord.js V13). If you have not installed it yet, you can install it by running: npm install discord.js#latest. Make sure, you have uninstalled the "normal" discord.js dependency beforehand, by running npm uninstall discord.js.
If you are not sure what version you currently have installed, simply run npm list
This worked for me, the idea is to render each command separately.
I also went for some hardcoded configs: guild_id & client_id (to win some time in dev mode)
const { Client, Collection, Intents } = require('discord.js');
const { token, client_id, guild_id } = require('./config.json');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.once('ready', () => {
console.log('Ready!');
});
client.on('messageCreate', async message => {
if (!client.application?.owner) await client.application?.fetch();
// => client_id was just a quick fix, the correct value should be the id of the guild owner(s)
if (message.content.toLowerCase() === '!deploy' && message.author.id === client_id) {
const data = [
{
name: 'ping',
description: 'Replies with Pong!',
},
{
name: 'foo',
description: 'Replies with bar!',
},
{
name: 'chicken',
description: 'Replies with sticks!',
},
];
// same here, guild_id should also be replaced by the correct call to the idea number, just as client_id in this code!
for (let i = 0; data.length > i; i++) {
await client.guilds.cache.get(guild_id)?.commands.create(data[i]);
}
}
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const command = interaction.commandName;
if (command === 'ping') {
await interaction.reply('pong')
} else if (command === 'foo') {
await interaction.reply('bar')
} else if (command === 'chicken') {
await interaction.reply('nuggets')
}
});
client.login(token);
Related
I want to build a discord bot with slash commands. I use the following script to register the commands:
index.js
require("dotenv").config();
const fs = require("node:fs");
const { REST } = require("#discordjs/rest");
const { Routes } = require("discord-api-types/v9");
const { Client, Intents, Collection, Interaction, ClientUser } = require('discord.js');
// Create a new client instance
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.GUILD_MESSAGES
]
});
const commandFiles = fs.readdirSync("./commands").filter(file => file.endsWith(".js"));
const commands = [];
const GUILDID = process.env.GUILDID;
client.commands = new Collection();
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
client.commands.set(command.data.name, command);
};
const rest = new REST ({version: "9"}).setToken(process.env.TOKEN);
client.once("ready", () => {
console.log("Ready");
console.log(commands);
const CLIENT_ID = client.user.id;
(async () => {
try {
if(process.env.ENV === "production"){
await rest.put(Routes.applicationCommands(CLIENT_ID),{
body: commands
});
console.log("Successfully registered commands globally");
} else {
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILDID), {
body: commands
});
console.log("Successfully registered commands locally");
}
} catch (err) {
if (err) console.error(err);
}
})();
});
client.login(process.env.TOKEN);
I have one command so far called "ping.js" which is in the commands folder, which is in my project folder.
ping.js
const { SlashCommandBuilder } = require("#discordjs/builders");
module.exports = {
data: new SlashCommandBuilder()
.setName("ping")
.setDescription("pong"),
async execute(interaction) {
interaction.reply({
content: "Pong",
ephemeral: true
})
}
}
I also have an .env file in the project folder.
ENV=test
TOKEN=****
GUILDID=****
The script runs without errors and I get "Successfully registered commands locally" as a feedback, but the command dont show up in Discord. I have tried to register the bot again, restart my PC and the terminal and I have checked the code multiple times.
Whats make this a bit frustrating is that it first works and let me run the ping command, but after adding another command, the new one dont showed up. And now I have deleted the secound command again but cant get back.
Thank you all very much for you help in advance
Update:
Following the advise from Gh0st I have added the line console.log(commands) which gives me the following response:
Ready
[
{
name: 'ping',
name_localizations: undefined,
description: 'pong',
description_localizations: undefined,
options: [],
default_permission: undefined
}
]
Successfully registered commands locally
To me it seems that the for loop works since they are in the array, but they commands still dont show up in Discord.
I am attempting to program a ban command to be used by an administrator at a user who has broken the rules or has been naughty enough to be banned. When I ran the following code:
const Discord = require("discord.js");
const config = require("./config.json");
const { MessageAttachment, MessageEmbed } = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS","GUILD_MEMBERS", "GUILD_MESSAGES", "DIRECT_MESSAGES", "DIRECT_MESSAGE_REACTIONS", "DIRECT_MESSAGE_TYPING"], partials: ['CHANNEL',] })
const RichEmbed = require("discord.js");
const prefix = "!";
client.on("messageCreate", function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (command === "news") {
if (message.channel.type == "DM") {
message.author.send(" ");
}
}
if (command === "help") {
message.author.send("The help desk is avaliable at this website: https://example.com/");
}
});
client.on("messageCreate", function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (command === "ping") {
const timeTaken = Date.now() - message.createdTimestamp;
message.channel.send(`Pong! ${timeTaken}ms.`);
}
if (command === "delete all messages") {
const timeTaken = Date.now() - message.createdTimestamp;
const code = Math.random(1,1000)
message.channel.send(`Executing command. Verification Required.`);
message.author.send(`Your code is the number ${code}.`)
message.channel.send(`Please confirm your code. The code has been sent to your dms. Confirm it in here.`)
}
if (command === "ban") {
const user = message.mentions.users.first().id
message.guild.members.ban(user).then(user => {
message.channel.send(`Banned ${user.id}`);
}).catch(console.error);
}
});
client.login(config.BOT_TOKEN)
I ran into the following error whilst trying to test the command on a dummy acc.
DiscordAPIError: Missing Permissions
at RequestHandler.execute (/home/runner/gwehuirw/node_modules/discord.js/src/rest/RequestHandler.js:350:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (/home/runner/gwehuirw/node_modules/discord.js/src/rest/RequestHandler.js:51:14) {
method: 'put',
path: '/guilds/891083670314680370/bans/943680142004322326',
code: 50013,
httpStatus: 403,
requestData: { json: { delete_message_days: 0 }, files: [] }
Could someone please help me with this? Thanks.
PS: I already had the necessary permissions for the bot to ban users. I also added the necessary intents for it to work. But I still am stuck.
Try removing the .id when you are trying to get the user. Getting the id would be making you ban the string that is the id, not the user.
I realized that the user who was trying to ban a user needed to have certain permissions. I have finished working on the command. Thanks to everyone who had helped me through this mess!
I'm coding a moderation bot in Discord.js v13, and for the mute, kick, warn and ban commands I need to check user permissions. However, my code fails to compile: "Cannot find name 'member'". I've checked the documentation and I've used the exact same method shown.
Here is my code, the error is in line 67. I've written this in TypeScript, however this should not have any effect on the error.
import { User, Permissions } from "discord.js";
import { SlashCommandBuilder } from "#discordjs/builders";
import mongoose from "mongoose";
import punishmentSchema from "./schemas/punishment-schema";
const config = require("./config.json");
const client = new Discord.Client({
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES,
Discord.Intents.FLAGS.GUILD_MEMBERS
]
});
client.on("ready", async () => {
console.log("Ready for your orders, boss!");
await mongoose.connect(`${config.mongodb_uri}`, {
keepAlive: true,
});
const guildId = "868810640913989653";
const guild = client.guilds.cache.get(guildId);
let commands;
if(guild) {
commands = guild.commands;
} else {
commands = client.application?.commands;
}
commands?.create({
name: "ping",
description: "Shows the bot's latency.",
});
commands?.create({
name: "help",
description: "Lists all commands and shows their usage.",
});
commands?.create({
name: "mute",
description: "Allows moderators to mute users.",
});
commands?.create({
name: "ban",
description: "Allows moderators to ban users.",
});
});
client.on("interactionCreate", async (interaction) => {
if(!interaction.isCommand()) return;
const { commandName, options } = interaction;
if(commandName === "ping") {
interaction.reply({
content: `Current latency: \`\`${client.ws.ping}ms\`\``,
ephemeral: false,
})
} else if(commandName === "help") {
interaction.reply({
content: `**__List of available commands:__**\n\n**/ping** Shows the bot's latency.\n**/help** Guess what this one does :thinking:\n**/cases** Allows non-moderators to check their punishment history.\n\n**/warn {user} [reason]** Applies a warning to a user. :shield:\n**/kick {user} [reason]** Kicks a user from the server. :shield:\n**/mute {user} [duration] [reason]** Kicks a user from the server. :shield:\n**/mute {user} [duration] [reason]** Mutes a user. :shield:\n**/ban {user} [duration] [reason]** Bans a user from the server. :shield:\n**/history {user}** Shows the punishment history of a user. :shield:`,
ephemeral: false,
})
} else if(commandName === "mute") {
if (member.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) {
console.log('test if kick');
}
} else if(commandName === "mute") {
}
});
client.login(config.token);```
According to docs, interaction object, should have member property. Try to get it with interaction.member or const { commandName, options, member } = interaction;
I've created a simple slash command. It works on the only guild. before that, I was using v12. Now I wanna switch to v13.
Now how can I make these global slash commands?
Code
client.on ("ready", () => {
console.log(`${client.user.tag} Has logged in`)
client.user.setActivity(`/help | ${client.user.username}`, { type: "PLAYING" })
const guildId = "914573324485541928"
const guild = client.guilds.cache.get(guildId)
let commands
if (guild) {
commands = guild.commands
} else {
commands = client.application.commands
}
commands.create({
name: 'ping',
description: 'Replies with pong'
})
commands.create({
name: 'truth',
description: 'Replies with truth'
})
});
client.on('interactionCreate', async (interaction) => {
if(!interaction.isCommand()){
return
}
const { commandName, options } = interaction
if (commandName === 'ping'){
interaction.reply({
content: 'pong'
})
}
```
I'm new in v13 so please explain it simply :|
Simply change the guild declaration. Your code checks if guild is truthy, and uses the guild if it is. Otherwise, it will use global commands
const guild = null
// any falsy value is fine (undefined, false, 0, '', etc.)
I have been following a few different guides to program a simple discord bot. Everything works except I cannot get it to send an image. I have looked at these previous questions 1 2, but their solutions are not working for me. This is my code:
const {Client, Intents} = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const prefix = '?';
client.once('ready', () => {
console.log("Dog is online!");
});
client.on('messageCreate', message => {
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if(command === 'ping') {
message.channel.send('pong!');
}
else if (command === 'bark') {
message.channel.send('bark bark bark grrrr...')
}
else if(command === 'nick') {
message.channel.send('grrr...');
}
else if (command === 'pic') {
message.channel.send("little dog", {files: ["https://i.imgur.com/xxXXXxx.jpeg"] });
}
});
//must be last line
client.login('');
my client login is there in my editor, just not sharing it here. the "pic" command is what is not working. It displays the "little dog" text, but does not send the image. The only reason I'm using imgur is because I'm not sure if you can send local images; if someone knows a solution using local files I'll take it.
You can use
files: [{ attachment: "YourImage.jpg" }] });
You can also rename the image with
files: [{ attachment: <images>.toBuffer(), name: 'newName.png' }] });
Example:
message.channel.send({ files: [{ attachment: 'YourImage.png' }] });
the <images> is your image variable
const images = blablabla
According to the V13 discord.js
You can do following, this is also working for me.
const { MessageAttachment } = require('discord.js')
const attachment = new MessageAttachment('URL'); //ex. https://i.imgur.com/random.jpg
message.channel.send({ content: "I sent you a photo!", files: [attachment] })
This example will send a photo with the text I sent you a photo!