Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from: https://blog.jermdavis.dev/posts/2016/personalising-on-page-events-with-custom-data-take-care

Personalising on Page Events with custom data? Take care...

Published 25 July 2016
Updated 25 August 2016

A colleague of mine has been looking at some custom page events and reporting in Sitecore 8.1 recently. One thing which came to light during this work is that some of the personalisation rule code in the product didn't appear to work as expected. In case anyone else is looking at this aspect of the software, he's a summary of the issue we were seeing, in the hope that it can help you avoid the time we spent looking into this:

The rule... url copied!

With 8.1, one of the new features for analytics is the ability to write rules which can detect Page Events (or Goals) in either the current session or a previous session. The one we were looking at was:

Page Event Rule

This is supposed to allow you to trigger a personalisation when a certain page event has been recorded for the current user, and it's custom data matches the criteria specified. However we found that this did not work as expected.

The issue... url copied!

When we set up test data for this rule in 8.1 Update 3 and tried it out, we noted that:
  • If the Page Event is recorded in the current session then the rule ignores the custom data when deciding whether to trigger. It will trigger no matter what custom data is recorded.
  • If the Page Event was recorded in a session from the past then the rule obeys the custom data when deciding whether to trigger.

Cue some head-scratching, and a bit of debugging...

The rule's logic is part of the PageEventWithCustomDataWasTriggeredDuringPastOrCurrentInteractionCondition class (Snappy name, huh?) in the Sitecore.Analytics.Rules.Conditions namespace. So we grabbed our trusty decompiler and looked through what this code was doing when a rule is evaluated. Through inheritance, this class makes use of the same Execute() method as the PageEventWasTriggeredDuringPastOrCurrentInteractionCondition class. That code, tidied up a bit, looks like:

protected override bool Execute(T ruleContext)
{
    // -- snip
    if (this.HasEventOccurredInInteraction((IInteractionData) Tracker.Current.Session.Interaction))
    {
        return true;
    }
    // -- snip
    return this.FilterKeyBehaviorCacheEntries(Tracker.Current.Contact.GetKeyBehaviorCache()).Any<KeyBehaviorCacheEntry>((Func<KeyBehaviorCacheEntry, bool>) (entry =>
    {
        Guid id = entry.Id;
        Guid? pageEventGuid = this.PageEventGuid;
        if (pageEventGuid.HasValue)
        {
            return id == pageEventGuid.GetValueOrDefault();
        }
        return false;
    }));
}

					

Based on that, if the event happened in the current session then only the HasEventOccurredInInteraction() method is called. If not, the FilterKeyBehaviorCacheEntries() method is called. Digging deeper FilterKeyBehaviorCacheEntries()‘s behaviour depends on which rule is being run (it may or may not filter based on custom event data, depending on whether you're using the "with custom data" version of the rule or not).

But HasEventOccurredInInteraction() does not have any code that looks at the custom data, and it makes no reference to the FilterKeyBehaviorCacheEntries() method which does. It looks like this:

protected override bool HasEventOccurredInInteraction(IInteractionData interaction)
{
    // -- snip
    return ((IEnumerable<Page>) interaction.Pages).SelectMany<Page, PageEventData>((Func<Page, IEnumerable<PageEventData>>) (page => page.PageEvents)).Any<PageEventData>((Func<PageEventData, bool>) (pageEvent =>
    {
        if (pageEvent.IsGoal)
        {
            return false;
        }
        Guid eventDefinitionId = pageEvent.PageEventDefinitionId;
        Guid? pageEventGuid = this.PageEventGuid;
        if (pageEventGuid.HasValue)
        {
            return eventDefinitionId == pageEventGuid.GetValueOrDefault();
        }
        return false;
    }));
}

					

That code seems to explain the behaviour we've been seeing – the logic is actually different depending on whether the Page Event fired in the current session or not...

The result... url copied!

Having spent a bit of time discussing this issue with Sitecore Support, they have agreed that this isn't the right behaviour and have raised a bug. If you encounter this issue, get in touch with support and ask about the fix for issue 118236. They can provide a patch which replaces this rule, and should resolve this problem until the fix can be rolled into a future release. ↑ Back to top