Email delivery in the Elastic Path Commerce Engine 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.
Technical details
The Commerce Engine 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 standard JavaMail API is used to send event-based emails via an SMTP server.
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 gracefully degrade to the text version.
How to add a new Email
You can add new emails by implementing the com.elasticpath.email.handler.producer.EmailProducer interface and injecting your new EmailProducer into a new EventMessageTriggeredEmailRouteBuilder bean, which in turn is added to an Apache Camel context.
Camel Context
Apache Camel is the engine that takes care of coordinating and communicating with the 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-3.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>
EmailProducer
The EmailProducer interface defines a method that takes a domain object's GUID and a Map of data, and returns a collection of org.apache.commons.mail.Email instances. Each Email instance returned represents an email to send. It is up to the EmailProducer implementation how an email is created. The existing Commerce Engine EmailProducers utilise Velocity to construct both the plain text and HTML contents of emails. See an existing EmailProducer implementation for more details.
If only one email needs to be sent, consider extending the AbstractEmailProducer which provides a convenience method that wraps a single Email instance in a Collection.
EventMessageTriggeredEmailRouteBuilder
After implementing your new 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 |
---|---|---|
routeId |
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. |
eventMessageDataFormat |
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>