Introduction
Adding component interactions with the .NET Generic Host is very easy. Use AddComponentInteractions<TInteraction, TContext>(IServiceCollection) to add a component interaction service to your host builder. Then, use AddComponentInteraction to add a component interaction using the minimal APIs way and/or use AddModules(IHost, Assembly) to add component interaction modules from an assembly. You also need to use UseGatewayEventHandlers(IHost) to bind the service event handlers.
Unlike application commands, component interactions require maintaining context for each interaction, as the data between component interaction types can vary significantly. While it's possible to use a single context for all component interactions and cast them as needed, it's generally recommended to use distinct contexts for different types of component interactions. This is why multiple services are added to the service collection here - each one handles a specific type of component interaction. However, you likely won't need all of them, so feel free to remove the ones that aren't relevant to your use case.
using Microsoft.Extensions.Hosting;
using NetCord;
using NetCord.Hosting.Gateway;
using NetCord.Hosting.Services;
using NetCord.Hosting.Services.ComponentInteractions;
using NetCord.Services.ComponentInteractions;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddDiscordGateway()
.AddComponentInteractions<ButtonInteraction, ButtonInteractionContext>()
.AddComponentInteractions<StringMenuInteraction, StringMenuInteractionContext>()
.AddComponentInteractions<UserMenuInteraction, UserMenuInteractionContext>()
.AddComponentInteractions<RoleMenuInteraction, RoleMenuInteractionContext>()
.AddComponentInteractions<MentionableMenuInteraction, MentionableMenuInteractionContext>()
.AddComponentInteractions<ChannelMenuInteraction, ChannelMenuInteractionContext>()
.AddComponentInteractions<ModalInteraction, ModalInteractionContext>();
var host = builder.Build();
// Add component interactions using minimal APIs
host.AddComponentInteraction<ButtonInteractionContext>("ping", () => "Pong!")
.AddComponentInteraction<StringMenuInteractionContext>("string", (StringMenuInteractionContext context) => string.Join("\n", context.SelectedValues))
.AddComponentInteraction<UserMenuInteractionContext>("user", (UserMenuInteractionContext context) => string.Join("\n", context.SelectedUsers))
.AddComponentInteraction<RoleMenuInteractionContext>("role", (RoleMenuInteractionContext context) => string.Join("\n", context.SelectedRoles))
.AddComponentInteraction<MentionableMenuInteractionContext>("mentionable", (MentionableMenuInteractionContext context) => string.Join("\n", context.SelectedMentionables))
.AddComponentInteraction<ChannelMenuInteractionContext>("channel", (ChannelMenuInteractionContext context) => string.Join("\n", context.SelectedChannels))
.AddComponentInteraction<ModalInteractionContext>("modal", (ModalInteractionContext context) => ((TextInput)context.Components[0]).Value);
// Add component interactions from modules
host.AddModules(typeof(Program).Assembly);
// Add handlers to handle the component interactions
host.UseGatewayEventHandlers();
await host.RunAsync();
Example Modules
Button Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class ButtonModule : ComponentInteractionModule<ButtonInteractionContext>
{
[ComponentInteraction("button")]
public static string Button() => "You clicked a button!";
}
String Menu Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class StringMenuModule : ComponentInteractionModule<StringMenuInteractionContext>
{
[ComponentInteraction("menu")]
public string Menu() => $"You selected: {string.Join(", ", Context.SelectedValues)}";
}
User Menu Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class UserMenuModule : ComponentInteractionModule<UserMenuInteractionContext>
{
[ComponentInteraction("menu")]
public string Menu() => $"You selected: {string.Join(", ", Context.SelectedUsers)}";
}
Role Menu Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class RoleMenuModule : ComponentInteractionModule<RoleMenuInteractionContext>
{
[ComponentInteraction("menu")]
public string Menu() => $"You selected: {string.Join(", ", Context.SelectedRoles)}";
}
Mentionable Menu Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class MentionableMenuModule : ComponentInteractionModule<MentionableMenuInteractionContext>
{
[ComponentInteraction("menu")]
public string Menu() => $"You selected: {string.Join(", ", Context.SelectedMentionables)}";
}
Channel Menu Module
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class ChannelMenuModule : ComponentInteractionModule<ChannelMenuInteractionContext>
{
[ComponentInteraction("menu")]
public string Menu() => $"You selected: {string.Join(", ", Context.SelectedChannels)}";
}
Modal Module
using NetCord;
using NetCord.Services.ComponentInteractions;
namespace MyBot;
public class ModalModule : ComponentInteractionModule<ModalInteractionContext>
{
[ComponentInteraction("modal")]
public string Modal() => string.Join('\n', Context.Components.OfType<TextInput>()
.Select(i => $"{i.CustomId}: {i.Value}"));
}