public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { Response response = new Response { Embed = EmbedUtility.ToEmbed(Help), Message = Help, ResponseType = ResponseType.Default }; ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string commandDetail = command.CommandDetail; response = waitHandler.CreatePleaseWaitResponse(senderDetail.ServerSettings.Language); Task.Run(async() => { Response asyncResponse = await BuildMemeAsync(senderDetail.ServerSettings.Language, args); if (asyncResponse == null) { string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoImageMessages")}"); asyncResponse = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } await asyncResponder.SendResponseAsync(args, asyncResponse); waitHandler.PopPleaseWaitMessage(); }); return(new[] { response }); }
private async Task <Response> CorrelatePokemonAsync(Languages language, IMessageDetail m) { string[] urls = m.URLs; Response response = null; for (int i = 0; i < urls.Length; i++) { string url = urls[i]; try { // Check if the url is a file if (WebHelper.IsImageUrl(url)) { // It is, download and perform the correlation var tuple = await WebHelper.DownloadFile(url).ConfigureAwait(false); if (tuple.Item2 != null) { response = Response.CreateFromString("URLs not yet supported."); //response = DoCorrelatePokemonAsync(language, tuple.Item2); } else { // We failed, return a response indicating the failure. string err = Emojis.NoEntrySign + " " + tuple.Item1.ReasonPhrase; response = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } break; } } catch (HttpRequestException ex) { errorLogger.LogDebug($"HttpRequestException exception downloading file: {url}. Assuming file too big.", true); errorLogger.LogException(ex, ErrorSeverity.Information); string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(language, "Error_NotAFile")}"); response = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; break; } catch (Exception ex) { errorLogger.LogDebug($"Exception downloading or handling Pokemon file: {url}", true); errorLogger.LogException(ex, ErrorSeverity.Information); // try other urls } } return(response); }
internal Response CreatePleaseWaitResponse(Languages language) { int r = rand.Next(0, 3); string output = Emojis.TimerSymbol + " " + languageHandler.GetPhrase(language, "PleaseWait_" + r); Response pleaseWaitResponse = new Response { Embed = EmbedUtility.ToEmbed(output, Discord.Color.Gold), Message = output, ResponseType = ResponseType.PleaseWaitMessage }; return(pleaseWaitResponse); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { // Responds asynchronously. Task.Run(async() => { JContainer json; string message = null; try { json = (JContainer)await JSONHelper.GetJsonAsync(url); } catch (Exception) { json = null; message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_ServerNotFound")}"); } string file = null; if (json != null) { file = formattedResponseURL.Replace("%file%", json[jsonProperty].ToString()); message = file; } Response asyncResponse = new Response { ResponseType = ResponseType.Default, Embed = (file == null) ? null : EmbedUtility.ToEmbed(imageURL: file), Message = message }; await asyncResponder.SendResponseAsync(args, asyncResponse); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string query = command.CommandDetail; // Responds asynchronously. Task.Run(async() => { JContainer json; string message = null; string weapon = Splatoon.SplatoonDefs.TryFindWeapon(query); if (weapon != null) { try { string buildsQuery = $@"query {{ searchForBuilds(weapon: ""{weapon}"") {{ headgear clothing shoes }} }}"; string builtUrl = $"{url}?query={Uri.EscapeUriString(buildsQuery)}"; json = (JContainer)JsonConvert.DeserializeObject(await RequestsHelper.CurlGetCommand(builtUrl, origin).ConfigureAwait(false)); } catch (Exception ex) { json = null; message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_ServerNotFound")}"); Console.WriteLine(ex); } try { dynamic jsonResult = json["data"]["searchForBuilds"]; int count = 0; foreach (var node in jsonResult) { JArray headgear = node["headgear"]; JArray clothing = node["clothing"]; JArray shoes = node["shoes"]; string[] mains = new string[] { headgear[0].ToString(), clothing[0].ToString(), shoes[0].ToString() }; List <string> subs = new List <string>(); subs.AddRange(headgear.Skip <JToken>(1).Values <string>()); subs.AddRange(clothing.Skip <JToken>(1).Values <string>()); subs.AddRange(shoes.Skip <JToken>(1).Values <string>()); var mainsDict = new Dictionary <string, int>(mains.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()).OrderByDescending(pair => pair.Value)); var subsDict = new Dictionary <string, int>(subs.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()).OrderByDescending(pair => pair.Value)); StringBuilder sb = new StringBuilder(); foreach (var pair in mainsDict) { sb.Append(pair.Value).Append("m"); if (subsDict.ContainsKey(pair.Key)) { sb.Append(pair.Value).Append("s"); subsDict.Remove(pair.Key); } sb.Append(" ").Append(pair.Key).Append(", "); } foreach (var pair in subsDict) { sb.Append(pair.Value).Append("s"); sb.Append(" ").Append(pair.Key).Append(", "); } sb.AppendLine(); message += sb.ToString(); count++; if (count > 6) { break; } } } catch (Exception ex) { message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}"); Console.WriteLine(ex); } } else { message = ($"{Emojis.QuestionSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}"); } Response asyncResponse = new Response { ResponseType = ResponseType.Default, Embed = EmbedUtility.ToEmbed(message, null), Message = message }; await asyncResponder.SendResponseAsync(args, asyncResponse); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CultureInfo cultureInfo = languageHandler.GetCultureInfo(serverSettings.Language); CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); Discord.Color responseColor = Discord.Color.Green; // First, check the cache if we already have this pokémon. string query = command.CommandDetail; if (args.URLs.Length > 0) { var response = new[] { waitHandler.CreatePleaseWaitResponse(senderDetail.ServerSettings.Language) }; Task.Run(async() => { Response asyncResponse = await CorrelatePokemonAsync(senderDetail.ServerSettings.Language, args); if (asyncResponse == null) { string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoImageMessages")}"); asyncResponse = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } await asyncResponder.SendResponseAsync(args, asyncResponse); waitHandler.PopPleaseWaitMessage(); }); return(response); } query = query.Replace("(Pokemon)", "").Replace("(Pokémon)", "").Trim(); query = query.Replace("(move)", "").Trim(); StringBuilder output = new StringBuilder(); Pokemon pokemon = KnowledgeBase.GetPokémon(query); string imageUrl = null; bool isCached = (pokemon != null); try { // For now, assume that it is a Pokémon. string url = "https://bulbapedia.bulbagarden.net/wiki/" + query.Capitalize() + "_(Pokémon)"; string urlRaw = url + "?action=raw"; if (!isCached) { // Assume correct URL pokemon = Pokemon.ParsePage(urlRaw); } if (pokemon != null) { string p = pokemon.Name + "_(Pokémon)"; dynamic imageJson = null; output .Append("https://bulbapedia.bulbagarden.net/wiki/") .Append(p) .AppendLine("#") // # is for mobile where () is not correctly parsed in the URL parser .AppendLine(MakeAPokemonString(pokemon, cultureInfo, serverSettings.Language)); try { cancellationTokenSource.CancelAfter(300000); Task.Run(async() => { imageJson = await JSONHelper.GetJsonAsync(Uri.EscapeUriString("https://bulbapedia.bulbagarden.net/w/api.php?action=query&format=json&prop=pageimages&titles=" + p)).ConfigureAwait(false); }, cancellationTokenSource.Token).Wait(); JToken token = imageJson["query"]["pages"]; token = token.First.First; imageUrl = token["thumbnail"]["source"]?.ToString(); } catch (TaskCanceledException tcex) { errorLogger.LogDebug("Did not query Bulbapedia in time to retrieve the Pokemon image.", true); errorLogger.LogException(tcex, ErrorSeverity.Warning); } catch (Exception ex) { errorLogger.LogDebug($"Exception occurred retrieving the Pokemon image for {pokemon?.Name}.\n" + $"imageUrl: {imageUrl}\n" + $"imageJson: {imageJson}", true); errorLogger.LogException(ex, ErrorSeverity.Error); } } else { output.AppendLine($"{Emojis.ExclamationSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_PokemonNotFound")}: {urlRaw}"); } } catch (WebException) { output.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_PokemonNotFound")}: {query}"); } catch (Exception ex) { output.AppendLine($"{languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}: {ex.Message}"); } return(Response.CreateArrayFromString(output.ToString(), responseColor, pokemon.Name, imageUrl)); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { // Responds asynchronously. Task.Run(async() => { CommandMessageHelper command = new CommandMessageHelper(senderDetail.ServerSettings.CommandSymbol, args.Message); string manualUrl = "http://minecraft.gamepedia.com/index.php?search=" + command.EscapedCommandDetail + "&title=Special%3ASearch&go=Go"; StringBuilder output = new StringBuilder(manualUrl + " \n"); string[] craftingTemplateParams = new string[] { "\n", "|" }; string query = command.EscapedCommandDetail; string json = ""; try { bool redirectResolved = true; // Resolve redirects do { json = await WebHelper.GetTextAsync($"http://minecraft.gamepedia.com/api.php?format=json&action=query&titles={query}&prop=revisions&rvprop=content&callback=?"); if (json.Contains(RedirectString)) { // Resolve redirect TextParser parser = new TextParser(json); parser.MovePast(RedirectString, true); parser.MovePast("[[", true); string article = parser.ExtractUntil("]]", false, true); string newQuery = Uri.EscapeDataString(article); if (query == newQuery) { output.AppendLine(Emojis.ExclamationSymbol + " infinite recursion error on: " + query); redirectResolved = false; break; } else { query = newQuery; } } }while (json.Contains(RedirectString)); if (redirectResolved) { string url = "http://minecraft.gamepedia.com/" + query; // Get the recipe. if (!json.ContainsIgnore(CraftingString, StringComparison.OrdinalIgnoreCase, " ", "\n", "\r")) { string error = Emojis.InfoSymbol + " " + languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_UnknownRecipe"); output.AppendLine(error + " " + command.CommandDetail + ": " + url); } else { // We're in business. TextParser parser = new TextParser(json); parser.MovePast(CraftingString, true); string recipeTemplate = parser.ExtractUntil("}}", false, true).Replace("|head=0", "").Replace("|head=1", "").Replace("|showdescription=0", "").Replace("|showdescription=1", "").Replace("|showname=0", "").Replace("|showname=1", ""); parser = new TextParser(recipeTemplate); parser.MovePast("|", true); // First parameter is template name string[,] recipe = new string[3, 3]; // Initialise all elements with an empty string. for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { recipe[x, y] = ""; } } if (recipeTemplate.Contains("A2") || recipeTemplate.Contains("B2") || recipeTemplate.Contains("C2")) { // Method 1, cells specified string a1Cell = parser.ExtractBetween("A1", craftingTemplateParams, true); recipe[0, 0] = TidyRecipeParameter(a1Cell); string b1Cell = parser.ExtractBetween("B1", craftingTemplateParams, true); recipe[1, 0] = TidyRecipeParameter(b1Cell); string c1Cell = parser.ExtractBetween("C1", craftingTemplateParams, true); recipe[2, 0] = TidyRecipeParameter(c1Cell); string a2Cell = parser.ExtractBetween("A2", craftingTemplateParams, true); recipe[0, 1] = TidyRecipeParameter(a2Cell); string b2Cell = parser.ExtractBetween("B2", craftingTemplateParams, true); recipe[1, 1] = TidyRecipeParameter(b2Cell); string c2Cell = parser.ExtractBetween("C2", craftingTemplateParams, true); recipe[2, 1] = TidyRecipeParameter(c2Cell); string a3Cell = parser.ExtractBetween("A3", craftingTemplateParams, true); recipe[0, 2] = TidyRecipeParameter(a3Cell); string b3Cell = parser.ExtractBetween("B3", craftingTemplateParams, true); recipe[1, 2] = TidyRecipeParameter(b3Cell); string c3Cell = parser.ExtractBetween("C3", craftingTemplateParams, true); recipe[2, 2] = TidyRecipeParameter(c3Cell); } else { // Method 2, all fields present -OR- clockwise layout. List <string> items = new List <string>(); for (int i = 0; i < 9; i++) { string candidateItem = TidyRecipeParameter(parser.ExtractUntil(craftingTemplateParams, false, true)); if (candidateItem.Contains("output", StringComparison.OrdinalIgnoreCase)) { break; } else { items.Add(candidateItem); parser.MovePast("|"); } } // If we have less than 4, then it's constructed in a clockwise fashion. switch (items.Count) { case 0: break; case 1: recipe[0, 1] = items[0]; break; case 2: recipe[0, 1] = items[0]; recipe[1, 1] = items[1]; break; case 3: recipe[0, 1] = items[0]; recipe[1, 1] = items[1]; recipe[1, 2] = items[2]; break; case 4: recipe[0, 1] = items[0]; recipe[1, 1] = items[1]; recipe[1, 2] = items[2]; recipe[0, 2] = items[3]; break; default: { recipe[0, 1] = items[0]; recipe[1, 1] = items[1]; recipe[1, 2] = items[2]; recipe[0, 2] = items[3]; break; } case 9: // Otherwise, all parameters are specified and just go from top left to bottom right. for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { recipe[x, y] = items[(x * 3) + y]; } } break; } } parser.MovePast(OutputNameString, true); string outputName = TidyRecipeParameter(parser.ExtractUntil(craftingTemplateParams, false, true)); if (string.IsNullOrWhiteSpace(outputName)) { string error = Emojis.ExclamationSymbol + " " + languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_UnknownRecipe"); output.AppendLine($"{error}{command.CommandDetail}: " + url); } else { const int pad = 14; output.AppendLine($"```"); // Mono-space engage! output.AppendLine($"|--------------|--------------|--------------|"); output.AppendLine($"|{recipe[0, 0].CentreString(pad)}|{recipe[1, 0].CentreString(pad)}|{recipe[2, 0].CentreString(pad)}|"); output.AppendLine($"|--------------|--------------|--------------|"); output.AppendLine($"|{recipe[0, 1].CentreString(pad)}|{recipe[1, 1].CentreString(pad)}|{recipe[2, 1].CentreString(pad)}|"); output.AppendLine($"|--------------|--------------|--------------|"); output.AppendLine($"|{recipe[0, 2].CentreString(pad)}|{recipe[1, 2].CentreString(pad)}|{recipe[2, 2].CentreString(pad)}|"); output.AppendLine($"|--------------|--------------|--------------|"); output.AppendLine($"```"); output.AppendLine($"{outputName}"); } } } } catch (Exception ex) { string error = Emojis.CrossSymbol + " " + languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops"); output.AppendLine(error + " " + command.CommandDetail); errorLogger.LogDebug("Query: " + query, true); errorLogger.LogDebug("JSON: " + json, true); errorLogger.LogDebug(ex.ToString(), true); } Response asyncResponse = new Response { ResponseType = ResponseType.Default, Embed = EmbedUtility.ToEmbed(output.ToString(), null), Message = output.ToString() }; await asyncResponder.SendResponseAsync(args, asyncResponse); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { Response response = new Response { Message = "https://www.youtube.com", ResponseType = ResponseType.Default }; ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string keywords = command.CommandDetail; if (!string.IsNullOrWhiteSpace(keywords)) { if (keywords.Length > 150) { response.Message = $"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_IncorrectParameter")}: {languageHandler.GetPhrase(serverSettings.Language, "Text")} < 150"; } else { // Already a YouTube URL? Extract the id and prepend it with youtube.com?v= var match = youtubeRegex.Match(keywords); if (match.Length > 1) { response.Message = $"https://www.youtube.com/watch?v={match.Groups["id"].Value}"; } else { response = waitHandler.CreatePleaseWaitResponse(senderDetail.ServerSettings.Language); Task.Run(async() => { string asyncRetVal; string query = $"https://www.googleapis.com/youtube/v3/search?" + $"part=snippet&maxResults=8" + $"&q={Uri.EscapeDataString(keywords)}" + $"&key={Tokens.GoogleAPIKey}"; string json = await GetResponseStringAsync(query); dynamic data = JsonConvert.DeserializeObject(json); if (data.items.Count > 0) { // Attempt to get the first item that is a video. int itemIndex = 0; string videoId; do { videoId = (data.items[itemIndex].id.videoId); itemIndex++; }while (itemIndex < data.items.Count && string.IsNullOrWhiteSpace(videoId)); if (string.IsNullOrWhiteSpace(videoId)) { asyncRetVal = ($"{Emojis.Warning} {languageHandler.GetPhrase(serverSettings.Language, "Error_NoResults")}"); } else { string youTubeURL = ("https://www.youtube.com/watch?v=" + videoId); switch (youTubeCommandType) { case YouTubeCommandType.YouTube: asyncRetVal = youTubeURL; break; case YouTubeCommandType.SaveFrom: asyncRetVal = ("http://en.savefrom.net/#url=" + youTubeURL); break; case YouTubeCommandType.Repeat: asyncRetVal = ("http://www.youtubeonrepeat.com/watch?v=" + videoId); break; default: asyncRetVal = $"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_Oops")}: {youTubeCommandType}"; break; } } } else { asyncRetVal = $"{Emojis.Warning} {languageHandler.GetPhrase(serverSettings.Language, "Error_NoResults")}"; } Response asyncResponse = new Response { Message = asyncRetVal, ResponseType = ResponseType.Default }; await asyncResponder.SendResponseAsync(args, asyncResponse); waitHandler.PopPleaseWaitMessage(); }); } } } response.Embed = EmbedUtility.ToEmbed(response.Message); return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { StringBuilder sb = new StringBuilder(); ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string commandDetail = command.CommandDetail; Discord.Color?embedColour = null; if (string.IsNullOrEmpty(commandDetail)) { sb.AppendLine(Help); } else { // Remove decorators commandDetail = commandDetail.Replace("0x", "").Replace("0b", "").Replace("#", ""); // Replace commas with spaces commandDetail = commandDetail.Replace(",", " ").Trim(); // Special case hex to decimal in cases of 6 or 8 characters. bool is6Chars = commandDetail.Length == 6; bool is8Chars = commandDetail.Length == 8; if (fromBase == 16 && (is6Chars || is8Chars)) { // Try and convert the source hex number into a colour. if (uint.TryParse(commandDetail, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint argb)) { // Remove alpha channel (N.B. this usually makes it transparent as a = 0, but Discord fixes this to fully opaque) argb &= 0x00FFFFFF; embedColour = new Discord.Color(argb); } commandDetail += " "; commandDetail += commandDetail.Substring(0, 2); commandDetail += " "; commandDetail += commandDetail.Substring(2, 2); commandDetail += " "; commandDetail += commandDetail.Substring(4, 2); if (is8Chars) { commandDetail += " "; commandDetail += commandDetail.Substring(6, 2); } } string[] commandParams = commandDetail.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); if (fromBase == 10) { // Try and convert the source decimal number(s) into a colour. if (commandParams.Length == 1) { if (uint.TryParse(commandParams[0], out uint argb)) { // Remove alpha channel (N.B. this usually makes it transparent as a = 0, but Discord fixes this to fully opaque) argb &= 0x00FFFFFF; embedColour = new Discord.Color(argb); } } else if (commandParams.Length == 3 || commandParams.Length == 4) { // Using -n here as alpha could be included at the front. bool canParseColour = (byte.TryParse(commandParams[commandParams.Length - 3], out byte r)); canParseColour &= (byte.TryParse(commandParams[commandParams.Length - 2], out byte g)); canParseColour &= (byte.TryParse(commandParams[commandParams.Length - 1], out byte b)); if (canParseColour) { embedColour = new Discord.Color(r, g, b); } } } foreach (string col in commandParams) { try { switch (fromBase) { case 2: case 8: case 10: case 16: { long part = Convert.ToInt64(col, fromBase); byte[] parts = BitConverter.GetBytes(part); if (toBase == 64) { sb.Append(Convert.ToBase64String(parts) + " "); } else if (toBase == 16) { sb.Append(part.ToString("X2") + " "); } else { sb.Append(Convert.ToString(part, toBase) + " "); } break; } case 64: { byte[] parts = Convert.FromBase64String(col); long part = BitConverter.ToInt64(parts, 0); if (toBase == 64) { sb.Append(Convert.ToBase64String(parts) + " "); } else if (toBase == 16) { sb.Append(part.ToString("X2") + " "); } else { sb.Append(Convert.ToString(part, toBase) + " "); } break; } } } catch (FormatException) { sb.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_IncorrectParameter")}: {col}."); } catch (Exception ex) { sb.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_Oops")}: {col} {ex.Message}"); } } // If multiple things to translate, also provide the answer without spaces. if (command.CommandParams.Length > 2) { string outputWithoutSpace = sb.ToString().Replace(" ", ""); sb.AppendLine(); switch (toBase) { case 2: sb.Append("0b "); break; case 8: sb.Append("0o "); break; case 16: sb.Append("0x "); break; } sb.AppendLine(outputWithoutSpace); } } string output = sb.ToString(); Response response = new Response { Embed = EmbedUtility.ToEmbed(output, embedColour), Message = output, ResponseType = ResponseType.Default }; return(new[] { response }); }