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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); } }
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()); }
public async Task <RuntimeResult> Invite() { if (FergunClient.IsDebugMode) { return(FergunResult.FromError("No")); } await SendEmbedAsync(Format.Url(Locate("InviteLink"), FergunClient.InviteLink)); return(FergunResult.FromSuccess()); }
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()); }
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"))); }
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()); }
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()); }
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"))); } }
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()); }
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()); }
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()); }
public async Task <RuntimeResult> Join() { await SendEmbedAsync(await _musicService.JoinAsync(Context.Guild, ((SocketGuildUser)Context.User).VoiceChannel, Context.Channel as ITextChannel)); return(FergunResult.FromSuccess()); }
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()); }
public async Task <RuntimeResult> Privacy() { string listToShow = ""; string[] configList = Locate("PrivacyConfigList").Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None); for (int i = 0; i < configList.Length; i++) { listToShow += $"**{i + 1}.** {configList[i]}\n"; } var userConfig = GuildUtils.UserConfigCache.GetValueOrDefault(Context.User.Id, new UserConfig(Context.User.Id)); string valueList = Locate(userConfig !.IsOptedOutSnipe); IUserMessage message = null; var builder = new EmbedBuilder() .WithTitle(Locate("PrivacyPolicy")) .AddField(Locate("WhatDataWeCollect"), Locate("WhatDataWeCollectList")) .AddField(Locate("WhenWeCollectData"), Locate("WhenWeCollectDataList")) .AddField(Locate("PrivacyConfig"), Locate("PrivacyConfigInfo")) .AddField(Locate("Option"), listToShow, true) .AddField(Locate("Value"), valueList, true) .WithColor(FergunClient.Config.EmbedColor); var data = new ReactionCallbackData(null, builder.Build(), false, false, TimeSpan.FromMinutes(5)) .AddCallBack(new Emoji("1️⃣"), async(_, reaction) => { userConfig.IsOptedOutSnipe = !userConfig.IsOptedOutSnipe; await HandleReactionAsync(reaction); }) .AddCallBack(new Emoji("❌"), async(_, reaction) => { await message.TryDeleteAsync(); }); message = await InlineReactionReplyAsync(data); return(FergunResult.FromSuccess()); async Task HandleReactionAsync(SocketReaction reaction) { FergunClient.Database.InsertOrUpdateDocument(Constants.UserConfigCollection, userConfig); GuildUtils.UserConfigCache[Context.User.Id] = userConfig; valueList = Locate(userConfig.IsOptedOutSnipe); if (reaction.Emote.Name == "1️⃣" && userConfig.IsOptedOutSnipe) { var toPurge = FergunClient.MessageCache.Where(p => p.Value.Author.Id == reaction.UserId).ToList(); var removed = toPurge.Count(p => FergunClient.MessageCache.TryRemove(p.Key, out _)); if (removed > 0) { await _logService.LogAsync(new LogMessage(LogSeverity.Verbose, "Command", $"Privacy: Removed {removed} deleted/edited messages from the cache from user {reaction.UserId}.")); } } builder.Fields[4] = new EmbedFieldBuilder { Name = Locate("Value"), Value = valueList, IsInline = true }; _ = message !.RemoveReactionAsync(reaction.Emote, reaction.UserId); await message.ModifyAsync(x => x.Embed = builder.Build()); } }