Tracking Adobe Experience Cloud ID With WebSDK

Adobe Experience Cloud ID (ECID) is the unique identifier in Adobe Experience Cloud/Platform to recognise the same people/devices. However, it is not available as a dimension in Adobe Analytics, and we may often want to have it captured as a custom dimension so we can do classification or other data linkage without going to the data feed.

This can be done with the Adobe Experience Cloud Identity Service, which provides a function getMarketingCloudVisitorID(). A good approach with old AppMeasurement tracking is calling the getMarketingCloudVisitorID() in the s.doPlugins(). Then assign the returned value to the desired custom dimension so that every hit will have the ECID.


[updated in 2024]

Adobe introduced a new and updated approach since I originally wrote this post back in 2023 using the Data Prep in Datastream, https://experienceleague.adobe.com/en/docs/experience-platform/tags/extensions/client/web-sdk/accessing-the-ecid.

In short, the ECID is automatically available in the WebSDK payload as part of the identity map at:

xdm.identityMap.ECID[0].id

We can directly map that into any custom dimension in Adobe Analytics.

The following old approach is still viable. We can use it to capture other identities from Adobe or other sources that come in an async approach.


However, something else is needed for the new WebSDK. The new JavaScript library combines and replaces the same for Adobe Analytics, Target, Audience Manager, and Experience Cloud Identity Service. There is no more Adobe Experience Cloud Identity Service to use.

WebSDK has the “onBeforeEventSend” callback function similar to the s.doPlugins() and also has command alloy(“getIdentity”) to retrieve ECID. The problem is the “getIdentity” command is an async function call which will return immediately with a JavaScript Promise. Unlike the getMarketingCloudVisitorID() as a blocking function returning the ECID directly.

The initial idea is to get the ECID and assign it to XDM, before sending the XDM out.

Calling the “getIdentity” from “onBeforeEventSend” with the “Promise.then” method to get the returning ECID for tracking doesn’t work. As the “getIdentity” command is async, all codes in the “onBeforeEventSend” keep going. The tracking is well gone to the Adobe Edge network when the “Promise” returned with value.

Another attempt is using the “await” to block the JavaScript execution and wait for the result from the “getIdentity” command. However, the “onBeforeEventSend” function does not allow “await”. We cannot utilise “onBeforeEventSend” to retrieve and assign ECID as with the old AppMeasurement library.

So we need to separately retrieve ECID before sending tracking data to the Edge network.

A good place should be with basic page view tracking. However, the async nature of the “getIdentity” command is still the issue. Especially if using Adobe Launch for the data collection instead of manually calling the WebSDK function for tracking. We need to find a way for the Adobe Launch to “wait” for the “getIdentity” command to return with value. So we need to get the ECID first, then send data in two steps.

The most common place in Adobe Launch related to order control is rule ordering. We control the sequence of rule execution by providing an order to the event. However, the rule event order cannot help either, as there is no “wait” feature in the rule event ordering.

Another place with the “order” concept in Adobe Launch is the rule component sequencing. It is the answer by the “wait to run next action” advanced option to pause rule execution until the current action is returned.

Adobe Launch action advanced options

So before the WebSDK send event action, we need a custom action to retrieve the ECID. That will wait and not proceed until the “getIdentity” command inside returns with the result. The “wait to run next action” alone is not enough to make it wait, as the “getIdentity” inside the custom code is still async and returns immediately. We should return a JavaScript “Promise” from the custom code to have this action wait until the “getIdentity” function returns the ECID.

return new Promise(function (resolve, reject) {
    alloy("getIdentity").then((identity) => {
        window.ecid = identity.identity.ECID;
        resolve();
    });
});

The sample code above assigned the ECID to a JavaScript variable at the window object. It can be assigned anywhere and even pushed to the data layer, as long as it is accessible by the WebSDK send event action.

We should also consider the execution time of the “getIdentity” command. Every action in Adobe Launch has a timeout assigned on how long Adobe Launch will wait for an action to execute before failing the entire rule. If the custom code action timed out, Adobe Launch will skip the subsequent WebSDK send event action as well. The default value is 2 seconds and seems long enough, but may exceeded depending on the user’s network speed.

It is better in the custom code to first check for the existence of the retrieved ECID, the window.ecid in the above sample code, and only run the “getIdentity” command if it is unavailable. We can store the ECID in a more persisting location, such as a session cookie or storage. So we only need to get it once per session. We can also increase the timeout from 2 seconds to a long time, as we need that executed at least once. Finally, we must handle the unsuccessful case from the “getIdentity” command, omitted from the sample code above.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *