Optimizely X Destination

This destination is currently in beta. If you are interested in joining, let us know!

Segment makes it easy to send your data to Optimizely X (and lots of other destinations). Once you've tracked your data through our open source libraries we'll translate and route your data to Optimizely X in the format they understand.

Getting Started

Optimizely X works differently than other integrations. When enabling this destination for mobile and to ensure that it is initialized as soon as possible, you will have to hard-code your Optimizely X project ID on initialization.

Because using Optimizely X via Segment requires familiarity with Optimizely’s native SDKs, we encourage you to review their documentation.

Mobile

Optimizley does provide different ways to initialize the client, however, Segment only supports initializing with the Optimizely Manager. The Optimizely Manager continuously checks for any updates made via the Optimizely UI and updates the cdn periodically with those changes.

In the unlikely scenario the Optimizely Client is slow to initialize, Segment automatically queues up to 100 events and polls the client asynchronously, flushing all events once a valid client is returned.

Initializing Optimizely synchronously with a manual or cached datafile would require more work on your end to keep the datafile up to date. Given that we queue events in memory before Segment is initialized, you can initialize Optimizely X synchronously and independently of Segment if you so choose. Just remember that we’ll only queue up to 100 events in memory, and only flush them once Optimizely X is finally initialized.

Android

To get started on Android, initialize the OptimizelyManager class in your app’s Application subclass. Before you can import the OptimizelyManager class, you must first include Optimizely X’s native SDK in your your app-level build.gradle file: compile 'com.optimizely.ab:android-sdk:+'. Then, pass the Manager instance to Segment’s Optimizely X integration factory.

Here’s a code example of what your application subclass could look like.

import com.segment.analytics.android.integrations.optimizelyx.OptimizelyXIntegration;
import com.optimizely.ab.android.sdk.OptimizelyManager;

public class OptimizelyApp extends Application {

    private static final String WRITE_KEY = "<YOUR_WRITE_KEY>";
    public static final String PROJECT_ID = "<YOUR_PROJECT_ID>";
    private OptimizelyManager optimizelyManager;

    public OptimizelyManager getOptimizelyManager() {
        return optimizelyManager;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        optimizelyManager = OptimizelyManager.builder(PROJECT_ID)
                .build(this);

        optimizelyManager.initialize(this, new OptimizelyStartListener() {
            @Override
            public void onStart(OptimizelyClient optimizely) {
                assert optimizely == optimizelyManager.getOptimizely();

                Analytics analytics = new Analytics.Builder(OptimizelyApp.this, WRITE_KEY) //
                        .use(OptimizelyXIntegration.factory(optimizelyManager))
                        .logLevel(LogLevel.VERBOSE).build();

                Analytics.setSingletonInstance(analytics);
            }
        });
    }
}

Here, initializing Segment in Optimizely’s onStart callback is non-blocking since Optimizely returns a dummy OptimizelyClient if a valid client cannot be initialized immediately.

iOS

To get started on iOS, initialize the OPTLYManager and provide this to the Segment Optimizely-X Integration.


    SEGAnalyticsConfiguration *configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"<YOUR_WRITE_KEY>"];

    // Initialize an Optimizely manager
    self.optlyManager = [OPTLYManager init:^(OPTLYManagerBuilder *_Nullable builder) {
        builder.projectId = @"<YOUR_PROJECT_ID";
    }];

    // Provide the OPTLYManager to SEGOptimizelyXIntegrationFactory
    [configuration use:[SEGOptimizelyXIntegrationFactory instanceWithOptimizely:self.optlyManager]];
    [SEGAnalytics setupWithConfiguration:configuration];

    // Initialize an Optimizely client by asynchronously downloading the datafile
    [self.optlyManager initializeWithCallback:^(NSError *_Nullable error, OPTLYClient *_Nullable client) {
        // Activate user in an experiment
        OPTLYVariation *variation = [client activate:@"<YOUR_VARIATION>" userId:@"<USER_ID>"];
        if ([variation.variationKey isEqualToString:@"variation1"]) {
          // execute code for variation1
        } else if ([variation.variationKey isEqualToString:@"variation2"]) {
          // execute code for variation2
        } else {
          // execute default code
        }
    }];

Note that if there are any delays to the Optimizely Client being initialized, the activate method may fail. You will want to consider wrapping the variation logic around a condition to check if Optimizely has been initialized.

Server Side

If you have entered your Account ID and Datafile URL in your destination settings, you can start sending server side events. Assuming you have called Optimizely’s own .activate() method else where in your codebase for a given userId and an Optimizely experiment, if you send conversion events to Segment, we will use the Optimizely’s Node SDK to send them to your project. Because we use Optimizely’s official Node SDK, each event will be sent with its attributed Optimizely variation IDs via what they call decisions.

NOTE: The server side integration only maps to your .track() event. However, if you would like to send custom user attributes you can send user traits under context.traits and we will forward those along with your events.

IMPORTANT: Note that before you can send Optimizely X events via server side, you MUST pre-create/define them inside Optimizely’s UI. The event name or key are case sensitive so please heed close attention and make sure what you create inside Optimizely and the event name syntax you are sending to Segment are equal. This requirement also applies to when you try to send context.traits. Make sure you pre-create/define these custom attributes inside Optimizely when you create your custom audiences.

Identify

When you call identify, Segment stores any user traits in memory and passes them to Optimizely as attributes when you call track using Segment’s API. Optimizely will reject any attributes you haven’t defined within their dashboard first, so be sure to set these up in advance of deploying your app with Optimizely X enabled. You can use attributes to define audience segments in your Optimizely dashboard.

Track

Segment maps our own track events to Optmizely track events. We will pass traits set via Segment identify calls as attributes and track event properties as eventTags.

Optimizely eventTags are contextual metadata about conversion events that you track and are accessible via raw data export in Optimizely’s event_features column. Please contact Optimizely’s support team for more information on how to access and manipulate eventTags.

Reset

Invalidates the listener for the Experiment Viewed event.

Revenue

To pass revenue to Optimizely, simply pass a property in your Segment track call with key revenue.

Settings

Sending Experiment Data to Segment

A key feature of our Optimizely destination is the ability to send your experiment data back into Segment so that you can analyze them in your other analytics providers. In your Optimizely settings, you can opt to choose to send experiment data via track.

Track Experiment Event

The corresponding event will look something like this in your Segment debugger:

Android:

analytics.track("Experiment Viewed", new Properties()
    .putValue("experimentId", "1234567890")
    .putValue("experimentName", "android_experiment")
    .putValue("nonInteraction", 1)
    .putValue("variationId", "0987654321")
    .putValue("variationName", "variation_name"));

iOS:

[[SEGAnalytics sharedAnalytics] track:@"Experiment Viewed", properties: @{
    @"experimentId" : @"8734392016",
    @"experimentName" : @"variation_view",
    @"nonInteraction" : @1,
    @"variationId" : @"8729081299",
    @"variationName" : @"variation1"
}];

Segment sends an Experiment Viewed event whenever you activate an Optimizely experiment, or whenever you access an Optimizely live variable.

If you’d prefer not to trigger an Experiment Viewed event each time you access a live variable, you can simply pass the false flag when you get your variable.

Android:

Boolean myVariable = optimizelyClient.getVariableBoolean("myVariable",
                                                         userId,
                                                         false);

iOS:

bool myVariable = [optimizely variableBoolean:@"myVariable"
                                       userId:userId]
                           activateExperiment:False];

nonInteraction Property

By default, Segment adds a nonInteraction property to your Experiment Viewed events to prevent creating new sessions in Google Analytics. If you don’t use Google Analytics, or if you’d prefer that we don’t append this property, you can disable this in your destination settings.

nonInteraction Setting


Supported Sources and Connection Modes

WebMobileServer
📱 Device-based
☁️ Cloud-based

To learn more about about Connection Modes and what dictates which we support, see here.

Segment offers an optional Device-based Connection Mode for Mobile data with Optimizely X. If you’d like to use those features that require client-based functionality, follow the steps above to ensure you have packaged the Optimizely X SDK with Segment’s.

Settings

Segment lets you change these destination settings via your Segment dashboard without having to touch any code.

Account ID

In order to use Optimizely X via server side, you must enter your Account ID from your Optimizely account. You can find this ID by visiting https://app.optimizely.com/v2/accountsettings/account/plan

Cache Exp

To optimize the server side integration, we will cache the fetched Datafile that you have provided for this amount of time (in seconds) in Redis. Since the datafile should not change unless you modified the conditions or variation rules of your experiments, it is advised to have a minimum floor of 300 seconds (5 minutes).

Datafile URL

In order to use Optimizely X server side, you must enter the entire URL for your datafile. It should look something like https://cdn.optimizely.com/json/9218021209.json

Sends the experiment and variation information as properties on a track call.

Send experiment data to other tools (as a track call)
An “Experiment Viewed” track event will be triggered each time you access an Optimizely live variable. If you’re regularly accessing live variables and want to reduce the number of track events triggered, pass the “false” flag, for example:
Boolean myVariable = optimizelyClient.getVariableBoolean("myVariable", userId, false);
bool myVariable = [optimizely variableBoolean:@"myVariable" userId:userId] activateExperiment:False];

Specifies the Experiment Viewed as a non-interaction event for Google Analytics

Send Experiment Viewed as a non-interaction event

Only Track Known Users

Optimizely does not alias known and unknown users. By default, Segment will only send the anonymousId to Optimizely. Enable this to only send the userId to Optimizely. This setting applies if you are bundling this integration for mobile sources.


If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!