29 Ağustos 2023 Salı

JavaMail IMAP

Örnek
Elimizde bir application.properties dosyası olsun
email.host=imap.example.com
email.port=993
email.protocol=imaps
email.username=your-email@example.com
email.password=your-email-password
Bir Session nesnesi yaratırız
import javax.mail.*;
import java.util.properties;

@Configuration
public class EmailConfiguration {

  @Value("${email.host}")
  private String emailHost;

  @Value("${email.port}")
  private String emailPort;

  @Value("${email.username}")
  private String emailUsername;

  @Value("${email.password}")
  private String emailPassword;

  @Bean
  public Session mailSession() {
    Properties props = new Properties();
    props.setProperty("mail.store.protocol", "imaps");
    props.setProperty("mail.imaps.host", emailHost);
    props.setProperty("mail.imaps.port", emailPort);

    // Create a new session with the properties
    Session session = Session.getInstance(props);
    session.setDebug(true); // Enable debug mode for troubleshooting

    return session;
  }
}
Sonra kendi listener nesnemizi yaratırız
@Configuration
public class EmailConfiguration {
  
  @Bean
  public EmailListener emailListener() {
    return new EmailListener(mailSession(), emailUsername, emailPassword);
  }
}
Listener şöyledir
import javax.mail.*;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;

import com.sun.mail.imap.IMAPFolder;

public class EmailListener extends MessageCountAdapter {
  private Session session;
  private String username;
  private String password;

  public EmailListener(Session session, String username, String password) {
    this.session = session;
    this.username = username;
    this.password = password;
  }
  ...
}
startListening() metodu şöyledir
import com.sun.mail.imap.IMAPFolder;

public class EmailListener extends MessageCountAdapter {
  ...
  public void startListening() throws MessagingException, InterruptedException,
    IOException {
    Store store = session.getStore("imaps");
    store.connect(username, password);

    IMAPFolder inbox = (IMAPFolder)store.getFolder("INBOX");
    inbox.open(Folder.READ_WRITE);

    // Create a new thread to keep the connection alive
    Thread keepAliveThread = new Thread(new KeepAliveRunnable(inbox),
      "IdleConnectionKeepAlive");
    keepAliveThread.start();

    inbox.addMessageCountListener(new MessageCountAdapter() {
      @Override
      public void messagesAdded(MessageCountEvent event) {
        // Process the newly added messages
        Message[] messages = event.getMessages();
        for (Message message : messages) {
          try {
            // Implement your email processing logic here
            System.out.println("New email received: " + message.getSubject());
          } catch (MessagingException e) {
            ...
          }
        }
      }
    });

    // Start the IDLE Loop
    while (!Thread.interrupted()) {
      try {
        System.out.println("Starting IDLE");
        inbox.idle();
      } catch (MessagingException e) {
        ...
        throw new RuntimeException(e);
      }
    }
    // Interrupt and shutdown the keep-alive thread
    if (keepAliveThread.isAlive()) {
      keepAliveThread.interrupt();
    }
  }
}
KeepAliveRunnable şöyledir
import com.sun.mail.imap.IMAPFolder;
import javax.mail.MessagingException;

public class KeepAliveRunnable implements Runnable {
  private static final long KEEP_ALIVE_FREQ = 300000; // 5 minutes
  private IMAPFolder folder;
  public KeepAliveRunnable(IMAPFolder folder) {
    this.folder = folder;
  }

  @Override
  public void run() {
    while (!Thread.interrupted()) {
      try {
        Thread.sleep(KEEP_ALIVE_FREQ);

        // Perform a NOOP to keep the connection alive
        System.out.println("Performing a NOOP to keep the connection alive");
        folder.doCommand(protocol -> {
          protocol.simpleCommand("NOOP", null);
          return null;
        });
      } catch (InterruptedException e) {
        // Ignore, just aborting the thread...
      } catch (MessagingException e) {
        // Shouldn't really happen...
        System.out.println("Unexpected exception");
        e.printStackTrace();
      }
    }
  }
}
Açıklaması şöyle
We need an email server that supports the IMAP IDLE feature. IMAP IDLE allows our application to receive immediate notifications when new messages arrive in the inbox rather than relying on periodic polling.

Some servers have specific setting or timeouts that may terminate the IDLE connection after a certain period of inactivity. e.g. Gmail ~ 10 mins. So KeepAlive mechanism is necessary to receive email indefinitely.


Hiç yorum yok:

Yorum Gönder