Reputation: 1469
I created a custom GEOIP provider but the code I have always returns unknown country in Experience Analytics.
Below are my codes:
public class GeoLiteProvider : LookupProviderBase
{
public override WhoIsInformation GetInformationByIp(string ip)
{
const string ModuleName = "Utilities.GeoIP";
string vLogging = Settings.GetSetting(ModuleName + ".VerboseLogging", "false");
bool vLoggingResult = false;
bool verboseLogging = bool.TryParse(vLogging, out vLoggingResult);
if (!vLoggingResult)
{
verboseLogging = false;
}
WebRequest rssReq = WebRequest.Create("http://www.telize.com/geoip/" + ip);
WebProxy px = new WebProxy("http://www.telize.com/geoip/" + ip, true);
rssReq.Proxy = px;
rssReq.Timeout = 2000;
WhoIsInformation information = new WhoIsInformation();
try
{
WebResponse rep = rssReq.GetResponse();
StreamReader content = new StreamReader(rep.GetResponseStream());
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
System.Collections.Generic.Dictionary<string, object> jsonObject = (System.Collections.Generic.Dictionary<string, object>)serializer.DeserializeObject(content.ReadToEnd());
if (jsonObject != null)
{
information.Country = jsonObject["country"] != null ? jsonObject["country"].ToString() : string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.Country = " + information.Country, this);
}
information.Region = jsonObject["region"] != null ? jsonObject["region"].ToString() : string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.Region = " + information.Region, this);
}
information.City = jsonObject["city"] != null ? jsonObject["city"].ToString() : string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.City = " + information.City, this);
}
information.PostalCode = string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.PostalCode = " + information.PostalCode, this);
}
information.Latitude = double.Parse(jsonObject["latitude"].ToString());
if (verboseLogging)
{
Log.Info(ModuleName + ": information.Latitude = " + information.Latitude, this);
}
information.Longitude = double.Parse(jsonObject["longitude"].ToString());
if (verboseLogging)
{
Log.Info(ModuleName + ": information.Longitude = " + ((information.Longitude == 0) ? string.Empty : information.Longitude.ToString()), this);
}
information.MetroCode = string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.MetroCode = " + information.MetroCode, this);
}
information.AreaCode = jsonObject["area_code"] != null ? jsonObject["area_code"].ToString() : string.Empty;
if (verboseLogging)
{
Log.Info(ModuleName + ": information.AreaCode = " + information.AreaCode, this);
}
}
else
{
Log.Info(ModuleName + ": IP location cannot be determined. IP Address: " + ip, this);
information.BusinessName = Settings.GetSetting(ModuleName + ".NoLocationText", "Not Available");
}
if (verboseLogging)
{
Log.Info(ModuleName + ": IP Lookup Complete", this);
}
}
catch(Exception ex)
{
Log.Error(ModuleName + ": Exception occurred. Exception: " + ex.Message, this);
}
return information;
}}
Config Patch:
<lookupManager>
<patch:attribute name="defaultProvider">geoLite</patch:attribute>
<providers>
<add patch:after="*[@type='Sitecore.Analytics.Lookups.MaxMindProvider,Sitecore.Analytics']" name="geoLite" type="Core.Utilities.LookupProvider.GeoLiteProvider, Core.Utilities" />
</providers>
</lookupManager>
I also created a pipeline to override the IP address so I could verify it in my local machine but still fails.
public class OverrideIPAddress
{
public void Process(StartTrackingArgs args)
{
Tracker.Current.Interaction.Ip = System.Net.IPAddress.Parse("1.68.0.0").GetAddressBytes();
}
}
Sitecore.Analytics.Tracking.Config:
<startTracking>
<processor type="Sitecore.Analytics.Pipelines.StartTracking.RaiseStartTracking, Sitecore.Analytics" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.InitializeTracker, Sitecore.Analytics" />
<processor type="Utilities.GEOIP.OverrideIPAddress, Core.Utilities" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.TrackerInitialized, Sitecore.Analytics" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.UpdateGeoIpData, Sitecore.Analytics" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.ProcessQueryStringCampaign, Sitecore.Analytics" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.ProcessQueryStringPageEvent, Sitecore.Analytics" />
<processor type="Sitecore.Analytics.Pipelines.StartTracking.ProcessQueryStringTriggers, Sitecore.Analytics">
<triggers hint="raw:AddTrigger">
<trigger querystring="sc_rss" eventname="RSS"/>
</triggers>
</processor>
<processor type="Sitecore.Analytics.Pipelines.StartTracking.ProcessItem, Sitecore.Analytics"/>
</startTracking>
Here is what I get when I debugg in my local machine:
Additionally, I added this in my BaseLayouts.
@Html.Sitecore().VisitorIdentification()
Let me know what I've missing.
Upvotes: 2
Views: 1237
Reputation: 1346
I'm fairly certain the Countries need to be country codes that line up with the items in the path /sitecore/system/Settings/Analytics/Lookups/Countries
You'll notice that those items all have a "Country code" field and this is the value you generally find in the analytics data.
Judging by what you posted above I am guessing that your service returns the full name? I would suggest setting up a static dictionary in the Init pipeline that reads all the CountryItem values keyed on Country name and you can use that to encode the values from your service. There may already be a dictionary like this in Sitecore somewhere but with only a cursory glance I wasn't able to locate one.
Upvotes: 0