How to download only new letters from imap?

I have an application that is used to archive emails using imap. Also in this application there are many IMAP accounts that need to be archived.

At this point, from time to time, the application connects to imap accounts and downloads only new emails. My problem is that every time it connects to the imap account, it checks all emails from all folders and downloads only emails that are not downloaded yet (I keep the Message-ID for all emails and download only emails with the message identifier is not saved). Therefore, I want to know if there is an alternative for this, because it takes some time to check all letters (for 10-20K it takes 2-5 minutes).

I am using the JavaMail API to connect to imap accounts.

+7
source share
4 answers

javadoc helps:

IMAPFolder provides the following methods:

getMessagesByUID (long start, long end) and

getUID (message message)

Using getUID () you can get the UID of the last message that you already downloaded. With getMessagesByUID, you can determine this last message that you downloaded as the start range, and look with the getUIDNext () method to find the last message that will be the end of the range.

+6
source

Check only the headers, and when you reach the famous (last known), release it:

for example (today I feel good) and that besides the real production code (some parts were cut out, so it cannot be compiled, state.processed is some set more preferable than LinkedHashMap surrogate [keySet ()] (and w / some maximum border boolean removeEldestEntry ())

try { store = mailSession.getStore("imap"); try { store.connect(); Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); int count = folder.getMessageCount(); for(int localProc=0, chunk=49;localProc<10 && count>0; count -=chunk+1){ Message messages[] = folder.getMessages(Math.max(count-chunk, 1), count); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.ENVELOPE); fp.add("Message-ID"); //add more headers, if need be folder.fetch(messages,fp); for (int i=messages.length;--i>=0;) { //can check abort request here Message message = messages[i]; String msgId = getHeader(message,"Message-ID"); if (msgId!=null && !state.processed.add(msgId)){ if (++localProc>=10){ break; } continue; } ///process here, catch exception, etc.. } } folder.close(false); } catch (MessagingException e) { logger.log(Level.SEVERE, "Mail messaging exception", e); } } catch (NoSuchProviderException e) { logger.log(Level.SEVERE, "No mail provider", e); } if(store != null) { try { store.close(); } catch (MessagingException e) {} } 
+3
source

Filter the SEEN flag. This flag is used to search for new messages. One caveat is that if your user uses multiple readers, this may have been seen with a different reader.

+1
source

message-Id, which is part of the header, is always unique, even if you set it manually. I tested it with gamil and racksoace.

0
source

All Articles