Extending XO Content Experiments

Content Experiments in SDL Web Experience Optimization (XO) allows editors to create experiments in page regions managed by XO. These experiments has a defined start and end time, specific trigger(s) and a set of variants to be selected.
The site visitor will get a randomly selected experiment variant shown if matching the defined trigger. The selected variant will then always be shown for the particular user during the the life span of the experiment. Read more about XO experiments here: http://docs.sdl.com/LiveContent/content/en-US/SDL%20Web-v5/GUID-44802E9F-1619-4A1E-B4FF-E8493152D121
 
Experience Optimization (XO) Content Experiments comes by default with analytics tracking provider for Google Analytics. It is also possible to create your own tracking provider to other analytics services/products.
To make this simple I’ve created a simple framework for analytics providers (based on the standard XO APIs for experiment tracking). The framework is available here:
 
 
The framework allows you to easy create your own analytics tracking provider and it also allows you to create your own algorithm to select an experiment winner. The framework comes with the following algorithms:
  • A configurable Chi Square algorithm - A configurable version of standard Chi Square algorithm where minimum conversions per variant can be configured. Chi Square is a algorithm often used in statistical calculations to determine whether there is a significant difference between different variants in a test.
  • Reach Conversion Goal algorithm - A simple algorithm that just make the variant that first a a specific number of conversions to the winner. Can be useful in demos etc.

Create your own analytics provider

To create your own analytics provider you basically only need to do the following:
  • Extend the class: com.sdl.experienceoptimization.analytics.AnalyticsManagerBase 
  • Implement 3 methods:
    • trackView() - track a view of an experiment variant
    • trackConversion() - track a conversion of an experiment variant (normally a click on the experiment banner)
    • getAnalyticsResults() - get tracking data to be presented in the XO experiment dashboard
 
Below is an example from a simple tracking provider to store tracking data into a local SQL database:
 
public class LocalAnalyticsManager extends AnalyticsManagerBase {
 
    // Worker thread to asynchronously store tracking data
    private static AnalyticsResultWorker resultWorker;
    // DB repository for tracking data
    private static AnalyticsResultRepository resultRepository;
 
    @Override
    public void trackView(ExperimentDimensions experimentDimensions,
                          Map<String, String> metadata)
{
        // Submit view tracking data to the worker thread
        //
        this.resultWorker.submitTracking(new TrackedExperiment(experimentDimensions,
                                                               ExperimentType.VIEW));
    }
 
    @Override
    public void trackConversion(ExperimentDimensions experimentDimensions,
                                Map<String, String> metadata)
{
        // Submit conversion tracking data to the worker thread
        //
        this.resultWorker.submitTracking(new TrackedExperiment(experimentDimensions,
                                                               ExperimentType.CONVERSION));
    }
 
    @Override
    protected AnalyticsResults getStatisticsResults(Date startDate,
                                                    Date endDate,
                                                    StatisticsExperimentDimensions experimentDimensions,
                                                    StatisticsTimeDimensions timeDimensions,
                                                    List<String> extraDimensions,
                                                    StatisticsFilters statisticsFilters,
                                                    int startIndex,
                                                    int maxResults) throws Exception {
 
        List<AggregatedTracking> trackings = this.resultRepository.getTrackingResults(statisticsFilters);
        SimpleAnalyticsResults results = new SimpleAnalyticsResults();
        if ( trackings != null ) {
            for (AggregatedTracking tracking : trackings) {
                this.addAnalyticsResultsRow(results, tracking, experimentDimensions, timeDimensions);
            }
        }
        return results;
    }
 
}

The full source code for the local database provider is found here:
 
When you’re done you package your code into a JAR file and create a new directory under ‘services’ in your install location for your XO query and management micro services. Into this directory you put your JAR file (plus needed dependencies) and the JAR file for the xo-analytics-provider-framework.
Then you just need to configure the analytics provider in the config/smarttarget_conf.xml file:
 
<Analytics implementationClass="[Analytics provider class name]" timeoutMilliseconds="5000" trackingRedirectUrl="/redirect/">
    [Properties to the analytics provider ...]
    ExperimentWinnerAlgorithmClassName>[Experiment winner class name]</ExperimentWinnerAlgorithmClassName>
    [Properties to the algorithm...]
</Analytics> 

Local Database Analytics Provider 

The analytics provider for storing tracking data into a local database can be handy in some situations. In some cases it can be overkill to send tracking data for an experiment to an external analytics provider and then read in all data again to be able to show the results for an CMS user.
However it does not stop you to anyway to submit tracking data to your analytics provider (to be able to combine with other analytics such as demographics etc) but then you do not need it to keep track of the ongoing progress of the experiment.
 
The source code for the analytics provider can be found here:
 
To setup the local database analytics provider you do the following:
 
<Analytics
    implementationClass="com.sdl.experienceoptimization.analytics.localdb.LocalAnalyticsManager"
    timeoutMilliseconds="5000" trackingRedirectUrl="/redirect/“>
    <!— Storage —>
    <Storage url=“[JDBC URL]" className=“[JDBC Driver classname]" cacheTime="10000”/>
    <!— How often the worker thread stores the results in the database —>
    <TrackingStoreInterval>10000</TrackingStoreInterval>
    <!— Winner algorithm -->
    <ExperimentWinnerAlgorithmClassName>
       com.sdl.experienceoptimization.analytics.algorithm.ReachConversionGoalAlgorithm
    </ExperimentWinnerAlgorithmClassName>
    <ConversionGoal>10</ConversionGoal>
    <!— Chi Square algorithm 
    <ExperimentWinnerAlgorithmClassName>
       com.sdl.experienceoptimization.analytics.algorithm.ConfigurableChiSquareAlgorithm
    </ExperimentWinnerAlgorithmClassName>
    <MinimumConversionsPerVariant>100</MinimumConversionsPerVariant>     
    —> 
 </Analytics>
 
  • Restart your XO micro services and then you are all set!
 
In addition the local database analytics provider has a “demo mode” where a specific experiment can be configured to use dummy data instead of actual tracking data. This can be configured as following:
 
<Analytics implementationClass="com.sdl.experienceoptimization.analytics.localdb.LocalAnalyticsManager"
           timeoutMilliseconds="5000" trackingRedirectUrl="/redirect/“>
    ...
    <Dummy experimentId=“[EXPERIMENT ID, e.g. a9cf5654-c6ab-41ec-a8da-3b13de130c0c]">
        <MinViews>[MAX VIEWS, e.g. 230]</MinViews>
        <MaxViews>[MIN VIEWS, e.g. 300]</MaxViews>
        <MinConversions>[MIN CONVERSIONS, e.g. 0]</MinConversions>
        <MaxConversions>[MAX CONVERSIONS, e.g. 70]</MaxConversions>
        <Winner>
            <Publication>[PUBLICATION ID, e.g. tcm:0-3-1]</Publication>
            <VariantIndex>[WINNER VARIANT ID, e.g. 1]</VariantIndex>
            <MinConversions>[WINNER MIN CONVERSIONS, e.g. 50]</MinConversions>
            <MaxConversions>[WINNER MAX CONVERSIONS; e.g. 100]</MaxConversions>
        </Winner>
    </Dummy>
</Analytics>
 
Let me know if you run into issues etc.
Good luck with your experiments! ;-)