Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos
In the first two parts of this series we had a look on the definition/design of the user interface as well as the integration of aBPM with SAP BPM workflows. This time we’ll have a look at the custom email feature that is included in aBPM and how to use it.

Email support in BPM standard


First of all: BPM includes already email support as a standard feature. You can configure that emails are sent out to all potential owners if a task is created in order to inform them that they need to check the inbox. The email contains a link to the task itself as well as to the inbox but the configuration of the content is limited. The second standard email function are notification activities that can be embedded in the process flow to inform people that are even don’t have access to the workflow environment about certain process states/results.

These two options already allow informing about necessary work items as well as certain steps or events in the process. So what is aBPM adding? The answer is: Fully integration in the aBPM data model and MIME support for emails so that HTML emails and attachments are possible!

aBPM Email Support


A closer look at aBPM’s email support shows that it provides a generic interface that allows different email support implementations. On top of this aBPM includes a default implementation that uses the Apache Velocity template engine (http://velocity.apache.org/) that can be directly used in customer projects.

So customer projects can either implement the generic interface and provide their own email support implementation or use the default implementation with Apache Velocity. In this blog we’ll just look at the second option. The Apache Velocity template engine allows flexible generation of different forms of text files, in our case HTML content. You should have a look at the user guide at http://velocity.apache.org/engine/1.7/user-guide.html that describes the features. aBPM’s implementation around the engine allows overloading of multiple methods so that you can define attachments and set variables that can be accessed in the templates.

Define email content


The definition of the email content is done at 2 places:

  • You need to define templates that are processed by the Apache Velocity engine. These templates can include other templates, can access variables and may also include control structures like conditional branches or loops.

  • By overriding some of the methods from the default implementation class you can add attachments to the email or define variables that are used inside the templates.


The resulting email of this blog will look like this:


Template


Each template consists of 2 template files: One for the subject (name like xxx.subject.vm) and one for the email content (name like xxx.content.vm) itself. Apache Velocity uses the suffix “vm” for its templates files and the default implementation supports internationalization in the same for as for property files.

The content of subject template file is quite easy:
Customer creation process $message.functionalId successfully finished.

For the content, we use a more flexible approach that makes use of including other templates files. There are 3 template files involved:

  • The top-level template defines the content area template file and then parses the base template for the email

  • The base template (“template.content.vm”) defines the HTML structure (header, footer) of the email and includes the content template (defined in the top-level template) to add the text in the content area of the email.


The top-level template file contains:
#set($message.content = "com/sap/consulting/showcase/email/process_success.content.content.vm")

#parse( "com/sap/consulting/showcase/email/template.content.vm" )

What does this mean? Answer: First it sets the content of a variable “message.content” with the name of a template file. The second line tells the template engine to include and parse the “template.content.vm” template file (the base template).

The “template.content.vm” file is the base template and provides the structure of the HTML content of the email. It will also use the variable “message.content” to include the text for the content area of the email:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>$message.subject</title>
</head>

<body bgcolor="#FFFFFF" style="width:100%;padding:0;border:0;margin:0">
<table width="100%" border="0" height="100%" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF">
<tr>
<td>
<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center" style="padding:1em">
<tr>
<td height="100%" valign="top">
<font style="font-family:Arial; color:#666766; font-size:12px; line-height:14px">
#parse( $message.content )
&nbsp;
</font>
</td>
</tr>
<tr>
<td>
<a href="http://www.sap.com" target="_blank"><img src='cid:$cid["logo"]' width="74" height="42" border="0" alt=""/></a>
<br>
<font style="font-family:Arial; color:#666766; font-size:10px; line-height:12px">
<strong>$legal.company</strong><br>
$legal.address <br>
$legal.registration <br>
Chairman of the Supervisory Board: $legal.chairman <br>
$legal.directors <br>
<a href="$legal.website" target="_blank">$legal.website</a>
</font>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

This base template makes heavy use of variables. One of them (“$message.content”) is defined in the top-level template and defines the template that should be included in the content area of the email. So we make us of nested including of template files! The other variables are defined in Java coding that is explained later in this section.

The specific content (defined in “process_success.content.content.vm”) looks like:
<h1>Success</h1>

<p>Customer creation process process $message.functionalId was finished successfully.</p>

<p>Data saved for the customer:</p>

<table>
<tr>
<td><strong>Name:</strong></td>
<td>$customer.KNA1_NAME1</td>
</tr>
<tr>
<td><strong>Street:</strong><td>
<td>$customer.KNA1_STRAS</td>
</tr>
</table>

Again we use variables as placeholders for dynamic data. In this case it’s data directly from the form.

Java interface


aBPM default email interface implementation with Velocity support provides some methods that are intended to be overwritten in customer scenarios. They allow including of pictures, attachments and setting variables that can be accessed in the templates. Here is an extension of the aBPM provided base class that defines the necessary information for our example:
public class ShowcaseEmailServiceCallback extends BaseEmailServiceCallback {

public ShowcaseEmailServiceCallback(ClassLoader classLoader) {

super(classLoader);

}


@Override

public boolean handleAttachments(ImageHtmlEmail email, EmailAddressInformation receiver, EmailServiceContext ctx) throws Exception {

// Adding an embedded image

URL url = this.getClassLoader().getResource("com/sap/consulting/showcase/email/sap_logo.png");

String cid = email.embed(url, "SAP Logo");

ctx.getCid().put("logo", cid);



// continue 🙂

return true;

}



@Override

protected Context createTemplateContext(EmailAddressInformation receiver, EmailServiceContext ctx) {

final Context c = super.createTemplateContext(receiver, ctx);

final ABPMProcess process = ctx.getProcess();



final Message msg = new Message();

msg.setSubject("Demo Email");

msg.setContent("Demo Content...");

msg.setFunctionalId(process.getFullFunctionIdSearch());

c.put("message", msg);



final Customer customer = new Customer(process.getBo());

c.put("customer", customer);



final LegalInfo li = new LegalInfo();

li.setCompany("SAP Deutschland SE & Co. KG");

li.setAddress("Sitz der Gesellschaft/Registered Office: Walldorf, Germany");

li.setRegistration("Registergericht/Commercial Register Mannheim HRA 350654; Persönlich haftende Gesellschafterin/General Partner: SAP SE, Sitz der Gesellschaft/Registered Office: Walldorf, Germany");

li.setChairman("Geschäftsführer/MD: Dr. Daniel Holz, Hartmut Thomsen, Dr. Carl-Christian von Weyhe");

li.setDirectors("Vorstand/Executive Board: Bill McDermott (CEO), Robert Enslin, Michael Kleinemeier, Bernd Leukert, Luka Mucic, Stefan Ries und Steve Singh");

li.setWebsite("www.sap.com");

c.put("legal", li);



return c;

}



public static class Message {

private String subject;

private String content;

private String functionalId;



public String getSubject() { return subject; }

public void setSubject(String subject) { this.subject = subject; }

public String getContent() { return content; }

public void setContent(String content) { this.content = content; }

public String getFunctionalId() { return functionalId; }

public void setFunctionalId(String functionalId) { this.functionalId = functionalId; }

}



public static class LegalInfo {

private String company;

private String address;

private String registration;

private String chairman;

private String directors;

private String website;



public String getCompany() { return company; }

public void setCompany(String company) { this.company = company; }

public String getAddress() { return address; }

public void setAddress(String address) { this.address = address; }

public String getRegistration() { return registration; }

public void setRegistration(String registration) { this.registration = registration; }

public String getChairman() { return chairman; }

public void setChairman(String chairman) { this.chairman = chairman; }

public String getDirectors() { return directors; }

public void setDirectors(String directors) { this.directors = directors; }

public String getWebsite() { return website; }

public void setWebsite(String website) { this.website = website; }

}
}

The scenario implementation overrides 2 methods:

  • handleAttachments – Allows adding attachments and images to the email. We use it to define an image that embedded into the email and used from the HTML code as logo in the signature. But it’s also possible to add attachments (e.g. documents) to the email.

  • createTemplateContext – Is used to define variables that are used in the template. You can see that all variables used in the template are defined (there are 2 sub-classes containing the data) here.


The email and its information are represented by classes from the Apache Commons Email project (https://commons.apache.org/proper/commons-email/).

Adding the email support into scenario


After the definition of the content of the email it needs to be included in the customer scenario. The first step is to add the email support itself into the scenario by implementing the method “queryInterface” and return an implementation of the Email interface. In our case we create an object of class “ShowcaseEmailServiceCallback”. This class was described in the previous section:
@Override

public Object queryInterface(AbstractWrappedCallbackContext<Customer> ctx, InterfaceType type) {
if (InterfaceType.IEmailServiceCallback == type) {
return new ShowcaseEmailServiceCallback(this.getClass().getClassLoader());
}

return super.queryInterface(ctx, type);
}

Please note that “queryInterface” is also used for other extensions like PDF generation, external storage of documents and much more.

After providing the email interface implementation object we can use the email support in 2 different ways:

  • As notification for newly created tasks. This function is more or less the same as in standard BPM. It requires the usage of JMS event notification and is integrated in the aBPM process modelling.

  • aBPM provides a Web Service for sending emails that allows the usage from BPM as well as from Java (although it’s better to use the underplaying EJB directly from Java).


Notification emails


Since one year the BPM engine offers an enhancement that allows external applications to be informed about different events in the BPM engine (see: https://blogs.sap.com/2015/12/03/easy-consumption-of-bpm-events-via-public-api-using-the-example-of-...). aBPM makes use of this and allows sending custom template based emails as notification emails to potential users of a task. The setup is quite easy:

  • You need to create an email template as described above in this blog

  • You need to specify the template in the input mapping of the human activity


If we use a template called "com/sap/consulting/showcase/email/task.approve" then the files “task.approve.content.vm” and “task.approve.subject.vm” are expected to be found in the Java package “com.sap.consulting.showcase.email”. The mapping looks like:


Email Service


Besides notification emails you can call the email service directly from the BPM process within a normal automated activity because it is provided as a web service. The following picture shows the input mapping:



As a minimal requirement you need to fill/map the “abpmProcessId”, “template” and the “to” field. As abpmProcessId and template are self explaining or already described some word to the “to” field: It can contain multiple users, groups or email addresses, separated by a semicolon. Each entry contains the value followed by the type. In our example we specify a user (type “user”) and use the requestor that is already saved in the aBPM process data.

Summary


As shown, aBPM offers and enhanced email support that allows sending HTML emails with completely free texts. The creation is supported by the usage of the Velocity template engine so that even complex requirements can be fulfilled.