What if your online store could identify shoppers with mobile devices and deliver content based on the device they're using? With the arrival of Dynamic Content and the Tagging Framework in Elastic Path Commerce 6.1.1, you can do just that.
This article takes a practical approach to extending the Tagging Framework. We'll look at how a developer can add a tag to identify mobile device users and how to create a tagging event listener to capture the information we need to store in that tag. And it's really quite easy, I promise. (Before diving in, you'll need a basic understanding of the Tagging Framework and Dynamic Content, so you'll want to take a look at my earlier posts and check out the 6.1.1 documentation.)
Solution Overview
When a visitor views a page on your Elastic Path storefront, the HTTP request includes a User-Agent header. The User-Agent header contains information about the application that's requesting
the page. This could be an automated web crawler, such as Googlebot or, if there's a person using that application to view web pages, a web browser. In the case of requests coming from mobile devices, like the iPhone, the user agent header also includes the name of the device.
We need to store this information in a tag and attach it to the shopper so that it can be accessed later on when we need to determine what Dynamic Content to display. Elastic Path Commerce doesn't have a tag that contains this information by default, so we need to do three things:
- define a USER_AGENT tag in the "who" tag dictionary
- create a tagging event listener (a tagger) class to get the User-Agent header from the request and store it in a USER_AGENT tag in the shopper's tag set
- add the listener to the collection of event listeners that are invoked each time an HTTP session is created in Elastic Path Commerce.
Once this is done, marketing users will be able to target Dynamic Content based on the type of mobile device the shopper is using.
Defining the USER_AGENT Tag
First, we need to define the USER_AGENT tag. To do this, we need to insert a row into the TTAGDEFINITION table of the Elastic Path Commerce database:
insert into ttagdefinition(uidpk, guid, name, description, data_type)
values(10, 'USER_AGENT', 'USER_AGENT', 'The User-Agent request header.', 'java.lang.String');
Next, we need to add the tag to one of the three tag libraries ("who", "when", and "where"). The user agent is a piece of information that helps us identify the shopper, so we need to add it to the "who"
library. To do this, we need to insert a row into the TTAGDICTIONARYTAGDEFINITION table:
insert into ttagdictionarytagdefinition(tagdictionary_guid, tagdefinition_guid)
values('WHO', 'USER_AGENT');
Now, marketing users can log in to the Commerce Manager client, create Dynamic Content, and configure the Dynamic Content Delivery to evaluate the USER_AGENT tag, but at this point that wouldn't be very useful, because we haven't yet set up the tagging event listener to get that information and store it in the shopper's tag set.
Creating the Tagger
There are two tagging event listener interfaces defined in the Elastic Path Commerce core library, under com.elasticpath.commons.listeners:
- NewHttpSessionEventListener, which is fired when the visitor arrives at the storefront and an HTTP session is created.
- CustomerLoginEventListener, which is fired when the visitor signs in to their store account.
Both interfaces expose an execute method that takes a CustomerSession and an HttpServletRequest as parameters.
In the storefront web application, the com.elasticpath.sfweb.listeners package contains several Tagger classes that implement one or both of the listener interfaces. These classes are responsible for populating the tags with the data they need. We can get the User-Agent header at the same time as the session is created, so we'll create a UserAgentTagger class that extends NewHttpSessionEventListener. The interface defines only one method: execute. We'll implement the execute method to capture the user agent header string and put it in a tag:
package com.elasticpath.sfweb.listeners;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import com.elasticpath.commons.listeners.NewHttpSessionEventListener;
import com.elasticpath.domain.customer.CustomerSession;
import com.elasticpath.tags.Tag;
import com.elasticpath.tags.TagSet;
public class UserAgentTagger implements NewHttpSessionEventListener {
private static final String USER_AGENT = "USER_AGENT";
private static final Logger LOG = Logger.getLogger(UserAgentTagger.class);
public void execute(CustomerSession session, HttpServletRequest request) {
// get the user agent header string
String userAgent = request.getHeader("User-Agent");
if (LOG.isDebugEnabled()) {
LOG.debug("User-Agent header contents: " + userAgent);
}
// get the shopper's tag set
TagSet tagSet = session.getCustomerTagSet();
// set the user agent in the shopper's tag set
Tag userAgentTag = new Tag();
userAgentTag.setValue(userAgent);
tagSet.addTag(USER_AGENT, userAgentTag);
}
}
Adding the Tagger to the Event Listeners Collection
When an HTTP session is created, the handleFilterRequest method of webCustomerSessionService calls each listener's execute method. So, we need to add the user agent tagger to the newHttpSessionEventListeners collection on the webCustomerSessionService bean. Open the storefront web app's serviceSF.xml file (located in WEB-INF/conf/spring/service) and add a bean definition for the user agent tagger:
<bean id="userAgentTagger" class="com.elasticpath.sfweb.listeners.UserAgentTagger"/>
Next, find the webCustomerSessionService bean definition. Inside bean definition, find the newHttpSessionEventListeners property and add a reference to the userAgentTagger bean:
We can now test this by enabling debug logging on the storefront and then accessing the storefront with various browsers. Each time a new customer session is created, a debug message is logged with the complete user agent header string. For example, when I use my iPod Touch to access my storefront, the following message is logged:
2009-04-22 17:48:26,246 [http-8080-Processor23] DEBUG com.elasticpath.sfweb.listeners.UserAgentTagger - User-Agent header contents: Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2_1 like Mac OS X;
en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20
There's a lot more information in there than we really need, but we see that it contains the word iPhone. So, if we want to target content at shoppers who are using an iPhone or an iPod, we can now do that.
Now, when we're creating the Dynamic Content Delivery, we can select the USER_AGENT tag and use its value as one of the criteria for displaying content. For example, if you're configuring Dynamic Content Delivery to show a different banner to iPhone users, add the USER_AGENT tag with the operator set to includes and the value set to iPhone.
This is just one way you can extend the Tagging Framework. You could also create a tag to get information from a cookie or a specific request parameter. And you're not limited to information in the HTTP request; for example, you could tag customers with products and categories they've viewed. Going forward, we'll be building more tags into the framework, so if you've got more ideas, we'd love to hear about them.
I know I've probably glossed over a few details, so if you have any questions or comments, please don't hesitate to post them here.
