Thursday 5 December 2013

Implementing email functionality in a JSR portlet using Liferay API's

Many a times we have a requirement to implement email functionality in our Portlets.
A simple use case can be the contact us form on your website. When the user submits it, it should send an email to the concerned department.

I am going to explain how to implement this.

I am using Liferay Portal and a JSR compliant portlet. We will be using Liferay's SubscriptionSender class to do the job of sending emails.

Another important thing is we can either use the tmpl file(email template) to do this or use a web content to
create the email template.

The advantage with web content is that it can be localized, which is currently not possible with a tmpl file, at the time of writing this post.

Here are the steps

1. If using a tmpl file create one like email_body.tmpl

The content of  this file can be something like


Following is the information provided by the user

Customer Name = [$PREFIX$] [$FIRST_NAME$] [$LAST_NAME$]
Gender = [$GENDER$]
Age = [$AGE$]

I placed this file at the following location in my Portlet project :  \src\main\resources\dependencies

2. If using web content, create a global content like "EmailTemplate" and put the same content that we used for step 1. Should be easy. You can also add translations.

3. Next lets look at the controller and helper methods which will implement the logic.

In my controller class I have created a method to first create all the input data, for the email, and then pass that to another class to send email. Lets see how.

Here is the controller class method

private void invokeEmailApi(ActionRequest actionRequest,
ActionResponse actionResponse, String toEmailAddress,
Model model) throws IOException{
String fromName = "";
String body = "";
String fromEmailAddress = "test@gmail.com";
String toName = "Test User";
String subject = "Hello";
String articleName = "EmailTemplate";
String bodyTemplate = "dependencies/email_body.tmpl";

HttpServletRequest httpServletRequest = PortalUtil.getHttpServletRequest(actionRequest);
long companyId = PortalUtil.getCompanyId(actionRequest);

//ContentArticleUtil is a helper class which gets content using JournalArticleLocalServiceUtil

body = ContentArticleUtil.getArticleContentByTitle(httpServletRequest, articleName);
if(body == null || body.equals("") || body.equals(articleName)){
body = StringUtil.read(this.getClass().getClassLoader(),bodyTemplate, false);
}

String[] contextAttributes = {"[$PREFIX$]",contactInfo.getPrefix(),
"[$FIRST_NAME$]", contactInfo.getFirstName(),
"[$LAST_NAME$]", contactInfo.getLastName(),
"[$GENDER$]", contactInfo.getGender() };

toEmailAddress = "test@gmail.com";
SendMail mail = new SendMailImpl();
mail.sendEmail(companyId, 0, fromEmailAddress, toEmailAddress, fromName, toName, subject, body, contextAttributes);
}

The code above should be self explanatory. "contextAttributes" is used to set values which are used in the template.

Next lets look at the SendMail interface.

public interface SendMail {
void sendEmail(long companyId, long userId, String fromEmailAddress,
                String toEmailAddress, String fromName, String toName, String subject,
                String body, Object[] contextAttributes) throws IOException;
}

Pretty simple.

Next lets look at the SendMailImpl class.

public class SendMailImpl implements SendMail{

@Override
public void sendEmail(long companyId, long userId, String fromEmailAddress,
                 String toEmailAddress, String fromName, String toName, String subject,
                 String body, Object[] contextAttributes)
throws IOException {
// TODO Auto-generated method stub
ServiceContext serviceContext = new ServiceContext();
InternetAddress to = new InternetAddress(toEmailAddress, toName);

SubscriptionSender subscriptionSender = new SubscriptionSender();
subscriptionSender.setBody(body);
subscriptionSender.setCompanyId(companyId);
subscriptionSender.setUserId(userId);
subscriptionSender.setContextAttributes(contextAttributes);
subscriptionSender.setFrom(fromEmailAddress, fromName);
subscriptionSender.setHtmlFormat(true);
subscriptionSender.setMailId("email_body", to);
subscriptionSender.setServiceContext(serviceContext);
subscriptionSender.setSubject(subject);
subscriptionSender.addRuntimeSubscribers(toEmailAddress, toName);

subscriptionSender.flushNotificationsAsync();
        /* Ends */
}
}

The above code is pretty straightforward. Liferay API makes life easier as you can see.
If you have the proper SMTP settings then you should see the email when you add this code to your portlet and run it.

Hope  this post is helpful .. :)


No comments:

Post a Comment