IMail |
Task<Stream> GetStreamAsync( UniqueId uid, string section, CancellationToken cancellationToken = default, ITransferProgress progress = null )
Asynchronously gets a substream of the specified message.
For more information about how to construct the section, see Section 6.4.5 of RFC3501.
public static void SaveAttachments (string baseDirectory) { using (var client = new ImapClient ()) { client.Connect ("imap.gmail.com", 993, SecureSocketOptions.SslOnConnect); client.Authenticate ("username", "password"); client.Inbox.Open (FolderAccess.ReadOnly); // search for messages where the Subject header contains either "MimeKit" or "MailKit" var query = SearchQuery.SubjectContains ("MimeKit").Or (SearchQuery.SubjectContains ("MailKit")); var uids = client.Inbox.Search (query); // fetch summary information for the search results (we will want the UID and the BODYSTRUCTURE // of each message so that we can extract the text body and the attachments) var items = client.Inbox.Fetch (uids, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure); foreach (var item in items) { // determine a directory to save stuff in var directory = Path.Combine (baseDirectory, item.UniqueId.ToString ()); // create the directory Directory.CreateDirectory (directory); // now iterate over all of the attachments and decode/save the content to disk foreach (var attachment in item.Attachments) { // default to using the sending client's suggested fileName value string fileName = attachment.FileName; if (string.IsNullOrEmpty (fileName)) { // the FileName wasn't defined, so generate one... if (!MimeTypes.TryGetExtension (attachment.ContentType.MimeType, out string extension)) extension = ".dat"; fileName = Guid.NewGuid ().ToString () + extension; } // we'll need the Content-Transfer-Encoding value so that we can decode it... ContentEncoding encoding; if (string.IsNullOrEmpty (attachment.ContentTransferEncoding) || !MimeUtils.TryParse (attachment.ContentTransferEncoding, out encoding)) encoding = ContentEncoding.Default; // if all we want is the content (rather than the entire MIME part including the headers), then // we want the ".TEXT" section of the part using (var stream = client.Inbox.GetStream (item.UniqueId, attachment.PartSpecifier + ".TEXT")) { // wrap the attachment content in a MimeContent object to help us decode it using (var content = new MimeContent (stream, encoding)) { var path = Path.Combine (directory, fileName); // decode the attachment content to the file stream using (var output = File.Create (path)) content.DecodeTo (output); } } } } client.Disconnect (true); } }