How to send custom emails in AEM (Part 2) – Multiple Providers

email blocks on gray surface
Photo by Miguel Á. Padriñán on Pexels.com

This is a continuation from my previous post How to send custom emails in AEM.

AEM out of the box only allows you to configure one email service, but in some situations you might need to send emails from different mail providers. For instance, if you need to send from different organisation domains. To do this, we will create a factory OSGI service that allows you add multiple OSGI configurations for each email provider.

Service

import org.apache.commons.mail.DefaultAuthenticator;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.List;
import java.util.Properties;

@Component(immediate = true, service = CustomEmailService.class)
@Designate(ocd = CustomEmailService.Config.class, factory = true)
public class CustomEmailService {
  private Session session;

  @Activate
  protected void activate(final Config config) {
    Properties prop = new Properties();
    prop.put("mail.smtp.auth", true);
    prop.put("mail.smtp.starttls.enable", "true");
    prop.put("mail.smtp.host", config.host());
    prop.put("mail.smtp.port", config.port());
    prop.put("mail.smtp.ssl.trust", config.host());
    session =
        Session.getDefaultInstance(
            prop, new DefaultAuthenticator(config.username(), config.password()));
  }

  public void sendEmail(String from, List<String> to, String subject, String msg)
      throws MessagingException {
    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress(from));
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(String.join(",", to)));
    message.setSubject(subject);

    MimeBodyPart mimeBodyPart = new MimeBodyPart();
    mimeBodyPart.setContent(msg, "text/html; charset=utf-8");

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(mimeBodyPart);

    message.setContent(multipart);

    Transport.send(message);
  }

  @ObjectClassDefinition(name = "Custom Email Service Config")
  @interface Config {

    @AttributeDefinition(name = "Host", type = AttributeType.STRING)
    String host();

    @AttributeDefinition(name = "Port", type = AttributeType.STRING)
    int port() default 25;

    @AttributeDefinition(name = "Username", type = AttributeType.STRING)
    String username();

    @AttributeDefinition(name = "Password", type = AttributeType.PASSWORD)
    String password();
  }
}

Configuration

Then add a configuration for your email service with file name com.example.email.CustomEmailService-provider1.xml to your config folder

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="sling:OsgiConfig"
        debug.email="{Boolean}false"
        from.address="[email protected]"
        smtp.host="my.smtp.host"
        smtp.password="password"
        smtp.port="465"
        smtp.ssl="{Boolean}true"
        smtp.user="user"/>

Reference

And finally, whenever you want to send an email, add a reference in your code to the service, ensuring to target the provider you need to use:

@Reference(target = "(service.pid=com.example.email.CustomEmailService~provider1)")
private CustomEmailService emailService;

Get in touch on LinkedIn or leave comments for any questions or suggestions.

One comment

Leave a Reply