Saturday, February 7, 2015

10 Days of Sitecore 8 Analytics. Day 3: A Picture's Worth a Thousand Words

Main point for today

OK, I admit it.  On my recent posts I faked my picture of Abraham Lincoln in my Experience Profile.  I didn't even use PhotoShop; it was just a cheap SnagIt copy-and-paste.  But now, here's the real deal:
A true Abraham Lincoln Sitecore Experience Profile Contact
Why is this such a big deal Mike?  Two reasons:

  1. Looking into how to add a contact's picture to the Sitecore Experience Profile reminded me of how incredible the Sitecore community is.  There are great blogs going back months (from people much more talented than I am) that discuss this subject in great detail.
  2. The main purpose of this blog series was to investigate the power of xDB.  I've been around reporting requirements long enough to know that power comes from modeling whatever it is you want to model, viewing it in whatever way you want to view it.  While my adding a picture here is a tip-of-the-iceberg kind of moment, it will hopefully get the creative juices flowing (it did for me).

About that community

First and foremost, two top examples of how great the Sitecore community is, and representative of much more thorough discussions of this subject than I will have here today:
  1. Anything by Adam Conn is great.  This is a series he did back in September (which shows how far ahead of the curve he is) that does a great job explaining developing against xDB.
  2. Sitecore's great partner, Horizontal Integration, does a fantastic job of showing code samples.

My summarized steps to get Mr. Lincoln's picture in my Experience Profile:

There are much better posts around all things Mongo, development in Sitecore and xDB, etc.  This is my quick list of things that I went through as I investigated this task, using just the information from the above two blogs.

Step 1.  Learn enough Mongo to become dangerous.

As you get into xDB within Mongo, you'll gravitate to the Contacts and Interactions collections.  As you're using RoboMongo or MongoVue or your tool of choice, you'll find yourselves wanting to query the collections for your documents.  Again Adam Conn comes to the rescue with an explanation of how to use ID based queries.  Here are a few find() statements that also helped me:

db.Identifiers.find({"_id" : /extranet\\abr?/i})

In this example, my Identifiers collection has a link between my Contact ID and Abraham Lincoln's Sitecore user record.  The above uses a Regular Expression since in this case the _id field seems to be a string (as opposed to Adam's description of how to deal with identifier types in the Contacts collection).  The RegEX looks for user in the extranet Sitecore security domain, staring with "abr" and case insensitive ("/i").

db.Contacts.find({"Personal.FirstName" : "Abraham"})

Switching to a find in the Contacts collection, above is a way to find a value in an embedded document.  Contacts have a "Personal" document, with an embedded document that can include FirstName and LastName.  The Personal.FirstName syntax allows me to find a value of "Abraham" within.  This could be another use of a RegEX as used in the first example.


db.Contacts.find({_id:new BinData(3, 'zgZHZ6RszESnllHXYIuUrA==')})

Adam's blog will really explain why we need to set up a find query in this way for the Contacts collection.  The example above is just an easy copy and paste (changing out the resultant ID for your system).

Step 2.  Look at an example of a Contacts document.


{
    "_id" : LUUID("4332583d-d8df-3a5c-6382-4cb8037a15f3"),
    "System" : {
        "IntegrationLabel" : ""
    },
    "Identifiers" : {
        "IdentificationLevel" : 2,
        "Identifier" : "extranet\\mike@test.com"
    },
    "ConversionInfo" : {
        "WasConverted" : true
    },
    "Lease" : null,
    "Personal" : {
        "FirstName" : "Mike",
        "Surname" : "Casey"
    },
    "Emails" : {
        "Preferred" : "work",
        "Entries" : {
            "work" : {
                "SmtpAddress" : "mike@test.com"
            }
        }
    }
}

The above document has some entries based on some typical activity on our Launch Sitecore site.  For instance, by registering we've gathered some "Personal" values and "Emails" values.  Notice there is no Pictures section of this document.  As expected with this NoSQL strategy, the document continues to build as information is collected.

Step 3.  Understand a bit about facets

As Adam explains, the Experience Profile makes use of Contact "facets".  As of Sitecore 8, the Sitecore.Analytics.Model.Config file contains the default facets, as shown below:
Default Facets in the Sitecore 8 Sitecore.Analytics.Model.Config

Since "Picture" is already an available facet, nothing to do here.  Adam explains the process of adding new facets and leveraging those new facets in a new SPEAK-based tab on the Experience Profile.

Step 4.  Get some code to write to the Picture facet

Still getting my terminology straight here, but basically we want to add a Picture section to that original Contact document shown in step 2 for Abraham Lincoln.  Thankfully, our friends at Horizontal Integration have already done the heavy lifting here:
Horizontal Integration Code to write to the Contact's Picture
As an aside, you'll be likely looking for some assembly references to use the above, so just in case:


Now, by having a Media Library item with Abraham's picture and replacing the GetItem statement above with its GUID, we're good to go.

Since this isn't a real-world example and just an investigation, I went ahead and created a control that just runs the above code when I visit my page on my local Launch Sitecore instance.  I'm really interested in the real-world sources for this picture--social, CRM, etc.  And now I'm more interested in taking the next steps in understanding the power this type of access to xDB unleashes in Sitecore 8 projects.  I'll leave you with the new section of the Abraham Lincoln Contact document:
Abraham Lincoln Contact Document with Picture


And now we can see good 'ol Abe's smiling face when we access all the great detail of his Experience Profile (and no copy-and-paste this time around!):
Searching for Abe and seeing our new picture facet


Tuesday, February 3, 2015

10 Days of Sitecore 8 Analytics. Day 2: Insights from the Experience Profile

Introduction to today's discussion

The Experience Profile is a new Sitecore view into analytics that provides incredible insight at a visitor (Contact) level.  From pages viewed, to patterns / personas matched to campaigns triggered to goals achieved, the Experience Profile paints a full picture of your visitors' interactions with your brand.

Today we'll take a bit of a deeper dive into this Experience Profile.  For those of you on the tech side, this view shows the power of what SPEAK interfaces can become in Sitecore, and as we get to the end of this series we'll see the ability to customize these views, add tabs to the reporting interface and more.  For this post I wanted make sure that some of the simple goals, campaigns and page events in our Launch Sitecore site are ready for the Experience Profile, and ready for those deeper conversations.

A reminder of what the Experience Profile looks like and what we'll be drilling into

Experience Profile with the Contact Timeline showing

Marketing Control Panel Considerations for the timeline


Campaign

For this exercise, I set up a new Campaign in Sitecore's Marketing Control Panel (as everything now is, one click away in the Sitecore 8 Launch Pad).  To those familiar with DMS, this is the same idea as the Marketing Center, the area of the content tree dedicated to setting up marketing initiatives.  I set up a new Campaign to track called "Video Blog Campaign" (our team is working on demo and other instructional videos that we plan to have a home for soon).


Some things to note that have been added to Sitecore 8.  The Campaign Group is a drop-down selector to allow us to start considering a richer taxonomies for our campaign organization.  This will become important later as we start looking at Campaign reports.  I added a new Campaign Group (Mike Campaigns) in this Taxonomies section, and it became available in the Campaign Group drop-list as I set up the Video Blog Campaign itself:

New Taxonomies Section for Campaign Management
  

Goals and Page Events

We can keep the goals we already have in place for Launch Sitecore.  These represent simple "transactions" that we are trying to encourage our visitors to take part in, like downloading the Launch Sitecore package, visiting certain targeted pages, adding articles to a logged in user's persistent profile:
List of Goals for LaunchSitecore.net

One interesting addition to Goals is shown below:

A Goal item shown in the Content Editor
Note that a new "Experience Profile Options" section with two checkbox field are now available for Goals (they are also available for Page Events).  This gives us the option to make sure these goals / conversions are prominently displayed on our Contacts' Experience Profile Reports.

With these simple Campaigns and Goals in place (and making sure all of these items are Deployed and Published), we can now start to see Abraham Lincoln's visit history start to take shape.

Below is a section of the Timeline where we can start to chart various interaction points with our Contact:

The Timeline gives us visual cues representing Goals achieved and Campaigns triggered.  It gives us a bar graph indication of value for the various visits from our Contact.  Below the Timeline we are able to see specific Goals achieved, the nature of the Campaign that was triggered, Page Views, Value and more.

Since we had many of the Digital Marketing considerations in place with Launch Sitecore (which started on Sitecore 6.6), we were able to ready the site for new Sitecore 8 features very easily.  The public site at launchsitecore.net is now on Sitecore 8 and tracking all this great Contact data so that we can enjoy the new insights that the Experience Profile and other analytics views provide.