Wednesday, January 23, 2013

Google Analytics Business Intelligence Project with C-Sharp

The following information will provide the detailed steps on how to navigate data in Google Analytics through Query Explorer and how to retrieve data from GA to Integration service using C sharp coding.




First we can see creating class files to write coding to retrieve data from Google Analytics

Open – MS Visual Studio 2012
Go to – File – New – Project and proceed as given in the below figure:

Click Ok to go to class file screen as given in the below figures:


Name the class file and type coding.

Can add the class files by right click on the Project Name – Add – Class – name it and save.

Below are the list of class files needed to retrieve data from Google Analytics

AnalyticsAccountInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoogleAnalyticsSupport
{
public class AnalyticsAccountInfo
{
#region Fields

private string _id = null;
private string _title = null;
private string _accountId = null;
private string _accountName = null;
private string _profileId = null;
private string _webProperty = null;

#endregion

#region Properties

public string ID
{
get { return _id; }
set { _id = value; }
}

public string Title
{
get { return _title; }
set { _title = value; }
}

public string AccountID
{
get { return _accountId; }
set { _accountId = value; }
}

public string AccountName
{
get { return _accountName; }
set { _accountName = value; }
}

public string ProfileID
{
get { return _profileId; }
set { _profileId = value; }
}

public string WebPropertyID
{
get { return _webProperty; }
set { _webProperty = value; }
}
#endregion
}
}

Dimension.cs

All the possible dimensions are added in the class file to use in the script component task in SSIS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoogleAnalyticsSupport
{
public enum Dimension
{
visitorType,
visitCount,
daysSinceLastVisit,
userDefinedValue,
visitLength,
referralPath,
campaign,
source,
medium,
keyword,
adContent,
socialNetwork,
hasSocialSourceReferral,
adGroup,
adSlot,
adSlotPosition,
adDistributionNetwork,
adMatchType,
adMatchedQuery,
adPlacementDomain,
adPlacementUrl,
adFormat,
adTargetingType,
adTargetingOption,
adDisplayUrl,
adDestinationUrl,
adwordsCustomerID,
adwordsCampaignID,
adwordsAdGroupID,
adwordsCreativeID,
adwordsCriteriaID,
browser,
browserVersion,
operatingSystem,
operatingSystemVersion,
isMobile,
mobileDeviceBranding,
mobileDeviceModel,
mobileInputSelector,
mobileDeviceInfo,
continent,
subContinent,
country,
metro,
region,
city,
latitude,
longitude,
networkDomain,
networkLocation,
flashVersion,
javaEnabled,
language,
screenColors,
screenResolution,
socialActivityEndorsingUrl,
socialActivityDisplayName,
socialActivityPost,
socialActivityTimestamp,
socialActivityUserHandle,
socialActivityUserPhotoUrl,
socialActivityUserProfileUrl,
socialActivityContentUrl,
socialActivityTagsSummary,
socialActivityAction,
socialActivityNetworkAction,
hostname,
pagePath,
pagePathLevel1,
pagePathLevel2,
pagePathLevel3,
pagePathLevel4,
pageTitle,
landingPagePath,
secondPagePath,
exitPagePath,
previousPagePath,
nextPagePath,
pageDepth,
searchUsed,
searchKeyword,
searchKeywordRefinement,
searchCategory,
searchStartPage,
searchDestinationPage,
eventCategory,
eventAction,
eventLabel,
transactionId,
affiliation,
visitsToTransaction,
daysToTransaction,
productSku,
productName,
productCategory,
socialInteractionNetwork,
socialInteractionAction,
socialInteractionNetworkAction,
socialInteractionTarget,
userTimingCategory,
userTimingLabel,
userTimingVariable,
customVarNamen,
customVarValuen,
date,
month,
year,
week,
day,
hour,
nthMonth,
nthWeek,
nthDay,
dayOfWeek
}
}

Metric.cs

All the possible metics are added in the class file to use in the script component task in SSIS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoogleAnalyticsSupport
{
public enum Metric
{
visitors,
newVisits,
percentNewVisits,
visits,
bounces,
entranceBounceRate,
visitBounceRate,
timeOnSite,
avgTimeOnSite,
organicSearches,
impressions,
adClicks,
adCost,
CPM,
CPC,
CTR,
costPerTransaction,
costPerGoalConversion,
costPerConversion,
RPC,
ROI,
margin,
goalnStarts,
goalStartsAll,
goalnCompletions,
goalCompletionsAll,
goalnValue,
goalValueAll,
goalValuePerVisit,
goalnConversionRate,
goalConversionRateAll,
goalnAbandons,
goalAbandonsAll,
goalnAbandonRate,
goalAbandonRateAll,
socialActivities,
entrances,
entranceRate,
pageviews,
pageviewsPerVisit,
uniquePageviews,
timeOnPage,
avgTimeOnPage,
exits,
exitRate,
searchResultViews,
searchUniques,
avgSearchResultViews,
searchVisits,
percentVisitsWithSearch,
searchDepth,
avgSearchDepth,
searchRefinements,
searchDuration,
avgSearchDuration,
searchExits,
searchExitRate,
searchGoalnConversionRate,
searchGoalConversionRateAll,
goalValueAllPerSearch,
pageLoadTime,
pageLoadSample,
avgPageLoadTime,
domainLookupTime,
avgDomainLookupTime,
pageDownloadTime,
avgPageDownloadTime,
redirectionTime,
avgRedirectionTime,
serverConnectionTime,
avgServerConnectionTime,
avgServerResponseTime,
serverResponseTime,
speedMetricsSample,
appviews,
uniqueAppviews,
appviewsPerVisit,
totalEvents,
uniqueEvents,
eventValue,
avgEventValue,
visitsWithEvent,
eventsPerVisitWithEvent,
transactions,
transactionsPerVisit,
transactionRevenue,
revenuePerTransaction,
transactionRevenuePerVisit,
transactionShipping,
transactionTax,
totalValue,
itemQuantity,
uniquePurchases,
revenuePerItem,
itemRevenue,
itemsPerPurchase,
socialInteractions,
uniqueSocialInteractions,
socialInteractionsPerVisit,
userTimingValue,
userTimingSample,
avgUserTimingValue,
exceptions,
fatalExceptions

}
}

GenericEntry.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoogleAnalyticsSupport
{
public class GenericEntry
{
#region Fields
List<KeyValuePair<Dimension, string>> _dimensions = null;
List<KeyValuePair<Metric, string>> _metrics = null;
List<KeyValuePair<Sort, string>> _sorts = null;
#endregion
#region Properties
public List<KeyValuePair<Dimension, string>> Dimensions
{
get { return _dimensions; }
set { _dimensions = value; }
}
public List<KeyValuePair<Metric, string>> Metrics
{
get { return _metrics; }
set { _metrics = value; }
}
public List<KeyValuePair<Sort, string>> Sorts
{
get { return _sorts; }
set { _sorts = value; }
}
#endregion
}
}


ReportRequestor.cs

It is a common class file to retrieve data with dimensions and metrics

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;

namespace GoogleAnalyticsSupport
{
public class ReportRequestor
{
#region Fields

private static readonly string requestUrlFormat = "https://www.google.com/analytics/feeds/data?ids={0}&dimensions={1}&metrics={2}&start-date={3}&end-date={4}&start-index={5}&max-results={6}";
private static readonly string authUrlFormat = "accountType=GOOGLE&Email={0}&Passwd={1}&source=reimers.dk-analyticsreader-0.1&service=analytics";
private static CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
private string _token = null;
private string _username = null;
private string _password = null;

#endregion

#region Constructor

public ReportRequestor() { }

public ReportRequestor(string email, string password)
{
_username = email;
_password = password;
}

#endregion

#region Properties

public string Email
{
get { return _username; }

set
{
if (!string.Equals(_username, value))
{
_username = value;
_token = null;
}
}
}

public string Password
{
get { return _password; }
set
{
if (!string.Equals(_password, value))
{
_password = value;
_token = null;
}
}
}

#endregion

#region Methods

private string GetToken(string username, string password)
{
if (string.IsNullOrEmpty(_username) || string.IsNullOrEmpty(_password))
{
throw new ArgumentNullException("Username, Password", "Username and/or password not set");
}

string authBody = string.Format(authUrlFormat, username, password);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.UserAgent = "Example.dk req";

Stream stream = req.GetRequestStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(authBody);
sw.Close();
sw.Dispose();

HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string token = sr.ReadToEnd();
string[] tokens = token.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string item in tokens)
{
if (item.StartsWith("Auth="))
{
return item.Replace("Auth=", "");
}
}

return string.Empty;
}

public IEnumerable<AnalyticsAccountInfo> GetAccounts()
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string responseXml = sr.ReadToEnd();

XDocument doc = XDocument.Parse(responseXml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var entries = from en in doc.Root.Descendants(defaultSpace + "entry")
select new AnalyticsAccountInfo
{
AccountID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountId").First().Attribute("value").Value,
AccountName = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountName").First().Attribute("value").Value,
ID = en.Element(defaultSpace + "id").Value,
Title = en.Element(defaultSpace + "title").Value,
ProfileID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:profileId").First().Attribute("value").Value,
WebPropertyID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:webPropertyId").First().Attribute("value").Value
};

return entries;
}

private XDocument getReport(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics, DateTime from, DateTime to, int startindex=1, int maxresults = 10000)
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

StringBuilder dims = new StringBuilder();

foreach (Dimension item in dimensions)
{
dims.Append("ga:" + item.ToString() + ",");
}

StringBuilder mets = new StringBuilder();

foreach (Metric item in metrics)
{
mets.Append("ga:" + item.ToString() + ",");
}

string requestUrl = string.Format(requestUrlFormat, "ga:" + account.ProfileID, dims.ToString().Trim(",".ToCharArray()), mets.ToString().Trim(",".ToCharArray()), from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"), startindex, maxresults);

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
string responseXml = new StreamReader(responseStream, Encoding.UTF8, true).ReadToEnd();
XDocument doc = XDocument.Parse(responseXml);

return doc;
}
public IEnumerable<GenericEntry> RequestReport(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics, DateTime from, DateTime to,int startindex=1, int maxresults=10000)
{
XDocument doc = getReport(account, dimensions, metrics, from, to, startindex, maxresults);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var gr = from r in doc.Root.Descendants(defaultSpace + "entry")
select new GenericEntry
{
Dimensions = new List<KeyValuePair<Dimension, string>>(
from rd in r.Elements(dxpSpace + "dimension")
select new KeyValuePair<Dimension, string>(
(Dimension)Enum.Parse(
typeof(Dimension),
rd.Attribute("name").Value.Replace("ga:", ""),
true),
rd.Attribute("value").Value)),
Metrics = new List<KeyValuePair<Metric, string>>(
from rm in r.Elements(dxpSpace + "metric")
select new KeyValuePair<Metric, string>(
(Metric)Enum.Parse(typeof(Metric), rm.Attribute("name").Value.Replace("ga:", ""), true),
rm.Attribute("value").Value))
};

return gr;
}

#endregion
}
}

ReportRequestorWithoutDimension.cs

It is a class file to retrieve data without having dimensions. Metrics value only.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;

namespace GoogleAnalyticsSupport
{
public class ReportRequestorWithoutDimension
{
#region Fields

private static readonly string requestUrlFormat = "https://www.google.com/analytics/feeds/data?ids={0}&metrics={1}&start-date={2}&end-date={3}&max-results={4}";
private static readonly string authUrlFormat = "accountType=GOOGLE&Email={0}&Passwd={1}&source=reimers.dk-analyticsreader-0.1&service=analytics";
private static CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
private string _token = null;
private string _username = null;
private string _password = null;

#endregion

#region Constructor

public ReportRequestorWithoutDimension() { }

public ReportRequestorWithoutDimension(string email, string password)
{
_username = email;
_password = password;
}

#endregion

#region Properties

public string Email
{
get { return _username; }

set
{
if (!string.Equals(_username, value))
{
_username = value;
_token = null;
}
}
}

public string Password
{
get { return _password; }
set
{
if (!string.Equals(_password, value))
{
_password = value;
_token = null;
}
}
}

#endregion

#region Methods

private string GetToken(string username, string password)
{
if (string.IsNullOrEmpty(_username) || string.IsNullOrEmpty(_password))
{
throw new ArgumentNullException("Username, Password", "Username and/or password not set");
}

string authBody = string.Format(authUrlFormat, username, password);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.UserAgent = "Example.dk req";

Stream stream = req.GetRequestStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(authBody);
sw.Close();
sw.Dispose();

HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string token = sr.ReadToEnd();
string[] tokens = token.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string item in tokens)
{
if (item.StartsWith("Auth="))
{
return item.Replace("Auth=", "");
}
}

return string.Empty;
}

public IEnumerable<AnalyticsAccountInfo> GetAccounts()
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string responseXml = sr.ReadToEnd();

XDocument doc = XDocument.Parse(responseXml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var entries = from en in doc.Root.Descendants(defaultSpace + "entry")
select new AnalyticsAccountInfo
{
AccountID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountId").First().Attribute("value").Value,
AccountName = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountName").First().Attribute("value").Value,
ID = en.Element(defaultSpace + "id").Value,
Title = en.Element(defaultSpace + "title").Value,
ProfileID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:profileId").First().Attribute("value").Value,
WebPropertyID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:webPropertyId").First().Attribute("value").Value
};

return entries;
}

private XDocument getReport(AnalyticsAccountInfo account, IEnumerable<Metric> metrics, DateTime from, DateTime to, int maxresults=10000)
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

StringBuilder mets = new StringBuilder();

foreach (Metric item in metrics)
{
mets.Append("ga:" + item.ToString() + ",");
}

string requestUrl = string.Format(requestUrlFormat, "ga:" + account.ProfileID,mets.ToString().Trim(",".ToCharArray()), from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"), maxresults);

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
string responseXml = new StreamReader(responseStream, Encoding.UTF8, true).ReadToEnd();
XDocument doc = XDocument.Parse(responseXml);

return doc;
}

public IEnumerable<GenericEntry> RequestReportwod(AnalyticsAccountInfo account
, IEnumerable<Metric> metrics, DateTime from, DateTime to, int maxresults=10000)
{
XDocument doc = getReport(account, metrics, from, to, maxresults);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var gr = from r in doc.Root.Descendants(defaultSpace + "entry")
select new GenericEntry
{
Dimensions = new List<KeyValuePair<Dimension, string>>(
from rd in r.Elements(dxpSpace + "dimension")
select new KeyValuePair<Dimension, string>(
(Dimension)Enum.Parse(
typeof(Dimension),
rd.Attribute("name").Value.Replace("ga:", ""),
true),
rd.Attribute("value").Value)),
Metrics = new List<KeyValuePair<Metric, string>>(
from rm in r.Elements(dxpSpace + "metric")
select new KeyValuePair<Metric, string>(
(Metric)Enum.Parse(typeof(Metric), rm.Attribute("name").Value.Replace("ga:", ""), true),
rm.Attribute("value").Value))
};

return gr;
}

#endregion
}
}


ReportRequestorWithSorting.cs

It is a class file to retrieve data by sorting in descending and ascending order

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;

namespace GoogleAnalyticsSupport
{
public class ReportRequestorWithSorting
{
#region Fields

private static readonly string requestUrlFormat = "https://www.google.com/analytics/feeds/data?ids={0}&dimensions={1}&metrics={2}&sort={3}&start-date={4}&end-date={5}&start-index={6}&max-results={7}";
private static readonly string authUrlFormat = "accountType=GOOGLE&Email={0}&Passwd={1}&source=reimers.dk-analyticsreader-0.1&service=analytics";
private static CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
private string _token = null;
private string _username = null;
private string _password = null;

#endregion

#region Constructor

public ReportRequestorWithSorting() { }

public ReportRequestorWithSorting(string email, string password)
{
_username = email;
_password = password;

}

#endregion

#region Properties

public string Email
{
get { return _username; }

set
{
if (!string.Equals(_username, value))
{
_username = value;
_token = null;
}
}
}

public string Password
{
get { return _password; }
set
{
if (!string.Equals(_password, value))
{
_password = value;
_token = null;
}
}
}

#endregion

#region Methods

private string GetToken(string username, string password)
{
if (string.IsNullOrEmpty(_username) || string.IsNullOrEmpty(_password))
{
throw new ArgumentNullException("Username, Password", "Username and/or password not set");
}

string authBody = string.Format(authUrlFormat, username, password);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.UserAgent = "Example.dk req";

Stream stream = req.GetRequestStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(authBody);
sw.Close();
sw.Dispose();

HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string token = sr.ReadToEnd();
string[] tokens = token.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string item in tokens)
{
if (item.StartsWith("Auth="))
{
return item.Replace("Auth=", "");
}
}

return string.Empty;
}

public IEnumerable<AnalyticsAccountInfo> GetAccounts()
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string responseXml = sr.ReadToEnd();

XDocument doc = XDocument.Parse(responseXml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var entries = from en in doc.Root.Descendants(defaultSpace + "entry")
select new AnalyticsAccountInfo
{
AccountID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountId").First().Attribute("value").Value,
AccountName = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountName").First().Attribute("value").Value,
ID = en.Element(defaultSpace + "id").Value,
Title = en.Element(defaultSpace + "title").Value,
ProfileID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:profileId").First().Attribute("value").Value,
WebPropertyID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:webPropertyId").First().Attribute("value").Value
};

return entries;
}

private XDocument getReport(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics
, IEnumerable<Sort> sorts, DateTime from, DateTime to, int startindex = 1, int maxresults = 250)
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

StringBuilder dims = new StringBuilder();

foreach (Dimension item in dimensions)
{
dims.Append("ga:" + item.ToString() + ",");
}

StringBuilder mets = new StringBuilder();

foreach (Metric item in metrics)
{
mets.Append("ga:" + item.ToString() + ",");
}
StringBuilder srt = new StringBuilder();

foreach (Sort item in sorts)
{
srt.Append("-" + "ga:" + item.ToString() + ",");
}
string requestUrl = string.Format(requestUrlFormat, "ga:" + account.ProfileID, dims.ToString().Trim(",".ToCharArray()), mets.ToString().Trim(",".ToCharArray())
, srt.ToString().Trim(",".ToCharArray()), from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"), startindex, maxresults);

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
string responseXml = new StreamReader(responseStream, Encoding.UTF8, true).ReadToEnd();
XDocument doc = XDocument.Parse(responseXml);

return doc;
}


public IEnumerable<GenericEntry> ReportRequestWF(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics
, IEnumerable<Sort> sorts, DateTime from, DateTime to, int startindex = 1, int maxresults = 250)
{
XDocument doc = getReport(account, dimensions, metrics
, sorts, from, to, startindex, maxresults);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var gr = from r in doc.Root.Descendants(defaultSpace + "entry")
select new GenericEntry
{
Dimensions = new List<KeyValuePair<Dimension, string>>(
from rd in r.Elements(dxpSpace + "dimension")
select new KeyValuePair<Dimension, string>(
(Dimension)Enum.Parse(
typeof(Dimension),
rd.Attribute("name").Value.Replace("ga:", ""),
true),
rd.Attribute("value").Value)),
Metrics = new List<KeyValuePair<Metric, string>>(
from rm in r.Elements(dxpSpace + "metric")
select new KeyValuePair<Metric, string>(
(Metric)Enum.Parse(typeof(Metric), rm.Attribute("name").Value.Replace("ga:", ""), true),
rm.Attribute("value").Value)),

Sorts = new List<KeyValuePair<Sort, string>>(
from rs in r.Elements(dxpSpace + "sort")
select new KeyValuePair<Sort, string>(
(Sort)Enum.Parse(typeof(Sort), rs.Attribute("name").Value.Replace("ga:", ""), true),
rs.Attribute("value").Value))

};

return gr;
}
#endregion
}
}

ReportRequestorWithFilterandSort.cs

It is a class file to retrieve data with filtering by some conditions and sorting by order

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;

namespace GoogleAnalyticsSupport
{
public class ReportRequestorWithFilterandSort
{
#region Fields

private static readonly string requestUrlFormat = "https://www.google.com/analytics/feeds/data?ids={0}&dimensions={1}&metrics={2}&filters={3}&sort={4}&start-date={5}&end-date={6}&start-index={7}&max-results={8}";
private static readonly string authUrlFormat = "accountType=GOOGLE&Email={0}&Passwd={1}&source=reimers.dk-analyticsreader-0.1&service=analytics";
private static CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
private string _token = null;
private string _username = null;
private string _password = null;

#endregion

#region Constructor

public ReportRequestorWithFilterandSort() { }

public ReportRequestorWithFilterandSort(string email, string password)
{
_username = email;
_password = password;
}

#endregion

#region Properties

public string Email
{
get { return _username; }

set
{
if (!string.Equals(_username, value))
{
_username = value;
_token = null;
}
}
}

public string Password
{
get { return _password; }
set
{
if (!string.Equals(_password, value))
{
_password = value;
_token = null;
}
}
}

#endregion

#region Methods

private string GetToken(string username, string password)
{
if (string.IsNullOrEmpty(_username) || string.IsNullOrEmpty(_password))
{
throw new ArgumentNullException("Username, Password", "Username and/or password not set");
}

string authBody = string.Format(authUrlFormat, username, password);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.UserAgent = "Example.dk req";

Stream stream = req.GetRequestStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(authBody);
sw.Close();
sw.Dispose();

HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string token = sr.ReadToEnd();
string[] tokens = token.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string item in tokens)
{
if (item.StartsWith("Auth="))
{
return item.Replace("Auth=", "");
}
}

return string.Empty;
}

public IEnumerable<AnalyticsAccountInfo> GetAccounts()
{
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
string responseXml = sr.ReadToEnd();

XDocument doc = XDocument.Parse(responseXml);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();

var entries = from en in doc.Root.Descendants(defaultSpace + "entry")
select new AnalyticsAccountInfo
{
AccountID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountId").First().Attribute("value").Value,
AccountName = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:accountName").First().Attribute("value").Value,
ID = en.Element(defaultSpace + "id").Value,
Title = en.Element(defaultSpace + "title").Value,
ProfileID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:profileId").First().Attribute("value").Value,
WebPropertyID = en.Elements(dxpSpace + "property").Where(xe => xe.Attribute("name").Value == "ga:webPropertyId").First().Attribute("value").Value
};

return entries;
}

private XDocument getReport(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics
, string filters, IEnumerable<Sort> sorts
,DateTime from, DateTime to, int startindex = 1, int maxresults = 250)
{
//string value = string.Empty;
if (string.IsNullOrEmpty(_token))
{
_token = GetToken(_username, _password);
}

StringBuilder dims = new StringBuilder();

foreach (Dimension item in dimensions)
{
dims.Append("ga:" + item.ToString() + ",");
}

StringBuilder mets = new StringBuilder();

foreach (Metric item in metrics)
{
mets.Append("ga:" + item.ToString() + ",");
}
StringBuilder srt = new StringBuilder();

foreach (Sort item in sorts)
{
srt.Append("-"+"ga:" + item.ToString() + ",");
}
//StringBuilder flt = new StringBuilder();

//foreach (Filter item in filters)
//{
// flt.Append("ga:" + item.ToString() + " ");//+ "%3D@Marriage");//.Equals("New York"));
//}
string requestUrl = string.Format(requestUrlFormat, "ga:" + account.ProfileID, dims.ToString().Trim(",".ToCharArray()), mets.ToString().Trim(",".ToCharArray())
,filters.ToString() , srt.ToString().Trim(",".ToCharArray()), from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"), startindex, maxresults);

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
req.Headers.Add("Authorization: GoogleLogin auth=" + _token);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();

Stream responseStream = response.GetResponseStream();
string responseXml = new StreamReader(responseStream, Encoding.UTF8, true).ReadToEnd();
XDocument doc = XDocument.Parse(responseXml);

return doc;
}


public IEnumerable<GenericEntry> ReportRequestWFS(AnalyticsAccountInfo account, IEnumerable<Dimension> dimensions, IEnumerable<Metric> metrics
, string filters, IEnumerable<Sort> sorts
, DateTime from, DateTime to, int startindex = 1, int maxresults = 250)
{
XDocument doc = getReport(account, dimensions, metrics
,filters, sorts, from, to, startindex, maxresults);
XNamespace dxpSpace = doc.Root.GetNamespaceOfPrefix("dxp");
XNamespace defaultSpace = doc.Root.GetDefaultNamespace();
string fil = string.Empty;
var gr = from r in doc.Root.Descendants(defaultSpace + "entry")
select new GenericEntry
{
Dimensions = new List<KeyValuePair<Dimension, string>>(
from rd in r.Elements(dxpSpace + "dimension")
select new KeyValuePair<Dimension, string>(
(Dimension)Enum.Parse(
typeof(Dimension),
rd.Attribute("name").Value.Replace("ga:", ""),
true),
rd.Attribute("value").Value)),
Metrics = new List<KeyValuePair<Metric, string>>(
from rm in r.Elements(dxpSpace + "metric")
select new KeyValuePair<Metric, string>(
(Metric)Enum.Parse(typeof(Metric), rm.Attribute("name").Value.Replace("ga:", ""), true),
rm.Attribute("value").Value)),
Sorts = new List<KeyValuePair<Sort, string>>(
from rs in r.Elements(dxpSpace + "sort")
select new KeyValuePair<Sort, string>(
(Sort)Enum.Parse(typeof(Sort), rs.Attribute("name").Value.Replace("ga:", ""), true),
rs.Attribute("value").Value)) //,
//Filters = new List<KeyValuePair<Filter, string>>(
// from rf in r.Elements(dxpSpace + "Filter")
// select new KeyValuePair<Filter, string>(
// (Filter)Enum.Parse(typeof(Filter), rf.Attribute("name").Value.Replace("ga:", ""), true),
// rf.Attribute("value").Value) )
};
return gr;
}
#endregion
}
}

Sort.cs

It is a class file to use for sorting functions

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoogleAnalyticsSupport
{
public enum Sort
{
visitorType,
visitCount,
daysSinceLastVisit,
userDefinedValue,
visitLength,
referralPath,
campaign,
source,
medium,
keyword,
adContent,
socialNetwork,
hasSocialSourceReferral,
adGroup,
adSlot,
adSlotPosition,
adDistributionNetwork,
adMatchType,
adMatchedQuery,
adPlacementDomain,
adPlacementUrl,
adFormat,
adTargetingType,
adTargetingOption,
adDisplayUrl,
adDestinationUrl,
adwordsCustomerID,
adwordsCampaignID,
adwordsAdGroupID,
adwordsCreativeID,
adwordsCriteriaID,
browser,
browserVersion,
operatingSystem,
operatingSystemVersion,
isMobile,
mobileDeviceBranding,
mobileDeviceModel,
mobileInputSelector,
mobileDeviceInfo,
continent,
subContinent,
country,
metro,
region,
city,
latitude,
longitude,
networkDomain,
networkLocation,
flashVersion,
javaEnabled,
language,
screenColors,
screenResolution,
socialActivityEndorsingUrl,
socialActivityDisplayName,
socialActivityPost,
socialActivityTimestamp,
socialActivityUserHandle,
socialActivityUserPhotoUrl,
socialActivityUserProfileUrl,
socialActivityContentUrl,
socialActivityTagsSummary,
socialActivityAction,
socialActivityNetworkAction,
hostname,
pagePath,
pagePathLevel1,
pagePathLevel2,
pagePathLevel3,
pagePathLevel4,
pageTitle,
landingPagePath,
secondPagePath,
exitPagePath,
previousPagePath,
nextPagePath,
pageDepth,
searchUsed,
searchKeyword,
searchKeywordRefinement,
searchCategory,
searchStartPage,
searchDestinationPage,
eventCategory,
eventAction,
eventLabel,
transactionId,
affiliation,
visitsToTransaction,
daysToTransaction,
productSku,
productName,
productCategory,
socialInteractionNetwork,
socialInteractionAction,
socialInteractionNetworkAction,
socialInteractionTarget,
userTimingCategory,
userTimingLabel,
userTimingVariable,
customVarNamen,
customVarValuen,
date,
month,
year,
week,
day,
hour,
nthMonth,
nthWeek,
nthDay,
dayOfWeek,
visitors,
newVisits,
percentNewVisits,
visits,
bounces,
entranceBounceRate,
visitBounceRate,
timeOnSite,
avgTimeOnSite,
organicSearches,
impressions,
adClicks,
adCost,
CPM,
CPC,
CTR,
costPerTransaction,
costPerGoalConversion,
costPerConversion,
RPC,
ROI,
margin,
goalnStarts,
goalStartsAll,
goalnCompletions,
goalCompletionsAll,
goalnValue,
goalValueAll,
goalValuePerVisit,
goalnConversionRate,
goalConversionRateAll,
goalnAbandons,
goalAbandonsAll,
goalnAbandonRate,
goalAbandonRateAll,
socialActivities,
entrances,
entranceRate,
pageviews,
pageviewsPerVisit,
uniquePageviews,
timeOnPage,
avgTimeOnPage,
exits,
exitRate,
searchResultViews,
searchUniques,
avgSearchResultViews,
searchVisits,
percentVisitsWithSearch,
searchDepth,
avgSearchDepth,
searchRefinements,
searchDuration,
avgSearchDuration,
searchExits,
searchExitRate,
searchGoalnConversionRate,
searchGoalConversionRateAll,
goalValueAllPerSearch,
pageLoadTime,
pageLoadSample,
avgPageLoadTime,
domainLookupTime,
avgDomainLookupTime,
pageDownloadTime,
avgPageDownloadTime,
redirectionTime,
avgRedirectionTime,
serverConnectionTime,
avgServerConnectionTime,
avgServerResponseTime,
serverResponseTime,
speedMetricsSample,
appviews,
uniqueAppviews,
appviewsPerVisit,
totalEvents,
uniqueEvents,
eventValue,
avgEventValue,
visitsWithEvent,
eventsPerVisitWithEvent,
transactions,
transactionsPerVisit,
transactionRevenue,
revenuePerTransaction,
transactionRevenuePerVisit,
transactionShipping,
transactionTax,
totalValue,
itemQuantity,
uniquePurchases,
revenuePerItem,
itemRevenue,
itemsPerPurchase,
socialInteractions,
uniqueSocialInteractions,
socialInteractionsPerVisit,
userTimingValue,
userTimingSample,
avgUserTimingValue,
exceptions,
fatalExceptions
}
}

Once the necessary class files created, we need to give the Strong name to the Dynamic link library (DLL file). Below are the steps to give strong name to DLL and how to install DLL in GAC.



Once the Strong name is created, that information needs to be added in the AssemblyInfo.cs class file. Below is the existing example coding. In the below coding, we should mention the path where the strong name key created and saved.

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GoogleAnalyticsSupport")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GoogleAnalyticsSupport")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile(@"M:\SSIS\MDR2.0\Imports\Assembly\GASupport\GASupport\bin\Debug\GoogleAnalyticsSupport.snk")]
[assembly: AssemblyKeyName("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("98b5b909-07b0-428a-b6d9-1e6561b8d855")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Once the information provided in the AssemblyInfo.cs file, the DLL file which is saved in the path should be added/installed in the Assembly folder. Example figure:

Go to – Start – Type as Run in the search option - and type as Assembly. Drag the DLL file and move it to this folder.

Example figure for class file process steps:

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.