feat: POC for supporting Optimizely fullstack / feature experimentation allocations#21
feat: POC for supporting Optimizely fullstack / feature experimentation allocations#21patrick-wu wants to merge 1 commit intodevelopmentfrom
Conversation
| userId = filteredAttributes['optimizely.userId']; | ||
| attributes = Object.keys(filteredAttributes) | ||
| .filter(function (key) { | ||
| return key.indexOf('optimizely.attributes') === 0; | ||
| }) | ||
| .reduce(function (obj, key) { | ||
| obj[key] = filteredAttributes[key]; | ||
| return obj; | ||
| }, {}); | ||
|
|
||
| // Remove all optimizely.* keys from filteredAttributes | ||
| filteredAttributes = Object.keys(filteredAttributes) | ||
| .filter(function (key) { | ||
| return key.indexOf('optimizely.') !== 0; | ||
| }) | ||
| .reduce(function (obj, key) { | ||
| obj[key] = filteredAttributes[key]; | ||
| return obj; | ||
| }, {}); | ||
| experimentAttributes = fetchOptimizelyFeatureExpAllocations( | ||
| userId, | ||
| attributes | ||
| ); |
There was a problem hiding this comment.
basically, for Optimizely Full Stack / Feature Experimentation, you need to pass in the user information (an ID, plus whatever additional attributes) to the SDK when trying to retrieve the bucketing information of the current user.
This kind of strategy is stateless (i.e. it doesn't keep track of what the allocation is) but idempotent, so we have to somehow pass in the user ID + attributes used when deciding
| }); | ||
|
|
||
| if (forwarders.length > 0 && window.optimizelyClient) { | ||
| var user = window.optimizelyClient.createUserContext( |
There was a problem hiding this comment.
I would do an additional check like && window.optimizelyClient.hasOwnProperty('createUserContext') just in case different versions of optimizely do or don't have this method. and put a try/catch block around it
| userId, | ||
| attributes | ||
| ); | ||
| var config = window.optimizelyClient.getOptimizelyConfig(); |
There was a problem hiding this comment.
same comment regarding this one. check for window.optimizelyClient.hasOwnProperty('getOptimizelyConfig')
| var selectPlacementsAttributes = mergeObjects( | ||
| filteredAttributes, | ||
| optimizelyAttributes, | ||
| experimentAttributes, |
There was a problem hiding this comment.
I notice in https://docs.rokt.com/developers/integration-guides/rokt-ads/web-sdk/attributes/#core-attributes that all attributes are strings, numbers, and not more complex types like dictionaries. should the value be stringified?
|
|
||
| module.exports = { | ||
| register: register, | ||
| OnboardingExpProvider: OnboardingExpProvider, |
There was a problem hiding this comment.
is this necessary? If it's only necessary for the tests, I think you can just duplicate the values in the test itself.
This is generally just used for an end developer to use.
rmi22186
left a comment
There was a problem hiding this comment.
couple of small suggestions. Also can you add a test for when OPTIMIZELY_FEATURE_EXP. There's a lot of complicated logic in here, so it's hard to know if it works or not and it's unclear what optimizely will return. You'll have to mock mParticle._getActiveForwarders, as well as a few optimizely methods that you are using. let me know if you need help with this and we can book like 15-30 min.
|
closing this one as we've aligned on the other approach with the Rokt Manager |
Summary
Adding support for Optimizely Full Stack / Feature Experimentation as 3rd party experimentation platforms we can integrate with.
This is more complex than Optimizely Web because unlike OW, the Full Stack / Feature Exp SDK does not keep the state of the current session's allocation.
Instead, it can guarantee to return consistent allocation, GIVEN an 'ID' and any additional optional attribute for consistent hashing / allocation, which mean the complexity now is we'll need to pass in the allocation ID and attributes into the
selectPlacementcall somehow.Solution Presented in POC
We pass these things in with specific keys that we look for, use them to generate allcoations, and remove them from the
filteredAttributesobject before passing it to theselectPlacementcall.Testing Plan
{explain how this has been tested, and what additional testing should be done}