Jul 11, 2023
The problem
Sitecore Personalize (from now on referred to as Personalize) is a powerful tool for providing unique experiences to users based on specific marketer-outlined parameters. These features are commonly used for campaigns, offers, and advertisements, all HTML-injected via the Personalize JavaScript Library.
In many instances, all components and markups are already running, and all we have to do is display them to certain users. This can be done using the personalization features embedded within Sitecore, but this may not be enough in some situations if more specific segmentation is required (e.g. if users need to be segmented based on the last visited pages on the current session or the number of clicks on an image).
The solution
Personalize can provide the ultimate solution in these situations; we’ll explain how in this blog. We’ll assume you have a little experience working with Sitecore CDP and Sitecore Personalize and know about web experiences.
Create a Decision Model
The first step is to create our decision model. This contains the logic to segment our users based on the last visited page. In Sitecore Personalize, go to menu Decisioning->Decision Models, click on Create Decision Model button, and name your Decision Model.
Use the Guest or Session data input (depending on your situation), then set a Programmable node, pick a Decision Table node, and choose a Decision Table node to provide the information that will go into our backend code.
In the programmable node, we set the logic to obtain what we need and send it to the decision table. For example, let’s search for the type of services my users visit. If they visit cloud services pages, they will belong to segment 1. If they visit on-premises solutions, they will belong to segment 2. Here is what the JavaScript code will look like:
(function () {
var session = guest.sessions[0];
var cloudServices = ‘cloud-services’;
var onPremiseSolutions = ‘solutions-onpremise’;
if(session){
if(session.status === ‘OPEN’) {
for (var j = 0; j < session.events.length; j++) {
if(session.events[j].type === ‘VIEW’){
var event = session.events[j].arbitraryData;
if(event.page.contains(cloudServices)){
return “1” ;
}
else if(event.page.contains(onPremiseSolutions)){
return “2”;
}
}
}
return “3”; //Default
}
}
})();
With the return value of the function we set the Decision Table rules. In order to do that, we must create an input column, then select the programmable node we set before, and an output column.
In the decision table, we create rules that match the return of the programmable node. With those values, we can work on our backend code. Don’t forget to provide a meaningful name to the columns and the decision table name. In this case, the table returns the segment name based on the result on the programmable node. In this case, the segments will be “Cloud”, “OnPremises”, and “Unsegmented”.
Use the Test Canvas feature to test that everything works correctly by clicking the button on the top right of the Decision Model page. We can run the test with the guest ref info. To find it, go to Dev Tools and type Engage in the console. Next, you will see the following:
With the guest ref info, go to Test Canvas and search. You will see the Request info.
Run the Test Canvas and see the Response tab info. Pay attention to the “outputs” on the “decisionModelResultNodes”. In this case, it says “segmentName” : “Cloud”, so, our rule works fine since the programmable node returns “1”.
Create a Web Experience
The second step is to create a web experience that consumes our decision model. Here, we need to use a web experience with an empty template. This is because we don’t need to inject any HTML on our site and must choose our Decision Model in the Decisioning section.
After creating the empty template and selecting the decision model, click Edit in the Content section. Then go to the API tab and paste the following code:
{
<#assign MyVariable = getDecisionModelResultNode(“Get Segment”)>
<#if (MyVariable)??>
“visitorSegment”: {“segment”: “${MyVariable.outputs[0].segmentName}”}
</#if>
}
The key here is to set the name of the Decision Table node correctly. In this case, “Get Segment” and the JSON attribute “segmentName” are on the response info when we ran using the Test Canvas before. In essence,we call the decision model, get the result of the decision table and then create a JSON object with the info of the segment name.
Use the Preview API button to test if everything is correct, then use the Guest Ref from before and click on Send request. In the Preview API window under the Response tab, we can see the JSON created on the API tab of the web experience. That JSON is the result we need on our backend code.
Connect to the Sitecore Personalize API
The third step to get the decision model result on our backend code is to call the Sitecore Personalize API. We first test the API request with Postman (or any other API testing tool) to identify parameters and the response. The API will call a method that retrieves the web experience response, the same one we set in the last step. So the friendly id of the web experience is the key parameter to get what we want. The input JSON is as follows:
{
“clientKey”: “xxxxxxxxxxxxxxxxxxxxxxxxxxx”,
“channel”: “WEB”,
“language”: “en”,
“currencyCode”: “USD”,
“pointOfSale”: “xxxxxxx”,
“browserId”: “5b7dfae8-576a-4dd3-bc00-01c9fb4150cb”,
“friendlyId”: “demo”
}
To get the browserId, go to the console and execute Engage.getBrowserId().
Set a Postman POST call to the API Url based on your location. Here we can use the US location, so the URL is: https://api-engage-us.sitecorecloud.io/v2/callFlows
Remember that the Web Experience on Personalize has to be started; if paused, the API will return a “No flow executed” message.
The result will be:
After that, the only thing that we need to do is to call the API from our back end code. We are using Sitecore 10 in this example, so we have a Foundation.Personalize project and then create a class with a method that calls the API and returns the segment. We can choose what content to show based on the segment. The gist of this class is here.
public string GetDecisionModelResult(string experienceId)
{
try
{
SiteContext site = Sitecore.Context.Site;
HttpCookie cookie;
string bid = string.Empty;
if (site != null)
{
cookie = System.Web.HttpContext.Current.Request.Cookies[“bid_” + Settings.GetSetting(“ClientKey”)];
if (cookie != null)
{
bid = cookie.Value;
var experience = new Experience
{
ClientKey = Settings.GetSetting(“ClientKey”),
Channel = “WEB”,
Language = “en”,
CurrencyCode = “USD”,
PointOfSale = Settings.GetSetting(“PointOfSale”),
BrowserId = bid,
FriendlyId = experienceId
};
var json = JsonConvert.SerializeObject(experience);
var data = new StringContent(json, Encoding.UTF8, “application/json”);
var url = Settings.GetSetting(“ApiUrl”);
var client = new HttpClient();
var response = client.PostAsync(url, data);
var result = response.Result.Content.ReadAsStringAsync();
dynamic JSONdata = JObject.Parse(result.Result);
var segment = JSONdata.visitorSegment.brand;
if (segment == “Unsegmented”)
segment = string.Empty;
return segment;
}
}
}
catch (Exception ex) {
Log.Error(“There was an issue on connecting the Personalize API “ + ex.Message, this);
}
return string.Empty;
}
This method uses an HttpClient to call an API with the parameters we saw before in the Postman call. However, to know the browserId for each user and find that value, we need to read a cookie that Sitecore Personalize creates on each user’s browser. The name of the cookie is bid_[clientId]. As good practice, we have to set the values for the clientId, the URL, and the PointOfSale parameters in a config file.
Now and then, we can call this method sending as a parameter the friendly Id of the web experience we want to get the response.
With this example we now know how to retrieve the result of a Sitecore Personalize Decision Model used in a Web Experience, and then that result is used in our Sitecore 9 or 10 backend code.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.