Getting messages ImapMessageInfo after it has been sent

0 votes
asked Jan 20, 2014 by SeToY (520 points)
edited Jan 20, 2014

Hello,

I'm trying to do the exact same thing as mentioned in the following ticket: http://forum.rebex.net/questions/851/get-message-id-after-storemessage

Unfortunately this does not work when using certain IMAP servers (such as hMailServer) since those return a null Message UniqueId.

Thus, the following code fails:

smtp.Send(mailMessage);
string messageUniqueId = imapClient.StoreMessage("Sent", mailMessage, ImapMessageFlags.Seen);

ImapMessageInfo imapMessageInfo = imapClient.GetMessageInfo(messageUniqueId, ImapListFields.Envelope);
MailMessage mailMessage = imapClient.GetMailMessage(messageUniqueId);

How can I get the messages ImapMessageInfo (so I can save it to a MS SQL database) after it has been sent? I also tried calling the CheckForUpdates() method, but to no avail.

Applies to: Rebex Secure Mail

1 Answer

+1 vote
answered Jan 20, 2014 by Lukas Pokorny (123,810 points)
edited Jan 20, 2014
 
Best answer

The StoreMessage method only returns a value if the IMAP server supports the UIDPLUS extension. Nowadays, most servers do, but still not all of them.

Unfortunately, determining the unique ID for those is not trivial. For applications that actually have control on messages they upload, we have found that searching for message ID works quite well - just make sure that all messages do actually have a unique message ID, preferably by generating it yourself by calling mailMessage.MessageId = new MessageId() before sending the message. Then, if StoreMessage returns null, try locating the message:

        if (messageUniqueId == null)
        {
            imapClient.SelectFolder("Sent");

            // try searching for the message ID (doesn't work on all servers either, unfortunately)
            ImapMessageCollection messageList = imapClient.Search(ImapSearchParameter.Header("Message-Id", mailMessage.MessageId.ToString()));
            if (messageList.Count > 0)
            {
                messageUniqueId = messageList[0].UniqueId;
            }
            else
            {
                // try searching or the message with the specific ID manually
                messageList = imapClient.Search(ImapListFields.UniqueId | ImapListFields.Envelope, ImapSearchParameter.Arrived(DateTime.Now.AddHours(-1), DateTime.MaxValue));
                foreach (var info in messageList)
                {
                    if (info.MessageId != null && info.MessageId.Id == mailMessage.MessageId.Id)
                    {
                        messageUniqueId = info.UniqueId;
                        break;
                    }
                }

                if (messageUniqueId == null)
                    throw new ApplicationException("Unable to find the message.");
            }
        }

This actually tries two approaches - searching for the message ID header should work, but on some server it sadly doesn't. As an alternative, all recently-arrived messages are searched instead.

commented Jan 20, 2014 by SeToY (520 points)
edited Jan 20, 2014

Awesome, that's just what I needed. Thank you!

...