(03-27-2018, 10:22 PM)david_navigator Wrote: I'm reading an IMAP folder using the UIDRetrieveAllEnvelopes method, a week later I want to get all the new emails that have arrived since the last read.
TIdIMAP4 has
SearchMailBox() and
UIDSearchMailBox() methods that you can use for that purpose. The
MsgNo or
UID of the matching emails will be in the
TIdIMAP4.MailBox.SearchResults property. You can then retrieve those emails as needed.
But, for true mailbox synchronization, simply searching for new emails is not enough. You also need to look for deleted/moved emails, too.
(03-27-2018, 10:22 PM)david_navigator Wrote: Currently I'm calling UIDRetrieveAllEnvelopes a second time and then looking at the messages with a greater UID than the max retrieved previously.
That will break if UIDs get regenerated between sessions.
You need to check the
TIdIMAP4.MailBox.UIDValidity property after selecting a mailbox. If the
UIDValidity does not change values between sessions, you know any UIDs you have previously saved for that mailbox are still valid (though the corresponding emails could have been deleted/moved in the meantime, of course). But, if the
UIDValidity does change value, you need to update your saved UIDs.
The
UIDValidity does not change often, but it can change nonetheless, so you should account for it if you save UIDs between sessions.
(03-27-2018, 10:22 PM)david_navigator Wrote: Up to now this has worked OK, but today I came across an IMAP folder with > 100,000 emails in it and so even UIDRetrieveAllEnvelopes take a very long time.
I would imagine so. That is a lot of data for it to download and parse.
(03-27-2018, 10:22 PM)david_navigator Wrote: I feel that there should be a faster way to get all the new emails, but I can't see how - am I missing some methods that might help here.
Yes. With the
SearchMailBox() and
UIDSearchMailBox() methods, you can search by many criteria, including dates and flags (like New, Unseen, etc).
Note: unfortunately, you can't currently search for everything that IMAP allows you to search for. The search methods do not allow for the level of flexibility that the IMAP
SEARCH command supports.
Another option is the
ExamineMailBox() method (which reports the same info as the
SelectMailBox() method, but keeps the mailbox read-only), followed by either:
- a
"FETCH 1:* (UID FLAGS)" command (unfortunately, it cannot be sent with any of the existing retrieval methods, so you have to send it manually), which will report all of the UIDs and Flags in the mailbox.
- a
"UID SEARCH 1:*" command (unfortunately, it cannot be sent with the
UIDSearchMailBox() method, so you have to send it manually), which will report all of the UIDs in the mailbox.
Then you can compare the reported UIDs (and in the case of
FETCH, the flags) to the ones you have previously saved, to know which emails have been added, deleted, moved, altered, etc, and then you can retrieve/update your local copies as needed.
See
RFC 4549: Synchronization Operations for Disconnected IMAP4 Clients for more details about what you should do when synchronizing with an IMAP server between sessions.
(03-28-2018, 03:32 PM)david_navigator Wrote: Seems that simply getting the UID of the last email and counting down seem to do the job
Sure, if:
- you are only interested in looking for new emails that have been added since the last check.
- you don't care about the state of any emails you have previously retrieved.
- the UIDs have not been changed since your last session.
(03-28-2018, 03:32 PM)david_navigator Wrote: though it astounds me that there's nothing like an IMAP query language that's universally supported.
IMAP has a standardized
SEARCH command.