Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ephemeral flag not applied on followUp and other edge cases #5702

Closed
DarkMio opened this issue May 29, 2021 · 2 comments
Closed

Ephemeral flag not applied on followUp and other edge cases #5702

DarkMio opened this issue May 29, 2021 · 2 comments

Comments

@DarkMio
Copy link

DarkMio commented May 29, 2021

Please describe the problem you are having in as much detail as possible:

Ephemeral interactions and followUp seem to be incorrect or a limitation by the discord API.

This is in regards of #5618

Include a reproducible code sample here, if possible:

const doesNotGoEphemeral = async (interaction: CommandInteraction) => {
  interaction.reply('This is not ephemeral', {ephemeral: false});
  await new Promise(resolve => setTimeout(resolve, 500));
  interaction.followUp('This works as ephemeral', {ephemeral: true});
  await new Promise(resolve => setTimeout(resolve, 500));
  interaction.deleteReply();
};

On this case, the bot will reply, the followup will posted separately and the original reply will be deleted:

Exhibit A

With the log looking later like that:

Exhibit B

This is expected behaviour, however, when deferring a reply (in this case the bot is doing some request-work that takes some time, then the defer-flag seems to break:

const doesNotGoPublic = async (interaction: CommandInteraction) => {
  interaction.defer({ephemeral: false});
  await new Promise(resolve => setTimeout(resolve, 500));
  interaction.followUp('This should not be ephemeral', {ephemeral: false});
};

Uh oh, we acknowledged in private that the bot is doing something but then can't break out of this state anymore. An additional reply will be met with Error [INTERACTION_ALREADY_REPLIED]

Exhibit C

In general it seems to be by design that you cannot do a reply after a defer. But additionally it seems to be that the initial defer sets and fixates the ephemeral flag.

There is however this curious interaction:

const doubleFollowUp = async (interaction: CommandInteraction) => {
    interaction.defer({ephemeral: true});
    await new Promise(resolve => setTimeout(resolve, 500));
    interaction.followUp('This should not be ephemeral', {ephemeral: false});
    interaction.followUp("This is a followup that's not ephemeral", {
      ephemeral: false,
    });
    await new Promise(resolve => setTimeout(resolve, 500));
    interaction.deleteReply();
  };

While this delete causes an error (DiscordAPIError: Unknown Message), it first sends the acknowledgement, does a followUp with ephemeral and then follows up with a publicly visible message in reference to the initial followUp

Exhibit D

Oddly enought, this is what a followup to an ephemeral message looks like:

Exhibit E

In an optimal case it should be possible to do a defer on time hidden and do a followUp/reply to the interaction in public and vice versa. This would allow to show the context that this message was generated from the slash command. However, I'm not sure if this is a limitation of the DiscordAPI. Additional followUp and reply. Additionally it might be useful to return the message object from reply as well as followUp to be able to delete it separately.

Further details:

  • discord.js version: e300518597955abf4bf3c3d2634b47b9b3964274
  • Node.js version: v14.15.3, v14.17.0
  • Operating system: Windows, Ubuntu
  • Priority this issue should have – please be realistic and elaborate if possible: low.

Relevant client options:

  • partials: none
  • gateway intents: GUILDS, GUILD_MESSAGES, GUILD_WEBHOOKS
  • other: none
  • I have also tested the issue on latest master, commit hash: e300518597955abf4bf3c3d2634b47b9b3964274
@monbrey
Copy link
Member

monbrey commented May 29, 2021

In an optimal case it should be possible to do a defer on time hidden and do a followUp/reply to the interaction in public and vice versa. This would allow to show the context that this message was generated from the slash command. However, I'm not sure if this is a limitation of the DiscordAPI.

It is an API limitation unfortunately. The first response to a Slash Command must be either defer() or reply(), and once you've sent that initial response all further messages must be via the webhook - either using editReply() or followUp().
If your initial response was defer(), sending a follow-up to Discord is processed in the same way as editReply() would be - replacing the deferred message with the new content. Because it's not possible to edit the ephemeral state of a message, the first follow-up to a deferred reply will keep the initial ephemeral state.

Additional followUp and reply. Additionally it might be useful to return the message object from reply as well as followUp to be able to delete it separately.

This again is a limitation of the API - it doesn't return anything from the /callback endpoint that defer/reply use. This is why the methods fetchReply() and deleteReply() need to exist. This is further limited by the fact that you can't fetch or delete an ephemeral message at all - they don't really exist server-side at all.

@DarkMio
Copy link
Author

DarkMio commented May 29, 2021

Thank you for explaining, I already guessed as much. Then at least this issue can be closed for now and is on record for future reference.

@DarkMio DarkMio closed this as completed May 29, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants