I can’t speak to the roadmap for Snowplow to natively support Google Optimize the way you’re describing. I’ve developed an approach that works well for my needs that may be of use to you and that I may look to develop a more robust feature & enrichment for.
- Parse the _gaexp cookie and attach custom contexts
GA & Optimize use the _gaexp
cookie to keep track of a users’ exposure to experiments. We can parse that cookie to attach a custom experiment context to snowplow events. Something like this:
// _gaexp cookie: client side
var expRx = /(\S{22})\.(?:\d{5})\.(\d{1})/g;
var co = getCookie('_gaexp');
var a;
var customContexts = [];
while ((a=expRx.exec(co)) !== null) {
var expId = a[1]
var expVariant = a[2];
var optimize_experiment_viewed = {
schema: "iglu:com.acme_company/optimize_experiment_viewed/jsonschema/1-0-0",
data: {
expId: expId,
variantId: expVariant
}
}
customContexts.push(optimize_experiment_viewed);
}
window.snowplow('trackPageView', null, customContexts);
yet another approach might be to handle this with a custom API enrichment that attaches the context
- Register a Google Analytics Task and send a custom event
To activate a client-side experiment after the GA page view event has been sent you you have to fire an activation event which is a separate data hit sent to GA to capture the experiment exposure. In the same way that Simo Ahava outlined in his excellent post (and in the sp-ga-plugin) we can register a customTask with GA to look for these hits and send a corresponding event to snowplow.
This is needed because the event is sent after the page view.
Example task
ga(function(tracker) {
// Grab a reference to the default sendHitTask
var originalSendHitTask = tracker.get('sendHitTask');
tracker.set('sendHitTask', function(model) {
// send original hit
originalSendHitTask(model);
// check model to determine if it is a 'data' hit
// and that 'exp' is a valid experiment id
var exp = model.get("exp"); // experiment id ex: nnNnnNnsNNNABDACDNNNNNN1.0
var hitType = model.get("hitType"); // pageview, data, adtiming, etc
var expRx = /(\S{22})\.(\d{1})/g; // experiment param regex format
if (hitType === 'data' && typeof exp !== 'undefined' && (a=expRx.exec(exp)) !== null) {
// valid data hit get attrs
var expId = a[1];
var expVariant = a[2];
/*
* Track custom snowplow event struct or unstruct as needed
*/
window.snowplow('trackUnstructEvent', {
schema: 'iglu:com.acme_company/optimize_experiment_viewed/jsonschema/1-0-0',
data: {
expId: expId,
variantId: expVariant
}
});
}
});
});
I hope this helps! I’d love to hear any feedback that others have on this, thanks!
Also just completeness, I have one minor clarification regarding something @Kennon_Ballou said:
Google didn’t acquire Optimizely they expanded their own experiment platform (formerly Content Experiments as you noted) – in fact, their approach to experiment segmentation and analysis have large philosophical and technical differences but that is an entirely different topic.