Alert about bounced emails using Spring Boot

1.5k Views Asked by At

I have a Spring Boot application that sends emails. For any action that requires notification, a Mail instance is created with status PENDING in the database and a job is run to send the pending emails every minute. The status of the Mail instances are set as PENDING, SENT or FAILED.

try {
    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", host);
    props.put("mail.smtp.port", port);
    props.put("mail.smtp.from", myEmailAddress);
    props.put("mail.smtp.timeout", 2000);

    Session session = Session.getInstance(props, new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    });

    MimeMessage message = new MimeMessage(session);
    MimeMultipart content = getContent(mail, message, username);
    message.setContent(content);
    Transport.send(message);
    mail.setStatus(MailStatus.SENT);
    mailService.save(mail);
} catch (MailConnectException mce) {
    mail.setStatus(MailStatus.FAILED);
    mailService.save(mail);
} catch (Exception e) {
    // other actions
}

Now, this works fine if a valid email id is provided. But when the receiving email address is a non-existent one like [email protected], there are no exceptions thrown. From what I read from similar questions in SO and elsewhere, I understand that mail sending is an asynchronous process and hence there is no way to determine that a given email is existing or not (or other issues like Inbox full). That is why after the Transport.send(message); statement, the mail.setStatus(MailStatus.SENT); statement will always be executed irrespective of the email address being present. Later the mail will actually be attempted to be sent and I get an email in myEmailAddress with content like the following:

The response from the remote server was: 550 5.1.1 [email protected] User unknown

Okay, accepted until this point. But now I need a way to alert the user that the email couldn't be sent because they entered an invalid email so that they can update their email. More specifically, I need to set the status of the Mail instance to FAILED. What is the best way to achieve this?

2

There are 2 best solutions below

0
Benjamin Vogler On

If you use a service like AWS SES to send your mail, you can receive notifications about bounces (and complaints) either simply as notifications for a human to read, or as programmatic triggers that could be used to call an alert endpoint on your spring boot server, for example through AWS Lambda. There are other services that may be able to do the same, such as SendGrid.

0
nic On

Your Spring Boot application would have to retrieve the notifications (an email itself) from your inbox corresponding to the sender address of the initial email. There are various options how to achieve this:

  • Use a service with provides callbacks (triggers) for incoming messages as mentioned by Benjamin
  • Poll your inbox using a standard protocol like POP or IMAP

Hint for the second option: https://docs.spring.io/spring-integration/reference/html/mail.html#mail-inbound