I’m working writing a script to migrate emails from one account to another. I’m having two issues.
-
The messages are moving over, but the mail client is showing their
received date as the date/time it was moved (in the list of messages
view), not the date/time that’s showing in the message header. I’m
guessing a file date isn’t being retained? -
The message flags aren’t being copied over. Such as the message
being read already. I’d like to see all of the flags being passed…basically I need to move the message as it exists on the previous account.protected void CopyBtn_Click(object sender, EventArgs e) { try { ImapClient Client = new ImapClient(); ImapClient Client2 = new ImapClient(); Client.Connect(SourceHostBox.Text.Trim(), 993, SecureSocketOptions.SslOnConnect); Client.Authenticate(SourceUsernameBox.Text.Trim(), SourcePasswordBox.Text.Trim()); Client.Inbox.Open(FolderAccess.ReadWrite); Client2.Connect(DestinationHostBox.Text.Trim(), 993, SecureSocketOptions.SslOnConnect); Client2.Authenticate(DestinationUsernameBox.Text.Trim(), DestinationPasswordBox.Text.Trim()); Client2.Inbox.Open(FolderAccess.ReadWrite); var folders = Client.GetFolders(Client.PersonalNamespaces[0]); //move all messages in folders & create folders if necessary foreach (var folder in folders) { folder.Open(FolderAccess.ReadWrite); var uids = folder.Search(SearchQuery.All); foreach (var uid in uids) { var folders2 = Client2.GetFolders(Client2.PersonalNamespaces[0]); var message = folder.GetMessage(uid); string currentFolder = folder.ToString().Replace("INBOX.", ""); //Remove the 'INBOX.' text that's getting prepended by cPanel/Dovecot var toplevel = Client2.GetFolder(Client2.PersonalNamespaces[0]); var folderExists = FindFolder(toplevel, currentFolder); if (folderExists == null) toplevel.Create(currentFolder, true); Client2.GetFolder(currentFolder).Append(message); } } //move inbox messages Client.Inbox.Open(FolderAccess.ReadWrite); Client2.Inbox.Open(FolderAccess.ReadWrite); var inboxuids = Client.Inbox.Search(SearchQuery.All); foreach (var uid in inboxuids) { var message = Client.Inbox.GetMessage(uid); Client2.Inbox.Append(message); } label1.Text = "Finished Successfully."; label1.ForeColor = System.Drawing.Color.Green; } catch (Exception ex) { label1.Text = ex.Message; label1.ForeColor = System.Drawing.Color.Red; } }
2
Answers
You need to use one of the other
Append()
methods that takes aMessageFlags
argument and aDateTimeOffset
argument to specify the timestamp for when the message arrived.But in order to get that information, you will also need to
Fetch()
that metadata for each of the messages.Here’s how I would change your loop:
Fixed:
Like the OP, I am having the same issue. I used the solution provided by @jstedfast but the destination account still shows the copied email having the date and time of the copy and not the original date and time. Below is my code. Any suggestions would be greatly appreciated!
Edit (12/21/2021):
I figured out the cause of this issue! I had initially tried copying over a bunch of emails without using the flags that retains the date and time. I didn’t know that would be required. So I then implemented the changes necessary to use those flags and before running the program again, I deleted all of the original emails that I had copied over from the previous version of my program, but I never emptied the trash in gmail. So although I was copying over the messages again, it must have just used the original copied messages and just removed the deleted flag. Once I emptied the gmail trash and ran my program again, the emails copied over correctly while retaining the original received date.