Sending Emails in SAP Hybris

Hybris Logo

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 = [email protected]
mail.replyto = [email protected]
mail.smtp.server = smtp.gmail.com
mail.smtp.port = 465
mail.smtp.user = [email protected]
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.

 

4.5 28 votes
Article Rating
Subscribe
Notify of
guest

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

39 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Himanshu
Himanshu
6 years ago

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.

Navi
Navi
Reply to  Mouad EL Fakir
5 years ago

Hi,

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

Thanks

Navi
Navi
Reply to  Mouad EL Fakir
5 years ago

Hi,

Can you please provide code to send email using EventListener because I am not able to understand that if we will enclose the sending email code in eventListener then what will be the event?

Thanks

CHARAFI
CHARAFI
6 years ago

Hi,

how to send an attachement csv file in email ?

narasimha
narasimha
6 years ago

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.

narasimha
narasimha
Reply to  Mouad EL Fakir
6 years ago

I am Adding acceleratorservices extension in two places.
1) in localextensions as

extension name=”acceleratorservices”

2) and also adding into inside my custom extension in file extensioninfo.xml as

requires-extension name=”acceleratorservices”

is it correct way or issue with me?.

Mohamed BELMAHI
Reply to  narasimha
6 years ago

requires-extension name=”acceleratorservices”
Is enough.

Mohamed BELMAHI
Reply to  narasimha
6 years ago

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
HecGot
5 years ago

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

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

Morza
Morza
5 years ago

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
vinay
5 years ago

wow, really nice explanation

upendar vandanapu
upendar vandanapu
5 years ago

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
Raghu
5 years ago

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.

Raghu
Raghu
Reply to  Mouad EL Fakir
5 years ago

Thanks a lot for your quick reply.I will check and will update.

Raghu
Raghu
Reply to  Raghu
5 years ago

Hi Mouad EL Fakir, updating the Renderer template through impex script resolved the issue.now I am able to see the changes made in the .vm file of the email.Thanks once again.

Navi
Navi
5 years ago

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

Navi
Navi
Reply to  Mouad EL Fakir
5 years ago

Thanks for reference..

Navi
Navi
Reply to  Mouad EL Fakir
5 years ago

HI Mouad,

Can you please tell me how do we get email id of the user to whom we want to send the email. Ofcourse we can’t specify it in properties file right?

vinay
vinay
5 years ago

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

Yeshwant
Yeshwant
Reply to  Mouad EL Fakir
4 years ago

How to embed logo or image in html email,i used cid but it is not working properly

Nisha
Nisha
5 years ago

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

sreekanth
sreekanth
4 years ago

Hi,

I am a new bee in SAP Hybris. I have followed your tutorial, struck in the process of going forward. Need your support !

2.4 section (sending email snippet) where to place ( which class, Extention ) is not aware. Can you help me out there?

ragahvendra
ragahvendra
4 years ago

this should be HelloWorldProcessModel replaced with HelloWorldEmailProcess. There is no model HelloWorldProcessModel .plse check sir, i am getting the build issues

Vivek
Vivek
4 years ago

Hi, I am getting null pointer exception at HelloWorldProcessModel helloWorldProcessModel = (HelloWorldProcessModel) getBusinessProcessService()
.createProcess(“helloWorld-” + System.currentTimeMillis(), “helloWorldEmailProcess”); this line can anyone solve

Anonymous
Anonymous
Reply to  Vivek
3 years ago

Check the bean for your business process service is loaded

STR
STR
Reply to  Vivek
2 years ago

I am facing the same can somone help me

Zoong
Zoong
3 years ago

Hi!

Mouad,It seems like you have not added firstName to email context.

sunil p
sunil p
3 years ago

In Section 2.4 :
Create a new instance of the process, it should be typeCast to “HelloWorldEmailProcessModel” ,
and not “HelloWorldProcessModel”.

Rakesh
Rakesh
2 years ago

Hi Mouad,

Thanks for the detailed explanation.Could you please let me know if we can make a switch like enable/disable simply using properties file to stop the mail trigger for certain business process..without actually configuring from. Backoffice.
Please share the process how we can achieve the same.
TIA

Adelina
Adelina
2 years ago

Hi! So, my collegue created cronjob to send particular emails for our customers every 6 months. When I try to run cronjob manually sometimes the templates of the emails are broken – sometimes they work ok. How can I find what causes those broken cases? .vm looks fine and it doesn’t depend on teh user, but for some reason sometimes it is broken. Any ideas? Thanks in advance

39
0
Would love your thoughts, please comment.x
()
x