Search code examples
javaemailjakarta-mail

Javamail IMAP retrieve latest emails within specific datetime


I'm confuse for javamail usage. I need to download latest emails from time to time from mail server, but javamail seem cannot query specific messages within hour, minute and second, only day is available?

(1) should I scan through all return emails for additional check is within time interval? Or I done something wrong?

(2) Should I assume email in ascending order by receivedDate and safely ignore top portion of emails (Assume previous already retrieved)

(3) Any recommend scan interval? What if compare to mail client?

private void retrieveEmailsWithinDateInterval() throws ParseException, MessagingException{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Calendar c = Calendar.getInstance();
    c.setTime(new Date());
    c.add(Calendar.DATE, 1);

    //Retrieval of email setting
    Date previousDate = sdf.parse("2018-02-13");
    Date tmrDate = new Date(c.getTimeInMillis());
    String imapHost = "***";
    int port = 587;
    String urlNameStr = "***";
    String emailAddr = "***";
    String emailPass = "***";
    String inboxFolderName = "***";

    Properties props           = System.getProperties();

    props.setProperty("mail.imap.host", imapHost);
    props.setProperty("mail.imap.port", Integer.toString(port));
    props.setProperty("mail.store.protocol", "imap");

    Session session = Session.getDefaultInstance(props, null);
    URLName urlName = new URLName(urlNameStr);
    Store   store   = session.getStore(urlName);

    store.connect(imapHost, emailAddr, emailPass);

    ReceivedDateTerm       minDateTerm = new ReceivedDateTerm(ComparisonTerm.GT, previousDate);
    ReceivedDateTerm       maxDateTerm = new ReceivedDateTerm(ComparisonTerm.LT, tmrDate);
    SearchTerm searchTerm = new AndTerm(minDateTerm, maxDateTerm); 

    IMAPFolder inboxFolder = (IMAPFolder) store.getFolder(inboxFolderName);

    if(!inboxFolder.isOpen())
        inboxFolder.open(Folder.READ_ONLY);

    Message[] messagesInbox = inboxFolder.search(searchTerm);

    for (Message msg : messagesInbox){
        //(1) Should I extra check or alternative solution? 
        //Seem it compare date only and ignore hour, minute and second.
        if (msg.getReceivedDate().getTime() <= previousDate.getTime())
            continue;
        //(2) Should I scan through email messages? 
        //Or will all mail server sort in receivedDate, that I can safely ignore top messages or bottom messages?

        processEmailWithinDatetimeInterval(msg);
    }

    if ((inboxFolder != null) && inboxFolder.isOpen()) {
        inboxFolder.close(true);
    }
    if (store != null) {
        store.close();
    }
}

Solution

  • It's a limitation of the IMAP protocol that you can only search by day, not time.

    If you're just trying to find the most recent messages in your INBOX that you haven't previously seen, you can keep track of the UID of the last message you've seen and then ask for messages with larger UIDs, e.g.,

    Message[] newMessages = ((UIDFolder)folder).getMessagesByUID(lastSeen + 1, UIDFolder.MAXUID);