Exemplo n.º 1
0
        public async Task <RuntimeResult> Hackban([Summary("hackbanParam1")] ulong userId,
                                                  [Remainder, Summary("hackbanParam2")] string reason = null)
        {
            if (await Context.Guild.GetBanAsync(userId) != null)
            {
                return(FergunResult.FromError(Locate("AlreadyBanned")));
            }
            var user = await Context.Client.Rest.GetUserAsync(userId);

            if (user == null)
            {
                return(FergunResult.FromError(Locate("InvalidID")));
            }
            var guildUser = await Context.Client.Rest.GetGuildUserAsync(Context.Guild.Id, userId);

            if (guildUser != null && Context.Guild.CurrentUser.Hierarchy <= guildUser.GetHierarchy())
            {
                return(FergunResult.FromError(Locate("UserNotLowerHierarchy")));
            }

            await Context.Guild.AddBanAsync(userId, 0, reason);

            await SendEmbedAsync(string.Format(Locate("Hackbanned"), user));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 2
0
        public async Task <RuntimeResult> Prefix([Summary("prefixParam1")] string newPrefix)
        {
            if (FergunClient.IsDebugMode)
            {
                return(FergunResult.FromError("No"));
            }

            if (newPrefix == GetPrefix())
            {
                return(FergunResult.FromError(Locate("PrefixSameCurrentTarget")));
            }
            if (newPrefix.Length > Constants.MaxPrefixLength)
            {
                return(FergunResult.FromError(string.Format(Locate("PrefixTooLarge"), Constants.MaxPrefixLength)));
            }

            // null prefix = use the global prefix
            var guild = GetGuildConfig() ?? new GuildConfig(Context.Guild.Id);

            guild.Prefix = newPrefix == DatabaseConfig.GlobalPrefix ? null : newPrefix;

            FergunClient.Database.InsertOrUpdateDocument(Constants.GuildConfigCollection, guild);
            GuildUtils.PrefixCache[Context.Guild.Id] = newPrefix;
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Command", $"Prefix: Updated prefix to: \"{newPrefix}\" in {Context.Guild.Name}"));

            await SendEmbedAsync(string.Format(Locate("NewPrefix"), newPrefix));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 3
0
        public async Task <RuntimeResult> Changelog([Summary("changelogParam1")] string version = null)
        {
            version ??= Constants.Version;
            if (version != Constants.Version && Constants.PreviousVersions.FirstOrDefault(x => x == version) == null)
            {
                return(FergunResult.FromError(string.Format(Locate("VersionNotFound"), string.Join(", ", Constants.PreviousVersions.Append(Constants.Version)))));
            }

            var builder = new EmbedBuilder()
                          .WithTitle("Fergun Changelog")
                          //.AddField($"v{version}", Locate($"Changelog{version}"))
                          .WithFooter(string.Format(Locate("OtherVersions"), string.Join(", ", Constants.PreviousVersions.Append(Constants.Version).Where(x => x != version))))
                          .WithColor(FergunClient.Config.EmbedColor);

            var split = Locate($"Changelog{version}").SplitBySeparatorWithLimit('\n', EmbedFieldBuilder.MaxFieldValueLength).ToList();

            for (int i = 0; i < split.Count; i++)
            {
                builder.AddField(i == 0 ? $"v{version}" : "\u200b", split[i]);
            }

            await ReplyAsync(embed : builder.Build());

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 4
0
        public async Task <RuntimeResult> Enable([Remainder, Summary("enableParam1")] string commandName)
        {
            var command = _cmdService.Commands.FirstOrDefault(x => x.Aliases.Any(y => y == commandName.ToLowerInvariant()) && x.Module.Name != Constants.DevelopmentModuleName);

            if (command != null)
            {
                if (command.Attributes.Concat(command.Module.Attributes).Any(x => x is AlwaysEnabledAttribute))
                {
                    return(FergunResult.FromError(string.Format(Locate("AlreadyEnabled"), Format.Code(command.Name))));
                }
            }
            else
            {
                return(FergunResult.FromError(string.Format(Locate("CommandNotFound"), GetPrefix())));
            }

            string complete = command.Module.Group == null ? command.Name : $"{command.Module.Group} {command.Name}";
            var    guild    = GetGuildConfig() ?? new GuildConfig(Context.Guild.Id);

            if (guild.DisabledCommands.Contains(complete))
            {
                guild.DisabledCommands.Remove(complete);
                FergunClient.Database.InsertOrUpdateDocument(Constants.GuildConfigCollection, guild);
                await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Command", $"Enable: Enabled command \"{complete}\" in server {Context.Guild.Id}."));

                await SendEmbedAsync("\u2705 " + string.Format(Locate("CommandEnabled"), Format.Code(complete)));
            }
            else
            {
                return(FergunResult.FromError(string.Format(Locate("AlreadyEnabled"), Format.Code(complete))));
            }

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 5
0
        public async Task <RuntimeResult> Softban(
            [Summary("softbanParam1"), RequireLowerHierarchy("UserNotLowerHierarchy", true)] IUser user,
            [Summary("softbanParam2")] uint days = 7,
            [Remainder, Summary("softbanParam3")] string reason = null)
        {
            if (user.Id == Context.User.Id)
            {
                await ReplyAsync(Locate("SoftbanSameUser"));

                return(FergunResult.FromSuccess());
            }

            if (await Context.Guild.GetBanAsync(user) != null)
            {
                return(FergunResult.FromError(Locate("AlreadyBanned")));
            }
            if (user is IGuildUser guildUser && Context.Guild.CurrentUser.Hierarchy <= guildUser.GetHierarchy())
            {
                return(FergunResult.FromError(Locate("UserNotLowerHierarchy")));
            }
            if (days > 7)
            {
                return(FergunResult.FromError(string.Format(Locate("MustBeLowerThan"), nameof(days), 7)));
            }

            await Context.Guild.AddBanAsync(user.Id, (int)days, reason);

            await Context.Guild.RemoveBanAsync(user.Id);

            await SendEmbedAsync(string.Format(Locate("Softbanned"), user));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 6
0
        public async Task <RuntimeResult> Play([Remainder, Summary("playParam1")] string query)
        {
            var user = (SocketGuildUser)Context.User;

            var(result, tracks) = await _musicService.PlayAsync(query, Context.Guild, user.VoiceChannel, Context.Channel as ITextChannel);

            if (tracks == null)
            {
                await SendEmbedAsync(result);
            }
            else
            {
                LavaTrack selectedTrack;
                bool      trackSelection = GetGuildConfig()?.TrackSelection ?? Constants.TrackSelectionDefault;
                if (trackSelection)
                {
                    string list  = "";
                    int    count = Math.Min(Constants.MaxTracksToDisplay, tracks.Count);

                    for (int i = 0; i < count; i++)
                    {
                        list += $"{i + 1}. {tracks[i].ToTrackLink()}\n";
                    }

                    var builder = new EmbedBuilder()
                                  .WithAuthor(user)
                                  .WithTitle(Locate("SelectTrack"))
                                  .WithDescription(list)
                                  .WithColor(FergunClient.Config.EmbedColor);

                    await ReplyAsync(embed : builder.Build());

                    var response = await NextMessageAsync(true, true, TimeSpan.FromMinutes(1));

                    if (response == null)
                    {
                        return(FergunResult.FromError($"{Locate("SearchTimeout")} {Locate("SearchCanceled")}"));
                    }
                    if (!int.TryParse(response.Content, out int option))
                    {
                        return(FergunResult.FromError($"{Locate("InvalidOption")} {Locate("SearchCanceled")}"));
                    }
                    if (option < 1 || option > count)
                    {
                        return(FergunResult.FromError($"{Locate("OutOfIndex")} {Locate("SearchCanceled")}"));
                    }
                    selectedTrack = tracks[option - 1];
                }
                else
                {
                    // people don't know how to select a track...
                    selectedTrack = tracks[0];
                }
                var result2 = await _musicService.PlayTrack(Context.Guild, user.VoiceChannel, Context.Channel as ITextChannel, selectedTrack);
                await SendEmbedAsync(result2);
            }
            return(FergunResult.FromSuccess());
        }
Exemplo n.º 7
0
        public async Task <RuntimeResult> Language()
        {
            if (FergunClient.Languages.Count <= 1)
            {
                return(FergunResult.FromError(Locate("NoAvailableLanguages")));
            }

            var guild = GetGuildConfig() ?? new GuildConfig(Context.Guild.Id);

            bool         hasReacted = false;
            IUserMessage message    = null;
            string       languages  = "";
            var          callbacks  = new List <(IEmote, Func <SocketCommandContext, SocketReaction, Task>)>();
            EmbedBuilder builder    = null;
            int          i          = 0;

            foreach (var language in FergunClient.Languages)
            {
                callbacks.Add((new Emoji($"{i + 1}\ufe0f\u20e3"), async(context, reaction) => await HandleLanguageUpdateAsync(language.Key)));
                languages += $"{i + 1}. {Format.Bold(language.Value.EnglishName)} ({language.Value.NativeName})\n";
                i++;
            }

            builder = new EmbedBuilder()
                      .WithTitle(Locate("LanguageSelection"))
                      .WithDescription($"{Locate("LanguagePrompt")}\n\n{languages}")
                      .WithColor(FergunClient.Config.EmbedColor);

            ReactionCallbackData data = new ReactionCallbackData(null, builder.Build(), false, false, TimeSpan.FromMinutes(1),
                                                                 async context => await HandleLanguageUpdateAsync(null)).AddCallbacks(callbacks);

            message = await InlineReactionReplyAsync(data);

            return(FergunResult.FromSuccess());

            async Task HandleLanguageUpdateAsync(string newLanguage)
            {
                if (hasReacted || guild.Language == newLanguage)
                {
                    return;
                }
                hasReacted = true;
                if (newLanguage == null)
                {
                    await message !.ModifyAsync(x => x.Embed = builder.WithDescription($"❌ {Locate("ReactTimeout")}").Build());
                    return;
                }
                guild.Language = newLanguage;
                FergunClient.Database.InsertOrUpdateDocument(Constants.GuildConfigCollection, guild);

                await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Command", $"Language: Updated language to: \"{newLanguage}\" in {Context.Guild.Name}"));

                await message !.ModifyAsync(x => x.Embed = builder.WithTitle(Locate("LanguageSelection")).WithDescription($"✅ {Locate("NewLanguage")}").Build());
            }
        }
Exemplo n.º 8
0
        public async Task <RuntimeResult> Spotify([Remainder, Summary("spotifyParam1")] IUser user = null)
        {
            if (!FergunClient.Config.PresenceIntent)
            {
                return(FergunResult.FromError(Locate("NoPresenceIntent")));
            }

            user ??= Context.User;
            var spotify = user.Activities?.OfType <SpotifyGame>().FirstOrDefault();

            if (spotify == null)
            {
                return(FergunResult.FromError(string.Format(Locate("NoSpotifyStatus"), user)));
            }

            string lyricsUrl = "?";

            if (!string.IsNullOrEmpty(FergunClient.Config.GeniusApiToken))
            {
                try
                {
                    var genius = await _geniusApi.SearchAsync($"{string.Join(", ", spotify.Artists)} - {spotify.TrackTitle}");

                    if (genius.Meta.Status == 200 && genius.Response.Hits.Count > 0)
                    {
                        lyricsUrl = Format.Url(Locate("ClickHere"), genius.Response.Hits[0].Result.Url);
                    }
                }
                catch (HttpRequestException e)
                {
                    await _logService.LogAsync(new LogMessage(LogSeverity.Warning, "Command", "Spotify: Error calling Genius API", e));
                }
            }

            var builder = new EmbedBuilder()
                          .WithAuthor("Spotify", Constants.SpotifyLogoUrl)
                          .WithThumbnailUrl(spotify.AlbumArtUrl)

                          .AddField(Locate("Title"), spotify.TrackTitle, true)
                          .AddField(Locate("Artist"), string.Join(", ", spotify.Artists), true)
                          .AddField("\u200b", "\u200b", true)

                          .AddField(Locate("Album"), spotify.AlbumTitle, true)
                          .AddField(Locate("Duration"), spotify.Duration?.ToShortForm() ?? "?", true)
                          .AddField("\u200b", "\u200b", true)

                          .AddField(Locate("Lyrics"), lyricsUrl, true)
                          .AddField(Locate("TrackUrl"), Format.Url(Locate("ClickHere"), spotify.TrackUrl), true)
                          .WithColor(FergunClient.Config.EmbedColor);

            await ReplyAsync(embed : builder.Build());

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 9
0
        public async Task <RuntimeResult> Invite()
        {
            if (FergunClient.IsDebugMode)
            {
                return(FergunResult.FromError("No"));
            }

            await SendEmbedAsync(Format.Url(Locate("InviteLink"), FergunClient.InviteLink));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 10
0
        public async Task <RuntimeResult> CmdStats()
        {
            var    stats   = DatabaseConfig.CommandStats.OrderByDescending(x => x.Value);
            int    i       = 1;
            string current = "";
            var    pages   = new List <EmbedBuilder>();

            foreach (var pair in stats)
            {
                string command = $"{i}. {Format.Code(pair.Key)}: {pair.Value}\n";
                if (command.Length + current.Length > EmbedFieldBuilder.MaxFieldValueLength / 2)
                {
                    pages.Add(new EmbedBuilder {
                        Description = current
                    });
                    current = command;
                }
                else
                {
                    current += command;
                }
                i++;
            }
            if (!string.IsNullOrEmpty(current))
            {
                pages.Add(new EmbedBuilder {
                    Description = current
                });
            }
            if (pages.Count == 0)
            {
                return(FergunResult.FromError(Locate("AnErrorOccurred")));
            }
            string creationDate = Context.Client.CurrentUser.CreatedAt.ToString("dd'/'MM'/'yyyy", CultureInfo.InvariantCulture);

            var pager = new PaginatedMessage
            {
                Title   = string.Format(Locate("CommandStatsInfo"), creationDate),
                Pages   = pages,
                Color   = new Color(FergunClient.Config.EmbedColor),
                Options = new PaginatorAppearanceOptions
                {
                    FooterFormat = Locate("PaginatorFooter"),
                    Timeout      = TimeSpan.FromMinutes(10)
                }
            };

            await PagedReplyAsync(pager, ReactionList.Default);

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 11
0
        public async Task <RuntimeResult> Code([Remainder, Summary("codeParam1")] string commandName)
        {
            var command = _cmdService.Commands.FirstOrDefault(x => x.Aliases.Any(y => y == commandName.ToLowerInvariant()) && x.Module.Name != Constants.DevelopmentModuleName);

            if (command == null)
            {
                return(FergunResult.FromError(string.Format(Locate("CommandNotFound"), GetPrefix())));
            }

            string link = $"{Constants.GitHubRepository}/raw/master/src/Modules/{command.Module.Name}.cs";
            string code;
            await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Command", $"Code: Downloading code from: {link}"));

            try
            {
                code = await _httpClient.GetStringAsync(new Uri(link));
            }
            catch (HttpRequestException e)
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Warning, "Command", $"Error downloading the code for module: {command.Module.Name}", e));

                return(FergunResult.FromError(e.Message));
            }
            catch (TaskCanceledException e)
            {
                await _logService.LogAsync(new LogMessage(LogSeverity.Warning, "Command", $"Error downloading the code for module: {command.Module.Name}", e));

                return(FergunResult.FromError(Locate("RequestTimedOut")));
            }

            // Not the best way to get the line number of a method, but it just works ¯\_(ツ)_/¯
            bool found = false;
            var  lines = code.Replace("\r", "", StringComparison.OrdinalIgnoreCase).Split('\n');

            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Contains($"[Command(\"{command.Name}\"", StringComparison.OrdinalIgnoreCase))
                {
                    found = true;
                }
                if (found && lines[i].Contains("public async Task", StringComparison.OrdinalIgnoreCase))
                {
                    await ReplyAsync($"{Constants.GitHubRepository}/blob/master/src/Modules/{command.Module.Name}.cs#L{i + 1}");

                    return(FergunResult.FromSuccess());
                }
            }

            return(FergunResult.FromError(Locate("CouldNotFindLine")));
        }
Exemplo n.º 12
0
        public async Task <RuntimeResult> Kick(
            [Summary("kickParam1"), RequireLowerHierarchy("UserNotLowerHierarchy")] IUser user,
            [Remainder, Summary("kickParam2")] string reason = null)
        {
            // IGuildUser parameter is bugged.
            if (!(user is IGuildUser guildUser))
            {
                return(FergunResult.FromError(Locate("UserNotFound")));
            }
            await guildUser.KickAsync(reason);

            await SendEmbedAsync(string.Format(Locate("Kicked"), user.Mention));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 13
0
        public async Task <RuntimeResult> Unban([Summary("unbanParam1")] ulong userId)
        {
            var ban = await Context.Guild.GetBanAsync(userId);

            if (ban == null)
            {
                return(FergunResult.FromError(Locate("UserNotBanned")));
            }

            await Context.Guild.RemoveBanAsync(userId);

            await SendEmbedAsync(string.Format(Locate("Unbanned"), ban.User));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 14
0
        public async Task <RuntimeResult> Reaction([Summary("reactionParam1")] string reaction,
                                                   [Summary("reactionParam2")] ulong?messageId = null)
        {
            IMessage msg;

            if (messageId == null)
            {
                msg = Context.Message;
            }
            else
            {
                msg = await Context.Channel.GetMessageAsync(messageId.Value);

                if (msg == null)
                {
                    return(FergunResult.FromError(Locate("InvalidMessageID")));
                }
            }
            try
            {
                IEmote emote;
                if (reaction.Length > 2)
                {
                    if (!Emote.TryParse(reaction, out Emote tempEmote))
                    {
                        return(FergunResult.FromError(Locate("InvalidReaction")));
                    }
                    emote = tempEmote;
                }
                else
                {
                    emote = new Emoji(reaction);
                }
                await msg.AddReactionAsync(emote);

                return(FergunResult.FromSuccess());
            }
            catch (ArgumentException) // Invalid emote format. (Parameter 'text')
            {
                return(FergunResult.FromError(Locate("InvalidReaction")));
            }
            catch (Discord.Net.HttpException) // The server responded with error 400: BadRequest
            {
                return(FergunResult.FromError(Locate("InvalidReaction")));
            }
        }
Exemplo n.º 15
0
        public async Task <RuntimeResult> Ban([Summary("banParam1"), RequireLowerHierarchy("UserNotLowerHierarchy")] IUser user,
                                              [Remainder, Summary("banParam2")] string reason = null)
        {
            if (user.Id == Context.User.Id)
            {
                await ReplyAsync(Locate("BanSameUser"));

                return(FergunResult.FromSuccess());
            }
            if (await Context.Guild.GetBanAsync(user) != null)
            {
                return(FergunResult.FromError(Locate("AlreadyBanned")));
            }
            if (!(user is IGuildUser))
            {
                return(FergunResult.FromError(Locate("UserNotFound")));
            }

            await Context.Guild.AddBanAsync(user, 0, reason);

            await SendEmbedAsync(string.Format(Locate("Banned"), user.Mention));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 16
0
        public async Task <RuntimeResult> Nick(
            [Summary("nickParam1"), RequireLowerHierarchy("UserNotLowerHierarchy")] IUser user,
            [Remainder, Summary("nickParam2")] string newNick = null)
        {
            // IGuildUser parameter is bugged.
            if (!(user is IGuildUser guildUser))
            {
                return(FergunResult.FromError(Locate("UserNotFound")));
            }
            if (guildUser.Nickname == newNick)
            {
                return(newNick == null
                    ? FergunResult.FromSuccess()
                    : FergunResult.FromError(Locate("CurrentNewNickEqual")));
            }

            await guildUser.ModifyAsync(x => x.Nickname = newNick);

            if (Context.Guild.CurrentUser.GuildPermissions.AddReactions)
            {
                await Context.Message.AddReactionAsync(new Emoji("\u2705"));
            }
            return(FergunResult.FromSuccess());
        }
Exemplo n.º 17
0
        public async Task <RuntimeResult> Clear([Summary("clearParam1")] int count,
                                                [Remainder, Summary("clearParam2")] IUser user = null)
        {
            count = Math.Min(count, DiscordConfig.MaxMessagesPerBatch);
            if (count < 1)
            {
                return(FergunResult.FromError(string.Format(Locate("NumberOutOfIndex"), 1, DiscordConfig.MaxMessagesPerBatch)));
            }

            var messages = await Context.Channel.GetMessagesAsync(Context.Message, Direction.Before, count).FlattenAsync();

            // Get the total message count before being filtered.
            int totalMessages = messages.Count();

            if (totalMessages == 0)
            {
                return(FergunResult.FromError(Locate("NothingToDelete")));
            }

            if (user != null)
            {
                // Get messages by user
                messages = messages.Where(x => x.Author.Id == user.Id);
                if (!messages.Any())
                {
                    return(FergunResult.FromError(string.Format(Locate("ClearNotFound"), user.Mention, count)));
                }
            }

            // Get messages younger than 2 weeks
            messages = messages.Where(x => x.CreatedAt > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(14)));
            if (!messages.Any())
            {
                return(FergunResult.FromError(Locate("MessagesOlderThan2Weeks")));
            }

            try
            {
                await((ITextChannel)Context.Channel).DeleteMessagesAsync(messages.Append(Context.Message));
            }
            catch (HttpException e) when(e.HttpCode == HttpStatusCode.NotFound)
            {
            }

            string message;

            if (user != null)
            {
                message = string.Format(Locate("DeletedMessagesByUser"), messages.Count(), user.Mention);
            }
            else
            {
                message = string.Format(Locate("DeletedMessages"), messages.Count());
            }
            if (totalMessages != messages.Count())
            {
                message += "\n" + string.Format(Locate("SomeMessagesNotDeleted"), totalMessages - messages.Count());
            }

            var builder = new EmbedBuilder
            {
                Description = message,
                Color       = new Color(FergunClient.Config.EmbedColor)
            };

            await ReplyAndDeleteAsync(null, false, builder.Build(), TimeSpan.FromSeconds(5));

            return(FergunResult.FromSuccess());
        }
Exemplo n.º 18
0
        public async Task <RuntimeResult> Lyrics([Remainder, Summary("lyricsParam1")] string query = null)
        {
            if (string.IsNullOrEmpty(FergunClient.Config.GeniusApiToken))
            {
                return(FergunResult.FromError(string.Format(Locate("ValueNotSetInConfig"), nameof(FergunConfig.GeniusApiToken))));
            }

            bool keepHeaders = false;

            if (string.IsNullOrWhiteSpace(query))
            {
                bool hasPlayer = _musicService.LavaNode.TryGetPlayer(Context.Guild, out var player);
                if (hasPlayer && player.PlayerState == PlayerState.Playing)
                {
                    if (player.Track.Title.Contains(player.Track.Author, StringComparison.OrdinalIgnoreCase))
                    {
                        query = player.Track.Title;
                    }
                    else
                    {
                        query = $"{player.Track.Author} - {player.Track.Title}";
                    }
                }
                else
                {
                    var spotify = Context.User.Activities?.OfType <SpotifyGame>().FirstOrDefault();
                    if (spotify == null)
                    {
                        return(FergunResult.FromError(Locate("LyricsQueryNotPassed")));
                    }
                    query = $"{string.Join(", ", spotify.Artists)} - {spotify.TrackTitle}";
                }
            }
            else if (query.EndsWith("-headers", StringComparison.OrdinalIgnoreCase))
            {
                query       = query.Substring(0, query.Length - 8);
                keepHeaders = true;
            }

            query = query.Trim();
            GeniusResponse genius;

            try
            {
                genius = await _geniusApi.SearchAsync(query);
            }
            catch (HttpRequestException e)
            {
                return(FergunResult.FromError(e.Message));
            }
            catch (TaskCanceledException)
            {
                return(FergunResult.FromError(Locate("RequestTimedOut")));
            }
            if (genius.Meta.Status != 200)
            {
                return(FergunResult.FromError(Locate("AnErrorOccurred")));
            }
            if (genius.Response.Hits.Count == 0)
            {
                return(FergunResult.FromError(string.Format(Locate("LyricsNotFound"), Format.Code(query.Replace("`", string.Empty, StringComparison.OrdinalIgnoreCase)))));
            }

            string url    = genius.Response.Hits[0].Result.Url;
            string lyrics = await CommandUtils.ParseGeniusLyricsAsync(url, keepHeaders);

            if (string.IsNullOrWhiteSpace(lyrics))
            {
                return(FergunResult.FromError(string.Format(Locate("ErrorParsingLyrics"), Format.Code(query.Replace("`", string.Empty, StringComparison.OrdinalIgnoreCase)))));
            }

            var    splitLyrics = lyrics.SplitBySeparatorWithLimit('\n', EmbedFieldBuilder.MaxFieldValueLength);
            string links       = $"{Format.Url("Genius", url)} - {Format.Url(Locate("ArtistPage"), genius.Response.Hits[0].Result.PrimaryArtist.Url)}";

            string title = genius.Response.Hits[0].Result.FullTitle;
            var    pager = new PaginatedMessage
            {
                Color  = new Color(FergunClient.Config.EmbedColor),
                Title  = title.Truncate(EmbedBuilder.MaxTitleLength),
                Fields = new List <EmbedFieldBuilder> {
                    new EmbedFieldBuilder {
                        Name = "Links", Value = links
                    }
                },
                Pages = splitLyrics.Select(x => new EmbedBuilder {
                    Description = x.Truncate(EmbedBuilder.MaxDescriptionLength)
                }),
                Options = new PaginatorAppearanceOptions
                {
                    FooterFormat    = $"{Locate("LyricsByGenius")} - {Locate("PaginatorFooter")}",
                    Timeout         = TimeSpan.FromMinutes(10),
                    ActionOnTimeout = ActionOnTimeout.DeleteReactions
                }
            };

            await PagedReplyAsync(pager, ReactionList.Default);

            return(FergunResult.FromSuccess());
        }