Beispiel #1
0
    public async Task NoWhiteListsConfigured_Should_ReplyMessage()
    {
        // Arrange
        var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
        var          command      = new WhiteListCommand(channelConfigurationServiceMock.Object);
        const string replyMessage = "You don't have Whitelist words configured";

        var chatConfig = new DiscordChannelConfig
        {
            WhiteListWords = null
        };

        var channelMock = new Mock <IMessageChannel>();
        var user        = new Mock <IGuildUser>();

        user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.All);
        var message = new Mock <IMessage>();

        message.Setup(v => v.Author).Returns(user.Object);
        message.Setup(v => v.Channel).Returns(channelMock.Object);

        channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
        .ReturnsAsync(chatConfig);

        // Act
        await command.Handle(message.Object);

        // Assert

        // Verify SendMessageAsync was called with the reply message "You don't have Whitelist words configured"
        channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
    }
Beispiel #2
0
    public async Task UserIsAdmin_Should_ChangeChatConfig_And_ReplyMessage()
    {
        // Arrange
        var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
        var          command      = new ShowDetailsCommand(channelConfigurationServiceMock.Object);
        const string replyMessage = "Show correction details ✅";

        var chatConfig = new DiscordChannelConfig
        {
            HideCorrectionDetails = true
        };

        var channelMock = new Mock <IMessageChannel>();
        var user        = new Mock <IGuildUser>();

        user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.All);
        var message = new Mock <IMessage>();

        message.Setup(v => v.Author).Returns(user.Object);
        message.Setup(v => v.Channel).Returns(channelMock.Object);

        channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
        .ReturnsAsync(chatConfig);

        // Act
        await command.Handle(message.Object);

        // Assert

        // Verify SendMessageAsync was called with the reply message "Show correction details ✅"
        channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
        channelConfigurationServiceMock.Verify(v => v.Update(chatConfig));
        Assert.False(chatConfig.HideCorrectionDetails);
    }
        public async Task ParameterNotReceived_Should_ReplyMessage()
        {
            // Arrange
            var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
            var          command      = new LanguageCommand(channelConfigurationServiceMock.Object);
            const string replyMessage = "Parameter not received";

            var chatConfig = new DiscordChannelConfig
            {
                SelectedLanguage = SupportedLanguages.Auto
            };

            var channelMock = new Mock <IMessageChannel>();
            var user        = new Mock <IGuildUser>();

            user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.All);
            var message = new Mock <IMessage>();

            message.Setup(v => v.Content).Returns(DiscordBotCommands.Language);
            message.Setup(v => v.Author).Returns(user.Object);
            message.Setup(v => v.Channel).Returns(channelMock.Object);

            channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
            .ReturnsAsync(chatConfig);

            // Act
            await command.Handle(message.Object);

            // Assert

            // Verify SendMessageAsync was called with the reply message "Parameter not received"
            channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
            Assert.Equal(SupportedLanguages.Auto, chatConfig.SelectedLanguage); // Make sure SelectedLanguage is still Auto
        }
        public async Task InvalidParameter_Should_ReplyMessage(string parameter)
        {
            // Arrange
            var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
            var          command      = new SetAlgorithmCommand(channelConfigurationServiceMock.Object);
            const string replyMessage = "Invalid parameter";

            var chatConfig = new DiscordChannelConfig
            {
                GrammarAlgorithm = GrammarAlgorithms.InternalAlgorithm
            };

            var channelMock = new Mock <IMessageChannel>();
            var user        = new Mock <IGuildUser>();

            user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.All);
            var message = new Mock <IMessage>();

            message.Setup(v => v.Content).Returns($"{DiscordBotCommands.SetAlgorithm} {parameter}");
            message.Setup(v => v.Author).Returns(user.Object);
            message.Setup(v => v.Channel).Returns(channelMock.Object);

            channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
            .ReturnsAsync(chatConfig);

            // Act
            await command.Handle(message.Object);

            // Assert

            // Verify SendMessageAsync was called with the reply message "Invalid parameter"
            channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
            Assert.Equal(GrammarAlgorithms.InternalAlgorithm, chatConfig.GrammarAlgorithm); // Make sure SelectedLanguage is still Auto
        }
Beispiel #5
0
        public async Task BotStoppedAndUserNotAdmin_Should_ReplyNotAdminMessage()
        {
            // Arrange
            var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
            var          command      = new StartCommand(channelConfigurationServiceMock.Object);
            const string replyMessage = "Only admins can use this command";

            var chatConfig = new DiscordChannelConfig
            {
                IsBotStopped = true
            };

            var channelMock = new Mock <IMessageChannel>();
            var user        = new Mock <IGuildUser>();

            user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.None);
            var message = new Mock <IMessage>();

            message.Setup(v => v.Author).Returns(user.Object);
            message.Setup(v => v.Channel).Returns(channelMock.Object);

            channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
            .ReturnsAsync(chatConfig);

            // Act
            await command.Handle(message.Object);

            // Assert

            // Verify SendMessageAsync was called with the reply message "Only admins can use this command"
            channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
            Assert.True(chatConfig.IsBotStopped); // Make sure IsBotStopped is still true
        }
Beispiel #6
0
        public async Task BotNotStopped_Should_ReplyBotStartedMessage()
        {
            // Arrange
            var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
            var          command      = new StartCommand(channelConfigurationServiceMock.Object);
            const string replyMessage = "Bot is already started";

            var chatConfig = new DiscordChannelConfig
            {
                IsBotStopped = false
            };

            var channelMock = new Mock <IMessageChannel>();
            var message     = new Mock <IMessage>();

            message.Setup(v => v.Channel).Returns(channelMock.Object);

            channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
            .ReturnsAsync(chatConfig);

            // Act
            await command.Handle(message.Object);

            // Assert

            // Verify SendMessageAsync was called with the reply message "Bot is already started"
            channelMock.Verify(v => v.SendMessageAsync(null, false, It.Is <Embed>(e => e.Description.Contains(replyMessage)), null, null, null, null, null, null, MessageFlags.None));
        }
        public async Task UserNotAdmin_Should_ReplyMessage()
        {
            // Arrange
            var          channelConfigurationServiceMock = new Mock <IDiscordChannelConfigService>();
            var          command      = new StopCommand(channelConfigurationServiceMock.Object);
            const string replyMessage = "Only admins can use this command.";

            var chatConfig = new DiscordChannelConfig
            {
                IsBotStopped = false
            };

            var channelMock = new Mock <IMessageChannel>();
            var user        = new Mock <IGuildUser>();

            user.Setup(v => v.GuildPermissions).Returns(GuildPermissions.None);
            var message = new Mock <IMessage>();

            message.Setup(v => v.Author).Returns(user.Object);
            message.Setup(v => v.Channel).Returns(channelMock.Object);

            channelConfigurationServiceMock.Setup(v => v.GetConfigurationByChannelId(message.Object.Channel.Id))
            .ReturnsAsync(chatConfig);

            // Act
            await command.Handle(message.Object);

            // Assert

            // Verify SendMessageAsync was called with the reply message "Only admins can use this command"
            channelMock.Verify(v => v.SendMessageAsync(replyMessage, false, null, null, null, It.Is <MessageReference>(m => m.MessageId.Value == message.Object.Id), null, null, null, MessageFlags.None));
            Assert.False(chatConfig.IsBotStopped); // Make sure IsBotStopped is still false
        }
        private IGrammarService GetConfiguredGrammarService(DiscordChannelConfig channelConfig, IServiceProvider serviceProvider)
        {
            var grammarServices = serviceProvider.GetService <IEnumerable <IGrammarService> >();

            var grammarService = grammarServices.First(v => v.GrammarAlgorith == channelConfig.GrammarAlgorithm);

            grammarService.SetSelectedLanguage(channelConfig.SelectedLanguage);
            grammarService.SetStrictnessLevel(channelConfig.CorrectionStrictnessLevel);
            grammarService.SetWhiteListWords(channelConfig.WhiteListWords);

            return(grammarService);
        }
        private async Task <DiscordChannelConfig> GetChatConfiguration(SocketUserMessage message, IServiceProvider serviceProvider)
        {
            var channelConfigService = serviceProvider.GetService <IDiscordChannelConfigService>();

            var channelConfig = await channelConfigService.GetConfigurationByChannelId(message.Channel.Id);

            if (channelConfig != null)
            {
                return(channelConfig);
            }

            var messageBuilder = new StringBuilder();

            messageBuilder.AppendLine("Hi, I'm GrammarNazi.");
            messageBuilder.AppendLine("I'm currently working and correcting all spelling errors in this channel.");
            messageBuilder.AppendLine($"Type `{DiscordBotCommands.Help}` to get useful commands.");

            ulong guild = message.Channel switch
            {
                SocketDMChannel dmChannel => dmChannel.Id,
                SocketGuildChannel guildChannel => guildChannel.Guild.Id,
                  _ => default
            };

            var channelConfiguration = new DiscordChannelConfig
            {
                ChannelId        = message.Channel.Id,
                GrammarAlgorithm = Defaults.DefaultAlgorithm,
                Guild            = guild,
                SelectedLanguage = SupportedLanguages.Auto
            };

            await channelConfigService.AddConfiguration(channelConfiguration);

            await message.Channel.SendMessageAsync(messageBuilder.ToString());

            return(channelConfiguration);
        }
 public async Task Update(DiscordChannelConfig channelConfig)
 {
     await _repository.Update(channelConfig, v => v.ChannelId == channelConfig.ChannelId);
 }
 public Task Delete(DiscordChannelConfig channelConfig)
 {
     return(_repository.Delete(channelConfig));
 }
 public Task AddConfiguration(DiscordChannelConfig channelConfig)
 {
     return(_repository.Add(channelConfig));
 }
        private async Task SocketClientOnMessageReceived(SocketMessage message)
        {
            if (message.Author.IsBot || message.Author.IsWebhook)
            {
                return;
            }

            var args = message.Content.Split();

            // if it doesn't start with the bot prefix, ignore it.
            if (!args[0].StartsWith(this.plugin.Config.DiscordBotPrefix))
            {
                return;
            }

            /*
             * // this is only needed for debugging purposes.
             * foreach (var s in args)
             * {
             *  PluginLog.Verbose(s);
             * }
             */

            PluginLog.Verbose("Received command: {0}", args[0]);

            try
            {
                if (args[0] == this.plugin.Config.DiscordBotPrefix + "setchannel" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length == 1)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify some chat kinds to use.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    // Is there any chat type that's not recognized?
                    if (kinds
                        .Any(x =>
                             XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        PluginLog.Verbose("Could not find kinds");
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (!this.plugin.Config.ChannelConfigs.TryGetValue(message.Channel.Id, out var config))
                    {
                        config = new DiscordChannelConfig();
                    }

                    foreach (var selectedKind in kinds)
                    {
                        PluginLog.Verbose(selectedKind);

                        if (selectedKind == "any")
                        {
                            config.SetUnique(DefaultChatTypes);
                        }
                        else
                        {
                            var chatType = XivChatTypeExtensions.GetBySlug(selectedKind);
                            config.SetUnique(chatType);
                        }
                    }

                    this.plugin.Config.ChannelConfigs[message.Channel.Id] = config;
                    this.plugin.Config.Save();

                    await SendGenericEmbed(message.Channel,
                                           $"OK! This channel has been set to receive the following chat kinds:\n\n```\n{config.ChatTypes.Select(x => $"{x.GetFancyName()}").Aggregate((x, y) => x + "\n" + y)}```",
                                           "Chat kinds set", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "unsetchannel" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length == 1)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify some chat kinds to use.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    // Is there any chat type that's not recognized?
                    if (kinds.Any(x =>
                                  XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (!this.plugin.Config.ChannelConfigs.TryGetValue(message.Channel.Id, out var config))
                    {
                        config = new DiscordChannelConfig();
                    }

                    foreach (var selectedKind in kinds)
                    {
                        if (selectedKind == "any")
                        {
                            config.UnsetUnique(DefaultChatTypes);
                        }
                        else
                        {
                            var chatType = XivChatTypeExtensions.GetBySlug(selectedKind);
                            config.UnsetUnique(chatType);
                        }
                    }

                    this.plugin.Config.ChannelConfigs[message.Channel.Id] = config;
                    this.plugin.Config.Save();

                    if (config.ChatTypes.Count() == 0)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"All chat kinds have been removed from this channel.",
                                               "Chat Kinds unset", EmbedColorFine);
                    }
                    await SendGenericEmbed(message.Channel,
                                           $"OK! This channel will still receive the following chat kinds:\n\n```\n{config.ChatTypes.Select(x => $"{x.GetSlug()} - {x.GetFancyName()}").Aggregate((x, y) => x + "\n" + y)}```",
                                           "Chat kinds unset", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "setprefix" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length < 3)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify some chat kinds and a prefix to use.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    // Is there any chat type that's not recognized?
                    if (kinds.Any(x =>
                                  XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (args[2] == "none")
                    {
                        args[2] = string.Empty;
                    }

                    foreach (var selectedKind in kinds)
                    {
                        var type = XivChatTypeExtensions.GetBySlug(selectedKind);
                        this.plugin.Config.PrefixConfigs[type] = args[2];
                    }

                    this.plugin.Config.Save();


                    await SendGenericEmbed(message.Channel,
                                           $"OK! The following prefixes are set:\n\n```\n{this.plugin.Config.PrefixConfigs.Select(x => $"{x.Key.GetFancyName()} - {x.Value}").Aggregate((x, y) => x + "\n" + y)}```",
                                           "Prefix set", EmbedColorFine);

                    return;
                }



                if (args[0] == this.plugin.Config.DiscordBotPrefix + "unsetprefix" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length < 2)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify some chat kinds and a prefix to use.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    // Is there any chat type that's not recognized?
                    if (kinds.Any(x =>
                                  XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    foreach (var selectedKind in kinds)
                    {
                        var type = XivChatTypeExtensions.GetBySlug(selectedKind);
                        this.plugin.Config.PrefixConfigs.Remove(type);
                    }

                    this.plugin.Config.Save();

                    if (this.plugin.Config.PrefixConfigs.Count() == 0)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"All prefixes have been removed.",
                                               "Prefix unset", EmbedColorFine);
                    }
                    else // this doesn't seem to trigger when there's only one entry left. I don't know why.
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"OK! The prefix for {XivChatTypeExtensions.GetBySlug(args[2])} has been removed.\n\n"
                                               + $"The following prefixes are still set:\n\n```\n{this.plugin.Config.PrefixConfigs.Select(x => $"{x.Key.GetFancyName()} - {x.Value}").Aggregate((x, y) => x + "\n" + y)}```",
                                               "Prefix unset", EmbedColorFine);
                    }

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "setchattypename" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length < 3)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify one or more chat kinds and a custom name.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }



                    var kinds = args[1].Split(',').Select(x => x.ToLower());
                    var chatChannelOverride = string.Join(" ", args.Skip(2)).Trim('"');

                    // PluginLog.Information($"arg1: {args[1]}; arg2: {chatChannelOverride}");

                    // Is there any chat type that's not recognized?
                    if (kinds.Any(x =>
                                  XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (chatChannelOverride == "none")
                    {
                        foreach (var selectedKind in kinds)
                        {
                            var type = XivChatTypeExtensions.GetBySlug(selectedKind);
                            this.plugin.Config.CustomSlugsConfigs[type] = type.GetSlug();
                        }

                        await SendGenericEmbed(message.Channel,
                                               $"OK! The following custom chat type names have been set:\n\n```\n{this.plugin.Config.CustomSlugsConfigs.Select(x => $"{x.Key.GetFancyName()} - {x.Value}").Aggregate((x, y) => x + "\n" + y)}```",
                                               "Custom chat type set", EmbedColorFine);
                    }
                    else
                    {
                        foreach (var selectedKind in kinds)
                        {
                            var type = XivChatTypeExtensions.GetBySlug(selectedKind);
                            this.plugin.Config.CustomSlugsConfigs[type] = chatChannelOverride;
                        }

                        await SendGenericEmbed(message.Channel,
                                               $"OK! The following custom chat type names have been set:\n\n```\n{this.plugin.Config.CustomSlugsConfigs.Select(x => $"{x.Key.GetFancyName()} - {x.Value}").Aggregate((x, y) => x + "\n" + y)}```",
                                               "Custom chat type set", EmbedColorFine);
                    }

                    this.plugin.Config.Save();

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "unsetchattypename" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length < 2)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }



                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    PluginLog.Information($"Unsetting custom type name for arg1: {args[1]}");

                    // Is there any chat type that's not recognized?
                    if (kinds.Any(x =>
                                  XivChatTypeExtensions.TypeInfoDict.All(y => y.Value.Slug != x) && x != "any"))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"One or more of the chat kinds you specified could not be found.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }


                    foreach (var selectedKind in kinds)
                    {
                        var type = XivChatTypeExtensions.GetBySlug(selectedKind);
                        this.plugin.Config.CustomSlugsConfigs[type] = type.GetSlug();
                    }

                    await SendGenericEmbed(message.Channel,
                                           $"OK! The following custom chat type names have been set:\n\n```\n{this.plugin.Config.CustomSlugsConfigs.Select(x => $"{x.Key.GetFancyName()} - {x.Value}").Aggregate((x, y) => x + "\n" + y)}```",
                                           "Custom chat type unset", EmbedColorFine);


                    this.plugin.Config.Save();

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "setduplicatems" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length == 1)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify a number in milliseconds to use.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    var kinds = args[1].Split(',').Select(x => x.ToLower());

                    // Make sure that it's a number (or assume it is)
                    int newDelay = int.Parse(args[1]);

                    this.plugin.Config.DuplicateCheckMS = newDelay;
                    this.plugin.Config.Save();

                    await SendGenericEmbed(message.Channel,
                                           $"OK! Any messages with the same content within the last **{newDelay}** milliseconds will be skipped, preventing duplicate posts.",
                                           "Duplicate Message Check", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "toggledf" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    if (!this.plugin.Config.ChannelConfigs.TryGetValue(message.Channel.Id, out var config))
                    {
                        config = new DiscordChannelConfig();
                    }

                    config.IsContentFinder = !config.IsContentFinder;

                    this.plugin.Config.ChannelConfigs[message.Channel.Id] = config;
                    this.plugin.Config.Save();

                    await SendGenericEmbed(message.Channel,
                                           $"OK! This channel has been {(config.IsContentFinder ? "enabled" : "disabled")} from receiving Duty Finder notifications.",
                                           "Duty Finder set", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "setcfprefix" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    // Are there parameters?
                    if (args.Length < 2)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You need to specify a prefix to use, or type \"none\" if you want to remove it.\nCheck the ``{this.plugin.Config.DiscordBotPrefix}help`` command for more information.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (args[1] == "none")
                    {
                        args[1] = string.Empty;
                    }

                    this.plugin.Config.CFPrefixConfig = args[1];

                    this.plugin.Config.Save();


                    await SendGenericEmbed(message.Channel,
                                           $"OK! The following prefix was set:\n\n```\n{this.plugin.Config.CFPrefixConfig}```",
                                           "Prefix set", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "listchannel" &&
                    await EnsureOwner(message.Author, message.Channel))
                {
                    if (!this.plugin.Config.ChannelConfigs.TryGetValue(message.Channel.Id, out var config))
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"You didn't set up any channel kinds for this channel yet.\nPlease use the ``{this.plugin.Config.DiscordBotPrefix}setchannel`` command to do this.",
                                               "Error", EmbedColorError);

                        return;
                    }

                    if (config == null || config.ChatTypes.Count == 0)
                    {
                        await SendGenericEmbed(message.Channel,
                                               $"There are no channel kinds set for this channel right now.\nPlease use the ``{this.plugin.Config.DiscordBotPrefix}setchannel`` command to do this.",
                                               "Error", EmbedColorFine);

                        return;
                    }

                    await SendGenericEmbed(message.Channel,
                                           $"OK! This channel has been set to receive the following chat kinds:\n\n```\n{config.ChatTypes.Select(x => $"{x.GetFancyName()}").Aggregate((x, y) => x + "\n" + y)}```",
                                           "Chat kinds set", EmbedColorFine);

                    return;
                }

                if (args[0] == this.plugin.Config.DiscordBotPrefix + "help")
                {
                    PluginLog.Verbose("Help time");

                    var builder = new EmbedBuilder()
                                  .WithTitle("Discord Bridge Help")
                                  .WithDescription("You can use the following commands to set up the Discord bridge.")
                                  .WithColor(new Color(EmbedColorFine))
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}setchannel", "Select, which kinds of chat should arrive in this channel.\n" +
                                            $"Format: ``{this.plugin.Config.DiscordBotPrefix}setchannel <kind1,kind2,...>``\n\n" +
                                            $"See [this link for a list of all available chat kinds]({Constant.KindListLink}) or type ``any`` to enable it for all regular chat messages.")
                                  //$"The following chat kinds are available:\n```all - All regular chat\n{XivChatTypeExtensions.TypeInfoDict.Select(x => $"{x.Value.Slug} - {x.Value.FancyName}").Aggregate((x, y) => x + "\n" + y)}```")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}unsetchannel", "Works like the previous command, but removes kinds of chat from the list of kinds that are sent to this channel.")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}listchannel", "List all chat kinds that are sent to this channel.")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}toggledf", "Enable or disable sending duty finder updates to this channel.")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}setduplicatems", "Set time in milliseconds that the bot will check to see if any past messages were the same. Default is 0 ms.")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}setprefix", "Set a prefix for chat kinds. "
                                            + $"This can be an emoji or a string that will be prepended to every chat message that will arrive with this chat kind. "
                                            + $"You can also set it to `none` if you want to remove it.\n"
                                            + $"Format: ``{this.plugin.Config.DiscordBotPrefix}setchannel <kind1,kind2,...> <prefix>``")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}setcfprefix", "Set a prefix for duty finder posts. "
                                            + $"You can also set it to `none` if you want to remove it.\n"
                                            + $"Format: ``{this.plugin.Config.DiscordBotPrefix}setcfprefix <prefix>``")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}setchattypename ", "Set custom text for chat kinds. "
                                            + $"This can be an emoji or a string that will replace the short name of a chat kind for every chat message that will arrive with this chat kind. "
                                            + $"You can also set it to `none` if you want to remove it.\n"
                                            + $"Format: ``{this.plugin.Config.DiscordBotPrefix}setchattypename  <kind1,kind2,...> <custom text>``")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}unsetprefix", "Remove prefix set for a chat kind. \n"
                                            + $"Format: ``{this.plugin.Config.DiscordBotPrefix}unsetprefix <kind>``")
                                  .AddField($"{this.plugin.Config.DiscordBotPrefix}unsetchattypename", "Remove custom name for a chat kind. \n"
                                            + $"Format: ``{this.plugin.Config.DiscordBotPrefix}unsetchattypename <kind>``")
                                  .AddField("Need more help?",
                                            $"You can [read the full step-by-step guide]({Constant.HelpLink}) or [join our Discord server]({Constant.DiscordJoinLink}) to ask for help.")
                                  .WithFooter(footer =>
                    {
                        footer
                        .WithText("Dalamud Discord Bridge")
                        .WithIconUrl(Constant.LogoLink);
                    })
                                  .WithThumbnailUrl(Constant.LogoLink);
                    var embed = builder.Build();

                    var m = await message.Channel.SendMessageAsync(
                        null,
                        embed : embed)
                            .ConfigureAwait(false);

                    ;
                    PluginLog.Verbose(m.Id.ToString());

                    return;
                }
            }
            catch (Exception ex)
            {
                PluginLog.Error(ex, "Could not handle incoming Discord message.");
            }
        }