Last active
June 18, 2018 07:04
-
-
Save LucGosso/d74e8299bbcc2084087f81c198c391d6 to your computer and use it in GitHub Desktop.
Google Analytics Service v3 C# .netframework examples with Episerver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using EPiServer.Core; | |
using EPiServer.Framework.Cache; | |
using EPiServer.ServiceLocation; | |
using Google.Apis.Analytics.v3; | |
using Google.Apis.Analytics.v3.Data; | |
using Google.Apis.Auth.OAuth2; | |
using Google.Apis.Services; | |
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.IO; | |
using System.Linq; | |
namespace Gosso.Web.Business.Services | |
{ | |
[ServiceConfiguration(typeof(IGoogleAnalyticsService), Lifecycle = ServiceInstanceScope.Singleton)] | |
public class GoogleAnalyticsService: IGoogleAnalyticsService | |
{ | |
private readonly ISynchronizedObjectInstanceCache _cache; | |
public GoogleAnalyticsService(ISynchronizedObjectInstanceCache cache) | |
{ | |
_cache = cache; | |
GetGoogleAnalyticDaysMostPopular = 15; | |
} | |
internal readonly string Key = "itemviewsGA"; | |
internal void CachePageItemsOfType(Dictionary<Guid, PageItemViews> pageitems, string cacheKey) | |
{ | |
var cache = ServiceLocator.Current.GetInstance<ISynchronizedObjectInstanceCache>(); | |
_cache.Remove(cacheKey); | |
_cache.Insert(cacheKey, pageitems, CacheEvictionPolicy.Empty); | |
} | |
public Dictionary<Guid, PageItemViews> GetItemViewsfromAnalytics(int typeid = 0, bool useCache = true) | |
{ | |
var cache = ServiceLocator.Current.GetInstance<ISynchronizedObjectInstanceCache>(); | |
var pageItemViews = cache.Get(Key + typeid) as Dictionary<Guid, PageItemViews>; | |
if (pageItemViews == null || !useCache) | |
{ | |
var service = GetService(); | |
var request = GetRequest(service, typeid); | |
pageItemViews = Execute(request); | |
CachePageItemsOfType(pageItemViews, Key + typeid); | |
} | |
return pageItemViews; | |
} | |
public IEnumerable<PageData> FilterItemsSortByMostPopular(Dictionary<Guid, PageItemViews> pagesViews, IEnumerable<PageData> articles, string firstSegmentUrl = null) | |
{ | |
if (pagesViews != null) | |
{ | |
var pageViewSorted = from f in pagesViews | |
orderby f.Value.PageViews descending | |
select f; | |
if (!string.IsNullOrEmpty(firstSegmentUrl)) | |
{ | |
//sort and filter | |
pageViewSorted = from f in pageViewSorted | |
where f.Value.CategoryName == firstSegmentUrl | |
orderby f.Value.PageViews descending | |
select f; | |
} | |
//match and join | |
var orderedByIdList = from i in pageViewSorted | |
join p in articles | |
on i.Key equals p.ContentGuid | |
select p; | |
return orderedByIdList.ToList(); | |
} | |
return null; | |
} | |
private AnalyticsService GetService() | |
{ | |
// Google Analytics API Service Account Authentication | |
// found in developer console under APIs & auth / Credentials | |
var keyFilePath = System.Web.Hosting.HostingEnvironment.MapPath(GetGoogleAnalyticsKeyFilePath) + string.Empty; | |
// These are the scopes of permissions you need. It is best to request only what you need and not all of them | |
string[] scopes = new string[] { AnalyticsService.Scope.Analytics }; // View your Google Analytics data | |
GoogleCredential credential; | |
using (var stream = new FileStream(keyFilePath, FileMode.Open, FileAccess.Read)) | |
{ | |
credential = GoogleCredential.FromStream(stream) | |
.CreateScoped(scopes); | |
} | |
// Create the Analytics service. | |
return new AnalyticsService(new BaseClientService.Initializer | |
{ | |
HttpClientInitializer = credential, | |
ApplicationName = "MyApp", | |
}); | |
} | |
private DataResource.GaResource.GetRequest GetRequest(AnalyticsService service, int typeid) | |
{ | |
//format the profile id | |
var profileId = GetGoogleAnalyticsProfileId; | |
if (!profileId.Contains("ga:")) | |
profileId = $"ga:{profileId}"; | |
var startDate = DateTime.Now.AddDays(-GetGoogleAnalyticDaysMostPopular); | |
var endDate = DateTime.Now; | |
var request = service.Data.Ga.Get(profileId, startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"), "ga:pageviews"); | |
request.Dimensions = "ga:pageTitle,ga:dimension1,ga:dimension2,ga:pagepathlevel1,ga:pagepathlevel2,ga:pagepathlevel3,ga:pagepathlevel4"; | |
if (typeid>0) | |
request.Filters = "ga:dimension2=="+typeid; | |
return request; | |
} | |
private Dictionary<Guid, PageItemViews> Execute(DataResource.GaResource.GetRequest request) | |
{ | |
// Retrieve data, performing paging if necessary. | |
var metrics = new Dictionary<Guid, PageItemViews>(); | |
GaData response = null; | |
do | |
{ | |
var startIndex = 1; | |
if (!string.IsNullOrEmpty(response?.NextLink)) | |
{ | |
var uri = new Uri(response.NextLink); | |
var paramerters = uri.Query.Split('&'); | |
var s = paramerters.First(i => i.Contains("start-index")).Split('=')[1]; | |
startIndex = int.Parse(s); | |
} | |
request.StartIndex = startIndex; | |
response = request.Execute(); | |
ProcessData(response, metrics); | |
} while (!string.IsNullOrEmpty(response.NextLink)); | |
return metrics; | |
} | |
private void ProcessData(GaData response, IDictionary<Guid, PageItemViews> metrics) | |
{ | |
//var pageTitleIndex = 0; | |
var pageViewsIndex = 0; | |
var epiPageguidIndex = 0; | |
var epiPagePathLevel1Index = 0; | |
var epiPagePathLevel2Index = 0; | |
// Find associated columns | |
for (var index = 0; index < response.ColumnHeaders.Count; index++) | |
{ | |
var header = response.ColumnHeaders[index]; | |
if (string.Equals(header.Name, "ga:pageviews", StringComparison.OrdinalIgnoreCase)) | |
pageViewsIndex = index; | |
else if (string.Equals(header.Name, "ga:dimension1", StringComparison.OrdinalIgnoreCase)) | |
epiPageguidIndex = index; | |
else if (string.Equals(header.Name, "ga:pagepathlevel1", StringComparison.OrdinalIgnoreCase)) | |
epiPagePathLevel1Index = index; | |
else if (string.Equals(header.Name, "ga:pagepathlevel2", StringComparison.OrdinalIgnoreCase)) | |
epiPagePathLevel2Index = index; | |
} | |
foreach (var row in response.Rows) | |
{ | |
var editpage = row[epiPagePathLevel2Index]; | |
if (editpage.ToLower() == "/cms/") | |
continue; | |
// Try to get the item id from the page title | |
var epiPageguid = row[epiPageguidIndex]; | |
Guid itemId; | |
if (!Guid.TryParse(epiPageguid.Trim(), out itemId)) | |
continue; | |
// Get page views | |
int pageViews; | |
if (!int.TryParse(row[pageViewsIndex], out pageViews)) | |
pageViews = 0; | |
var categoryName = ""; | |
//if (!row[epiPagePathLevel1Index].IsNullOrEmpty())//.IsNotNullOrEmpty()) | |
if (!string.IsNullOrEmpty(row[epiPagePathLevel1Index])) | |
categoryName = row[epiPagePathLevel1Index].Trim(); | |
if (!metrics.ContainsKey(itemId)) | |
{ | |
categoryName = categoryName.TrimEnd('/').TrimStart('/'); | |
metrics.Add(itemId, new PageItemViews { PageViews = pageViews, CategoryName = categoryName }); | |
} | |
else | |
{ | |
var entry = metrics[itemId]; | |
entry.PageViews += pageViews; | |
} | |
} | |
} | |
private string GetGoogleAnalyticsProfileId => ConfigurationManager.AppSettings["GoogleAnalyticsProfileId"]; | |
private string GetGoogleAnalyticsKeyFilePath => ConfigurationManager.AppSettings["GoogleAnalyticsKeyFilePath"]; | |
private int GetGoogleAnalyticDaysMostPopular | |
{ | |
get; | |
set; | |
} | |
} | |
public class PageItemViews | |
{ | |
public int PageViews { get; internal set; } | |
public string CategoryName { get; internal set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using EPiServer.Core; | |
using System; | |
using System.Collections.Generic; | |
namespace Gosso.Web.Business.Services | |
{ | |
public interface IGoogleAnalyticsService | |
{ | |
Dictionary<Guid, PageItemViews> GetItemViewsfromAnalytics(int typeid= 0, bool useCache = true); | |
IEnumerable<PageData> FilterItemsSortByMostPopular(Dictionary<Guid, PageItemViews> pagesViews, IEnumerable<PageData> articles, string inspiration = null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment