Thursday, March 23, 2017

Identifying a contact in Sitecore via JavaScript

Its becoming more common these days to make use of JavaScript frameworks such as Angular, Knockout and React to build Sitecore web sites with great user experiences. However, as this is done there is less and less work being done inside the standard code behind (for web form sublayouts), and controllers (for MVC renderings). This is instead replaced by service calls asynchronously to Web API or standard WCF, which leaves one downside to the Sitecore developer.

In a standard service call you won't have access to the Sitecore context, which of course can be overcome by simply creating your own context to access the data. Yet when it comes to the tracker and the great features available with identified contacts, it might not work so cleanly. You can't fake access to the current tracker (and by association the current Contact). Using contact repositories involve getting a copy of that contact, attempting a lock and leaves many chances for error.

The cleanest and simplest way I have found to allow the front end to interact with the current contact is to make use of an MVC controller. Web forms users should not stop reading because this works in both MVC projects and web forms the same! Effectively we create an MVC controller which inherits off of Sitecore MVC controllers. This means that there is full access to the context of Sitecore and the tracker, and these controllers can be called the same way in AJAX as you would Web API or any other service.

So lets get down to an example, the following code is a controller which allows a contact to be identified by email address.

The controller

This is just a simple example showing that you have access to the current session/contact.
using System;
using System.Web.Mvc;
using Sitecore.Analytics;
using Sitecore.Mvc.Controllers;

namespace MyProject.Controllers
{
    /// <summary>
    /// MVC controller to allow Sitecore context access
    /// </summary>
    public class ContactController : SitecoreController
    {
        [HttpPost]
        public ActionResult IdentifyContact(string emailAddress)
        {
            var result = false;

            try
            {
                Tracker.Current.Session.Identify(emailAddress);
                result = true;
            }
            catch (Exception)
            {
                return Json(result);
            }

            return Json(result);
        }
    }
}

Registering the controller

The controller needs to be registered during the initialization pipeline in Sitecore.
using Sitecore.Pipelines;
using System.Web.Mvc;
using System.Web.Routing;

namespace MyProject
{
    class RegisterMvcRoute
    {
        public virtual void Process(PipelineArgs args)
        {
            Register();
        }

        public static void Register()
        {
            RouteTable.Routes.MapRoute("CustomContact", "Contact/IdentifyContact", new { controller = "Contact", action = "IdentifyContact" });
        }
    }
}
The patch file for this is:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor type="MyProject.RegisterMvcRoute, MyProject" patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']" />   
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

Calling the controller

It's as simple as making an AJAX request in your JavaScript.
$.ajax({
    type: "POST",
    url: "/Contact/IdentifyContact",
    data: JSON.stringify({'emailAddress': 'testing@email.com'}),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (result) { },
    error: function (request, status, error) { }
});
In this example the result object would be boolean, but obviously whole objects can be returned as desired.

Conclusion

This concept can be further extended to allow contact facets to be modified and accessed via JavaScript as well as registering goals and events.

No comments:

Post a Comment