Passing an External Visitor Identifier

If you're using certain Conductrics features, you may want to consider providing an "external" visitor identifier to Conductrics.

For instance, if you're using one of our Analytics Connectors to send variation selections to Adobe Analytics (AA) or Google Analytics (GA), you may want to provide Conductrics with the same identifier that AA or GA uses, so that Conductrics can pass the identifier through to AA or GA as selections are made.

Via the Conductrics REST API

If you're using Conductrics via our REST-style API, you can pass the identifier as the optional vid parameter. Here's a quick example:

POST https://api.v3.conductrics.com/owner_xxxxxx/v3/agent-api?apikey=api-1234567890&session=visitor-id-123&vid=analytics-id-456

{"commands": [ {"a":"my-agent"} ]}

The above snippet asks Conductrics for a variation selection for the test/agent called my-agent. The snippet uses the vid parameter to provide an external visitor identifier of analytics-id-456, which would presumably be the same value used by your analytics platform (Adobe Analytics, Google Analytics, etc).

Note that regardless of whether you provide the optional vid parameter, you must still provide the session parameter, which is required when using the REST-style API. The session parameter is used to identify the visitor with Conductrics; the vid parameter is just for passing to other systems.

📘

Alternatively, if you will always be able to provide the external identifier (from your analytics platform, etc), you could just provide that identifier as the session parameter and not bother providing a separate vid parameter. In that case, you would want to check the "Use Conductrics Session ID as External Visitor ID" option (under "Data Passing" for your Deploy Target). See "Allowing the Passing of Visitor Info" on the Analytics Connectors page in these docs.

Please see the Runtime API Reference for details on all the parameters you can provide to the API.

📘

Providing an External Identifier with Provisional Selections

When you ask for a Provisional Selection, the variation selection is not sent via our Analytics Connectors. If you later "confirm" the selection (by specifying "s":"ok"), the selection will then be sent via the connector. You can use this behavior as a workaround if you need a variation selection from Conductrics before you necessarily have the external ID. You can first ask for the variation assignment as a provisional selection, then "confirm" it once you know the external ID (pass it as vid when you make the confirmation call).

Q: What happens if we make Provisional Selections while also using Analytics Connectors?
A: When you ask for a provisional selection (by specifying "s":"p" as discussed above), the variation selection is not sent via the connector. If you later "confirm" the selection (by specifying "s":"ok"), the selection will then be sent via the connector. You can use this behavior as a workaround if you need a variation selection from Conductrics before you necessarily have the external ID (first get the variation as a provisional selection, then confirm it when you have the vid to provide). See also Analytics Connectors and Passing an External Visitor Identifier.

Via Express or Local JS API in the Browser

You can use the "Preboot" field in your Deploy Target's options to define simple logic to "grab" the external visitor identifier you want. Once you have the value, pass it to the visitor_callback function as shown in the examples below.

Example 1
Let's say the external visitor ID that you want to pass is available as a global variable called window.our_visitor_id, presumably set by some other code on your side. You could then use this one-liner in your Preboot:

visitor_callback({}, {
    vid: window.our_visitor_id
});

Example 2
Let's say that you want to read the external visitor ID from a cookie called s_ecid, and if that is not present, read from a secondary cookie called s_vi. That's also a "one-liner", assuming we first define a convenience function to read the value of a cookie:

var readCookie = function(key) {return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null}

visitor_callback({}, {
    vid: readCookie('s_ecid') || readCookie('s_vi')
});

(The example above defines a readCookie function because browsers don't provide a direct way to read a cookie by name; if your page already defines some equivalent convenience function, feel free to use that instead.)

📘

A note on the timing

The "Preboot" will be executed first, before Conductrics proceeds to do any "real" processing (agent selections, applying Express variations, etc), and it will wait for your code to call the visitor_callback. Therefore, you should call the visitor_callback right away (synchronously) if possible, otherwise there might be a delay before normal Conductrics processing kicks in.

It's possible that the identifier you want may not exist yet when the Preboot executes (at least not on the first page load of the visitor's browser session). If this is the case, you may have to choose between calling visitor_callback right away (without the external identifier), or waiting for it to become available before calling visitor_callback. You can also define a "selection callback", as shown in the next example. Feel free to discuss with Conductrics if you have questions.

🚧

Please note that your company may already be using the "Preboot" to pass Custom Visitor Traits. If so, you'll need to adjust the Preboot code accordingly to add the vid param while preserving whatever the existing logic is. Feel free to reach out to Conductrics if you have questions.

Getting the Visitor ID Asynchronously in the Browser

If it's possible that the visitor identifier that you want to pass to Conductrics may not be available early in the page-load process, you can define a presend_callback within your Preboot code. So, rather than grabbing the identifier right away (when the Preboot executes), instead you are defining an anonymous function that Conductrics will call a few moments later to get the identifier.

visitor_callback({}, {
    // Conductrics will call this function to get the vid
    presend_callback: function(options, cb) {
      cb({vid: window.our_visitor_id});
    }
});

A few notes about the presend_callback:

  • If you provide a presend_callback function, it must execute the callback function passed to it (cb in the example above), even if it turns out there is no vid to provide. If your function never calls cb, then the Conductrics script will essentially be left waiting forever, which means that the visitor will never be counted in the reporting. You may want to implement a timeout of some kind, calling cb() with no arguments after a certain amount of time.

  • If Conductrics agents didn't make any new selections or receive any new goals/conversions during the processing of a given page view, it won't bother calling your presend callback. This is normal.

📘

Passing the vid to the Local JS API directly

Alternatively, you can provide the vid parameter when calling the Local JS API in the Browser. This won't help with Conductrics Express agents, however, so if you want an identifier to be passed for both Express and the Local JS API, use the "Preboot" method described above instead. Please see the Runtime API Reference for details on all the parameters you can provide to the API.

Example: Reading a Google Analytics ID

If you would like to use the _ga cookie set by Google Analytics as your External Visitor ID, you can use the following example as a "boilerplate" Preboot to do so.

In this example:

  • Conductrics processing is allowed to start immediately (because visitor_callback is called right away, without waiting on anything).
  • A presend_callback is specified, which will be executed by Conductrics after any variation selections have been made that may need an External Visitor ID (vid in the code) to be added.
  • If the _ga cookie is present, it is returned as the vid, and Conductrics will then proceed to send the selection event(s) in for reporting purposes. Because there is a vid, the events will be eligible for sending by any Analytics Connectors.
  • If the _ga cookie isn't present, the script waits for 300 milliseconds before checking for the _ga cookie again.
  • After 10 tries (so, about 3 seconds total), the script will give up and allow Conductrics to report the event(s) without an External Visitor ID. (As such, the events will not be eligible for sending by Analytics Connectors.)

This example can be adapted to your needs as you see fit. Feel free to contact Conductrics if you want to discuss.

// simple utility to read cookie value by name
var _cookie=function(e){var o;try{o=decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"+encodeURIComponent(e).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1"))}finally{return o}};

visitor_callback(
  {}, // could provide traits here (not used in this example)
  {
    // called by Conductrics when/if there are events to report 
    presend_callback: function(options, cb) {
      var attempts_left = 10; // counts down

      (function presend_checker() {
        var _ga = _cookie('_ga'); // have it?

        if (_ga) { // yes, got it
          // console.log('>> got GA ID', _ga)
          cb({vid: _ga}); // proceed with vid

        } else { // no, don't have it
          if (attempts_left-- > 0) { // decrement by one
            // console.log('>> waiting for GA ID', attempts_left)
            setTimeout(presend_checker, 300); // reattempt soon

          } else {
            // console.log('>> proceeding without GA ID')
            cb({}) // proceed without vid

          }
        }
      })(); // presend_checker "self-executes" the first time
    }
  }
);
📘

The above preboot example has a few console.log lines that you can uncomment if you want to verify that it's running correctly. Feel free to remove the logging lines entirely if you wish.

Example: Reading an Adobe Analytics ID

The following snippet can be used or adapted as needed to:

  • Wait for the Adobe Analytics library (window.s) to be available
  • Ask the Adobe Analytics library for the visitor's Marketing Cloud Visitor ID, as well as the visitor's legacy Analytics Visitor ID.
  • Provide the two identifiers (if known) to Conductrics as the vid parameter, so that events sent from Conductrics to Adobe via an Adobe Analytics Connector are tied to the correct visitor/session on the Adobe Analytics side.
// helper function to "await" presence of window.s.visitor
var wait_for = function(fn, ms, max, cb, i) {
	if (fn()) {
		return cb(true); // already done, return right away
	} else if (i > max) {
		return cb(false); // too many times
	} else {
		i = (i > 0) ? i+1 : 1; // increment counter
		setTimeout(function () {
			wait_for(fn, ms, max, cb, i); // try again soon
		}, ms);
	}
}

// "await" adobe id and provide to Conductrics as "vid"
visitor_callback({}, {
	presend_callback: function(options, cb) {
		var check_fn = function() {return window.s && (typeof window.s.visitor == 'object')}
		wait_for(check_fn, 400, 5, function(exists) {
			if (exists) {
				var vids = [];
				var s = window.s.visitor;
				var m = s.getMarketingCloudVisitorID()
				var v = s.getAnalyticsVisitorID();
				if (m && m.length > 0) {
					vids.push('MCMID|' + m);
				}
				if (v && v.length > 0) {
					vids.push('v1|' + v);
				}
				cb({
					vid: vids.join(',')
				});
			} else {
				cb()
			}
		});
	}
});