Email delivery in Elastic Path Commerce is triggered by messages sent within the Event Messaging framework. Certain event messages trigger the publishing of a corresponding email message that contains the contents and metadata of the outgoing email. For example, when a new order is created, an ORDER_CREATED event message is published. One of the consumers of this message is the component that generates an order confirmation email.
The following events will trigger the sending of an email:
- A new customer registers an account
- A customer requests a forgotten password
- A Commerce Manager user creates a new Commerce Manager user account
- A Commerce Manager user requests a forgotten password
- A customer or Commerce Manager user resets the customer's password
- A customer places a new order
- A Commerce Manger user completes an order shipment
- A customer sends their wish list to a friend
- A customer purchases a gift certificate (the recipient is notified)
- A CSV Import job completes (the Commerce Manager user is notified)
- A Commerce manager user processes a returned or exchanged item (an RMA email is sent to the customer)
All emails have plain text and HTML versions. Each email event uses a different template and includes event-specific content (such as the order number). Email templates are store-specific, so each store should have a separate set of templates.
Elastic Path Commerce uses Velocity for the email templates. The general administration (non-store) email templates are located in <assets>/cmassets/templates/velocity/email. Store specific email templates are located in <assets>/themes/<theme_name>/default/templates/velocity/email.
The Commerce Engine does not include an SMTP server out of the box.
Emails are sent as multi-part MIME messages. If the email client cannot accept an HTML version, the email will degrade to the text version.
Adding a new Email
You can add new emails by implementing the com.elasticpath.email.producer.spi.AbstractEmailProducer class and injecting your new EmailProducer class into a new EventMessageTriggeredEmailRouteBuilder bean, which in turn is added to an Apache Camel context.
Creating a Camel Context
Apache Camel coordinates and communicates with the various systems involved in event messaging, such as a JMS broker. A Camel context is required to route the incoming event messages to the components that create each individual email message.
When creating a new email handler module, copy the following into a new Spring configuration file and configure accordingly to create the Camel context:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd "> <camel:camelContext id="ep-custom-email-handler" xmlns="http://camel.apache.org/schema/spring"> </camel:camelContext> </beans>
Implementing an EmailProducer
The com.elasticpath.email.producer.api.EmailProducer interface and com.elasticpath.email.producer.spi.AbstractEmailProducer class define methods that take a domain object's GUID and a Map of data, and return com.elasticpath.email.EmailDto instances that represent an email to be sent.
The EmailProducer interface is the primary API class involved in constructing an email. While this interface can be implemented directly, most implementations should extend AbstractEmailProducer instead.
To send a single email, extend the AbstractEmailProducer class and override the createEmail(String, Map) method. To construct multiple emails at the same time, implement the EmailProducer interface and override the createEmails(String, Map) method.
Each implementation is free to determine the manner by which an email is created. The existing Commerce Engine EmailProducer classes utilise Velocity to construct both the plain text and HTML contents of emails. See an existing EmailProducer implementation for more details.
Injecting an EmaiProducer Into a EventMessageTriggeredEmailRouteBuilder
After implementing an EmailProducer, inject it into an EventMessageTriggeredEmailRouteBuilder so that it gets invoked when a particular event message is published.
You can define new Event Messages to trigger your email. Refer to Asynchronous Event Messaging in Elastic Path Commerce Engine for instructions on how to create new Event Types.
To create a new EventMessageTriggeredEmailRouteBuilder, add the following bean definition into your email handler's Spring context and configure accordingly:
<bean id="customEmailHandlingRouteBuilder" parent="abstractEventMessageTriggeredEmailRouteBuilder"> <property name="routeId" value="customEmailHandlingRoute" /> <property name="incomingEndpoint"> <bean class="org.apache.camel.spring.CamelEndpointFactoryBean"> <property name="camelContextId" value="ep-custom-email-handler" /> <property name="uri" value="jms:topic:ep.eventmessagetype"/commerce-legacy/> </bean> </property> <property name="outgoingEndpoint"> <bean class="org.apache.camel.spring.CamelEndpointFactoryBean"> <property name="camelContextId" value="ep-custom-email-handler" /> <property name="uri" value="jms:ep.emails"/commerce-legacy/> </bean> </property> <property name="eventMessagePredicateFilter" ref="customEventTypePredicate"/commerce-legacy/> <property name="emailProducer" ref="customEmailProducer"/commerce-legacy/> </bean>
The required properties of the EventMessageTriggeredEmailRouteBuilder are:
|Property name||Description||Recommended value|
|A unique ID by which your route can be identified.||<Email type>EmailHandlingRoute|
|incomingEndpoint||The endpoint URI from which the event messages should be consumed.||
The channel containing the relevant event messages.
Existing routes defer this definition to a settings framework value - see existing EventMessageTriggeredEmailRouteBuilder bean definitions for an example.
|outgoingEndpoint||The endpoint URI of the email delivery queue. This queue is consumed by the email sending component, which is responsible for sending all email messages via the configured SMTP(S) server.||
The channel containing the relevant event messages. By default, this value is jms:ep.emails.
Existing routes defer this definition to a Settings Framework value - see existing EventMessageTriggeredEmailRouteBuilder bean definitions for an example.
|eventMessagePredicateFilter||An EventMessagePredicate instance that determines whether or not a given event message should trigger an Email to be sent.||A CompatibleEventTypePredicate implementation that accepts the appropriate Event Type.|
|emailProducer||The EmailProducer responsible for creating the email message.||An instance of your newly-created EmailProducer class.|
The parent abstractEventMessageTriggeredEmailRouteBuilder bean defines the following default properties:
|Property name||Description||Default value|
|eventMessageDataFormat||The DataFormat used to unmarshal event messages from a String to an EventMessage instance.||
|emailDataFormat||The DataFormat used to marshal an Email into a String for publishing to the email delivery JMS queue.||emailDataFormat|
|emailEnabledPredicate||A Camel Predicate instance that determines whether or not emails should be sent. We recommend you use the emailEnabledPredicate bean, which returns the value of the COMMERCE/SYSTEM/emailEnabled setting value.||emailEnabledPredicate|
Add the EventMessageTriggeredEmailRouteBuilder to the Camel context configuration to activate it and have it respond to event messages:
<camel:camelContext id="ep-custom-email-handler" xmlns="http://camel.apache.org/schema/spring"> <routeBuilder ref="customEmailHandlingRouteBuilder"/commerce-legacy/> </camel:camelContext>
Sending File Attachments
You can send file attachments with your emails if required. Existing out of the box emails do not implement file attachments.
- addAttachmentUrl(): Adds the URL of a file to attach to a collection of attachment URLs.
- withAttachmentUrls(): Clears the current collection of attachment URLs, and adds the attachment URL(s) to a collection of attachments.
- addAttachment(): Adds a file attachment's binary data to a collection of attachments.
- withAttachments(): Clears the current collection of binary data attachments, and adds the attachment data to a collection of attachments.
LegacyEmailProducer and LegacyEmailComposer
If you are migrating functionality to Elastic Path Commerce 7.1 from an earlier version and need to maintain backwards compatibility, use the com.elasticpath.email.handler.producer.LegacyEmailProducer and com.elasticpath.email.util.LegacyEmailComposer interfaces instead of the default EmailProducer and EmailComposer interfaces. The legacy interfaces produce org.apache.commons.mail.Email instances, and do not support email attachments. The legacy interfaces should use the com.elasticpath.email.handler.LegacyEventMessageTriggeredEmailRouteBuilder route.