Are you looking to make it easier to preview and QA Optimizely experiments? Download the OptiPilot Companion to easily see active experiments, preview events & more!

Send Events from Optimizely Full Stack to Optimizely Web

If you’re a customer running both Optimizely Full Stack & Web on your platform, it could make sense to trigger your conversion events once and have these be sent to both Full Stack & Web. This is exactly what we’re going to cover today.

Step 1: Requirements

This is the scenario where you have Optimizely Full Stack running on your pages but the Optimizely Web snippet isn’t present. With the code snippet below, you’ll be able to send an Optimizely Web event every time you trigger an Optimizely Full Stack event.

Step 2: Get the required identifiers

Grab the following identifiers:

  1. Your Optimizely account ID
  2. The Optimizely project ID where the Web events will be dispatched to
  3. The userId used in Optimizely Web (normally the optimizelyEndUserId)
  4. The name of the Optimizely SDK client on your page

Step 3: Copy the code below

Include the code below in your pages where you’d like to forward events from FS to Web:

// This code is meant to be added on every page where you'd like to mirror events
// It needs to run AFTER createInstance is called
// in the last line, replace optimizelyClient with the name of your optimizely instance pointing to the notificationCenter
window.FSWebIntegrator = (function() {
    return {
         account_id: "", // Optimizely Account ID
         project_id:"", // project ID where the web events need to be dispatched to
         user_id:'1234', // where the Web userId is
         endpoint:"https://logx.optimizely.com/v1/events",
         method:"POST",
         optimizelyClientNotificationCenter:optimizelySdk
     };
   });
   
window.FSWebIntegrator.dispatchNetworkEvent = function() {
    var Http = new XMLHttpRequest();
     Http.open(FSWebIntegrator().method, FSWebIntegrator().endpoint);
 
     Http.send(JSON.stringify(this.body));
     
     Http.onreadystatechange = function(e) {
     };
 
     // todo: handle event failure
     Http.onerror = function(e) {
       console.log(e);
     };
 
 }

 window.FSWebIntegrator.buildEventPayload = function(event) {
    // We copy the web attributes
    if(event.attributes !== undefined) {
    var attributes = Object.entries(event.attributes).map(function(entry) {
        return {
            entity_id: null, // entity_id set to null as web snippet doesn't expose attribute ID
            key: entry[0],
            type:"custom",
            value: entry[1]+''
        }
    })
  }
    // Support for bot filtering
    var attributes = attributes || [];
    attributes.push(
        {
            entity_id: "$opt_bot_filtering",
            key: "$opt_bot_filtering",
            type:"custom",
            value: false
        }
    );
     this.body = {
       "account_id": window.FSWebIntegrator().account_id,
       "project_id":window.FSWebIntegrator().project_id,
       "revision":"100",
       "visitors":
         [
           {
            "visitor_id":window.FSWebIntegrator().user_id,
             "attributes": attributes,
             "snapshots": [
             {
               "decisions": [],
               "events": [
                 {
                   "entity_id": event.eventId,
                   "key": event.eventKey,
                   "timestamp": Date.now(),
                   "uuid":Math.round(Math.random()*100000000),
                   "revenue":event.eventTags !== undefined ? event.eventTags.revenue : 0,
                   "value":event.eventTags !== undefined ? event.eventTags.value : 0
                 }
               ]
             }
             ]
            }
          ],
          "anonymize_ip": true,
          "client_name": "Optimizely/webfsintegration",
          "client_version": "1.0.0",
          "enrich_decisions": true
     };
     return this;
   }

window.FSWebIntegrator.sendWebEvent = function(event) {
    window.FSWebIntegrator.buildEventPayload(event);
    window.FSWebIntegrator.dispatchNetworkEvent();
}

var onTrack = (event) => {
    if(event.eventKey !== undefined) {

        var optlyEvents = localStorage.getItem('Optly_events');
        if(optlyEvents === null) {
            return true;
        }
        // Get the list of events from localStorage
        var whitelistedEvent = Object.entries(JSON.parse(optlyEvents)).map(function(obj) 
        {
            return {
                'key':obj[1].apiName,
                'id':obj[1].id
            }
         });
    
        if(whitelistedEvent.some(function(i) { return i.key.includes(event.eventKey)})) {
            var eventId = function(e) {
                return whitelistedEvent.filter(function(e) {
                  if(event.eventKey === e.key) {
                    return true;
                  }
                }).map(function(event) {
                    return event.id;
                  }).join();
              }

            event.eventId = eventId();  
            window.FSWebIntegrator.sendWebEvent(event);
        }
    }
}

FSWebIntegrator().optimizelyClientNotificationCenter.addNotificationListener("TRACK:event_key, user_id, attributes, event_tags, event", onTrack);

Step 4: Personnalize the code to your needs

Between lines 6-11, change:

  1. Line 6 to include your Optimizely account ID
  2. Line 7 to include the project where the web events will be created
  3. Line 8 to include a reference to your Optimizely Web userid (normally this is be the optimizelyEndUserId cookie)
  4. Line 11 to include your reference to the Optimizely SDK client

Step 5: Create the events in Optimizely Web

In the Optimizely Web project, create the event you’d like to forward from Full Stack to Web. Make sure to create them as custom events and with the same API name as your Full Stack events.

Step 6: Benefit!

This code will then automatically send an Optimizely Web event for every Optimizely Full Stack triggered on your pages.

Leave a Comment