Adding commands with the .NET Generic Host is very easy. Use AddCommands(IServiceCollection) to add the command service to your host builder. Then, use AddCommand to add a command using the minimal APIs way and/or use AddModules(IHost, Assembly) to add command modules from an assembly. You also need to use UseGatewayEventHandlers(IHost) to bind the service event handlers.
using Microsoft.Extensions.Hosting;
using NetCord.Hosting.Gateway;
using NetCord.Hosting.Services;
using NetCord.Hosting.Services.Commands;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddDiscordGateway()
.AddCommands();
var host = builder.Build();
// Add a command using minimal APIs
host.AddCommand(["ping"], () => "Pong!");
// Add commands from modules
host.AddModules(typeof(Program).Assembly);
// Add handlers to handle the commands
host.UseGatewayEventHandlers();
await host.RunAsync();
Specifying a prefix
You can specify a prefix in the configuration. You can for example use appsettings.json
file. It should look like this:
{
"Discord": {
"Prefix": "!"
// You can also specify multiple prefixes using 'Prefixes'
// "Prefixes": [ "!", "?" ]
}
}
First, add the following lines to the using section.
using NetCord.Services;
using NetCord.Services.Commands;
Now, it's time to create CommandService<TContext> instance and add commands to it.
// Create the command service
CommandService<CommandContext> commandService = new();
// Add commands using minimal APIs
commandService.AddCommand(["ping"], () => "Pong!");
// Add commands from modules
commandService.AddModules(typeof(Program).Assembly);
We can add a command handler now.
// Add the handler to handle commands
client.MessageCreate += async message =>
{
// Check if the message is a command (starts with '!' and is not from a bot)
if (!message.Content.StartsWith('!') || message.Author.IsBot)
return;
// Execute the command
var result = await commandService.ExecuteAsync(prefixLength: 1, new CommandContext(message, client));
// Check if the execution failed
if (result is not IFailResult failResult)
return;
// Return the error message to the user if the execution failed
try
{
await message.ReplyAsync(failResult.Message);
}
catch
{
}
};
The Final Product
Program.cs
using NetCord;
using NetCord.Gateway;
using NetCord.Services;
using NetCord.Services.Commands;
GatewayClient client = new(new BotToken("Token from Discord Developer Portal"), new GatewayClientConfiguration()
{
Intents = GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.MessageContent,
});
// Create the command service
CommandService<CommandContext> commandService = new();
// Add commands using minimal APIs
commandService.AddCommand(["ping"], () => "Pong!");
// Add commands from modules
commandService.AddModules(typeof(Program).Assembly);
// Add the handler to handle commands
client.MessageCreate += async message =>
{
// Check if the message is a command (starts with '!' and is not from a bot)
if (!message.Content.StartsWith('!') || message.Author.IsBot)
return;
// Execute the command
var result = await commandService.ExecuteAsync(prefixLength: 1, new CommandContext(message, client));
// Check if the execution failed
if (result is not IFailResult failResult)
return;
// Return the error message to the user if the execution failed
try
{
await message.ReplyAsync(failResult.Message);
}
catch
{
}
};
client.Log += message =>
{
Console.WriteLine(message);
return default;
};
await client.StartAsync();
await Task.Delay(-1);