3

I did a "roll my own" implementation of Geo IP Location, instead of paying for the Sitecore one.

My data is getting recorded. I can see it under each contacts profile details.

But when I go into the Experience Analytics Dashboard > Audience > Locations the Country and Region show only [unknown country] and [unknown region]

The city is filled out just fine.

I am guessing this is because country and region are being expected in some specific format.

Here we see country is recorded for contacts. Country is recorded

But here, we see that all countries show up as unknown. All countries shown up as unknown


UPDATE: This is my implementation code:

using Newtonsoft.Json;
using Sitecore;
using Sitecore.Analytics.Lookups;
using Sitecore.Analytics.Model;
using Sitecore.Diagnostics;
using System;
using System.Net;


namespace MySite.Analytics
{
    public class IPLookupProvider : LookupProviderBase
    {
        [UsedImplicitly]
        public override WhoIsInformation GetInformationByIp(string ipAddress)
        {
            WhoIsInformation whois = new WhoIsInformation();
            if (!string.IsNullOrWhiteSpace(ipAddress))
            {
                try
                {
                    if (Location.IsPrivateIP(ipAddress) == false)
                    {

                        Uri geoLocationServiceUrl = new Uri("https://freegeoip.net/json/" + ipAddress);
                        WebClient client = new WebClient();
                        var serviceResponse = client.DownloadString(geoLocationServiceUrl);
                        dynamic serviceData = JsonConvert.DeserializeObject(serviceResponse);

                        whois.City = serviceData.city ?? string.Empty;
                        whois.MetroCode = serviceData.metro_code.ToString() ?? string.Empty;
                        whois.Region = serviceData.region_name ?? string.Empty;
                        whois.PostalCode = serviceData.zip_code ?? string.Empty;
                        whois.Country = serviceData.country_name ?? string.Empty;
                        whois.Latitude = serviceData.latitude ?? 0;
                        whois.Longitude = serviceData.longitude ?? 0;
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("JDA.Analytics.IPLookupProvider.GetInformationByIp: " + ex.StackTrace.ToString(), ex, "Location");
                }
            }
            return whois;
        }
    }
}

And my patch file:

<lookupManager>
    <patch:attribute name="defaultProvider">custom</patch:attribute>
    <providers>
        <add name="custom" type="MySite.Analytics.IPLookupProvider, MySite.Analytics"/>
    </providers>
</lookupManager>

When I look in Mongo it appears that all the Country, Region, etc. fields are "N/A". But if I look at the details for the Contact they are populated.

3
  • 1
    Hey, can you post what you have saved against the contacts in mongo's geoip collection. I believe you need to save the country code in "Country" property and that should an item in: /sitecore/system/Settings/Analytics/Lookups/Countries
    – josedbaez
    Dec 13, 2016 at 9:57
  • I was using the country and region name instead of the "code". I updated , and it appears that it may be working now. I will know more tomorrow once more data is populated. Dec 13, 2016 at 21:21
  • This was the trick! By using @dnstommy example and using the country and region codes instead of the names resulted in a working solution. Dec 15, 2016 at 16:22

1 Answer 1

3

Here is my roll you own provider. I have tested this in 8.0 and 8.1.

   public class IPLookupProvider : LookupProviderBase
    {
        [UsedImplicitly]
        public override WhoIsInformation GetInformationByIp(string ip)
        {
            Assert.ArgumentNotNull(ip, "ip");
            WhoIsInformation whoIsInformation = new WhoIsInformation();

            Log.Info("Looking up IP " + ip, "WhoIsInformation");

            try
            {
                string text = RequestIPData(ip);
                var matchCollection = Regex.Matches(text, "(?<=^|,)(\\\"[^\\\"]*\\\"|[^,]*)");

                if (text.IndexOf("IP_NOT_FOUND", StringComparison.Ordinal) >= 0)
                {
                    return ContactLocation.CreateUnknown();
                }


                string[] array = kickfireFormat.Split(',');
                if (matchCollection.Count == 0)
                {

                    throw new Exception("Unexpected format. Cannot parse the IP lookup response for IP address: {0}{1}{2}".FormatWith(ip, Environment.NewLine, text));
                }

                Log.Info("IP info is " + text, "WhoIsInformation");

                var model = JsonConvert.DeserializeObject<IpLookup.RootObject>(text);

                if (model != null
                    && model.status == "success")
                {
                    double latitude = 0;
                    double longitude = 0;

                    whoIsInformation.BusinessName = model.data.name;
                    whoIsInformation.City = model.data.city;
                    whoIsInformation.Country = model.data.country;
                    double.TryParse(model.data.latitude, out latitude);
                    double.TryParse(model.data.longitude, out longitude);

                    whoIsInformation.Latitude = latitude;
                    whoIsInformation.Longitude = longitude;

                    whoIsInformation.Region = model.data.region;

                }

                Log.Info("Model was successful." + whoIsInformation.BusinessName + "-" + whoIsInformation.City, "WhoIsInformation");

            }
            catch (Exception exception)
            {
                Logging.Helpers.Logging.LogError(exception.StackTrace, exception);
            }
            return whoIsInformation;
        }

The RequestIP data looks like this

{  
   "status":"success",
   "result":1,
   "data":{  
      "name":"Vodafone GmbH",
      "city":"Disteln",
      "region":"Nordrhein-Westfalen",
      "countryShort":"DE",
      "country":"Germany",
      "latitude":"51.606010",
      "longitude":"7.149110"
   }
}

Config

  <sitecore>
    <lookupManager>
      <x:attribute name="defaultProvider">bonfire</x:attribute>
      <providers>
        <add name="bonfire" type="YourApp.IPLookupProvider, YourApp"/>
      </providers>
    </lookupManager>
  </sitecore>

Also have you looking in Mongo to see if you country is there and valid? Its in the GeoIP table.

enter image description here

7
  • Thanks, I will take a look into this when I am back in the office on Thursday Nov 16, 2016 at 5:01
  • You will see my update above. Still not working. I noticed in your code you push the "country" attribute. But in your GeoIP your data looks like "countryShort". Nov 17, 2016 at 20:47
  • Did you ever solve this?
    – Chris Auer
    Dec 8, 2016 at 15:42
  • Nope. Implemented the suggested changes with no change. :( Dec 8, 2016 at 16:01
  • By using this example AND using the country and region codes (as josedbaez suggested) instead of the names I now have a working solution. Dec 15, 2016 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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