Discord.Addons.Hosting 5.1.0-labs

Additional Details

Discord.Net.Labs is end of life, please move to the normal Discord.Net package.

This is a prerelease version of Discord.Addons.Hosting.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Discord.Addons.Hosting --version 5.1.0-labs                
NuGet\Install-Package Discord.Addons.Hosting -Version 5.1.0-labs                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Discord.Addons.Hosting" Version="5.1.0-labs" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Discord.Addons.Hosting --version 5.1.0-labs                
#r "nuget: Discord.Addons.Hosting, 5.1.0-labs"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Discord.Addons.Hosting as a Cake Addin
#addin nuget:?package=Discord.Addons.Hosting&version=5.1.0-labs&prerelease

// Install Discord.Addons.Hosting as a Cake Tool
#tool nuget:?package=Discord.Addons.Hosting&version=5.1.0-labs&prerelease                

Discord.Addons.Hosting

.NET Core Build NuGet Nuget

Discord.NET Fork Original Labs
Nuget Version 5.1.0 5.1.0-labs

Discord.NET hosting with Microsoft.Extensions.Hosting. This package provides extensions to a .NET Generic Host (IHostBuilder) that will run a Discord.NET socket/sharded client as a controllable IHostedService. This simplifies initial bot creation and moves the usual boilerplate to a convenient builder pattern.

.NET 6.0+ is required.

// CreateDefaultBuilder configures a lot of stuff for us automatically
// See: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host
var host = Host.CreateDefaultBuilder()   
    .ConfigureDiscordHost((context, config) =>
    {
        config.SocketConfig = new DiscordSocketConfig
        {
            LogLevel = LogSeverity.Verbose,
            AlwaysDownloadUsers = true,
            MessageCacheSize = 200
        };

        config.Token = context.Configuration["token"];
    })
    // Optionally wire up the command service
    .UseCommandService((context, config) =>
    {
        config.DefaultRunMode = RunMode.Async;
        config.CaseSensitiveCommands = false;
    })
    // Optionally wire up the interactions service
    .UseInteractionService((context, config) =>
    {
        config.LogLevel = LogSeverity.Info;
        config.UseCompiledLambda = true;
    })
    .ConfigureServices((context, services) =>
    {
        //Add any other services here
        services.AddHostedService<CommandHandler>();
        services.AddHostedService<BotStatusService>();
        services.AddHostedService<LongRunningService>();
    }).Build();
  
await host.RunAsync();

Getting Started

  1. Create a .NET 6 Worker Service using Visual Studio or via the dotnet cli (dotnet new worker -o MyWorkerService)
  2. Add Discord.Addons.Hosting to your project.
  3. Set your bot token via the dotnet secrets manager: dotnet user-secrets set "token" "your-token-here"
  4. Add your bot prefix to appsettings.json
  5. Configure your Discord client with ConfigureDiscordHost.
  6. Enable the CommandService and/or the InteractionService with UseCommandService and UseInteractionService
  7. Create and start your application using a HostBuilder as shown above and in the examples linked below.

Examples

Fully working examples are available here

Sharded Client

To use the sharded client instead of the socket client, simply replace ConfigureDiscordHost with ConfigureDiscordShardedHost:

.ConfigureDiscordShardedHost((context, config) =>
{
    config.SocketConfig = new DiscordSocketConfig
    {
    	// Manually set the required shards, or leave empty for the recommended count
	TotalShards = 4
    };

    config.Token = context.Configuration["token"];
})

Serilog

Microsoft's default logging has an unfortunate default output format, so I highly recommend using Serilog instead of the standard Microsoft logging.

Serilog should be added to the host with Serilog.Extensions.Hosting.

See the Serilog example for usage.

Discord Client Services

This section assumes some prior knowledge of Dependency Injection within the .NET ecosystem. Take a read of this if you have no idea what any of this means.

During bot development, it's highly like you'll require the ability to execute code immediately after startup, such as setting the bot's status, reaching out to a web server, registering an event, or kicking off the continuous execution of code in the background. Given we're using the generic host and have its IHostedService & BackgroundService capabilities in our toolbelt, this is easily achievable in a clean and concise way.

This package ships with the DiscordClientService and DiscordShardedClientService base classes for the socket client and sharded client respectively. For convenience, both of them expose the Client and Logger. Simply inherit from the given type, implement the required constructor, place your execution requirements within ExecuteAsync and register the service with your service collection via services.AddHostedService.

public class CommandHandler : DiscordClientService
{
    private readonly IServiceProvider _provider;
    private readonly CommandService _commandService;
    private readonly IConfiguration _config;

    public CommandHandler(DiscordSocketClient client, ILogger<CommandHandler> logger,  IServiceProvider provider, CommandService commandService, IConfiguration config) : base(client, logger)
    {
        _provider = provider;
        _commandService = commandService;
        _config = config;
    }
    // This'll be executed during startup.
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Client.MessageReceived += HandleMessage;
        _commandService.CommandExecuted += CommandExecutedAsync;
        await _commandService.AddModulesAsync(Assembly.GetEntryAssembly(), _provider);
    }
        
    //.....
}
 .ConfigureServices((context, services) =>
{
    services.AddHostedService<CommandHandler>();
    //....
});

The WaitForReadyAsync extension method is also available for both client types to await execution of your service until the client has reached a Ready state:

public class BotStatusService : DiscordClientService
{
   public BotStatusService(DiscordSocketClient client, ILogger<DiscordClientService> logger) : base(client, logger)
   {
   }

   protected override async Task ExecuteAsync(CancellationToken stoppingToken)
   {
   	// Wait for the client to be ready before setting the status
       await Client.WaitForReadyAsync(stoppingToken);
       Logger.LogInformation("Client is ready!");

       await Client.SetActivityAsync(new Game("Set my status!"));
   }
}
Additional notes:
  • Services that do not require access to the Discord Client should use an implementation of BackgroundService.

  • Services with complex startup & shutdown activities should implement IHostedService directly.

Shutdown

When shutdown is requested, the host will wait a maximum of 5 seconds for services to stop before timing out.

If you're finding that this isn't enough time, you can modify the shutdown timeout via the ShutdownTimeout host setting.

IOptions

This package uses Microsoft.Extensions.Options internally, so both the DiscordHostConfiguration and CommandServiceConfig can be configured within the services registration instead of within the HostBuilder extensions if it better suits your scenario.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Discord.Addons.Hosting:

Package Downloads
Discord.Addons.ChainHandlers

Simple Discord.Net chain handler implementation

FoundryBot

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.