"DiscordAPIError[40060]: Interaction has already been acknowledged." Throws this when ever i run a command on discord [duplicate] - javascript

I am creating a bot using guide by Discord.js, however after like 3 or sometimes 3 commands the bot stops working and i get
discord message
i have tried to restart it many times but after sometime it just stop working again and again
const fs = require('node:fs');
const path = require('node:path')
const { Client, Events, GatewayIntentBits, Collection ,ActionRowBuilder,EmbedBuilder, StringSelectMenuBuilder } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.commands = new Collection();
const commandsPath = path.join(__dirname,'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);
if('data' in command && 'execute' in command){
client.commands.set(command.data.name,command);
}else{
console.log(`[WARNING] The command at ${filePath} is missing`);
}
}
client.once(Events.ClientReady, () => {
console.log('Ready!');
})
//menu
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
const row = new ActionRowBuilder()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId('select')
.setPlaceholder('Nothing selected')
);
const embed = new EmbedBuilder()
.setColor(0x0099FF)
.setTitle('pong')
.setDescription('Some description here')
.setImage('https://media.istockphoto.com/id/1310339617/vector/ping-pong-balls-isolated-vector-illustration.jpg?s=612x612&w=0&k=20&c=sHlz5sbJrymDo7vfTQIuaj4lbmwlvAhVE7Uk_631ZA8=')
await interaction.reply({ content: 'Pong!', ephemeral: true, embeds: [embed]});
}
});
//======================================================================================================================
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand ||
interaction.isButton() ||
interaction.isModalSubmit()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found`)
return;
}
try {
await command.execute(interaction);
}catch(error){
console.error(error);
await interaction.reply({content: 'There was an error while executing this command!', ephemeral: true});
}
console.log(interaction);
});
client.login(token);
Error i get in terminal
I wanted this bot to continue to execute commands as long as it's up and running

This is a common error in Discord.JS that occurs when you already replied to an interaction and you attempt to reply again.
From the discord.js discord server:
You have already replied to the interaction.
• Use .followUp() to send a new message
• If you deferred reply it's better to use .editReply()
• Responding to slash commands / buttons / select menus
To fix this error, you can use .followUp() to send another message to the channel or .editReply() to edit the reply as shown above.
You can see the documentation on a command interaction here

Yes the problem is that you cant reply to a slash command more then once in discords api so instead you should use
interaction.channel.send()
or
interaction.editReply()

Related

Edit Snipe command sending more than one embed instead of just one

const editedMessages = new Discord.Collection();
client.on("messageUpdate", (oldMessage, newMessage) => {
if(oldMessage.content === newMessage.content)return
client.on('message', message => {
if (message.author.bot) return;
const args = message.content.trim().split(/\s+/g);
const command = args.shift().toLowerCase();
switch (command) {
case 'y!edit':
const msg = editedMessages.get(message.channel.id);
if (!message) return message.reply('There is nothing to snipe');
const edembed = new Discord.MessageEmbed()
.setColor('#deffff')
.setAuthor(newMessage.author.tag, newMessage.author.avatarURL({ dynamic: true }))
.setDescription(`**Old message:** ${oldMessage.content} \n **New message:** ${newMessage.content}`)
.setFooter(`ID: ${newMessage.author.id}`).setTimestamp()
message.channel.send({ embeds: [edembed] }).catch(err => console.error(err));
break;
}
});
});
client.on('messageUpdate', message => {
editedMessages.set(message.channel.id, message);
});
I want it to send only one embed when the command is used repeatedly. As you can see in the screenshot provided, every time the command was used it sent the previous embeds too. I've been stuck on this command line for ages.
It appears as if you are forgetting to close your preexisting bot connections.

How to store the ID of the user who sent a slash command and compare with user who interacted with a button in Discord.js

I'm using the following code to create a quick database to store the ID of the user who called a bot via a slash command. I then want to compare this ID with the ID of the person interacting with the bot. My aim is to prevent anyone but the user that called the bot being able to interact with it.
The following code works but it's temperamental in that it fails without a clear reason on occasion (i.e. it returns the error which states that the person interacting isn't the person who sent the slash command even if they are).
I'm new to discord.js and quick.db tables so I'm hoping someone more competent than me has a better way of achieving this.
const { Client, Intents, MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'),
client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES ] });
client.db = require("quick.db");
var quiz = require("./quiz.json");
client.login(config.token);
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
if ([null, undefined].includes(client.db.get(`quiz`))) client.db.set(`quiz`, {});
if ([null, undefined].includes(client.db.get(`quiz.spawns`))) client.db.set(`quiz.spawns`, {});
});
client.on('messageCreate', async (message) => {
if (!message.content.startsWith(config.prefix)) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift();
if (command == "unlock") {
message.delete();
const m = await message.channel.send(getMMenuPage());
client.db.set(`quiz.spawns.m${m.id}`, message.author.id);
}
});
client.on('interactionCreate', async (interaction) => {
if (interaction.isButton()) {
if (client.db.get(`quiz.spawns.m${interaction.message.id}`) != interaction.user.id) return interaction.reply(getMessagePermissionError(client.db.get(`quiz.spawns.m${interaction.message.id}`)));
const q = quiz;
Please let me know if you need more information.
Thanks.
Instead of using:
const db = require("quick.db");
You should be using:
const { QuickDB } = require("quick.db");
const db = new QuickDB();
Other than that I haven't see any problems.

DiscordJs registered command dont show up

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.

Only reply in dms discord.js

So I was working on this project where people will DM the BOT and run command and it replies test. But it doesn't reply.
client.on("messageCreate", async message => {
if (message.content.startsWith(prefix)) {
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (message.channel.type === 'dm') {
message.reply("test");
}
}
});
That's because you didn't enable the intents for getting a dm message,
try putting those two on your client declarations :
const client = new Discord.Client({
intents : ['DIRECT_MESSAGES','GUILD_MESSAGES'],
partials: ["CHANNEL","MESSAGE"]
})
here is a way:
1.Create a file named ** 'privateMessage.js'** and in the main file add:
const privateMessage = require('./privateMessage')
client.on('ready' ,() =>{
console.log('I am online')
client.user.setActivity('YouTube Music 🎧', {type:'PLAYING'})
privateMessage(client, 'ping', 'pong')
})
and in the file we just created privateMessage.js add:
module.exports=(client, triggerText, replyText)=>{
client.on('message', message =>{
if(message.content.toLowerCase()===triggerText.toLowerCase()){
message.author.send(replyText)
}
})
}

Discord.js | Making a message sniper command

I'm trying to make a bot log/snipe a message, when someone says 'zsnipe', I want to know how would i make 'zsnipe' a command but its not working, am I doing something wrong? here's the code:
bot.on('messageDelete', message => {
const embed8 = new Discord.MessageEmbed()
.setAuthor(`${message.author.username}#${message.author.discriminator}`, message.author.avatarURL({dynamic : true}))
.setDescription(message.content)
if (message.content === 'zsnipe'){
message.channel.send(embed8)
}
})
Your Help Will be Appreciated!
Here is some code that saves the last deleted message in a channel and allows it to be retrieved when someone says zsnipe.
Warning: the deleted messages will be lost if the bot restarts.
const deletedMessages = new Discord.Collection();
bot.on('message', async message => {
if (message.author.bot) return;
const args = message.content.trim().split(/\s+/g);
const command = args.shift().toLowerCase();
switch (command) {
case 'zsnipe':
const msg = deletedMessages.get(message.channel.id);
if (!msg) return message.reply('could not find any deleted messages in this channel.');
const embed = new Discord.MessageEmbed()
.setAuthor(msg.author.tag, msg.author.avatarURL({ dynamic: true }))
.setDescription(msg.content);
message.channel.send(embed).catch(err => console.error(err));
break;
});
bot.on('messageDelete', message => {
deletedMessages.set(message.channel.id, message);
});

Categories