/// <summary>Removes X(count) messages from chat. /// </summary> public async Task CleanMessagesAsync(int count, SocketCommandContext context) { //We only delete 100 messages at a time to prevent bot from getting overloaded if (count <= 100) { /* Saves all messages user specified in a variable, next * those messages are deleted and a message is sent to the textChannel * saying that X messages were deleted <- this message is deleted 2.3s later */ //Save messages to delete in a variable var messagesToDelete = await context.Channel.GetMessagesAsync(count + 1).FlattenAsync(); //Delete messages to delete await context.Guild.GetTextChannel(context.Channel.Id).DeleteMessagesAsync(messagesToDelete, new RequestOptions() { AuditLogReason = "Clean messages command" }); //Send success message that will disappear after 2300 milliseconds _interactivityService.DelayedSendMessageAndDeleteAsync(context.Channel, null, TimeSpan.FromMilliseconds(2300), null, false, CustomFormats.CreateBasicEmbed("Messages deleted", $":white_check_mark: Deleted **{count}** messages.", 0x268618)); } else { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed(context.User.Mention + " You cannot delete more than 100 messages at once")); } }
/// <summary>Shuffles queue and returns an embed. /// </summary> public async Task ShuffleAsync(SocketCommandContext context) { var guild = context.Guild; var shuffleEmoji = new Emoji("🔀"); //Checks if bot is connected to a voice channel if (!_lavaNode.HasPlayer(guild)) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("Could not acquire player.")); return; } //Bot is connected to voice channel, so we get the player associated with the guild var player = _lavaNode.GetPlayer(guild); //Check if the queue is > 1 if (player.Queue.Count <= 1) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("No songs in queue to shuffle!")); return; } //If all conditions check, then shuffle the queue and react to sent message with shuffleEmoji player.Queue.Shuffle(); await context.Message.AddReactionAsync(shuffleEmoji); }
/// <summary> /// Mutes specified user. /// <para>Prevents the user from sending chat messages.</para> /// </summary> public async Task <Embed> MuteAsync(SocketCommandContext context, IGuildUser user, string reason) { //Get Muted role if it exists or create it if it doesn't exist var muteRole = Helper.DoesRoleExist(context.Guild, "Muted") ?? await context.Guild.CreateRoleAsync("Muted", GuildPermissions.None, Color.DarkGrey, false, null); if (user.RoleIds.Any(role => role == muteRole.Id)) { return(CustomFormats.CreateErrorEmbed($"{user} is already muted!")); } //Add muted role to the user await user.AddRoleAsync(muteRole); //Loop through every channel in the guild and deny the user from sending messages foreach (var channel in context.Guild.TextChannels) { await channel.AddPermissionOverwriteAsync(user, new OverwritePermissions(sendMessages : PermValue.Deny)); } var caseId = await GenerateModCaseId(context.Guild.Id); //Create modCase var modCase = new ModCase(context, user, caseId, PunishmentType.Mute, reason); await _botContext.ModCases.AddAsync(modCase); await _botContext.SaveChangesAsync(); await SendModLog(context.Guild, modCase); return(ModerationFormats.CreateModerationEmbed(user, $"{user} muted", $"{user} has been muted for: {reason ?? "_No reason_"}.", Color.DarkGrey)); }
/// <summary>Stops playback, clears queue, makes bot leave channel, and reacts to user message with 'stopEmoji'. /// </summary> public async Task StopAsync(SocketCommandContext context) { var guild = context.Guild; var stopEmoji = new Emoji("🛑"); try { if (!_lavaNode.HasPlayer(guild)) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("Could not acquire player.")); return; } var player = _lavaNode.GetPlayer(guild); //If the player is playing, stop its playback if (player.PlayerState is PlayerState.Playing) { await player.StopAsync(); } //Clears the queue and makes bot leave channel player.Queue.Clear(); await _lavaNode.LeaveAsync(player.VoiceChannel); await context.Message.AddReactionAsync(stopEmoji); } catch (Exception ex) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed(ex.Message)); } }
/// <summary> /// Voice mutes specified user. /// <para>Prevents the user from talking on voice channels.</para> /// </summary> public async Task <Embed> VoiceMuteAsync(SocketCommandContext context, IGuildUser user, string reason) { //If user is already muted, tell the command issuer that the specified user is already muted if (user.IsMuted) { return(CustomFormats.CreateErrorEmbed($"{user} is already voice muted.")); } //If user isn't already muted, then mute him await user.ModifyAsync(x => x.Mute = true, new RequestOptions { AuditLogReason = reason }); var caseId = await GenerateModCaseId(context.Guild.Id); //Create modCase var modCase = new ModCase(context, user, caseId, PunishmentType.VMute, reason); await _botContext.ModCases.AddAsync(modCase); await _botContext.SaveChangesAsync(); await SendModLog(context.Guild, modCase); return(ModerationFormats.CreateModerationEmbed(user, $"{user} voice muted", $"{user} has been voice muted for: {reason ?? "_No reason_"}.", Color.DarkGrey)); }
/// <summary>Makes bot leave voice channel and reacts to user message with 'byeEmoji'. /// </summary> public async Task LeaveAsync(SocketCommandContext context) { var guild = context.Guild; var byeEmoji = new Emoji("👋"); if (!_lavaNode.HasPlayer(guild)) { await context.Message.AddReactionAsync(byeEmoji); return; } try { //Get The Player Via GuildID. var player = _lavaNode.GetPlayer(guild); //if The Player is playing, Stop it. if (player.PlayerState is PlayerState.Playing) { await player.StopAsync(); } //Leave the voice channel. await _lavaNode.LeaveAsync(player.VoiceChannel); await context.Message.AddReactionAsync(byeEmoji); } //Tell the user about the error so they can report it back to us. catch (Exception ex) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed(ex.Message)); } }
/// <summary> Method for deleting the command's invoker private channel. </summary> /// <param name="context"> The command context. </param> public async Task DeleteChannelAsync(SocketCommandContext context) { var privateChat = await _botContext.PrivateChats.AsQueryable().FirstOrDefaultAsync(x => x.UserId == context.User.Id); //Check if the user already has an active voice channel if (privateChat == null) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("You don't have an active channel!")); return; } var channelToDelete = context.Guild.GetVoiceChannel(privateChat.ChannelId); if (channelToDelete != null) { await channelToDelete.DeleteAsync(new RequestOptions { AuditLogReason = "User deleted his private channel" }); } _botContext.PrivateChats.Remove(privateChat); await _botContext.SaveChangesAsync(); await context.Message.AddReactionAsync(new Emoji("👍")); }
/// <summary> Shows hex color. </summary> public static async Task <Embed> GetRgbColorAsync(string hexColor) { if (hexColor.Contains('#')) { hexColor = hexColor.Replace("#", ""); } try { var response = await HttpHelper.HttpClient.GetAsync($"https://some-random-api.ml/canvas/rgb?hex={hexColor}"); var jsonString = await response.Content.ReadAsStringAsync(); var jsonParsed = JObject.Parse(jsonString); var r = (int)jsonParsed["r"]; var g = (int)jsonParsed["g"]; var b = (int)jsonParsed["b"]; var imageUrl = $"https://some-random-api.ml/canvas/colorviewer?hex={hexColor}"; return(CustomFormats.CreateColorEmbed(imageUrl, r, g, b, hexColor)); } catch (Exception) { return(CustomFormats.CreateErrorEmbed("**Color not found!**")); } }
/// <summary>Retrieves a random image from KSoft.Si database according to the specified tag. /// </summary> public static async Task <Embed> GetImageFromTagAsync(string tag) { try { //Create request to specified url var request = new HttpRequestMessage() { RequestUri = new Uri($"https://api.ksoft.si/images/random-image?tag={tag}"), Method = HttpMethod.Get, Headers = { { "Authorization", $"Bearer {Configuration.KSoftApiKey}" } } }; var jsonResponse = await HttpHelper.HttpRequestAndReturnJson(request); //Deserialize json response var image = JsonConvert.DeserializeObject <KSoftImages>(jsonResponse); var embed = new EmbedBuilder() .WithImageUrl(image.Url) .WithColor(Color.DarkBlue) .WithFooter("Powered by KSoft.Si") .Build(); return(embed); } catch (Exception e) { return(CustomFormats.CreateErrorEmbed(e.Message)); } }
/// <summary> /// Unmutes specified user. /// </summary> public static async Task <Embed> UnmuteAsync(SocketCommandContext context, IGuildUser user) { //Get Muted role if it exists var muteRole = Helper.DoesRoleExist(user.Guild, "Muted"); if (muteRole == null) { return(CustomFormats.CreateErrorEmbed("Your server doesn't have a **'Muted'** role!")); } if (user.RoleIds.All(role => role != muteRole.Id)) { return(CustomFormats.CreateErrorEmbed($"{user} is not muted!")); } //Loop through every channel in the guild and remove the permission overwrite foreach (var channel in context.Guild.TextChannels) { await channel.RemovePermissionOverwriteAsync(user); } //Remove muted role from user await user.RemoveRoleAsync(muteRole); return(ModerationFormats.CreateModerationEmbed(user, $"{user} unmuted", $"{user} has been unmuted.", 0x268618)); }
/// <summary> Sends an error message to the channel where the command was issued. </summary> /// <param name="context"> The command context. </param> /// <param name="errorMessage"> The error message to show. </param> /// <param name="deleteDelay"> The delay in milliseconds to delete the message. </param> private void SendErrorMessage(SocketCommandContext context, string errorMessage, double deleteDelay = 4700) { var errorEmbed = CustomFormats.CreateErrorEmbed(errorMessage); _interactivityService.DelayedSendMessageAndDeleteAsync(channel: context.Channel, deleteDelay: TimeSpan.FromMilliseconds(deleteDelay), embed: errorEmbed); }
/// <summary>Method called when OnTrackException event is fired. /// </summary> private static async Task OnTrackException(TrackExceptionEventArgs arg) { var track = arg.Track; //For some reason Lavalink returns error messages with \n, so we remove them var errorMessage = arg.ErrorMessage.Replace("\\n", ""); await arg.Player.TextChannel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed($"**An error occurred**\n Playback failed for {track.Title}\n{errorMessage}")); }
/// <summary> Sends an error message to the channel where the command was issued. </summary> /// <param name="context"> The command context. </param> /// <param name="errorMessage"> The error message to show. </param> private static async Task SendErrorMessage(ICommandContext context, string errorMessage) { var errorEmbed = CustomFormats.CreateErrorEmbed(errorMessage); await context.Channel.SendMessageAsync(embed : errorEmbed); //_interactivityService.DelayedSendMessageAndDeleteAsync(channel: context.Channel, // deleteDelay: TimeSpan.FromMilliseconds(4700), // embed: errorEmbed); }
private async Task RoleOnJoinSetup(SocketCommandContext context) { var tmpMessage = await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Role on Join Setup", "Cobra will automatically give the specified role when someone joins the server.\n" + "Please type the name or ID of the role you want to setup as the role on join.\n" + "Type `reset` to reset the role on join thus disabling this functionality.", Color.Blue)); var nextMessageResult = await _interactivityService.NextMessageAsync(x => x.Author == context.User); if (nextMessageResult.IsSuccess) { var msgContent = nextMessageResult.Value.Content; if (msgContent == "reset") { await ChangeRoleOnJoin(context); await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed("Role on join changed", "Role on join was reset.\nYour server doesn't have a role on join setup right now.", Color.DarkMagenta)); } else { var tr = new ExtendedRoleTypeReader(); var readResult = await tr.ReadAsync(context, msgContent, _serviceProvider); if (!readResult.IsSuccess) { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed("Unable to find role!")); } else { if (readResult.Values.First().Value is IRole role) { await ChangeRoleOnJoin(context, role); await context.Channel.SendMessageAsync( embed : CustomFormats.CreateBasicEmbed("Role on join changed", $"Role on join was set to **{role.Name}**", 0x268618)); } else { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed("Unable to find role!")); } } } await nextMessageResult.Value.DeleteAsync(); await tmpMessage.DeleteAsync(); } }
private async Task WelcomeChannelSetup(SocketCommandContext context) { var tmpMessage = await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Welcome Channel Setup", "Cobra will send messages to this channel when someone joins/leaves the server.\n" + "Please mention the #textChannel you want to setup as the Welcome Channel.\n" + "Type `reset` to reset the Welcome Channel thus disabling this functionality.", Color.Blue)); var nextMessageResult = await _interactivityService.NextMessageAsync(x => x.Author == context.User); if (nextMessageResult.IsSuccess) { var msgContent = nextMessageResult.Value.Content; if (msgContent == "reset") { await ChangeWelcomeChannel(context); await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Welcome channel changed", "Welcome channel was reset.\nYour server doesn't have a welcome channel setup right now.", Color.DarkMagenta)); } else { if (nextMessageResult.Value.MentionedChannels.Any()) { if (nextMessageResult.Value.MentionedChannels.First() is ITextChannel textChannel) { await ChangeWelcomeChannel(context, textChannel); await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Welcome channel changed", $"Welcome channel is now {textChannel.Mention}", 0x268618)); } else { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed("Invalid text channel!")); } } else { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed("No text channels mentioned!")); } } await nextMessageResult.Value.DeleteAsync(); await tmpMessage.DeleteAsync(); } }
/// <summary>Gets currently playing song and returns an embed with it. /// </summary> public async Task <Embed> NowPlayingAsync(IGuild guild) { if (!_lavaNode.HasPlayer(guild)) { return(CustomFormats.CreateErrorEmbed("Could not acquire player.")); } var player = _lavaNode.GetPlayer(guild); return(player?.Track == null ? CustomFormats.CreateErrorEmbed("No music playing.") : await CustomFormats.NowPlayingEmbed(player.Track, true)); }
/// <summary>Voice unmutes specified user. /// </summary> public static async Task <Embed> UnmuteVoiceAsync(IGuildUser user) { //If user isn't muted, tell the command issuer that the specified user isn't muted if (!user.IsMuted) { return(CustomFormats.CreateErrorEmbed($"{user} isn't voice muted.")); } //If user is muted, then unmute him await user.ModifyAsync(x => x.Mute = false); return(ModerationFormats.CreateModerationEmbed(user, $"{user} voice unmuted", $"{user} has been voice unmuted.", Color.DarkGrey)); }
/// <summary>Removes specified track from queue and returns an embed. /// </summary> public Embed RemoveFromQueueAsync(IGuild guild, int index, int indexMax) { if (!_lavaNode.HasPlayer(guild)) { return(CustomFormats.CreateErrorEmbed("Could not acquire player.")); } var player = _lavaNode.GetPlayer(guild); /* We decrement 2 to the index, as queue command shows first song in queue with number 2 * and first item in queue has an index of 0 */ index -= 2; if (player.Queue.ElementAt(index) == null) { return(CustomFormats.CreateErrorEmbed("There is no song in queue with specified index!")); } try { /*By default indexMax = 0, so the user has the option to use the command with only 'index' which in turn removes * only 1 song from the queue. If the users chooses to use indexMax as well, then the bot knows that the user * wants to remove a range of songs instead of only 1 song. */ if (indexMax != 0) { //We decrement 2 to the indexMax, as queue command shows first song in queue with number 2 //and first item in queue has an index of 0 indexMax -= 2; int count = indexMax - index; /*We use count+1 because RemoveRange() also counts the first index, for example: * If user wants to remove tracks number 2 to 5, it would only remove tracks 2, 3 and 4 * because count would be = to 3 */ var tracksToRemove = player.Queue.RemoveRange(index, count + 1); return(CustomFormats.CreateBasicEmbed("", $"Removed {tracksToRemove.Count} songs from queue", Color.Blue)); } var trackToRemove = player.Queue.RemoveAt(index); return(CustomFormats.CreateBasicEmbed("", $"Removed {trackToRemove.Title} from queue", Color.Blue)); } catch (Exception ex) { return(CustomFormats.CreateErrorEmbed(ex.Message)); } }
private async Task PrivateChatSetup(SocketCommandContext context) { var tmpMessage = await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Private Chats Setup", "Paste the ID of the category where you want private chats to be created.\n\n" + "If you don't have that category yet, create one category with the name you like and move it to where you would like the private chats to be created." + "Don't change any channel permissions as Cobra takes care of that\n\n" + "Type `reset` to reset the Private Chat category thus disabling this functionality.", Color.Blue)); var nextMessageResult = await _interactivityService.NextMessageAsync(x => x.Author == context.User); if (nextMessageResult.IsSuccess) { var msgContent = nextMessageResult.Value.Content; if (msgContent == "reset") { await ChangePrivateChat(context); await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Private Chat changed", "Private Chat category was reset.\nYour server doesn't have private chats setup right now.", Color.DarkMagenta)); } else { if (ulong.TryParse(msgContent, out var categoryId)) { var category = context.Guild.GetCategoryChannel(categoryId); await ChangePrivateChat(context, category); await context.Channel.SendMessageAsync(embed : CustomFormats.CreateBasicEmbed( "Private Chat changed", $"Private chats will now appear under the category {category.Name}", 0x268618)); } else { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed("Invalid category id!")); } } await nextMessageResult.Value.DeleteAsync(); await tmpMessage.DeleteAsync(); } }
/// <summary> /// Updates private chat category in database. If no category is specified, the private chat category will be /// reset. /// </summary> /// <param name="context"> The command context. </param> /// <param name="category"> The category to set as the private chat category. </param> public async Task ChangePrivateChat(SocketCommandContext context, SocketCategoryChannel category = null) { var guildSettings = await _botContext.GetGuildSettings(context.Guild.Id); if (category?.Id == guildSettings.PrivChannelsCategory) { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed($"Private chats category is already {category.Name}!")); return; } guildSettings.PrivChannelsCategory = category?.Id ?? 0; await _botContext.SaveChangesAsync(); }
/// <summary> /// Updates role on join in database. If no IRole is specified, the role on join for the specified guild will be /// reset. /// </summary> /// <param name="context"> The command context. </param> /// <param name="role"> The IRole to set as the role on join. </param> public async Task ChangeRoleOnJoin(SocketCommandContext context, IRole role = null) { var guildSettings = await _botContext.GetGuildSettings(context.Guild.Id); if (role?.Id == guildSettings.RoleOnJoin) { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed($"Role on join is already {role.Name}!")); return; } guildSettings.RoleOnJoin = role?.Id ?? 0; await _botContext.SaveChangesAsync(); }
/// <summary> /// Updates moderation channel in database. If no ITextChannel is specified, the moderation channel for the /// specified guild will be reset. /// </summary> /// <param name="context"> The command context. </param> /// <param name="textChannel"> The ITextChannel to set as the moderation channel. </param> public async Task ChangeModerationChannel(SocketCommandContext context, ITextChannel textChannel = null) { var guildSettings = await _botContext.GetGuildSettings(context.Guild.Id); if (textChannel?.Id == guildSettings.ModerationChannel) { await context.Channel.SendMessageAsync( embed : CustomFormats.CreateErrorEmbed($"Moderation channel is already {textChannel.Name}!")); return; } guildSettings.ModerationChannel = textChannel?.Id ?? 0; await _botContext.SaveChangesAsync(); }
/// <summary> Retrieve specified word definition from Oxford Dictionary. </summary> public async Task <Embed> SearchDictionaryAsync(string wordToSearch) { //If we have a response cached, then return that response if (_memoryCache.TryGetValue($"DICTIONARY{wordToSearch}", out Embed savedResponse)) { return(savedResponse); } string jsonResponse; try { //Make request with necessary headers var request = new HttpRequestMessage { RequestUri = new Uri( $"https://od-api.oxforddictionaries.com/api/v2/entries/en-gb/{wordToSearch}?strictMatch=false"), Method = HttpMethod.Get, Headers = { { "app_id", Configuration.DictAppId }, { "app_key", Configuration.DictApiKey } } }; jsonResponse = await HttpHelper.HttpRequestAndReturnJson(request); } catch (Exception e) { var httpException = (HttpRequestException)e; //Error handling return(httpException.StatusCode switch { //If not found HttpStatusCode.NotFound => CustomFormats.CreateErrorEmbed( "**Word not found!** Please try again."), //If bad request HttpStatusCode.BadRequest => CustomFormats.CreateErrorEmbed( "**Not supported!** Please try again."), //Default error message _ => CustomFormats.CreateErrorEmbed($"An error occurred\n{e.Message}") });
/// <summary> /// Retrieves a random post from specified subreddit. /// </summary> public static async Task <Embed> GetRandomPostAsync(string subreddit, string span = "week") { string[] availableSpans = { "hour", "day", "week", "month", "year", "all" }; if (!availableSpans.Contains(span)) { return(CustomFormats.CreateErrorEmbed( $"Invalid span `{span}`. Span can be `hour`, `day`, `week`, `month`, `year` and `all`")); } try { //Create request to specified url var request = new HttpRequestMessage { RequestUri = new Uri($"https://api.ksoft.si/images/rand-reddit/{subreddit}?span={span}&remove_nsfw=true"), Method = HttpMethod.Get, Headers = { { "Authorization", $"Bearer {Configuration.KSoftApiKey}" } } }; var jsonResponse = await HttpHelper.HttpRequestAndReturnJson(request); //Deserialize json response var randomPost = JsonConvert.DeserializeObject <KSoftReddit>(jsonResponse); var embed = new EmbedBuilder() .WithTitle(randomPost.Title) .WithImageUrl(randomPost.ImageUrl) .WithColor(Color.DarkBlue) .WithFooter($"{randomPost.Subreddit} • {randomPost.Author} | Powered by KSoft.Si") .WithUrl(randomPost.Source).Build(); return(embed); } catch (Exception e) { var httpException = (HttpRequestException)e; return(CustomFormats.CreateErrorEmbed(httpException.StatusCode == HttpStatusCode.NotFound ? "**Subreddit not found**" : e.Message)); } }
/// <summary> /// Unbans specified user from the server. /// </summary> public async Task <Embed> UnbanAsync(IUser user, SocketCommandContext context) { await context.Message.DeleteAsync(); var isBanned = await context.Guild.GetBanAsync(user); if (isBanned == null) { return(CustomFormats.CreateErrorEmbed($"{user} is not banned!")); } _banCache.Set(user.Id, new CacheModel(context.Guild.Id, CacheType.UnbanReject), TimeSpan.FromSeconds(5)); await context.Guild.RemoveBanAsync(user); return(CustomFormats.CreateBasicEmbed($"{user} unbanned", $"{user} was unbanned successfully.", 0x268618)); }
/// <summary>Retrieves a random WikiHow post from KSoft.Si database. /// </summary> public static async Task <Embed> GetRandomWikiHowAsync(bool channelIsNsfw) { try { //Create request to specified url var request = new HttpRequestMessage() { RequestUri = new Uri("https://api.ksoft.si/images/random-wikihow"), Method = HttpMethod.Get, Headers = { { "Authorization", $"Bearer {Configuration.KSoftApiKey}" } } }; string httpResponse = await HttpHelper.HttpRequestAndReturnJson(request); var jsonParsed = JObject.Parse(httpResponse); string title = (string)jsonParsed["title"]; string url = (string)jsonParsed["url"]; string articleUrl = (string)jsonParsed["article_url"]; bool nsfw = (bool)jsonParsed["nsfw"]; if (!channelIsNsfw && nsfw) { return(CustomFormats.CreateErrorEmbed("NSFW isn't enabled on this channel!")); } var embed = new EmbedBuilder() .WithTitle(title) .WithImageUrl(url) .WithColor(Color.DarkBlue) .WithFooter("Powered by KSoft.Si") .WithUrl(articleUrl).Build(); return(embed); } catch (Exception e) { return(CustomFormats.CreateErrorEmbed(e.Message)); } }
///// <summary>Plays sound from file on the attachment. ///// <para>It also joins the voice channel if the bot isn't already joined.</para> ///// </summary> //public async Task PlayFileAsync(SocketCommandContext context) //{ //} /// <summary>Skips current track and returns an embed. /// </summary> public async Task SkipTrackAsync(SocketCommandContext context) { var guild = context.Guild; if (!_lavaNode.HasPlayer(guild)) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("Could not acquire player.")); return; } var player = _lavaNode.GetPlayer(guild); //There are no more songs queued, so stop the player if (player.Queue.Count < 1) { //If the player is playing, stop its playback (no need to clear the queue as we already checked if queue < 1) if (player.PlayerState is PlayerState.Playing) { await player.StopAsync(); } await context.Message.AddReactionAsync(new Emoji("🛑")); return; } try { //Skips current song and returns next song in queue await player.SkipAsync(); var okEmoji = new Emoji("👍"); await context.Message.AddReactionAsync(okEmoji); } catch (Exception ex) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed(ex.Message)); } }
/// <summary>Seeks the current track to specified position. /// </summary> public async Task SeekTrackAsync(SocketCommandContext context, string positionToSeek) { var guild = context.Guild; if (!_lavaNode.TryGetPlayer(guild, out var player)) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("Could not acquire player.")); return; } //Check if player is playing if (player.PlayerState is not PlayerState.Playing) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("No music playing!")); return; } var currentTrack = player.Track; if (!TimeSpan.TryParse(positionToSeek, out var positionToSeekParsed)) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("**Invalid position to seek**")); return; } //If user wants to seek to a position greater than the track duration, warn him if (positionToSeekParsed > currentTrack.Duration) { await context.Channel.SendMessageAsync(embed : CustomFormats.CreateErrorEmbed("Position to seek cannot be greater than track duration!")); return; } //If all checks pass, then seek the current track to specified position await player.SeekAsync(positionToSeekParsed); await context.Message.AddReactionAsync(new Emoji("👍")); }
/// <summary>Retrieves a random meme from KSoft.Si database. /// </summary> public static async Task <Embed> GetRandomMemeAsync(bool channelIsNsfw) { //Create request to specified url var request = new HttpRequestMessage() { RequestUri = new Uri("https://api.ksoft.si/images/random-meme"), Method = HttpMethod.Get, Headers = { { "Authorization", $"Bearer {Configuration.KSoftApiKey}" } } }; try { string jsonResponse = await HttpHelper.HttpRequestAndReturnJson(request); //Deserialize json response var meme = JsonConvert.DeserializeObject <KSoftReddit>(jsonResponse); if (!channelIsNsfw && meme.Nsfw) { return(CustomFormats.CreateErrorEmbed("NSFW isn't enabled on this channel!")); } var embed = new EmbedBuilder() .WithTitle($"{meme.Title}") .WithImageUrl(meme.ImageUrl) .WithColor(Color.DarkBlue) .WithFooter($"{meme.Subreddit} • {meme.Author} | Powered by KSoft.Si") .WithUrl(meme.Source).Build(); return(embed); } catch (Exception e) { return(CustomFormats.CreateErrorEmbed(e.Message)); } }
/// <summary> Shows hex color. </summary> public static async Task <Embed> GetHexColorAsync(int r, int g, int b) { try { var response = await HttpHelper.HttpClient.GetAsync($"https://some-random-api.ml/canvas/hex?rgb={r},{g},{b}"); var jsonString = await response.Content.ReadAsStringAsync(); var jsonParsed = JObject.Parse(jsonString); var hex = (string)jsonParsed["hex"]; hex = hex?.Replace("#", ""); var imageUrl = $"https://some-random-api.ml/canvas/colorviewer?hex={hex}"; return(CustomFormats.CreateColorEmbed(imageUrl, r, g, b, hex)); } catch (Exception) { return(CustomFormats.CreateErrorEmbed("**Color not found!**")); } }