public static async Task MainAsync(string[] args) { // Read the config json file ... using FileStream fs = new(Path.Join("Config", "bot_config.json"), FileMode.Open); using StreamReader sr = new(fs); var json = await sr.ReadToEndAsync(); var jobj = JObject.Parse(json); // ... create a new DiscordClient for the bot ... Discord = new DiscordClient(new DiscordConfiguration { Token = jobj["token"].ToString(), TokenType = TokenType.Bot, ShardCount = 1, Intents = DiscordIntents.AllUnprivileged }); // ... register commands ... var next = Discord.UseCommandsNext(new CommandsNextConfiguration { StringPrefixes = new string[] { jobj["prefix"].ToString() } }); next.RegisterCommands(Assembly.GetExecutingAssembly()); // ... connect to discord ... await Discord.ConnectAsync(); var defaultResponseData = new InteractionApplicationCommandCallbackDataBuilder() .WithContent("`Test Automated Response`"); IServiceCollection c = new ServiceCollection(); c.AddTransient <TestService>(); // ... use the discord connection to build the Slash Client config ... Slash = new DiscordSlashClient(new DiscordSlashConfiguration { Client = Discord, Token = jobj["token"].ToString(), DefaultResponseType = InteractionResponseType.ChannelMessageWithSource, DefaultResponseData = defaultResponseData }, c); Slash.RegisterCommands(Assembly.GetExecutingAssembly()); // ... start the slash client ... await Slash.StartAsync(); // ... build the web server for receiving HTTP POSTs from discord ... var host = Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup <Startup>(); }); // ... and start the webserver ... await host.Build().StartAsync(); // ... then hold here to prevent premature closing. await Task.Delay(-1); }
static void Main(string[] args) { // Read the config json file ... using FileStream fs = new(Path.Join("Config", "bot_config.json"), FileMode.Open); using StreamReader sr = new(fs); var json = sr.ReadToEnd(); var jobj = JObject.Parse(json); // ... create a new DiscordClient for the bot ... Discord = new DiscordClient(new DiscordConfiguration { Token = jobj["token"].ToString(), TokenType = TokenType.Bot, ShardCount = 1, Intents = DiscordIntents.AllUnprivileged, MinimumLogLevel = Microsoft.Extensions.Logging.LogLevel.Debug }); // ... create a custom default response ... var defaultResponseData = new InteractionApplicationCommandCallbackDataBuilder() .WithContent("`Test Automated Response`"); // ... use the discord client to build the Slash Client config ... Slash = new DiscordSlashClient(new DiscordSlashConfiguration { Client = Discord, Token = jobj["token"].ToString(), DefaultResponseType = InteractionResponseType.ChannelMessageWithSource, DefaultResponseData = defaultResponseData, Logger = Discord.Logger }); // ... register normal bot commands ... var next = Discord.UseCommandsNext(new CommandsNextConfiguration { StringPrefixes = new string[] { jobj["prefix"].ToString() } }); next.RegisterCommands(Assembly.GetExecutingAssembly()); // ... register the interaction event ... Discord.InteractionCreated += Slash.HandleGatewayEvent; Discord.InteractionCreated += (x, y) => { Discord.Logger.LogInformation("Interaction Created Received"); return(Task.CompletedTask); }; Discord.ApplicationCommandCreated += Discord_ApplicationCommandCreated; Discord.ApplicationCommandDeleted += Discord_ApplicationCommandDeleted; Discord.ApplicationCommandUpdated += Discord_ApplicationCommandUpdated; // ... connect to discord ... Discord.ConnectAsync().GetAwaiter().GetResult(); // ... register the slash commands ... Slash.RegisterCommands(Assembly.GetExecutingAssembly()); // ... start the slash client ... Slash.StartAsync().GetAwaiter().GetResult(); // ... and prevent this from stopping. Task.Delay(-1).GetAwaiter().GetResult(); }
public InteractionContext(DiscordSlashClient c, DiscordInteraction i) { _client = c; Interaction = i; }
public Task HandleInteraction(BaseDiscordClient discord, Interaction interact, DiscordSlashClient c) { // This should not get here, but check just in case. if (interact.Type == InteractionType.Ping) { return(Task.CompletedTask); } // Create a cancellation token for the event in which it is needed. var cancelSource = new CancellationTokenSource(); // Store the command task in a ConcurrentDictionary and continue with execution to not hodlup the webhook response. RunningInteractions[interact] = new( Task.Run(async() => await ExecuteInteraction(discord, interact, c, cancelSource.Token)), cancelSource); return(Task.CompletedTask); }
private async Task ExecuteInteraction(BaseDiscordClient discord, Interaction interact, DiscordSlashClient c, CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); if (interact.Data is null) { throw new Exception("Interact object has no command data."); } if (Commands.TryGetValue(interact.Data.Name, out var cmd)) { // TODO: Check how subcommands are returned. // TODO: Do argument parsing. var context = new InteractionContext(c, interact); if (interact.Data.Options is not null) { var args = await GetRawArguments(interact.Data.Options); cmd.ExecuteCommand(discord, context, args); } else { cmd.ExecuteCommand(discord, context); } } } catch (Exception ex) { _logger.LogError(ex, "Interaction Handler failed"); } finally { RunningInteractions.TryRemove(interact, out _); } }