Some years ago I needed to write a Java application that receives emails and process some business stuff on those. It wasn't an easy task as I didn't find a lot of information. Because of that I decided, one day, I'll write about it and maybe that could helps 🙂.
Code example
This post has a working code example available here.
Context
Why ?
You would ask why do you need that ? I would say :
Business requirements can surprise you every day
Below a small list of some use cases when this incoming emails processing can be helpful.
Testing : Can be good option for integration testing the email capabilities of your services/applications (The old FakeSMTP is a good GUI example)
Analyse received emails and extract some specific information
...
What ?
SubEtha SMTP is low-level API for writing almost any kind of SMTP mail-receiving application.
To avoid you a long history presentation, the most updated version of SubEtha SMTP is a fork by David Moten (many thanks to him for his excellent work and keeping this library updated). We'll use this fork in this post.
I think no need to describe what's Spring Boot in nowadays.
Let's code
Before starting the code, I suggest to see how we can send an email via terminal. We'll need that to send an email to our future emails receiver application.
Send email with cURL
Below an example of sending email to specific mail server with parameters like from, recipient, auth and the content of the email.
SubEtha dependency
Here we add the maven dependency of SubEtha SMTP.
Start the embedded SMTP server
It's very easy to start a simple SMTP server with the library. Just create/build an instance of SMTPServer with the right parameters like port and start this instance.
Now our SMTP server is started but not fully ready to receive emails. We need to implement a MessageListener to extract important data like from and recipient addresses but also the subject and the body of the received email.
For that we can implement the SimpleMessageListenerinterface :
As you can see here, I added a simple business rule inside accept method to handle only emails sent to marketing department.
The accept method is responsible for defining if the received message will be proceeded by this listener or not.
The deliver method is responsible for extracting :
From : The sender address
Recipient : The receiver address
Data : It's an InputStream type from which we can extract content and relevant information related to the received email like : subject, body, CC, attachments and else.
Let's see how we can extract the content of the email :
Convert to MimeMessage
We can retrieve content from multipart content-typed message using MimeMessage instance.
Extract email content
To extract the email content, we'll create an ReceivedEmail model to facilitate the processing.
For the sake of simplicity I used String for recipientAddress, CC and BCC but it's can be a list of addresses (example in the code).
We create dedicated service for email content extraction and the extract method could looks like :
Now we have a full complete email receiver with minimal lines of code.
Secure SMTP Server
Let's go further step to see how we can secure our mail server.
First thing to do is to indicate that the authentication is required and implement basic auth with username and password.
Different implementations of authenticationHandlerFactory can be done, I chose here, again for the sake of simplicity, the EasyAuthenticationHandlerFactory class which needs implementation of the UsernamePasswordValidator interface.
And this how our SMTPServerConfig looks like :
Go deeper
More parameters can be customised to fit your needs and improve your SubEtha server, I list those below and you can try to explore them to improve your mail receiver implementation :
Max connections and connection timeout
TLS support
Messages size
Shutdown of the SMTP server
Testing
Conclusion
I presented how we can, with small lines of code, write an application that can receive emails, handle those and apply some magic to them with SubEtha SMTP and Spring Boot.
If you have any questions or suggestions, please, leave your comments down below.
I believe in knowledge sharing and this is why internet revolute our lives and mindsets thus I try to do my best to participate even with a little bit to this change.