Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Prebid.js
Submodule Prebid.js added at b121ed
1 change: 1 addition & 0 deletions libraries/intentIqConstants/intentIqConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const GVLID = "1323";
export const VERSION = 0.33;
export const PREBID = "pbjs";
export const HOURS_24 = 86400000;
export const HOURS_72 = HOURS_24 * 3;

export const INVALID_ID = "INVALID_ID";

Expand Down
33 changes: 19 additions & 14 deletions libraries/intentIqUtils/getRefferer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ import { getWindowTop, logError, getWindowLocation, getWindowSelf } from '../../
* Determines if the script is running inside an iframe and retrieves the URL.
* @return {string} The encoded vrref value representing the relevant URL.
*/
export function getReferrer() {

export function getCurrentUrl() {
let url = '';
try {
const url = getWindowSelf() === getWindowTop()
? getWindowLocation().href
: getWindowTop().location.href;
if (getWindowSelf() === getWindowTop()) {
// top page
url = getWindowLocation().href || '';
} else {
// iframe
url = getWindowTop().location.href || '';
}

if (url.length >= 50) {
const { origin } = new URL(url);
return origin;
}
return new URL(url).origin;
};

return url;
} catch (error) {
// Handling access errors, such as cross-domain restrictions
logError(`Error accessing location: ${error}`);
return '';
}
Expand All @@ -31,12 +37,12 @@ export function getReferrer() {
* @return {string} The modified URL with appended `vrref` or `fui` parameters.
*/
export function appendVrrefAndFui(url, domainName) {
const fullUrl = encodeURIComponent(getReferrer());
const fullUrl = getCurrentUrl();
if (fullUrl) {
return (url += '&vrref=' + getRelevantRefferer(domainName, fullUrl));
}
url += '&fui=1'; // Full Url Issue
url += '&vrref=' + encodeURIComponent(domainName || '');
if (domainName) url += '&vrref=' + encodeURIComponent(domainName);
return url;
}

Expand All @@ -47,10 +53,9 @@ export function appendVrrefAndFui(url, domainName) {
* @return {string} The relevant referrer
*/
export function getRelevantRefferer(domainName, fullUrl) {
if (domainName && isDomainIncluded(fullUrl, domainName)) {
return fullUrl;
}
return domainName ? encodeURIComponent(domainName) : fullUrl;
return encodeURIComponent(
domainName && isDomainIncluded(fullUrl, domainName) ? fullUrl : (domainName || fullUrl)
);
}

/**
Expand All @@ -61,7 +66,7 @@ export function getRelevantRefferer(domainName, fullUrl) {
*/
export function isDomainIncluded(fullUrl, domainName) {
try {
return fullUrl.includes(domainName);
return new URL(fullUrl).hostname === domainName;
} catch (error) {
logError(`Invalid URL provided: ${error}`);
return false;
Expand Down
17 changes: 17 additions & 0 deletions libraries/intentIqUtils/getUnitPosition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function getUnitPosition(pbjs, adUnitCode) {
const adUnits = pbjs?.adUnits;
if (!Array.isArray(adUnits) || !adUnitCode) return;

for (let i = 0; i < adUnits.length; i++) {
const adUnit = adUnits[i];
if (adUnit?.code !== adUnitCode) continue;

const mediaTypes = adUnit?.mediaTypes;
if (!mediaTypes || typeof mediaTypes !== 'object') return;

const firstKey = Object.keys(mediaTypes)[0];
const pos = mediaTypes[firstKey]?.pos;

return typeof pos === 'number' ? pos : undefined;
}
}
36 changes: 33 additions & 3 deletions libraries/intentIqUtils/intentIqConfig.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
export const iiqServerAddress = (configParams, gdprDetected) => typeof configParams?.iiqServerAddress === 'string' ? configParams.iiqServerAddress : gdprDetected ? 'https://api-gdpr.intentiq.com' : 'https://api.intentiq.com'
export const iiqPixelServerAddress = (configParams, gdprDetected) => typeof configParams?.iiqPixelServerAddress === 'string' ? configParams.iiqPixelServerAddress : gdprDetected ? 'https://sync-gdpr.intentiq.com' : 'https://sync.intentiq.com'
export const reportingServerAddress = (reportEndpoint, gdprDetected) => reportEndpoint && typeof reportEndpoint === 'string' ? reportEndpoint : gdprDetected ? 'https://reports-gdpr.intentiq.com/report' : 'https://reports.intentiq.com/report'
const REGION_MAPPING = {
gdpr: true,
apac: true,
emea: true
};

function checkRegion(region) {
if (typeof region !== 'string') return '';
const lower = region.toLowerCase();
return REGION_MAPPING[lower] ? lower : '';
}

function buildServerAddress(baseName, region) {
const checkedRegion = checkRegion(region);
if (checkedRegion) return `https://${baseName}-${checkedRegion}.intentiq.com`;
return `https://${baseName}.intentiq.com`;
}

export const getIiqServerAddress = (configParams = {}) => {
if (typeof configParams?.iiqServerAddress === 'string') return configParams.iiqServerAddress;
return buildServerAddress('api', configParams.region);
};

export const iiqPixelServerAddress = (configParams = {}) => {
if (typeof configParams?.iiqPixelServerAddress === 'string') return configParams.iiqPixelServerAddress;
return buildServerAddress('sync', configParams.region);
};

export const reportingServerAddress = (reportEndpoint, region) => {
if (reportEndpoint && typeof reportEndpoint === 'string') return reportEndpoint;
const host = buildServerAddress('reports', region);
return `${host}/report`;
};
10 changes: 6 additions & 4 deletions libraries/intentIqUtils/urlUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export function appendSPData (url, firstPartyData) {
const spdParam = firstPartyData?.spd ? encodeURIComponent(typeof firstPartyData.spd === 'object' ? JSON.stringify(firstPartyData.spd) : firstPartyData.spd) : '';
url += spdParam ? '&spd=' + spdParam : '';
return url
export function appendSPData (url, partnerData) {
const spdParam = partnerData?.spd ? encodeURIComponent(typeof partnerData.spd === 'object' ? JSON.stringify(partnerData.spd) : partnerData.spd) : '';
if (!spdParam) {
return url;
}
return `${url}&spd=${spdParam}`;
};
37 changes: 25 additions & 12 deletions modules/intentIqAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { ajax } from '../src/ajax.js';
import { EVENTS } from '../src/constants.js';
import { detectBrowser } from '../libraries/intentIqUtils/detectBrowserUtils.js';
import { appendSPData } from '../libraries/intentIqUtils/urlUtils.js';
import { appendVrrefAndFui, getReferrer } from '../libraries/intentIqUtils/getRefferer.js';
import { appendVrrefAndFui, getCurrentUrl, getRelevantRefferer } from '../libraries/intentIqUtils/getRefferer.js';
import { getCmpData } from '../libraries/intentIqUtils/getCmpData.js';
import { getUnitPosition } from '../libraries/intentIqUtils/getUnitPosition.js';
import {
VERSION,
PREBID,
Expand All @@ -16,10 +17,12 @@ import { reportingServerAddress } from '../libraries/intentIqUtils/intentIqConfi
import { handleAdditionalParams } from '../libraries/intentIqUtils/handleAdditionalParams.js';
import { gamPredictionReport } from '../libraries/intentIqUtils/gamPredictionReport.js';
import { defineABTestingGroup } from '../libraries/intentIqUtils/defineABTestingGroupUtils.js';
import { getGlobal } from '../src/prebidGlobal.js';

const MODULE_NAME = 'iiqAnalytics';
const analyticsType = 'endpoint';
const prebidVersion = '$prebid.version$';
const pbjs = getGlobal();
export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000);
let globalName;
let identityGlobalName;
Expand Down Expand Up @@ -70,10 +73,7 @@ const PARAMS_NAMES = {
const DEFAULT_URL = 'https://reports.intentiq.com/report';

const getDataForDefineURL = () => {
const cmpData = getCmpData();
const gdprDetected = cmpData.gdprString;

return [iiqAnalyticsAnalyticsAdapter.initOptions.reportingServerAddress, gdprDetected];
return [iiqAnalyticsAnalyticsAdapter.initOptions.reportingServerAddress, iiqAnalyticsAnalyticsAdapter.initOptions.region];
};

const getDefaultInitOptions = () => {
Expand All @@ -92,7 +92,8 @@ const getDefaultInitOptions = () => {
abPercentage: null,
abTestUuid: null,
additionalParams: null,
reportingServerAddress: ''
reportingServerAddress: '',
region: ''
}
}

Expand Down Expand Up @@ -123,12 +124,13 @@ function initAdapterConfig(config) {

const options = config?.options || {}
iiqConfig = options
const { manualWinReportEnabled, gamPredictReporting, reportMethod, reportingServerAddress, adUnitConfig, partner, ABTestingConfigurationSource, browserBlackList, domainName, additionalParams } = options
const { manualWinReportEnabled, gamPredictReporting, reportMethod, reportingServerAddress, region, adUnitConfig, partner, ABTestingConfigurationSource, browserBlackList, domainName, additionalParams } = options
iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled =
manualWinReportEnabled || false;
iiqAnalyticsAnalyticsAdapter.initOptions.reportMethod = parseReportingMethod(reportMethod);
iiqAnalyticsAnalyticsAdapter.initOptions.gamPredictReporting = typeof gamPredictReporting === 'boolean' ? gamPredictReporting : false;
iiqAnalyticsAnalyticsAdapter.initOptions.reportingServerAddress = typeof reportingServerAddress === 'string' ? reportingServerAddress : '';
iiqAnalyticsAnalyticsAdapter.initOptions.region = typeof region === 'string' ? region : '';
iiqAnalyticsAnalyticsAdapter.initOptions.adUnitConfig = typeof adUnitConfig === 'number' ? adUnitConfig : 1;
iiqAnalyticsAnalyticsAdapter.initOptions.configSource = ABTestingConfigurationSource;
iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = defineABTestingGroup(options);
Expand All @@ -155,7 +157,7 @@ function receivePartnerData() {
return false
}
iiqAnalyticsAnalyticsAdapter.initOptions.fpid = FPD
const { partnerData, clientsHints = '', actualABGroup } = window[identityGlobalName]
const { partnerData, clientHints = '', actualABGroup } = window[identityGlobalName]

if (partnerData) {
iiqAnalyticsAnalyticsAdapter.initOptions.dataIdsInitialized = true;
Expand All @@ -172,7 +174,7 @@ function receivePartnerData() {
if (actualABGroup) {
iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = actualABGroup;
}
iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints = clientsHints;
iiqAnalyticsAnalyticsAdapter.initOptions.clientHints = clientHints;
} catch (e) {
logError(e);
return false;
Expand Down Expand Up @@ -268,9 +270,10 @@ function getRandom(start, end) {

export function preparePayload(data) {
const result = getDefaultDataObject();
const fullUrl = getCurrentUrl();
result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner;
result[PARAMS_NAMES.prebidVersion] = prebidVersion;
result[PARAMS_NAMES.referrer] = getReferrer();
result[PARAMS_NAMES.referrer] = getRelevantRefferer(iiqAnalyticsAnalyticsAdapter.initOptions.domainName, fullUrl);
result[PARAMS_NAMES.terminationCause] = iiqAnalyticsAnalyticsAdapter.initOptions.terminationCause;
result[PARAMS_NAMES.clientType] = iiqAnalyticsAnalyticsAdapter.initOptions.clientType;
result[PARAMS_NAMES.siteId] = iiqAnalyticsAnalyticsAdapter.initOptions.siteId;
Expand Down Expand Up @@ -345,6 +348,15 @@ function prepareData(data, result) {
if (data.status) {
result.status = data.status;
}
if (data.size) {
result.size = data.size;
}
if (typeof data.pos === 'number') {
result.pos = data.pos;
} else if (data.adUnitCode) {
const pos = getUnitPosition(pbjs, data.adUnitCode);
if (typeof pos === 'number') result.pos = pos;
}

result.prebidAuctionId = data.auctionId || data.prebidAuctionId;

Expand Down Expand Up @@ -410,6 +422,7 @@ function getDefaultDataObject() {
function constructFullUrl(data) {
const report = [];
const reportMethod = iiqAnalyticsAnalyticsAdapter.initOptions.reportMethod;
const partnerData = window[identityGlobalName]?.partnerData;
const currentBrowserLowerCase = detectBrowser();
data = btoa(JSON.stringify(data));
report.push(data);
Expand All @@ -432,11 +445,11 @@ function constructFullUrl(data) {
'&source=' +
PREBID +
'&uh=' +
encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints) +
encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.clientHints) +
(cmpData.uspString ? '&us_privacy=' + encodeURIComponent(cmpData.uspString) : '') +
(cmpData.gppString ? '&gpp=' + encodeURIComponent(cmpData.gppString) : '') +
(cmpData.gdprString ? '&gdpr_consent=' + encodeURIComponent(cmpData.gdprString) + '&gdpr=1' : '&gdpr=0');
url = appendSPData(url, iiqAnalyticsAnalyticsAdapter.initOptions.fpid);
url = appendSPData(url, partnerData);
url = appendVrrefAndFui(url, iiqAnalyticsAnalyticsAdapter.initOptions.domainName);

if (reportMethod === 'POST') {
Expand Down
11 changes: 6 additions & 5 deletions modules/intentIqAnalyticsAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,8 @@ pbjs.enableAnalytics({
provider: 'iiqAnalytics',
options: {
partner: 1177538,
manualWinReportEnabled: false,
reportMethod: "GET",
adUnitConfig: 1,
ABTestingConfigurationSource: 'IIQServer',
domainName: "currentDomain.com",
gamPredictReporting: false
}
});
```
Expand Down Expand Up @@ -90,7 +87,9 @@ originalCpm: 1.5, // Original CPM value.
originalCurrency: 'USD', // Original currency.
status: 'rendered', // Auction status, e.g., 'rendered'.
placementId: 'div-1' // ID of the ad placement.
adType: 'banner' // Specifies the type of ad served
adType: 'banner', // Specifies the type of ad served,
size: '320x250', // Size of adUnit item,
pos: 0 // The following values are defined in the ORTB 2.5 spec
}
```

Expand All @@ -108,6 +107,8 @@ adType: 'banner' // Specifies the type of ad served
| status | String | Status of the impression. Leave empty or undefined if Prebid is not the bidding platform | rendered | No |
| placementId | String | Unique identifier of the ad unit on the webpage that showed this ad | div-1 | No |
| adType | String | Specifies the type of ad served. Possible values: “banner“, “video“, “native“, “audio“. | banner | No |
| size | String | Size of adUnit item | '320x250' | No |
| pos | number | The pos field specifies the position of the adUnit on the page according to the OpenRTB 2.5 specification | 0 | No |

To report the auction win, call the function as follows:

Expand Down
Loading
Loading