How to set up an engagement value to multiple pages?
Example:
Assign the same value to all "product pages view" or all "add to cart" event
I had a similar development whereby pages that the user has visited, the should receive the same engagement value.
First, I had to keep track of the pages that the user visited. Those were stored in the PageEvents
in MongoDB. Each time a user visited a page, I triggered the below code to register the event.
public void CreateViewContentEvent(Guid itemId)
{
try
{
if (Tracker.IsActive && Tracker.Current != null)
{
Assert.IsNotNull(Tracker.Current, "Tracker.Current");
if (Tracker.Current != null && Tracker.Current.Session != null && Tracker.Current.Session.Interaction != null)
{
string viewEventName = $"{itemId}_view";
var itemPath = $"/sitecore/system/Settings/Analytics/Page Events/Content Events View/{viewEventName}";
Item viewEventItem = Context.Database.GetItem(itemPath, Language.Parse("en"));
if (viewEventItem != null)
{
CreatePageEventWithGoal(viewEventName, "Viewed", itemId, viewEventItem.ID.ToGuid());
}
}
}
}
catch (Exception ex)
{
Log.Error($"Error on Content Click Event {ex.StackTrace} with message {ex.Message} + msg {msg}", "AnalyticsService");
}
}
private static void CreatePageEventWithGoal(string eventName, string eventText, Guid itemId, Guid pageEventDefinitionId)
{
PageEventData pageEventData = new PageEventData(eventName, pageEventDefinitionId)
{
ItemId = itemId,
Data = itemId.ToString(),
DataKey = itemId.ToString("B"),
PageEventDefinitionId = pageEventDefinitionId,
Text = eventText,
Name = eventName
};
if (Tracker.Current.Contact != null)
{
try
{
Tracker.Current.Interaction.CurrentPage.Register(pageEventData);
}
catch (Exception)
{
Log.Error($"Error on register tracking... ", "CreatePageEventWithGoal");
}
}
}
The below statement is to fetch the pageEvents in Sitecore. Those gets generated on item saved.
var itemPath = $"/sitecore/system/Settings/Analytics/Page Events/Content Events View/{viewEventName}";
Once I have the view
events registered into MongoDB, I had implemented a custom Aggregation Processor to aggregate the data into a custom table.
A visit is a collection of PageEvents. So, to be able to add the same value to user view stream, when you loop through the PageEvents
, you need to set the same visit value. Below is a code snippet I have used in my custom aggregator to retrieve the data from mongoDb to push it to a custom table in the analytics database.
private readonly IDictionary<string, string> typeMap = new Dictionary<string, string>
{
{ "Viewed", "View" },
{ "Clicked", "Click" }
};
protected override void OnProcess(AggregationPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
try
{
VisitData visit = args.Context.Visit;
List<Guid> tempList = new List<Guid>();
if (visit.Pages == null || visit.Pages.Count <= 0)
{
return;
}
ContentPerformance contentPerformance = null;
foreach (PageData page in visit.Pages)
{
if (page.PageEvents == null || page.PageEvents.Count <= 0)
{
continue;
}
var pageEvents = page.PageEvents.Where(pe => !pe.Text.IsNullOrEmpty()).ToList();
IEnumerable<PageEventData> relevantPageEvents = new List<PageEventData>();
if (pageEvents.Any())
{
relevantPageEvents = pageEvents.Where(pe => this.typeMap.ContainsKey(pe.Text)).ToList();
}
if (relevantPageEvents.Any())
{
foreach (PageEventData pageEvent in relevantPageEvents)
{
Guid? patternId = null;
using (var context = GetSearchIndex("my index name").CreateSearchContext())
{
var itemId = new ID(pageEvent.ItemId);
var content = context.GetQueryable<ContentBox>().FirstOrDefault(w => w.ItemId == itemId);
ContentPerformanceKey contentPerformanceKey = new ContentPerformanceKey
{
ItemId = pageEvent.ItemId,
PatternName = patternName
};
ContentPerformanceValue contentPerformanceValue = new ContentPerformanceValue();
bool notYetProcessed = !tempList.Contains(pageEvent.PageEventDefinitionId);
if (notYetProcessed)
{
contentPerformanceValue.Visits = 1;
contentPerformanceValue.Value = visit.Value;
tempList.Add(pageEvent.PageEventDefinitionId);
}
else
{
contentPerformanceValue.Visits = 0;
}
if (contentPerformance == null)
{
contentPerformance = args.GetFact<ContentPerformance>();
}
contentPerformance.Emit(contentPerformanceKey, contentPerformanceValue);
}
}
}
}
}
catch (Exception ex)
{
Log.Error($"[Perso] Error occured in Content Performance: StackTrace: {ex.StackTrace}. Message: {ex.Message}. InnerException: {ex.InnerException}", this);
}
}
You may need to change the above to accommodate your requirement. You can read more from my post about Sitecore Aggregation Process