Skip to content

Commit

Permalink
IntentIQ Analytics Adapter: initial release (prebid#11930)
Browse files Browse the repository at this point in the history
* IntentIQ Analytics Module

* update intentiq analytics adapter

* remove percentage and change group

* update analytics adapter and tests

* updated flow

* remove 'this'

* rename privacy parameter

* add callback timeout

* Extract only used parameters from CryptoJS

* add new unit tests

* change callback timeout order

* added tests and small fixes

* change saving logic

* support "html5" and "cookie" storage types

* support storage type, update flow

* add documentation

* small updates

* IntentIQ Analytics Module

* Multiple modules: clean up unit tests (prebid#11630)

* Test chunking

* update some bidder eid tests

* split eid tests into each userId submodule

* cleanup userId_spec

* add TEST_PAT config

* fix idx, lmp

* clean up userId_spec

* fix double run, invibes, intentIq

* small fixes

* undo package-lock changes

* update colors, remove empty test

* 8pod analytics: clean up interval handler

* update intentiq analytics adapter

* undo unnecessary changes

* undo change by mistake

* update params and documentation

* turn back storage clearing

* fix linter error

* fix wording and spelling mistakes

* change test to handle full url to check other ids not reported

---------

Co-authored-by: Eyvaz <62054743+eyvazahmadzada@users.noreply.github.com>
Co-authored-by: Eyvaz Ahmadzada <eyvaz.ahmedzade.12@gmail.com>
Co-authored-by: Demetrio Girardi <dgirardi@prebid.org>
  • Loading branch information
4 people authored and mefjush committed Jul 19, 2024
1 parent 846e7ee commit c57b8c5
Show file tree
Hide file tree
Showing 4 changed files with 433 additions and 0 deletions.
234 changes: 234 additions & 0 deletions modules/intentIqAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import { logInfo, logError } from '../src/utils.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import { ajax } from '../src/ajax.js';
import { getStorageManager } from '../src/storageManager.js';
import { config } from '../src/config.js';
import { EVENTS } from '../src/constants.js';
import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js';

const MODULE_NAME = 'iiqAnalytics'
const analyticsType = 'endpoint';
const defaultUrl = 'https://reports.intentiq.com/report';
const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME });
const prebidVersion = '$prebid.version$';
export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000);

const FIRST_PARTY_KEY = '_iiq_fdata';
const FIRST_PARTY_DATA_KEY = '_iiq_fdata';
const JSVERSION = 0.1

const PARAMS_NAMES = {
abTestGroup: 'abGroup',
pbPauseUntil: 'pbPauseUntil',
pbMonitoringEnabled: 'pbMonitoringEnabled',
isInTestGroup: 'isInTestGroup',
enhanceRequests: 'enhanceRequests',
wasSubscribedForPrebid: 'wasSubscribedForPrebid',
hadEids: 'hadEids',
ABTestingConfigurationSource: 'ABTestingConfigurationSource',
lateConfiguration: 'lateConfiguration',
jsversion: 'jsversion',
eidsNames: 'eidsNames',
requestRtt: 'rtt',
clientType: 'clientType',
adserverDeviceType: 'AdserverDeviceType',
terminationCause: 'terminationCause',
callCount: 'callCount',
manualCallCount: 'mcc',
pubprovidedidsFailedToregister: 'ppcc',
noDataCount: 'noDataCount',
profile: 'profile',
isProfileDeterministic: 'pidDeterministic',
siteId: 'sid',
hadEidsInLocalStorage: 'idls',
auctionStartTime: 'ast',
eidsReadTime: 'eidt',
agentId: 'aid',
auctionEidsLength: 'aeidln',
wasServerCalled: 'wsrvcll',
referrer: 'vrref',
isInBrowserBlacklist: 'inbbl',
prebidVersion: 'pbjsver',
partnerId: 'partnerId'
};

let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analyticsType }), {
initOptions: {
lsValueInitialized: false,
partner: null,
fpid: null,
currentGroup: null,
dataInLs: null,
eidl: null,
lsIdsInitialized: false,
manualReport: false
},
track({ eventType, args }) {
switch (eventType) {
case BID_WON:
bidWon(args);
break;
default:
break;
}
}
});

// Events needed
const {
BID_WON
} = EVENTS;

function readData(key) {
try {
if (storage.hasLocalStorage()) {
return storage.getDataFromLocalStorage(key);
}
if (storage.cookiesAreEnabled()) {
return storage.getCookie(key);
}
} catch (error) {
logError(error);
}
}

function initLsValues() {
if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) return;
iiqAnalyticsAnalyticsAdapter.initOptions.fpid = JSON.parse(readData(FIRST_PARTY_KEY));
let iiqArr = config.getConfig('userSync.userIds').filter(m => m.name == 'intentIqId');
if (iiqArr && iiqArr.length > 0) iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized = true;
if (!iiqArr) iiqArr = [];
if (iiqArr.length == 0) {
iiqArr.push({
'params': {
'partner': -1,
'group': 'U'
}
})
}
if (iiqArr && iiqArr.length > 0) {
if (iiqArr[0].params && iiqArr[0].params.partner && !isNaN(iiqArr[0].params.partner)) {
iiqAnalyticsAnalyticsAdapter.initOptions.partner = iiqArr[0].params.partner;
iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = iiqAnalyticsAnalyticsAdapter.initOptions.fpid.group;
}
}
}

function initReadLsIds() {
if (isNaN(iiqAnalyticsAnalyticsAdapter.initOptions.partner) || iiqAnalyticsAnalyticsAdapter.initOptions.partner == -1) return;
try {
iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = null;
let iData = readData(FIRST_PARTY_DATA_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner)
if (iData) {
iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true;
let pData = JSON.parse(iData);
iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = pData.data;
iiqAnalyticsAnalyticsAdapter.initOptions.eidl = pData.eidl || -1;
}
} catch (e) {
logError(e)
}
}

function bidWon(args) {
if (!iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) { initLsValues(); }
if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); }
if (!iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) {
ajax(constructFullUrl(preparePayload(args, true)), undefined, null, { method: 'GET' });
}

logInfo('IIQ ANALYTICS -> BID WON')
}

function getRandom(start, end) {
return Math.floor((Math.random() * (end - start + 1)) + start);
}

export function preparePayload(data) {
let result = getDefaultDataObject();

result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner;
result[PARAMS_NAMES.prebidVersion] = prebidVersion;
result[PARAMS_NAMES.referrer] = getReferrer();

result[PARAMS_NAMES.abTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup;

result[PARAMS_NAMES.isInTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup == 'A';

result[PARAMS_NAMES.agentId] = REPORTER_ID;

fillPrebidEventData(data, result);

fillEidsData(result);

return result;
}

function fillEidsData(result) {
if (iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) {
result[PARAMS_NAMES.hadEidsInLocalStorage] = iiqAnalyticsAnalyticsAdapter.initOptions.eidl && iiqAnalyticsAnalyticsAdapter.initOptions.eidl > 0;
result[PARAMS_NAMES.auctionEidsLength] = iiqAnalyticsAnalyticsAdapter.initOptions.eidl || -1;
}
}

function fillPrebidEventData(eventData, result) {
if (eventData.bidderCode) { result.bidderCode = eventData.bidderCode; }
if (eventData.cpm) { result.cpm = eventData.cpm; }
if (eventData.currency) { result.currency = eventData.currency; }
if (eventData.originalCpm) { result.originalCpm = eventData.originalCpm; }
if (eventData.originalCurrency) { result.originalCurrency = eventData.originalCurrency; }
if (eventData.status) { result.status = eventData.status; }
if (eventData.auctionId) { result.prebidAuctionId = eventData.auctionId; }

result.biddingPlatformId = 1;
result.partnerAuctionId = 'BW';
}

function getDefaultDataObject() {
return {
'inbbl': false,
'pbjsver': prebidVersion,
'partnerAuctionId': 'BW',
'reportSource': 'pbjs',
'abGroup': 'U',
'jsversion': JSVERSION,
'partnerId': -1,
'biddingPlatformId': 1,
'idls': false,
'ast': -1,
'aeidln': -1
}
}

function constructFullUrl(data) {
let report = []
data = btoa(JSON.stringify(data))
report.push(data)
return defaultUrl + '?pid=' + iiqAnalyticsAnalyticsAdapter.initOptions.partner +
'&mct=1' +
((iiqAnalyticsAnalyticsAdapter.initOptions && iiqAnalyticsAnalyticsAdapter.initOptions.fpid)
? '&iiqid=' + encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.fpid.pcid) : '') +
'&agid=' + REPORTER_ID +
'&jsver=' + JSVERSION +
'&vrref=' + getReferrer() +
'&source=pbjs' +
'&payload=' + JSON.stringify(report)
}

export function getReferrer() {
return document.referrer;
}

iiqAnalyticsAnalyticsAdapter.originEnableAnalytics = iiqAnalyticsAnalyticsAdapter.enableAnalytics;

iiqAnalyticsAnalyticsAdapter.enableAnalytics = function (myConfig) {
iiqAnalyticsAnalyticsAdapter.originEnableAnalytics(myConfig); // call the base class function
};

adapterManager.registerAnalyticsAdapter({
adapter: iiqAnalyticsAnalyticsAdapter,
code: MODULE_NAME
});

export default iiqAnalyticsAnalyticsAdapter;
27 changes: 27 additions & 0 deletions modules/intentIqAnalyticsAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Overview

Module Name: iiqAnalytics
Module Type: Analytics Adapter
Maintainer: julian@intentiq.com

# Description

By using this Intent IQ adapter, you will be able to obtain comprehensive analytics and metrics regarding the performance of the Intent IQ Unified ID module. This includes how the module impacts your revenue, CPMs, and fill rates related to bidders and domains.

## Intent IQ Universal ID Registration

No registration for this module is required.

## Intent IQ Universal IDConfiguration

<B>IMPORTANT</B>: only effective when Intent IQ Universal ID module is installed and configured. [(How-To)](https://docs.prebid.org/dev-docs/modules/userid-submodules/intentiq.html)

No additional configuration for this module is required. We will use the configuration provided for Intent IQ Universal IQ module.

#### Example Configuration

```js
pbjs.enableAnalytics({
provider: 'iiqAnalytics'
});
```
Empty file modified modules/intentIqIdSystem.md
100755 → 100644
Empty file.
Loading

0 comments on commit c57b8c5

Please sign in to comment.