Interaction.reply stopped working properly

I’m making a discord bot using discords javascript api and everything was working fine up until I got to 5 commands. I keep getting this same error messages and I’m not sure what’s causing them. What’s weird is that occasionally it works but when i restart the bot it stops working. I need some help finding and fixing this issue.

const { Client, GatewayIntentBits, EmbedBuilder, MessageAttachment, SlashCommandBuilder, PermissionsBitsField, Permissions, AttachmentBuilder } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });

const server = require('./server.js')
const randomCat = require('random-cat-img');
const redditParse = require("redditparse");
const fs = require('fs');

const token = process.env['token']

client.on("ready", () => {
  console.log(client.user.tag + " online")
  client.user.setActivity('cooking meth')

  const ping = new SlashCommandBuilder()
    .setName('ping')
    .setDescription('This is a ping command')
  const kitten = new SlashCommandBuilder()
    .setName('kitten')
    .setDescription('Gives a random image of a cat')
  const pokemon = new SlashCommandBuilder()
    .setName('pokemon')
    .setDescription('Syntax: /pokemon *number here*')
    .addIntegerOption(option =>
      option
        .setName('number')
        .setDescription('Pokemon number')
        .setRequired(true))
  const meme = new SlashCommandBuilder()
    .setName('meme')
    .setDescription('Random memed from r/funny')
  const help = new SlashCommandBuilder()
    .setName('help')
    .setDescription('List every command')
  const bugreport = new SlashCommandBuilder()
    .setName('bugreport')
    .setDescription('Report a bug')
    .addStringOption(option =>
      option
        .setName('content')
        .setDescription('Bug')
        .setRequired(true))

  client.application.commands.create(ping)
  client.application.commands.create(kitten)
  client.application.commands.create(pokemon)
  client.application.commands.create(meme)
  client.application.commands.create(help)
  client.application.commands.create(bugreport)
})

client.on('interactionCreate', (interaction) => {
  if (!interaction.isChatInputCommand()) return;
  if (interaction.commandName === 'ping') {
    interaction.reply('pong')
  }
  if (interaction.commandName === 'pokemon') {
    const number = interaction.options.getInteger('number')

    if (number > 721 || number < 1) {
      interaction.reply("This pokemon doesn't exist or is from generation 7 onwards")

      return
    } else {
      interaction.reply({ files: ['pokemon_jpg/' + number + '.jpg'] });
    }

  }
  if (interaction.commandName === 'kitten') {
    getKittenImage();

    async function getKittenImage() {
      let resultObject;
      do {
        const result = await redditParse.randomPost("cats");
        resultObject = JSON.parse(result);
      } while (resultObject.type != "image")
      console.log(resultObject)
      const kittenEmbed = new EmbedBuilder()
        .setTitle(resultObject.title)
        .setImage(resultObject.image)
        .setColor(0x93C54B)

      interaction.reply({
        embeds: [kittenEmbed]
      })
    };
  }
  if (interaction.commandName === 'meme') {
    getMemeImage();

    async function getMemeImage() {
      let resultObject;
      do {
        const result = await redditParse.randomPost("funny");
        resultObject = JSON.parse(result);
      } while (resultObject.type != "image")
      console.log(resultObject)
      const memeEmbed = new EmbedBuilder()
        .setTitle(resultObject.title)
        .setImage(resultObject.image)
        .setColor(0x93C54B)

      interaction.reply({
        embeds: [memeEmbed]
      })
    };
  }
  if (interaction.commandName === 'help') {
    const helpEmbed = new EmbedBuilder()
      .setTitle("**Commands**")
      .setDescription("`/ping` - Testing purposes\n`/kitten` - Sends a random reddit picture of a cat\n`/pokemon` - Sends a picture of the pokemon associated with the given number\n`/meme` - Sends a random meme from reddit\n\nHeisenburger v1.0")
      .setColor(0x93C54B);

    interaction.reply({
      embeds: [helpEmbed]
    })
  }
  if (interaction.commandName === 'bugreport') {
    const content = interaction.options.getString('content')
    fs.writeFile('bugs.txt', content, err => {
      if (err) {
        console.error(err);
      }
    })
  }
});

client.login(token)

Hello @Kermitdotexe !

Can you show us the error message you are getting? (What appears in the console)

3 Likes


Are you sure this is the full error? Usually there is something more in the last line

2 Likes

image
image
I’m sorry I didn’t think it was very important

Unknown Interaction typically means that you’re trying to respond to an interaction that Discord doesn’t think exists, like, you’re trying to respond to the same interaction more than once. It can be caused if your bot doens’t have permissions to reply too.

Another thing is that I think Discord only wait for 3 seconds (I’m not sure) for the bot to know that received the interaction, so you either check response time or change the interaction defer.

For example, when you fetch data from an external API, the delay could be causing Discord to consider the interaction as “timed out”.

2 Likes

So basically I have to make the bot tell discord that it will reply and then the bot can take longer than 3 seconds to reply?

Yep. You could initially reply with a loading message, then edit the reply when the actual data is ready.

Well the problem is that even with the /ping command it doesn’t load fast enough so I don’t think that would fix this.

Can you share your repl? I’ll try to fork the project and see if there’s anything more going on

https://replit.com/@Kermitdotexe/Heisenburger

I tinkered the code a little, you can check it here:
https://replit.com/@WindLother/Heisenburger-test#index.js

You can copy the full code and paste in your repl.

What did I changed:

  • Added async keyword to allow await inside
  • Added deferral to provide time for image fetching
  • Edited reply with the fetched image

I also moved getKittenImage and getMemeImage functions outside of interactionCreate event, it’s a good thing to make these functions being separate which allows them being more reusable.

With this the bot should behave more reliably.

I’d suggest add error handling if the code above does not solve the problem (which makes my entire assumption wrong but you can still use the code).

3 Likes

This didn’t seem to fix the issue, so I don’t think that was the problem. I’m really clueless as to how i can fix this.

It’s now giving this error message along with the original one
image

Yeah, you need to add error handling to find out the issue.

I’ve added error handling to the code, can you copy the code again and tell me the error’s that are showing?

(Remember that this is not to correct the issue, just to know what is causing it).


It’s giving this same error as before for every command.

Now we know that the error ocurred in interactionCreate, which is great!

I’ll be responding to you via private message to avoid getting this topic any bigger. (If the issue is solved i’ll post the solution here)

1 Like

Working now!

Thanks to error handling, we discovered that the code was failing when an error was thrown after deferReply , but before editReply was called. This is because followUp was being used in the catch block, which requires either reply or deferReply to have been called previously.
We got to fix by adding a conditional statement in the catch block to use followUp if the interaction has been replied to or deferred, and reply otherwise.

1 Like