I'm using TypeScript to write my Discord bot, and its main purpose is sending cute axolotl pictures.
It uses a REST API to do this, but it's on free hosting so it can be quite slow sometimes, especially when it hasn't been used in a while. So to prevent the same issue Nextcord (discord.py fork) - How can I return to Discord that a command is currently running? had, I'm deferring the reply. However, this only seems to work sometimes, other times it crashes the code because it's trying to edit a non-deferred reply?
Relevant part of ImageCommand.ts:
export default (client: Client, commandsArray: Array<CommandInterface>) => {
commandsArray.push({
name: "image",
description: "Sends you a cute axolotl picture from Reddit.",
executor: async (interaction: ChatInputCommandInteraction, client: Client) => {
interaction.deferReply();
const channel: TextChannel = interaction.channel as TextChannel;
let payload = "?minImages=1&flair=Just Showing Off 😍";
if (channel.nsfw) payload += "&nsfw=1"; // If for some reason a cute axolotl picture is marked as NSFW, only show it when sent from a NSFW channel
const post = (await Axios.get("https://axolotlapi.kirondevcoder.repl.co/reddit" + payload)).data.data[0];
const images: Array<ImageInterface> = post.media.filter((m: any) => m.kind === "image");
const image: string = images[Math.floor(Math.random() * images.length)].url;
const embed = new EmbedBuilder()
.setTitle(post.title)
.setAuthor({ name: `u/${post.author}`, url: `https://reddit.com/u/${post.author}` })
.setURL(post.link)
.setTimestamp(post.created_utc * 1000)
.setImage(image)
;
interaction.editReply({ embeds: [ embed ]});
}
});
}
I tried deferring the reply like in Nextcord (discord.py fork) - How can I return to Discord that a command is currently running?, but that only works sometimes. When it does not work, it just crashes the code.
<ChatInputCommandInteraction>#deferReply
returns a promise which you are not awaiting.
Change
interaction.deferReply();
to
await interaction.deferReply();
It is also worth noting the type for the interaction should be ChatInputCommandInteraction<"cached">
not just ChatInputCommandInteraction
since the interaction is already cached. (source)