Search code examples
c#imap

C#: How to connect to imap server and download attachments from an inbox subfolder


Assume, we have an email inbox sub-folder with hundreds of emails with many image attachments inside of every email in the folder. And we want to download all attachments locally.

How can we do that?


Solution

  • We will use MailKit package. Add this nuget to your project dependencies.

    So, let's connect:

    using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    const int imapPortNumber = 993;
    client.Connect(configuration.ImapServerAddress, imapPortNumber, true, cancellationTokenSource.Token);
    

    And authenticate:

    client.Authenticate(configuration.FullEmailAddress, configuration.ApplicationPassword, cancellationTokenSource.Token);
    

    Some servers require separate application password for extra security, provide it here. Otherwise, provide password for your email account.

    Now get and open inbox subfolder (for this example its name is stored in configuration.InboxSubfolderName)

    // getting inbox folder
    IMailFolder inboxFolder = client.Inbox;
    
    // getting subfolder for Inbox
    IMailFolder inboxSubfolderWithPictures = inboxFolder.GetSubfolder(configuration.InboxSubfolderName);
    
    inboxSubfolderWithPictures.Open(FolderAccess.ReadOnly, cancellationTokenSource.Token);
    

    And let's process every message from the folder:

        for (int i = 0; i < inboxSubfolderWithPictures.Count; i++)
        {
            using MimeMessage message = inboxSubfolderWithPictures.GetMessage(i, cancellationTokenSource.Token);
    
            string messageFolderName = ... // build message folder name as you want
            string messageFolderPath = Path.Combine(configuration.DownloadDestinationFolder, messageFolderName);
    
            // creating directory for a message to store its attachments
            Directory.CreateDirectory(messageFolderPath);
    
            foreach (MimeEntity? emailAttachment in message.Attachments)
            {
                if (emailAttachment.IsAttachment)
                {
                    using MimePart fileAttachment = (MimePart)emailAttachment;
                    string fileName = fileAttachment.FileName;
                    string fullPathToFile = Path.Combine(messageFolderPath, fileName);
                    using FileStream fileStream = File.Create(fullPathToFile);
                    fileAttachment.Content.DecodeTo(fileStream);
                }
            }
        }
    

    And don't forget to disconnect from the server:

    client.Disconnect(true, cancellationTokenSource.Token);