public async Task SavelinksAsync([Summary("The message link to quote")] string link, [Summary("The qauntities of link to save")] int quantity) { // Initializes the control boolean bool success = false; // Remove the message base part and splits all the IDs into an array string[] stringIDs = link.Replace(MessageBaseLink, "").Split('/'); // Creates a new array to hold the IDs ulong[] ids = new ulong[3]; // Parses all the IDs from strings to unsigned longs and saves the result into the array, also it stores the successes or failures into the boolean for (int i = 0; i < 3; i++) { success = UInt64.TryParse(stringIDs[i], out ids[i]); } // If the parse fails, delete the original user command message if (!success) { await Context.Message.DeleteAsync(); await Ageha.Log(LogSeverity.Error, "Could not parse some ID"); return; } // Free up memory stringIDs = null; // Tries to get the guild from the ID SocketGuild sourceGuild = Context.Client.GetGuild(ids[0]); // If the guild is null, reply to the user if (sourceGuild == null) { await ReplyAsync("I'm not in the linked server"); return; } // Tries to get the channel from the ID SocketTextChannel sourceChannel = sourceGuild?.GetTextChannel(ids[1]); // If the channel is null, reply to the user if (sourceChannel == null) { await ReplyAsync("I can't view the linked channel"); return; } // Tries to get the message from the ID IMessage linkedMessage = sourceChannel?.GetMessageAsync(ids[2]).Result; // If the message is null, reply to the user if (linkedMessage == null) { await ReplyAsync("The linked message doesn't exist"); return; } // Free up some memory ids = null; // Gets the cached messages var cachedMessages = await sourceChannel.GetMessagesAsync(linkedMessage, Direction.Before, quantity).FlattenAsync(); // Puts the linked message in the list cachedMessages.Append(linkedMessage); // Reverses the list to be in chronological order cachedMessages.Reverse(); // Sends the quantity of found messages in the channel await ReplyAsync($"Found {cachedMessages.Count()} links."); // Creates an empty dictionary and a counter Dictionary <int, string> links = new Dictionary <int, string>(); int counter = 0; // Only proceeds if any messages are found if (cachedMessages != null || cachedMessages.Count() > 0) { // Creates a valid file name to save the links string fileName = $"{MakeValidFileName(sourceGuild.Name)}_{MakeValidFileName(sourceChannel.Name)}_{linkedMessage.Id}.json"; // Iterates over all messages found foreach (IMessage message in cachedMessages) { // Only tries to pick emotes if the message isn't empty if (!String.IsNullOrWhiteSpace(message.Content)) { // Iterates over all tags foreach (ITag tag in message.Tags) { // Only procceeds on emote tags if (tag.Type == TagType.Emoji) { // Adds the emote link and updates the counter links.Add(counter++, Emote.Parse($"<:{(tag.Value as Emote).Name}:{tag.Key.ToString()}>").Url); } } } // Checks to seed if there are any embeds if (message.Embeds.Count > 0) { GetEmbeds(message.Embeds, ref links, ref counter); } // Checks to seed if there are any attachments if (message.Attachments.Count > 0) { GetAttachments(message.Attachments, ref links, ref counter); } } // Writes the json on a file JsonWrapper.WriteJSON <int, string>(fileName, links); // Sends the json back in the channel await Context.Channel.SendFileAsync(fileName, $"Here is the json containing {cachedMessages.Count()} links from before the message : {linkedMessage.GetJumpUrl()}"); // Deletes the original file File.Delete(fileName); } }