Search code examples
c#.net-coreemail-attachmentsmailkitmimekit

How to move an attachment from one e-mail to another using MailKit/MimeKit?


If we have the UniqueId to the mail we wish to move the attachment to via the usage of an ImapClient, how exactly can we achieve this?

Thank you!


Solution

  • UniqueId? AddAttachmentToMessage (ImapClient client, ImapFolder folder, UniqueId uid, MimeEntity attachment)
    {
        var message = folder.GetMessage (uid);
        var body = message.Body;
        Multipart multipart;
    
        if (message.Body is Multipart && message.Body.ContentType.IsMimeType ("multipart", "mixed")) {
            multipart = (Multipart) message.Body;
        } else {
            multipart = new Multipart ("mixed");
            multipart.Add (message.Body);
            message.Body = multipart;
        }
    
        multipart.Add (attachment);
    
        var newUid = folder.Append (message);
        folder.AddFlags (uid, MessageFlags.Deleted, true);
    
        if (client.Capabilities.HasFlag (ImapCapabilities.UidPlus))
            folder.Expunge (new UniqueId[] { uid });
    
        return newUid;
    }
    

    If the server doesn't support UIDPLUS and you need the newUid value, then you can probably do something like this:

    if (!client.Capabilities.HasFlag (ImapCapabilities.UidPlus)) {
        var initialUids = folder.Search (SearchQuery.All);
        folder.Append (message);
        var updatedUids = folder.Search (SearchQuery.All);
    
        // find the new uids
        var newUids = new UniqueIdSet (SortOrder.Ascending);
        for (int i = updatedUids.Count - 1; i >= 0; i--) {
            if (!initialUids.Contains (updatedUids[i]))
                newUids.Add (updatedUids[i]);
        }
    
        // get envelope info for each of the new messages
        var newItems = folder.Fetch (newUids, MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope);
        foreach (var item in newItems) {
            var msgid = MimeUtils.ParseMessageId (item.Envelope.MessageId);
    
            if (message.MessageId.Equals (msgid))
                return item.UniuqeId;
    
            // Note: if you want to be more pedantic, you can compare the From/To/Cc/ReplyTo and Subject fields as well.
        }
    }