Adobe Target

Getting started with Adobe Target and setting it up

Lemnisk CDP exposes its segmentation/audience of end-users and user macros derived from user behaviour over an endpoint. This is made available as a DataProvider for Adobe Target to consume. Our customers who have Adobe Target can consume this real-time segmented user information for creating audiences and experiences in Target.

Getting Started

Adobe Launch Extension can make the data provider available directly in AEM. You can also add this to AEM directly.

You need a server URL to configure DataProvider. Based on the region, we have three server URL. If you're not sure which one to configure, please contact your Lemnisk Customer Success Manager.

var lemniskDataProvider = {
    name: "Lemnisk Dataprovider",
    version: "1.1.0",
    timeout: 1500,
    config: {
        advid: '100001',
        server: <server url based on your region>,
        caching: false,
        ttl: 24 * 60 * 60 * 1000 //Number of milliseconds in a day
    },
    getCookie: function (cookieId) {
        var cookies = document.cookie;
        if (!cookieId) {
            return '';
        }
        var cookieArray = cookies.split(';');
        for (var key in cookieArray) {
            if (cookieArray.hasOwnProperty(key)) {
                var matchArray = cookieArray[key].match(/\s*(.*)=(.*)/);
                if (matchArray) {
                    if (matchArray[1] === cookieId && matchArray[2]) {
                        return matchArray[2];
                    }
                }
            }
        }
        return '';
    },
    storageAvailable: function (type) {
        if (!lemniskDataProvider.config.caching) {
            return false;
        }
        var storage;
        try {
            storage = window[type];
            var x = '__storage_test__';
            storage.setItem(x, x);
            storage.removeItem(x);
            return true;
        } catch (e) {
            return e instanceof DOMException && (
                    // everything except Firefox
                    e.code === 22 ||
                    // Firefox
                    e.code === 1014 ||
                    // test name field too, because code might not be present
                    // everything except Firefox
                    e.name === 'QuotaExceededError' ||
                    // Firefox
                    e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
                // acknowledge QuotaExceededError only if there's something already stored
                (storage && storage.length !== 0);
        }
    },
    setWithExpiry: function (key, value, ttl) {
        const now = new Date()

        // `item` is an object which contains the original value
        // as well as the time when it's supposed to expire
        const item = {
            value: value,
            expiry: now.getTime() + ttl,
        }
        localStorage.setItem(key, JSON.stringify(item))
    },
    getWithExpiry: function (key) {
        const itemStr = localStorage.getItem(key)
        // if the item doesn't exist, return null
        if (!itemStr) {
            return null
        }
        const item = JSON.parse(itemStr)
        const now = new Date()
        // compare the expiry time of the item with the current time
        if (now.getTime() > item.expiry) {
            // If the item is expired, delete the item from storage
            // and return null
            localStorage.removeItem(key)
            return null
        }
        return item.value
    },

    getFromServer: function (useStorage, url, cookie, callback) {
        const ttl = lemniskDataProvider.config.ttl;
        const xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function (data) {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    var data = {};
                    try {
                        var pData = JSON.parse(xhr.response);
                        var segments = pData['Segments'];
                        var custParameterModified = new Object();
                        var entries = pData['Customization Parameters'];
                        for (const key in entries) {
                            var _key = key.split(" ").join("_");
                            custParameterModified[_key] = entries[key];
                        }
                        data = Object.assign({'segments': segments.join("|")}, custParameterModified);
                        console.log(data)
                    } catch (e) {
                        callback("Error Response from Lemnisk Dataprovider");
                        console.log(e);
                    }
                    callback(null, data);
                    lemniskDataProvider.setWithExpiry(cookie, data, ttl);

                } else {
                    callback("Error Response from Lemnisk Dataprovider");
                    console.log("error");
                }
            }
        };
        xhr.open("GET", url);
        xhr.send();
    },
    provider: function (callback) {
        const cookie = lemniskDataProvider.getCookie('_vz');
        const advid = lemniskDataProvider.config.advid;
        const url = lemniskDataProvider.config.server + advid + "?cs=" + cookie;

        if (lemniskDataProvider.storageAvailable("localStorage")) {
            const storedData = lemniskDataProvider.getWithExpiry(cookie);
            if (storedData === null) {
                lemniskDataProvider.getFromServer(true, url, cookie, callback);
            } else {
                callback(null, storedData);
            }
        } else {
            lemniskDataProvider.getFromServer(false, url, cookie, callback);
        }
    }
};
window.targetGlobalSettings = {
    dataProviders: [
        lemniskDataProvider
    ]
};
  • You will have to list the DataProvider before Target scripts are added. This needs to be loaded before at.js

  • The configurations are present in the config key. For advid, server, please reach out to your customer success partner.

  • Thetimeoutfield is about how long Target will wait for the DataProvider to load.

  • Theconfig.cachingcan be set to true if the DataProvider data can be cached (for config.ttl period - this is in milliseconds). This will make the DataProvider return data from local storage instead of reaching the servers.

Data Flow

The DataProvider relies on the Lemnisk AdServer endpoint which lists down the active segment for this user and the relevant customization parameters. For example:

The above URL (at the time of this documentation) returns:

This data is passed over to Adobe Target via a mbox call as shown below:

Using the data, we can create audiences and offers in Adobe Target.

The page gets customized for the end-user as shown below:

For users where no segmentation is available, Target will continue to serve the default experience.

Last updated