Note that the following integrations are deprecated. Use the newer integrations instead. For details, see:

Developer Help Centre > Integrations Overview

Who is this article for?

  • Web Developers who build Maxymiser campaigns and need to pass testing data to 3rd-party platforms
  • Marketers working closely with Web Developers managing optimization campaigns

Getting started

Integrating with 3rd-party services allows you to send campaign information so you can manage your analytics / DMP more accurately by enriching it with the information of generated campaign experience.

Note: This article describes how to use CD API Integrations module to pass campaign data to a 3rd-party service. This module can only be used on CD API sites.

The module must be applied as a site script. Once applied at site level, all campaigns within the site can use the module.

Source code:

// Integrations module v0.9.7 !function(){function a(){function a(a,b){function i(b){return a=a||"",g("Integrations.register("+a+"): "+(b||"").toString())}var j,k;return b=e(b)?b:{},(a=("string"==typeof a?a:"").toLowerCase().replace(/^\s+|\s+$/g,""))?l[a]?(i(m.errors.alreadyRegistered),null):(b.name=a,j=h(b,{}),k={validate:c(j.validate)?j.validate:f,check:c(j.check)?j.check:f,interval:d(j.interval)?j.interval:50,timeout:d(j.timeout)?j.timeout:2e3,exec:c(j.exec)?j.exec:f,options:j},j=h(k,j),l[a]=j):(i(m.errors.missingRegisterName),null)}function i(a,b){b=e(b)?b:{};var c,d,f,g,i=new Deferred;if(a=(a||"").toLowerCase(),i.integrationName=a,!l[a])return m.reject(i,m.errors.unregisteredIntegration);if(c=h(l[a],{}),c=h(b,c),(f=c.validate(c))!==!0)return m.reject(i,f);if(d=c.campaign,(g=m.validateCampaignRequired(c,i))!==!0)return m.reject(i,g);if(c.isProduction=m.isProduction(),c.attributeMapRequired){var j=m.isValidAttributeMap(c.attributeMap);if(j!==!0)return m.reject(i,j)}return"pending"!==i.state()?i.promise():("never"!==c.timeout&&m.setFailTimeout(c,i),m.check(c).then(function(a){return m.exec(c)}).then(function(a){return c.result=a,m.resolve(i,c)}).fail(function(a){return m.reject(i,a)}),i.promise())}function j(a,b){a=(a||"").toLowerCase();var c=l[a];return!!c&&(b=e(b)?b:{},l[a]=h(b,c),this)}function k(a){if(!a)return l;var b=(a||"").toLowerCase();return l[b]}var l={},m={errors:{missingRegisterName:"Invalid integration reigstration. Name argument is required.",missingRegisterExec:"Missing `exec` for integration registration",alreadyRegistered:"Integration has already been registered",missingRunName:"Missing `name` for `integration.run`",unregisteredIntegration:"Unknown integration name",noCampaignExperience:"Integration was run before the campaign has generated",noRedirectCampaign:"Redirect Integration is not in a valid campaign scope",noRedirectCampaignData:"Redirect Integration is not on a generation page",campaignRequired:"Integration must be deployed within a campaign script",failedToSaveRedirectData:"Failed to save redirect data"},HALFHOUR:1/48,isProduction:function(){function a(a){for(var c,d={},e="",f=0;c=b(a+f++);)e+=c;e=decodeURIComponent(e);try{d=JSON.parse(e)}catch(g){}return d}function b(a){var b=new RegExp("(?:^|; )"+encodeURIComponent(a).replace(/([.$?*|{}()\[\]\\\/+^])/g,"\\$1")+"=([^;]+)"),c=(document.cookie.match(b)||["",""])[1];return c}var c=mmsystem.getConfig().storageType;if("cookie-key-value"===c||"cookie-key-value-secure"===c)return!/mmapi.p.cfgid/i.test(document.cookie)&&!/mmapi.p.un/i.test(document.cookie);for(var d=a("mmcore.store.p.")||{},e=a("mmcore.store.s.")||{},f=a("mmapi.store.p.")||{},g=a("mmapi.store.s.")||{},h=[d,e,f,g],i={"mmparams.p":1,"mmparams.d":1},j={un:1,cfgID:1,pruh:1},k=h.length;k--;){var l=h[k];for(var m in i||{})for(var n in j||{})if((l[m]||{})[n])return!1}return!0},isValidIntegrationName:function(a){return"string"==typeof a&&/^\w+/.test(a)},isCampaignScope:function(a){return!!(e(a)&&a.getName&&a.getExperience)},getCampaignExperience:function(a){var b={};return m.isCampaignScope(a)&&(b=a.getExperience&&a.getExperience()||{}),!!Object.keys(b)&&m.formatCampaignExperience(b)},formatCampaignExperience:function(a){a=e(a)?a:{};var b=[];for(var c in a)b.push(c+":"+a[c]);return b.join("|")},getData:function(a){a=(a||"").toLowerCase();var b=visitor.getData("Integrations");return b=e(b)?b:{},a&&(b[a]=b[a]||{}),b},setRedirectData:function(a,b){if(a=(a||"").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();return c[a][d]=c[a][d]||{},c[a][d].redirectData=b.getExperience(),visitor.setData("Integrations",c,m.HALFHOUR),!0},removeRedirectData:function(a,b){if(a=(a||"").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();return c[a][d]=c[a][d]||{},c[a][d].redirectData=null,visitor.setData("Integrations",c,m.HALFHOUR),!0},getRedirectData:function(a,b){if(a=(a||"").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();if(c[a][d]=c[a][d]||{},!c[a]||!c[a][d])return c[a]=c[a]||{},c[a][d]=c[a][d]||{},c[a][d].redirectData=null,visitor.setData("Integrations",c,m.HALFHOUR),!1;for(var e in c[a])if(e===d)return c[a][e].redirectData;return!1},getSessionDate:function(a,b){var c=m.getData(a),d=c[a][b.getName()]||{},e=d.sessionDate;return e},setSessionDate:function(a,b){var c=m.getData(a),d=b.getName();c[a][d]=c[a][d]||{},c[a][d].sessionDate=(new Date).getTime(),visitor.setData("Integrations",c,m.HALFHOUR)},resolve:function(a,b){return a.resolve(b),a.promise()},reject:function(a,b){var c=a.integrationName||"unknown name";return b=b||"unknown reason",g("Integration ["+c+"]: "+b.toString()),a.reject(b),a.promise()},validateCampaignRequired:function(a,b){if(!a.campaignRequired)return a.oncePerSession?"campaign option is required when using the oncePerSession option":!a.redirect||"campaign option is required when using the redirect option";var c=a.campaign,d="",e=m.isCampaignScope(c);if(e!==!0)return m.errors.campaignRequired;if(a.campaignExperience=m.getCampaignExperience(c),a.campaignExperience===!1&&!a.redirect)return m.errors.noCampaignExperience(a.name);if(a.oncePerSession&&!a.redirect&&a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d))return g("Integration ["+a.name+"]: data has already been sent this session"),m.resolve(b,a),!0;if(a.redirect){var f=function(){var a=c.getElements();for(var b in a)return!0;return!1}();return f?c.isDefault()?!(a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d))||(g("Integration ["+a.name+"]: data has already been sent this session"),m.resolve(b,a),!0):m.setRedirectData(a.name,c)?(m.resolve(b,a),!0):m.errors.failedToSaveRedirectData:a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d)?(g("Integration ["+a.name+"]: data has already been sent this session"),m.resolve(b,a),!0):(a.campaignExperience=m.getRedirectData(a.name,c),a.campaignExperience=m.formatCampaignExperience(a.campaignExperience),m.removeRedirectData(a.name,c),!!a.campaignExperience||m.errors.noRedirectCampaignData)}return!0},setFailTimeout:function(a,b){!function(b){setTimeout(function(){setTimeout(function(){if("pending"===b.state())return m.reject(b,"Integration timed out after "+a.timeout+"ms")},0)},a.timeout+1)}(b)},isValidAttributeMap:function(a){if(!a)return"Missing required attributeMap parameter";if(!e(a)||!Object.keys(a).length)return"The attributeMap parameter is empty or not an object";for(var b in a){var c=a[b];if("string"!=typeof b||!/^[a-zA-Z]+/.test(b))return"Invalid attribute name in the attributeMap";if(!e(c))return"attributeMap values must be stored in an object";if(!Object.keys(c).length)return"attributeMap attribute object is empty";for(var d in c)if(!/^\w+$/.test(d)&&"default"!==d)return"Invalid attribute ID in attributeMap"}return!0},check:function(a){var c=new Deferred,d=!1;return function e(){var f=a.check.call(this,a);return b(f)?void setTimeout(function(){f.done(function(){return c.resolve()}).fail(function(a){return c.reject(a)})},0):f?void setTimeout(function(){c.resolve()},0):void(d||setTimeout(e,a.interval))}(),setTimeout(function(){d=!0},a.timeout),c.promise()},exec:function(a){var c=new Deferred,d=a.exec.call(this,a);return b(d)?(setTimeout(function(){d.done(function(a){return c.resolve(a)}).fail(function(a){return c.reject(a)})},0),c.promise()):(d===!0?m.resolve(c,a.result):m.reject(c,d),c.promise())}};return{register:a,run:i,setDefaults:j,get:k}}function b(a){return e(a)&&c(a.then)}function c(a){return"function"==typeof a}function d(a){return"number"==typeof a&&a>0}function e(a){return"object"==typeof a&&!!a}function f(){return!0}function g(a){window.mm_error=window.mm_error||"",window.mm_error+=a+"\n"}function h(a,b){a=e(a)?a:{},b=e(b)?b:{};var c={};for(var d in b)c[d]=b[d];for(var f in a)c[f]=a[f];return c}if("object"==typeof modules&&"function"==typeof modules.define){var i={autoDefine:!0,singleton:!0};modules.define("Integrations",i,a)}else modules={require:function(){return new a}}}();

You can copy and paste the above code as a site script and then make campaign-specific calls to the module from every campaign you want to be exposed.

Module reference

The Integrations module is automatically defined and becomes available in all campaign and site scripts on pages where the original integration script was mapped. You can access the module's interface using "Integrations" variable.

Methods

get( name ) → {Object}

Retrieves both registered and default properties for an integration.

Parameters

Name Description Type
name

Integration name

String

Code example

// Provides all the properties for the 'analytics provider' integration Integrations.get( 'analytics provider' );

register( name, properties )

Registers an integration, so it can be called with the Integrations.run() method.

Parameters

Name Description Type
name

Integration name

String
properties

Integration logic

Object

Code example

Integrations.register( 'analytics provider', // Is campaign generation required? campaignRequired: true, // Send data once per 30-minute session? oncePerSession: true, // Validate user inputs validate: function( integration ){ if ( !integration.accountId ) { return 'Missing required accountId'; } }, // Check recursively whether the integration is ready to proceed (until the condition returns true) check: function( integration ) { return window.readyToIntegrate === true; }, // Send custom data via the 3rd-party API exec: function( integration ){ window.sendAnalytics( { key: integration.campaign.getName(), value: integration.campaignExperience } ); } });

run( name, properties ) → {Promise}

Proceeds with the integration itself by using the 3rd-party API on the page where called.

Parameters

Name Description Type
name

A registered integration name

String
properties

Optional properties to override the defaults for the current integration run.

Object

Code example

Integrations.run( 'analytics provider', { campaign: campaign, accountId: 12345, } ).done( function( integration ){ // integration.result would contain any data returned by the exec function }).fail(function(reason){ // console.warn( 'Integration with analytics provider could not proceed!' ); });

setDefaults( name, properties )

Sets the default configurational properties for the integration.

Parameters

Name Description Type
name

A registered integration name

String
properties

Default properties for the integration

Object

Code example

Integrations.setDefaults( 'analytics company', { accountId: 12345 } ); Integrations.run( 'analytics company' );

Actual integration scripts

Click on any of the 3rd-party service logos below to review instructions of how to activate campaign data sending to the specific service.

  • Adobe Analytics Integration
  • Clicktale Integration
  • DemandBase Integration
  • Google Analytics Integration
  • Heap Analytics Integration
  • IBM Analytics Integration
  • SessionCam Integration

Configure sample integration for a campaign

Step 1

Create a site script and insert the module source code. You only need to do this once.

Map the site script to all the http/https site pages that you need it.

Note: Make sure the script has low output order value (such as -100) to execute first, so that any other script can use it.

Step 2

Create a site script with custom integration logic or choose one from the available integrations. This should be done once for every 3rd-party service provider you want to integrate with.

Map it to the same pages as the Integrations module, but with higher output order value (such as -50).

Step 3

Run the integration from a campaign script on the same page where campaign elements arrive.

Make sure this campaign script has a higher output order number than both the Integration module and the Integration logic scripts (e.g., 0 or bigger).