#Strange Component Interaction Error

1 messages · Page 1 of 1 (latest)

twin forum
#

I have a button command, that sometimes works, and sometimes gives me an "Invalid context type. Expected SocketInteractionContext'1, got SocketInteractionContext" exception. I'm not even really sure what code I can provide here to help with this, but I'll provide what makes sense to. It seems to error out most of the time but every once and a while it works (very rarely).

The command sending the button:

[Group("voicemaster", "Commands for managing automatically created voice channels.")]
public class VoiceMasterModule : InteractionModuleBase<SocketInteractionContext>
{
    [SlashCommand("settings", "View (and change) the settings for voice master.")]
    [RequireUserPermission(GuildPermission.Administrator, Group = "Permission")]
    [RequireOwner(Group = "Permission")]
    public async Task SettingsAsync()
    {
        var settingsEmbed = new EmbedBuilder()
            .WithTitle("Voice Master Settings")
            .WithColor(Color.Blue)
            .WithDescription("Please select one of the options below.")
            .AddField("1️⃣", "Set the voice master channel.", true)
            .AddField("❌", "Remove voice master functionality from a channel.", true)
            .AddField("✏️", "Modify the name template of temporary voice channels.", true)
            .Build();

        var settingsComponents = new ComponentBuilder()
            .WithButton("1️⃣", "voicemaster.setchannel", ButtonStyle.Primary)
            .WithButton("✖️", "voicemaster.removechannel", ButtonStyle.Danger)
            .WithButton("✏️", "voicemaster.setname", ButtonStyle.Secondary)
            .Build();

        // Send the embed with its components.
        await RespondAsync(embed: settingsEmbed, components: settingsComponents, ephemeral: true);
    }
}

The ComponentCommand for "voicemaster.setchannel" (I have not implemented the others):

public class VoiceMasterComponentModule : InteractionModuleBase<SocketInteractionContext<SocketMessageComponent>>
{
    [ComponentInteraction("voicemaster.setchannel")]
    public async Task SetChannelAsync()
    {
        var setChannelEmbed = new EmbedBuilder()
            .WithColor(Color.Blue)
            .WithDescription("Please select the voice master channel below.")
            .Build();

        // Get a list of all of the Context.Guild's voice channels.
        var voiceChannels = Context.Guild.Channels.Where(c => c.ChannelType == ChannelType.Voice);

        var options = voiceChannels.Select(vc => new SelectMenuOptionBuilder
        {
            Label = vc.Name,
            Value = vc.Id.ToString()
        }).ToList();

        var setChannelComponents = new ComponentBuilder()
            .WithSelectMenu("voicemaster.setchannel.select", options)
            .Build();

        await RespondAsync(embed: setChannelEmbed, components: setChannelComponents, ephemeral: true);
    }
}

DiscordSocketClient.ButtonExecuted event handler:

private async Task ButtonExecuted(SocketMessageComponent component)
{
    try
    {
        var context = new SocketInteractionContext<SocketMessageComponent>(Client, component);
        await InteractionService.ExecuteCommandAsync(context, ServiceProvider);
    }
    catch (Exception e)
    {
        Log.Error("An error occurred while executing a command.", e);
    }
}

Thanks in advance for any help!

rocky token
#

you have other buttons that work right?

twin forum
#

Honestly I was confused for a while, then I got upset and spammed the button and it worked when I did that, but now I'm 10x more confused about all this...

rocky token
#

yeah...

twin forum
#

I've never been so lost 😭

rocky token
#

is the exception from using the select menu, or from the slash command which shares the select menu?

twin forum
rocky token
#

ohhhh ok

twin forum
#

any ideas lol

#

I'm on the edge of my seat with this one lol

rocky token
#

so this code:

public class VoiceMasterComponentModule : InteractionModuleBase<SocketInteractionContext<SocketMessageComponent>>
{
    [ComponentInteraction("voicemaster.setchannel")]
    public async Task SetChannelAsync()
    {
        var setChannelEmbed = new EmbedBuilder()
            .WithColor(Color.Blue)
            .WithDescription("Please select the voice master channel below.")
            .Build();

        // Get a list of all of the Context.Guild's voice channels.
        var voiceChannels = Context.Guild.Channels.Where(c => c.ChannelType == ChannelType.Voice);

        var options = voiceChannels.Select(vc => new SelectMenuOptionBuilder
        {
            Label = vc.Name,
            Value = vc.Id.ToString()
        }).ToList();

        var setChannelComponents = new ComponentBuilder()
            .WithSelectMenu("voicemaster.setchannel.select", options)
            .Build();

        await RespondAsync(embed: setChannelEmbed, components: setChannelComponents, ephemeral: true);
    }
}
#

is the button handler

twin forum
#

yes

rocky token
#

when you try just repsonding with some test response does it work?

#

like if you commented out all the code, and then tried RespondAsync("test")

twin forum
#

I'm gonna go with "sometimes" on this one again lol

rocky token
#

hmmm

#

ok

#

it seems like you are partially using the interaction framework if that mnakes sense

#

if you use the interaction framework, you only have to listen to interactions and not each and every type of interaction

#
    private static async Task InteractionCreated(SocketInteraction interaction)
    {
        try
        {
            SocketInteractionContext ctx = new(Client, interaction);
            await Service.ExecuteCommandAsync(ctx, null);
        }
        catch
        {
            if (interaction.Type == InteractionType.ApplicationCommand)
            {
                await interaction.GetOriginalResponseAsync().ContinueWith(async (msg) => await msg.Result.DeleteAsync());
            }
        }
    }
#

Client.InteractionCreated += InteractionCreated; in your Ready handler

#

also

#

this could just be my lack of understanding, but:
: InteractionModuleBase<SocketInteractionContext> I inherit from this

twin forum
#

The buttons weren't working at all without DiscordSocketClient.ButtonExecuted, I only did that because of this snippet I found here:

discordClient.ButtonExecuted += async (interaction) => 
{
    var ctx = new SocketInteractionContext<SocketMessageComponent>(discordClient, interaction);
    await _interactionService.ExecuteCommandAsync(ctx, serviceProvider);
};

public class MessageComponentModule : InteractionModuleBase<SocketInteractionContext<SocketMessageComponent>>
{
    [ComponentInteraction("custom_id")]
    public async Task Command()
    {
        await Context.Interaction.UpdateAsync(...);
    }
}
rocky token
#

I am looking at what you sent btw

#

but just know I dont use it at all

twin forum
rocky token
#

no

#

but also

#

I still edit messages

#

without doing what you did

#

you can use

SocketMessageComponent component = (SocketMessageComponent)Context.Interaction;
component.Message.ModifyAsync(text: "test");
#

(in the button handler)

#

that is what I currently do

#

so.... does it work now?

twin forum
rocky token
#

yaaay