JavaMail читает последние непрочитанные письма с использованием протокола IMAP

У меня есть требование получить непрочитанные письма из Gmail. Я использую Java Mail API. По умолчанию этот API получает сообщения от самых старых до новейших. Но сначала мне нужно получить последние письма. Является ли это возможным? Спасибо заранее.

Ответ 1

Вот пример. Не забудьте добавить javax.mail в свой путь к классам.

import javax.mail.*;
import javax.mail.search.FlagTerm;
import java.util.*;

public class GmailFetch {

  public static void main( String[] args ) throws Exception {

    Session session = Session.getDefaultInstance(new Properties( ));
    Store store = session.getStore("imaps");
    store.connect("imap.googlemail.com", 993, "[email protected]", "password");
    Folder inbox = store.getFolder( "INBOX" );
    inbox.open( Folder.READ_ONLY );

    // Fetch unseen messages from inbox folder
    Message[] messages = inbox.search(
        new FlagTerm(new Flags(Flags.Flag.SEEN), false));

    // Sort messages from recent to oldest
    Arrays.sort( messages, ( m1, m2 ) -> {
      try {
        return m2.getSentDate().compareTo( m1.getSentDate() );
      } catch ( MessagingException e ) {
        throw new RuntimeException( e );
      }
    } );

    for ( Message message : messages ) {
      System.out.println( 
          "sendDate: " + message.getSentDate()
          + " subject:" + message.getSubject() );
    }
  }
}

Ответ 2

JavaMail предоставляет вам массив объектов Message. Сообщения находятся в полученном порядке. Если вы хотите сначала просмотреть самые последние полученные сообщения, пройдите через массив в обратном порядке. Если вы хотите сначала просмотреть последние сообщения отправленные, вам нужно будет отсортировать массив, как описано в другом ответе.

Ответ 3

Убедитесь, что вы используете протокол IMAP, так как он поддерживает маркировку.

Сделайте следующие изменения в вашем коде:

  1. заменить inbox.open( Folder.READ_ONLY ); от inbox.open( Folder.READ_WRITE );
  2. Затем, прочитав сообщение, установите флаг следующим образом:

    message.setFlag(Flags.Flag.SEEN, true);
    

Полный пример:

    import javax.mail.*;
    import javax.mail.search.FlagTerm;
    import java.util.*;

    public class GmailFetch {

      public static void main( String[] args ) throws Exception {

        Session session = Session.getDefaultInstance(new Properties( ));
        Store store = session.getStore("imaps");
        store.connect("imap.googlemail.com", 993, "[email protected]", "password");
        Folder inbox = store.getFolder( "INBOX" );
        inbox.open( Folder.READ_WRITE );

        // Fetch unseen messages from inbox folder
        Message[] messages = inbox.search(
            new FlagTerm(new Flags(Flags.Flag.SEEN), false));

        // Sort messages from recent to oldest
        Arrays.sort( messages, ( m1, m2 ) -> {
          try {
            return m2.getSentDate().compareTo( m1.getSentDate() );
          } catch ( MessagingException e ) {
            throw new RuntimeException( e );
          }
        } );

        for ( Message message : messages ) {
          System.out.println( 
              "sendDate: " + message.getSentDate()
              + " subject:" + message.getSubject() );
              message.setFlag(Flags.Flag.SEEN, true);
        }
      }
    }

Ответ 4

Я думаю, что это может помочь получить доступ к прочитанным/непрочитанным/недавним письмам и изменить ваши переменные в соответствии с вашими потребностями.

// search for all "unseen" messages

Flags seen = new Flags(Flags.Flag.SEEN);// try changing this SEEN to RECENT 

// set it true or false for seen & unseen mail

FlagTerm unseenFlagTerm = new FlagTerm(seen, false)
Message messages[] = inbox.search(unseenFlagTerm);