Thumbnail image

Spring Boot: Listening for incoming emails in your application

Tue, Jan 14, 2020 2-minute read

There are several options how to process incoming emails in our applications. We can for example route email into standard mailbox and periodically download emails into our application with POP3 protocol. Or we can run our own SMTP server inside Spring Boot application. And this is the case!

Adding Spring Boot project dependency

I prefer using Gradle for all my Spring Boot projects so adding dependency means adding one line into build.gradle file in my project directory. SubethaSMTP is library that contains embeddable SMTP server implementation, great option for our purpose.

compile ("org.subethamail:subethasmtp:3.1.7")

Starting SMTP server when Spring Boot starts

SMTP is an active service that must be started during Spring Boot application startup. To do so, we can create @Service class, like the one below, with @PostConstruct and @PreDestroy annotated methods. We can also inject properties parameters that will help us to configure service properly. This code is detected during Spring Boot start up process and @PostConstruct method is run for us. We must not to forget to stop SMTP server in @PreDestroy method otherwise the service would occupy the TCP port.

@Service
public class SMTPServerService {
  @Value("${smtpserver.enabled}")
  String enabled="";
  @Value("${smtpserver.hostName}")
  String hostName="";
  @Value("${smtpserver.port}")
  String port="";
  SMTPServer smtpServer;
  public SMTPServerService() {
  }
  @PostConstruct
  public void start() {
    if(enabled.equalsIgnoreCase("true")){
      SimpleMessageListenerImpl l = new SimpleMessageListenerImpl();
      smtpServer = new SMTPServer(new SimpleMessageListenerAdapter(l));
      smtpServer.setHostName(this.hostName);
      smtpServer.setPort(Integer.valueOf(port));
      smtpServer.start();
      System.out.println("****** SMTP Server is running for domain "+smtpServer.getHostName()+" on port "+smtpServer.getPort());
    } else {
      System.out.println("****** SMTP Server NOT ENABLED by settings ");
    }
  }
  @PreDestroy
  public void stop() {
    if(enabled.equalsIgnoreCase("true")){
      System.out.println("****** Stopping SMTP Server for domain "+smtpServer.getHostName()+" on port "+smtpServer.getPort());
      smtpServer.stop();
    }
  }
  public boolean isRunning() {
    return smtpServer.isRunning();
  }
}

Processing incoming emails

While starting SMTP server with code above, we specified ‘SimpleMessageListenerImpl()’ class as SMTP Server parameter. The processing class must implement ‘SimpleMessageListener’ that requires implementation of two methods only. Method accept can check originator / recipient emails and optionally allow or reject email delivery. Method deliver then processes email based on application logic. Everything is quite clear and processing requires minimal of code.

public class SimpleMessageListenerImpl implements SimpleMessageListener {
  public SimpleMessageListenerImpl() {
  }
  @Override
  public boolean accept(String from, String recipient) {
    return true;
  }
  @Override
  public void deliver(String from, String recipient, InputStream data) {
    Session session = Session.getDefaultInstance(new Properties());
    MimeMessage m = new MimeMessage(session,data);
    ReceivedEmail email=new ReceivedEmail(m);
    // ... here we go with email message ...
  }