Ejemplo n.º 1
0
        public async Task HandleAsync(DiscordInteraction interaction)
        {
            if (interaction.Guild is null)
            {
                throw new Exception("User tried to execute a command in DMs, somehow.");
            }

            var request = CommandRequest.FromInteractionData(interaction.Data);

            if (!_commands.ContainsKey(request.FullName))
            {
                throw new Exception($"An interaction was created, but no command was registered for it: '{request.FullName}'");
            }
            var command = _commands[request.FullName];

            using var scope = _provider.CreateScope();
            if (ActivatorUtilities.CreateInstance(scope.ServiceProvider, command.Class) is not ICommand instance)
            {
                throw new Exception($"Could not create an instance of a type {command.Class} for a command '{request.FullName}'.");
            }

            var context = new CommandContext(_client, interaction, instance.Ephemeral);

            await AcknowledgeInteraction(interaction, instance.Ephemeral);

            CommandResult result;

            try
            {
                if (request.Parameters is not null)
                {
                    command.FillParameters(instance, request.Parameters, interaction.Data.Resolved);
                }

                var checkResult = await command.RunChecksAsync(context, _provider);

                if (!checkResult.IsSuccessful)
                {
                    await context.RespondWithAccessDeniedAsync(checkResult.Reason);

                    return;
                }

                result = await instance.HandleAsync(context);
            }
            catch (Exception e)
            {
                await context.RespondWithCriticalErrorAsync(e);

                throw;
            }

            if (instance.Ephemeral)
            {
                await RespondWithMessageAsync(context, result);
            }
            else
            {
                await RespondWithEmbedAsync(context, result);
            }
        }