Sending Emails in SAP Hybris

Hybris featured image

1. Overview

In this article, I will show how to create, configure and send emails in SAP Hybris.

An email in Hybris consists of at least 3 different components :

  • Email Template and Email Page.
  • Email Process.
  • Email Context.

In order to explore all of them we are going to create a simple example, a Hello World Email.

This is a simplified version of how we are going to setup our Hello World Email.

Email process overview in hybris

2. Implementation

2.1. Business Process

1. Create an Item type that extends StoreFrontCustomerProcess or StoreFrontProcess, call it HelloWorldEmailProcess.

<itemtype code="HelloWorldEmailProcess" extends="StoreFrontCustomerProcess" 
	jaloclass="com.stackextend.training.core.jalo.process.HelloWorldEmailProcess">

	<attributes>

		<attribute qualifier="firstName" type="java.lang.String">
			<persistence type="property" />
		</attribute>
		
	</attributes>

</itemtype>

2. Create a new xml file, call it helloWorldEmailProcess.xml, it’s  where we are going to define the steps to be executed by the Process Engine.

<!-- .../trainingcore/processes/helloWorldEmailProcess.xml -->

<?xml version="1.0" encoding="utf-8"?>
<process xmlns="http://www.hybris.de/xsd/processdefinition" 
	start="generateHelloWorldEmail" 
	name="helloWorldEmailProcess"
	processClass="com.stackextend.core.model.process.HelloWorldEmailProcessModel" 
	onError="error">

	<action id="generateHelloWorldEmail" bean="generateHelloWorldEmail">
		<transition name="OK" to="sendEmail"/>
		<transition name="NOK" to="error"/>
	</action>

	<action id="sendEmail" bean="sendEmail">
		<transition name="OK" to="removeSentEmail"/>
		<transition name="NOK" to="failed"/>
	</action>

	<action id="removeSentEmail" bean="removeSentEmail">
		<transition name="OK" to="success"/>
		<transition name="NOK" to="error"/>
	</action>
	
	<end id="error" state="ERROR">Something went wrong.</end>
	<end id="failed" state="FAILED">Could not send HelloWorld email.</end>
	<end id="success" state="SUCCEEDED">Sent HelloWorld email.</end>

</process>

3. Register the generateHelloWorldEmail as a bean in Spring :

<bean id="generateHelloWorldEmail" parent="abstractGenerateEmailAction">
	<property name="frontendTemplateName" value="HelloWorldEmailTemplate"/>
</bean>

Note that sendEmail and removeSentEmail beans are already registered in Spring.

4. Register your process as a ProcessDefinitionResource into Spring, to be recognized by Hybris Process Engine.

<bean id="helloWorldEmailProcessDefinitionResource" 
	class="de.hybris.platform.processengine.definition.ProcessDefinitionResource" >
	
	<property name="resource" value="classpath:/traingingcore/processes/helloWorldEmailProcess.xml"/>
	
</bean>

5. Create a new Java class that extends CustomerEmailContext or AbstractEmailContext, call it HelloWorldEmailContext.

An EmailContext is the one that holds the data to be passed to the email template, in our case we will passe to the template a single attribute called firstName.

public class HelloWorldEmailContext extends CustomerEmailContext
{
	private String firstName;

	@Override
	public void init(final StoreFrontCustomerProcessModel processModel, final EmailPageModel emailPageModel)
	{
		super.init(processModel, emailPageModel);
		if (processModel instanceof HelloWorldEmailProcessModel)
		{
			setFirstName(((HelloWorldEmailProcessModel) processModel).getFirstName());
		}
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
}

6. Register the HelloWorldEmailContext as a bean in Spring.

<bean id="helloWorldEmailContext" 
	class="com.stackextend.training.facades.process.email.context.HelloWorldEmailContext" 
	parent="customerEmailContext" 
	scope="prototype" >
	
</bean>

2.2. Email Template

The concept of Emails Template in Hybris is similar to Pages Template of the WCMS module, refer to this article for more details.

1. Create 2 Velocity templates, one for the email Subject and the other for the Body.

<%-- .../trainingcore/import/emails/email-helloworld-subject.vm --%>

${ctx.messages.emailSubject}

<%-- .../trainingcore/import/emails/email-helloworld-body.vm --%>

<html>
    <head>
    </head>

    <body bgcolor="#ffffff">

        <h1>Hello ${ctx.firstName}</h1>

        <p>This is a Hello World Email from Hybris</p>

    </body>
</html>

2. The following impex allows you to create RendererTemplates for the Subject and the Body, and attach them to an EmailPageTemplate.

# Content Catalog Version
$contentCV=...

# Path to the Velocity Templates
$emailResource=...

# Package of the Context class
$emailPackageName=...

# Create Template Renderers
INSERT_UPDATE RendererTemplate	;code[unique=true]			;contextClass								;templateScript[lang=en,translator=de.hybris.platform.commerceservices.impex.impl.FileLoaderValueTranslator];rendererType(code)[default='velocity']
								;email-helloworld-body		;$emailPackageName.HelloWorldEmailContext	;$emailResource/email-helloworld-body.vm
								;email-helloworld-subject	;$emailPackageName.HelloWorldEmailContext	;$emailResource/email-helloworld-subject.vm

# Create Email page Template
INSERT_UPDATE EmailPageTemplate	;$contentCV[unique=true];uid[unique=true]		;active	;frontendTemplateName	;subject(code)							;htmlTemplate(code)		;restrictedPageTypes(code)
								;						;HelloWorldEmailTemplate;true	;helloWorldEmail		;email-helloworld-subject				;email-helloworld-body	;EmailPage
			
# Create Email Page			
INSERT_UPDATE EmailPage	;$contentCV[unique=true];uid[unique=true]	;masterTemplate(uid,$contentCV);approvalStatus(code)[default='approved']
						;						;HelloWorldEmail	;HelloWorldEmailTemplate;

2.3. Email Config

Before sending the email make sure to add these properties to your local.properties.

emailservice.send.enabled = true
mail.from = xxx@gmail.com
mail.replyto = xxx@gmail.com
mail.smtp.server = smtp.gmail.com
mail.smtp.port = 465
mail.smtp.user = xxx@gmail.com
mail.smtp.password = password

2.4. Sending Email

Sending a Hello World Email means starting a new instance of the Hello World Process.

// Create a new instance of the process
HelloWorldProcessModel helloWorldProcessModel = (HelloWorldProcessModel) getBusinessProcessService()
	.createProcess("helloWorld-" + System.currentTimeMillis(), "helloWorldEmailProcess");
	
// Fill the process with the appropriate data	
helloWorldProcessModel.setSite(...);
helloWorldProcessModel.setCustomer(...);
helloWorldProcessModel.setLanguage(...);
helloWorldProcessModel.setCurrency(...);
helloWorldProcessModel.setStore(...);

helloWorldProcessModel.setFirstName("Mouad");

// Save the process
getModelService().save(helloWorldProcessModel);

// Then start the process = send the Email
getBusinessProcessService().startProcess(helloWorldProcessModel);

The code snippet above requires modelService and emailService to be injected (Autowired).

3. Conclusion

Creating emails in Hybris is quite tricky because you have to go for a bunch of components, however this separation of responsibilities (process, context, template,…) comes with many more benefits especially for debugging and maintaining.

 

30
Leave a Reply

avatar
11 Comment threads
19 Thread replies
8 Followers
 
Most reacted comment
Hottest comment thread
13 Comment authors
YeshwantNishaNaviRaghuupendar vandanapu Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
Himanshu
Guest
Himanshu

Hi,

In the above explanation, Sending email code should be enclosed in an EventListener class and that class should be registered as a bean in spring xml file.

Thanks.

CHARAFI
Guest
CHARAFI

Hi,

how to send an attachement csv file in email ?

narasimha
Guest
narasimha

Hi,

How To inject emailService to be injected (Autowired) can you expline please..
I am getting Exception.
Ex: private EmailService emailservice;
in my class . is there any extension i need to add to my Custom Extension to get EmailService.

Mohamed BELMAHI
Admin
Mohamed BELMAHI

it could be also dependency issue between your custom extension and acceleratorservices extension.

Make sure your custom extension is required acceleratorservices extension by adding in its extensioninfo.xml

HecGot
Guest
HecGot

Hi Mouad.
I have no idea what values put in the following macros.

$contentCV=…
$emailResource=…
$emailPackageName=…

Morza
Guest
Morza

It’s Hybris , the is not such easy, it’s a bunch of configurations. I need to send a simply email, using spring-boot, it’s just some injections and services, that all. Hybris make me unhappy.

vinay
Guest
vinay

wow, really nice explanation

upendar vandanapu
Guest
upendar vandanapu

Hi Mouad EL Fakir,

when I get the email the URL link should be expired after 30 minutes after that If the link has already expired, please request a new activation email here: Request a new activation email.

Could you please suggest how to work on it.

Thanks & Regards,
Upendar

Raghu
Guest
Raghu

Hi,
we are already having an Email setup configured and everything works fine until now.But Now I made some changes to the email body (i mean in the respective .vm file) ,did a build of the project and then performed server restart.
The problem here is the new changes done in the .vm file are not getting reflected in the email generated.I am still getting the old email .could you please let me know if I am missing any other steps apart from build and server restart.

Thanks a lot.

Navi
Guest
Navi

Hi,

Can you please provide code to send email using EventListener. Because I am not able to understand that if we will enclose the sendingEmail code in EventListener then what will be the Event in that case?

Thanks

vinay
Guest
vinay

what is the use of frontendtemplatename here, which value it is referring to?

Nisha
Guest
Nisha

Hi @Mouad EL Fakir
How to set BCC to this email process.