9

In the Sitecore Experience Profile -- on the right side of a contact detail page --- you will see a section labeled Latest Visit.

It has fields for City, Region, Country.

I understand that if you purchase the Geo Location service from Sitecore this gets filled in.

If we want to fill it in with another source of data -- is this possible? I can't seem to find this visit item exposed anywhere under the contact facets.

I am utilizing Sitecore 8.1 Update 2.

  • I see the items under Interactions, but they all appear to be read only (i.e. get only, no set). Obviously, I must be approaching it wrong. I will update the post with a screenshot when I have actual access to my Sitecore instance on Monday. – eat-sleep-code Oct 22 '16 at 4:10
6

Answer

It is possible to set this data on your own. It can be done as Gatogordo suggests, using the following code snippet.

Tracker.Current.Session.Interaction.SetGeoData(new WhoIsInformation 
{ City = "Boston", Country= "US", Region = "North America" });

However, it's important to know how this data is initially collected in an out-of-the-box scenario.

Background Information for Sitecore Version 8+

Within Sitecore Analytics, if you do a search in your configs for UpdateGeoIpData, you'll find 4 pipelines with a processor to handle retrieving this information. Each pipeline cares a little differently depending on what's going on. UpdateGeoIpData() on the Interaction returns a bool value depending on the success of gathering GeoIP data.

Those pipelines include:

  • commitSession <processor type="Sitecore.Analytics.Pipelines.CommitSession.UpdateGeoIpData, Sitecore.Analytics" patch:source="Sitecore.Analytics.Tracking.Database.config"/>
    • This is the last line of defense in the system for making sure that GeoIP data can be recorded.
  • createVisit <processor type="Sitecore.Analytics.Pipelines.CreateVisits.UpdateGeoIpData, Sitecore.Analytics"/>
    • This is making sure that the GeoData is set on the Interaction when the visit is first created.
  • ensureClassification <processor type="Sitecore.Analytics.Pipelines.EnsureClassification.UpdateGeoIpData, Sitecore.Analytics"/>
    • This processor actually is a precursor processor for other functionality. It's purposes is to set the ShouldClassificationBeGuessed argument for the continuation of that pipeline. It utilizes !Tracker.Current.Interaction.UpdateGeoIpData(); as it's conditional statement. There is a side effect that in the envent the VisitData.GeoData is null, it will go ahead and attempt to set the geographical information. If the GeoData is present, it returns a fast true.
  • startTracking <processor type="Sitecore.Analytics.Pipelines.StartTracking.UpdateGeoIpData, Sitecore.Analytics"/>
    • This processor initially populates the GeoData inSession Interaction on Tracker.Current.Session.

Specifically, these pipeline processes utilize Session.Interaction.UpdateGeoIpData(Timespan). Also important to note that Interaction is actually based off of CurrentInteraction which is an abstract class. There are four out-of-the-box implementations of this class, of which CurrentVisitContext is most commonly used:

enter image description here

Unfortunately, CurrentVisitContext is NOT a class that can easily be extended or overridden through Sitecore configuration patching.

A Closer Look at the Start Tracking Processor

  public class UpdateGeoIpData : StartTrackingProcessor
  {
    public override void Process(StartTrackingArgs args)
    {
      Assert.IsNotNull((object) Tracker.Current, "Tracker.Current is not initialized");
      Assert.IsNotNull((object) Tracker.Current.Session, "Tracker.Current.Session is not initialized");
      if (Tracker.Current.Session.Interaction == null)
        return;
      Tracker.Current.Session.Interaction.UpdateGeoIpData();
    }
  }

Notice it's a pretty simple processor. There is also an Expiry option for location data. Out of the box, the Expiry is turned off (hence TimeSpan.MaxValue). However, this is an option.

Rolling Your Own - Overriding Default Functionality

To override default functionality and seed your own Geographical Data, I would create processors of your own, mimicking the 4 processors mentioned above. This would ensure that your custom implementation is not confused with the out-of-the-box.

An Example
  public class CustomGeoIpData : StartTrackingProcessor
  {
    public override void Process(StartTrackingArgs args)
    {
      Assert.IsNotNull((object) Tracker.Current, "Tracker.Current is not initialized");
      Assert.IsNotNull((object) Tracker.Current.Session, "Tracker.Current.Session is not initialized");
      if (Tracker.Current.Session.Interaction == null)
        return;
      Tracker.Current.Session.Interaction.SetGeoData(new WhoIsInformation { City = "Boston", Country= "US", Region = "North America" });
    }
  }

By setting it here in startTracking pipeline or createVisit pipeline, all other instances, which utilize UpdateGeoIpData(), will be ignored. This is because the very first thing UpdateGeoIpData() does is a check to see if VistiData.GeoData is set, which SetGeoData() does directly.

public override bool UpdateGeoIpData(TimeSpan timeout)
{
  VisitData visitData = this.visitData;
  if (visitData.GeoData != null)
    return true;

  ...  snipped code ....

  return true;
}

Lastly, you can also run SetGeoIpData() during the course of a visit through code, to overwrite the data previously set.

  • I have this code: WhoIsInformation whois = new WhoIsInformation(); whois.City = serviceData.city; whois.MetroCode = serviceData.metro_code.ToString(); whois.Region = serviceData.region_name; whois.PostalCode = serviceData.zip_code; whois.Country = serviceData.country_name; whois.Latitude = serviceData.latitude; whois.Longitude = serviceData.longitude; Tracker.Current.Interaction.SetGeoData(whois); I am getting an Object reference not set to an instance error on the last line? – eat-sleep-code Oct 24 '16 at 19:52
  • Is Tracker.Current = null? – Pete Navarra Oct 24 '16 at 21:25
  • Above this code I call var contact = Tracker.Current.Session.Contact; and that works fine so not sure how it could become suddenly null? – eat-sleep-code Oct 24 '16 at 21:29
  • I would need to see the stack trace of the error. Might be coming from serviceData. – Pete Navarra Oct 24 '16 at 22:37
  • find me on Slack or shoot me an email. – Pete Navarra Oct 24 '16 at 22:39
6

I'm sure Pete will elaborate further on this, but to get you going already: the property on the Interaction is indeed only a getter, but there is a function called SetGeoData. This would end up in this:

Tracker.Current.Interaction.SetGeoData(new WhoIsInformation { City = "", Country= "", Region = "" });

Found some code here that fills the geo data (amongst others) that you can use as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.