Table of Contents

Built-In Attributes

CommandsNext has a variety of built-in attributes to enhance your commands and provide some access control. The majority of these attributes can be applied to your command methods and command groups.

Custom Attributes

If the above attributes don't meet your needs, CommandsNext also gives you the option of writing your own! Simply create a new class which inherits from CheckBaseAttribute and implement the required method.

Our example below will only allow a command to be ran during a specified year.

public class RequireYearAttribute : CheckBaseAttribute
{
    public int AllowedYear { get; private set; }

    public RequireYearAttribute(int year)
    {
        AllowedYear = year;
    }

    public override Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help)
    {
        return Task.FromResult(AllowedYear == DateTime.Now.Year);
    }
}

You'll also need to apply the AttributeUsage attribute to your attribute. For our example attribute, we'll set it to only be usable once on methods.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RequireYearAttribute : CheckBaseAttribute
{
    // ...
}

You can provide feedback to the user using the CommandsNextExtension#CommandErrored event.

private async Task MainAsync()
{
    var discord = new DiscordClient();
	var commands = discord.UseCommandsNext();

	commands.CommandErrored += CmdErroredHandler;
}

private async Task CmdErroredHandler(CommandsNextExtension _, CommandErrorEventArgs e)
{
    var failedChecks = ((ChecksFailedException)e.Exception).FailedChecks;
    foreach (var failedCheck in failedChecks)
    {
        if (failedCheck is RequireYearAttribute)
        {
            var yearAttribute = (RequireYearAttribute)failedCheck;
            await e.Context.RespondAsync($"Only usable during year {yearAttribute.AllowedYear}.");
        }
    }
}

Once you've got all of that completed, you'll be able to use it on a command!

[Command("generic"), RequireYear(2030)]
public async Task GenericCommand(CommandContext ctx, string generic)
{
    await ctx.RespondAsync("Generic response.");
}
!generic Only usable during the year 2030!