#DiscordSocketClient.SelectMenuExecuted is getting invoked twice?

1 messages · Page 1 of 1 (latest)

little totem
#

I have a slash command that returns a select menu containing available commands that the user can run. However, upon select menu execution, I was getting a The server responded with error 40060: Interaction has already been acknowledged. exception. After debugging, I believe this to be a symptom of a second attempt of UpdateAsync due to the HandleHelpMenu getting invoked twice. I tried to ensure only one event was being fired by stripping it prior as a stopgap, but it is still executing twice.

Thoughts ?

P.S. This could just be 5am brain being stupid, so hoping for a second pair of eyes.

public class SlashHelp : InteractionModuleBase<SocketInteractionContext> {

    private readonly DiscordSocketClient _client;
    private readonly InteractionService _commands;
    private readonly IServiceProvider _services;

    public SlashHelp(IServiceProvider services) {
        _commands = services.GetRequiredService<InteractionService>();
        _client = services.GetRequiredService<DiscordSocketClient>();
        _services = services;

        // Bind menu event
        _client.SelectMenuExecuted -= HandleHelpMenu; // This was to try debugging to ensure only one event was binded.
        _client.SelectMenuExecuted += HandleHelpMenu;
    }

    [SlashCommand("help", "Get help with the bot or a command.")]
    public async Task Help(
        [Summary(description: "What do you need help with?")][Choice("Bot", "bot"), Choice("Command", "command")] string with = "bot"
        ) {

        if(with == "command") {
            // Build select menu for all available Slash Commands
            var slashcmds = _commands.SlashCommands.ToList();

            SelectMenuBuilder menu = new SelectMenuBuilder()
                    .WithCustomId("helpMenu")
                    .WithPlaceholder("Select Command...")
                    .WithMinValues(1).WithMaxValues(1);

            foreach(var scmd in slashcmds) {
                if((await scmd.CheckPreconditionsAsync(Context, _services)).IsSuccess) {
                    menu.AddOption(scmd.Name, scmd.Name, scmd.Description);
                }
            }

            // Send response.
            await this.RespondAsync("Select the command you would like help with:", ephemeral: true, components: new ComponentBuilder().WithSelectMenu(menu).Build());
        } else {
            // TODO: Implement /help with:bot
            await this.RespondAsync("You need help with the bot.", ephemeral: true);
        }
    }

    private async Task HandleHelpMenu(SocketMessageComponent menu) {
        Console.WriteLine("HandleHelpMenu");
        if (menu.Data.CustomId != "helpMenu") return;
        await menu.UpdateAsync(m => { m.Content = $"You are requesting help for the command: **{menu.Data.Values.First()}**."; m.Components = null; });
    }

}
atomic crescent
#

You are doing couple of things wrong here

little totem
#

Always open to learn, only started on my bot conversion to interactions the other day AYAYA

atomic crescent
#

module classes are only ment to hold code for handling interactions
modules are initialised for every interaction => which leads to your issue - every time the slash command gets executed the SlashHelp constructor will be called => it will subscribe to the event

#

So ye, you'd probably need to move event subscription code in another place... but you don't need to handle the event manually at all

little totem
#

Yep, that was my thought at first too, hence the -= there, but even still I tested it before and multiple slash executions did not increase the events fired (I'd expect it to go to 2, then 3, then 4 if that was the case of resubbing to the event: it stays at 2).

atomic crescent
#

Since you are already using IF you can also handle component interactions with it too

atomic crescent
little totem
#

Yeah, I'm running it locally through Visual Studio's debugger

#

It's also 5am, so let me remove the unsub and double check my observation for sanity

#

Yeah, always twice even after repeated /help's

little totem
#

~~still want to understand why this stuff being called twice though KEKW ~~

atomic crescent
#

huh
not sure about the event issue tbh...

but just for now
Comment this event related code & add this to the module

[ComponentInteraction ("helpMenu")]
public async Task HelpMenu(string[] selections)
{
   await (Context.Interaction as IComponentInteraction).UpdateAsync(m => { changesss });
}
#

&see if the error still occurs

little totem
#

Nope, that fixed it sir. Much easier than what I was doing. y_yay

#

Gunna sleep and take another look at why this is calling twice though. I hate unsolved puzzles feelslife9man

atomic crescent
#

Same w_garold
Good night morning

little totem
#

yeaaa work in 3 hours