Sitecore Behavior Personalisation InSession

One of the key selling point of Sitecore 8 compared to the other CMS products is the Personalisation Engine.

The definition of “Behavior Personalisation” should be self Explanatory, providing personalised content based on the behavior of the user….

InSession Personalisation DOES NOT REQUIRE XDB license and MONGODB capabilities. Most of the features are enabled also if you are running Sitecore in CMSONLY mode.

The main advantage of XDB comes from the power of Analytics data and it will give you the ability to personalised based on the historic interactions and behavior (eg. checking if the customer has visited the page within the previous visits to the web site, or if the customer has never triggered a specific goal.)

The way of delivering personalised content within Sitecore is common within the personalisation framework and as you would expect you would need to define within your presentation details your personalisation rules.

Within the personalisation engine there are several way to define visitors behavior:

  • Visit user visit a page, or check the entrypage of the journey

personalvisit

  • Goal / Event /Outcome user trigger a goal -Event -Outcome during the visit

PersonalGoal.PNG

  • Campaigns  user come from a campaign landing page/email or his journey qualify with a campaign

PersonalCampaign.PNG

  • Referrals/search keyword user come from a specific website or through a specific keyword

personalgooglesearch

 

 

Advertisements

Integrate AKAMAI with Sitecore to deliver GeoIP personalisation

As probably not everybody knows AKAMAI offer as well GEOIP resolution capabilities based on MaxMind database.

OOTB Sitecore offer GeoIP personalisation based on their cloud service that consume MaxMind database, Sitecore charge customers for this service and in case you are not using Akamai, this could be an easy and effective way to have GeoIP in place without writing any code but just paying for Sitecore GeoIP service.

Therefore if you are already using AKAMAI and Sitecore GeoIP personalisation you should consider following this route…

In order to get AKAMAI to deliver personalisation you need to enable Content Targeting via property manager obviously you need to ensure that Content Targeting is included within your AKAMAI contract.

https://community.akamai.com/community/web-performance/blog/2016/03/16/content-targeting-a-basic-introduction

the-world-in-flags-570x293

Once that you have this in place, you will simply get GeoIp information injected within your http header that should look like:

X-Akamai-Edgescape: georegion=263,country_code=US,region_code=MA,city=CAMBRIDGE,dma=50 6,pmsa=1120,areacode=617,county=MIDDLESEX,fips=25017,lat=42.3933,l ong=-71.1333,timezone=EST,zip=02138-02142+02238-02239,continent=NA ,throughput=vhigh,asnum=21399

In order to configure Sitecore to read the following header instead than calling the original service, it is recommended to implement your custom lookup provider. Implementing your custom lookup provider is fairly simple since you need to inherit from Sitecore.Analytics.Lookups.LookupProviderBase and override WhoIsInformation to read your information from the HttpHeader and return the information as within the whoIsInformation object.

using Sitecore.Analytics.Lookups;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using System;
using System.Web;
using System.Web.Hosting;

namespace xxx.Akamai.LookupProvider
{
    public class AkamaiGEoIpProvider : LookupProviderBase
    {
        public string ExtractValue(string keyName, string headerValue)
        {
            //ToDo: nice regex to Parse Value
        }

        public override WhoIsInformation GetInformationByIp(string ip)
        {

            WhoIsInformation information = new WhoIsInformation();
            var headerValue = Request.Headers["X-Akamai-Edgescape"];
            information.Country = ExtractValue("country_code", headerValue);
            information.PostalCode = ExtractValue("zip", headerValue);
            //etc etc to set all the value for the information object

            return information;
        }
    }
}

Once that you have implemented your lookup provider you would need to regiter within the web.config your own provider

 <lookupmanager>
        <patch:attribute name="defaultProvider">akamai</patch:attribute>
        <providers>
          <add name="akamai" patch:after="processor[@type='Sitecore.Analytics.Lookups.MaxMindProvider,Sitecore.Analytics']" type="xxx.Akamai.LookupProvider.AkamaiGEoIpProvider,xxx.AkamaiGeoIp">/>
</add></providers></lookupmanager>

Useful resources to consider when you implement a custom lookup provider are the following ones:

Sitecore GeoLiteProvider: https://github.com/craigtfromatl/Sitecore-GeoLite-Lookup-Provider

CircuitBreaker design pattern: http://www.redmoon.london/sitecore-ip-geolocation-service-resolving-geoip-information-on-the-first-request-using-circuit-breaker-design-pattern/

Akamai Edgescape Parser: https://github.com/madglory/edgescape-parser

Create and configure XDB Custom Facet

In this post I am describing the required steps to create a custom facet on XDB and how to use it to personalize the experience…

  • Create your Interface extending IFacet
using System;
using System.Linq;
using Sitecore.Analytics.Model.Framework;

namespace Testing.ContactFacets.Model
{
    public interface ICRMSegment : IFacet
    {
        string CRMSegmentId { get; set; }
    }
}
  • Implement your Custom Facet
namespace Testing.ContactFacets.Model
{
    public class CrmSegment : Facet, ICRMSegment
    {
        private const string FIELD_CRMSegmentId = "CRMSegmentId";
        public CrmSegment()
        {
            base.EnsureAttribute< string>(FIELD_EMPLOYEE_ID);
        }
        public string CRMSegmentId
        {
            get { return base.GetAttribute< string>(FIELD_CRMSegmentId ); }
            set { base.SetAttribute< string>(FIELD_CRMSegmentId , value); }
        }
    }
}
  • Register your Facet via config file
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <model>
      <elements>
        <element interface="Testing.ContactFacets.Model.ICRMSegment,XXX.AssemblyName " implementation="Testing.ContactFacets.Model.CrmSegment, XXX.AssemblyName" />
      </elements>
      <entities>
        <contact>
          <facets>
            <facet name="CRMSegment" contract="Testing.ContactFacets.Model.ICRMSegment, XXX.AssemblyName" />
          </facets>
        </contact>
      </entities>
    </model>
  </sitecore>
</configuration>

  • Create a new XDB Contact
@using Sitecore.Web;
@using Testing.ContactFacets.Model;
@using Sitecore.Analytics.Model.Entities;
@{
 Sitecore.Analytics.Tracker.Current.Session.Identify("stelio.dibello@xxxxx.com");
 var contact =  Sitecore.Analytics.Tracker.Current.Contact;
 var data = contact.GetFacet<ICRMSegment>("CRMSegment");
 data.CRMSegmentId = "BargainHunter";

var personalInfo = Sitecore.Analytics.Tracker.Current.Contact.GetFacet<Sitecore.Analytics.Model.Entities.IContactPersonalInfo>("Personal");

personalInfo.FirstName = "Stelio";
personalInfo.Surname = "Di Bello";
personalInfo.Gender="M";

var contactEmail =  Sitecore.Analytics.Tracker.Current.Contact.GetFacet<IContactEmailAddresses>("Emails");

            // this email to show in the Experience Profiles backend.
 if (!contactEmail.Entries.Contains("Home"))
    {
      contactEmail.Entries.Create("Home");
    }
            // set the email
  var email = contactEmail.Entries["Home"];
  email.SmtpAddress = "stelio.dibello@xxxxx.com";
 contactEmail.Preferred = "Home";
}

CRM data contact facet updated.

Contact ID: @contact.ContactId.ToString() /b>

Employee #: <b> @data.CRMSegmentId </b>

  • Personalize based on CRMSegmentId rule

 

  • crmsegmentpersonalisation

Sitecore 8 Personalisation rules for beginners

Probably most of you are already aware of what it means personalisation in Sitecore 8 but in case you have not heard about it, this post will give you a better idea of how Sitecore has implemented it…

Within Sitecore the easier way to deliver a Personalised experience is through Personalisation Rules at Rendering level.

The starting point is defining a page with one rendering and click on the Personalise button

personalisebutton

From here you will be able to select your rule:

rulesselector

Once that you have selected your rule, you will than be able to select the actions associated to the conditional rendering that could be setting a different datasource, or Hiding the rendering or displaying a different rendering

personalisecomponent

Sitecore 8 allows the Developer to customise Rules but OOTB it comes with the following rules to personalise your content:

Sitecore Rules are grouped in the following logical categories:

Campaigns: Condition based on the campaign defined, newsletter, landing page, etc
Channel: Condition based on the channel, web, mobile etc
Date: Condition based on the date & time of the visit
Device: Condition based on Device capability (it rely on NetBiscuit service charged separately)
GeoIp: Condition based on user geolocation (rely on Sitecore service based on MaxMind, charged separately
Outcomes: Condition based on the engagement plan status and outcomes triggered
Security: Condition based on user security context, eg.  is anonymous etc
Social : Conditions based on Social network information, in the case the user has a federated identity via social network can be used to personalised on the profile information
Visit: Condition based on the current visit (eg. goal / event, campaign, previous interactions, engagement value, search keyword etc)
Visitor: Condition based on previous interactions (require analytics to be enabled)

 

 

How integrate your favourite Javascript framework with Sitecore

Recently within Sitecore community Developers have started to discuss a lot about the frontend/backend integration patterns and all the related topics, like Isomorphic javascript etc…

This blog summarise pretty well your option within a SPA scenario using Sitecore nowdays http://www.deleteagency.com/news/3-approaches-to-single-page-applications or an other good resource could be this one: http://www.sitecoredevelopment.com/ChrisDaly/2016/April/AngularJS%20and%20Sitecore.aspx

My personal consideration on this topic, is that does not exist an universal “solution” each project has different requirements and each solution has Pro and Cons, therefore my advise would be to understand the possible options, understand the pros and cons and try to take an informed decision… Anyhow if you are paying for XDB I would definitively recommend not using Sitecore as a content service in the headless mode but taking advantage of Sitecore Processor & Pipelines to make page composition and routing.

In the case you are interested in React the advise would be to check out the following blogposts:

http://sitecoreblog.alexshyba.com/sitecore-and-react-how-hard-can-it-be/

https://github.com/GuitarRich/sitecore.react

http://www.sitecorenutsbolts.net/2016/07/23/Sitecore-and-React-It-IS-that-easy/

https://asmagin.com/2016/10/10/how-to-marry-reactjs-and-sitecore-with-webpack/

https://asmagin.com/2016/10/20/how-to-marry-reactjs-and-sitecore-with-webpack-part-2-adding-redux/

In the case you are interested in NitroNet:

http://intothecore.cassidy.dk/2016/07/gentlemen-mf-restart-your-view-engines.html 

In the case you are interested in Angular

https://asmagin.com/2016/07/05/using-angularjs-directives-in-sitecore-edit-mode/

http://www.ehrendames.com/sitecore-with-angular-js-part-1/

 

Tracker is not initialized error

Within Sitecore 8.1 and 8.2 you could get easily this “Tracker is not initialized error” even if you are not planning to use analytics but for laziness you have not disabled analytics and/or you left within your layout the VisitorIdentification tag…

The simpler way to get rid of this issue if you are not using Analytics is to remove  Sitecore.Analytics.Tracking.config from your include folder.

In the case you want to use analytics therefore you should check that in Sitecore.Analytics.Tracking.config your hostname property is set to the DNS name that you are using to access to your website….

Sitecore as a Service… is it really a good idea?

Sitecore as a Service is the first thing that would come to the mind to a Developer / Architect who is not familiar with Sitecore.

The idea is pretty simple, the non Sitecore developer think: “I do not like products, I do not know how to use Sitecore, I do not want really use it, but I have to… therefore I am limiting the dependency and the role of Sitecore within my architecture”

Unfortunately most of Developers still understand Sitecore as a CMS rather than a Digital Martketing Suite and cannot really get the difference and the benefit of it…

If you have heard about this consideration and you have been in similar situation, this is the right post for you….

As you probably know, Sitecore architecture is pretty flexible and allow you to use Sitecore in a variety of way, consuming Sitecore through the OOTB web api to manage the items or write a custom webApi just to serve content items as a web service or a rest endpoint serving Json is fairly simple and you can find plenty of documentation about it. Other way to access your content structure is through the use of Dictionaries or customising your publish pipeline to create static Json/JS files is also a simple way to consume the content information.

The following approaches are considered a quick win for “non Sitecore developers” who think I will be in control of my website / application, Sitecore will just give me HTML via Json and I will do the rest without having to tunnel all my request through Sitecore pipeline…

Reality for Sitecore people is very different…. the reason for tunnelling all your request through Sitecore pipelines are multiple ones and before going for the “content as a service” should be really considered to tunnel all your request through Sitecore for the following reasons:

  1. Content structure and your website features are very bounded and you cannot decouple it. Decoupling it, you would loose a lot of benefits (eg. Seo, friendly url, linking content elements, etc)
  2. Page Edit mode you would loose it
  3. Page composition having the ability to control page structure on Sitecore open the doors to an infinite number of possibility for your Authoring team allowing them to control your application.
  4. Renderings associated to Content Items associating renderings to Content Items via Datasource allow you to test different configuration and permutation of your application and encourage re-usability principles within your code.
  5. Personalisation allows your content team to deliver a personalised experience is one of the key selling point of Sitecore, decoupling the content from the application would effectively prevent you to Personalise the experience through Sitecore. Sitecore echosystem leverage personalization of Renderings to show and Datasource to use via Sitecore rules.
  6. Content Testing is key in the digital age, continuos testing is the new culture and bypassing Sitecore pipeline force you to a Non Sitecore MVT testing approach.
  7. Analytics & Behaviour personalisation require your Sitecore implementation to tunnel all the request within Sitecore pipelines, moving out from it would mean effectively preventing your trading team to benefit from the great benefits coming from Sitecore

Having done these considerations, is fair to say that if all what you need from Sitecore is the Authoring shell to upload content and images and you are happy to consume Sitecore as Service, you would still benefit some of the features of an enterprise CMS