Skip to content

Commit

Permalink
GrowthCode Analytics Adaptor Module: initial module release (#9021)
Browse files Browse the repository at this point in the history
* Initial check-in ofthe GrowthCode Adaptor

* Growthcode ID System

* Working on test module

* Tests for the growthCode Id System

* Clean up tests for GrowthCode

* Fixed the default values for shareID

* New Analyics package

* Growthcode Analyics Adapter

* Backout growthcode User ID module
  • Loading branch information
southern-growthcode committed Nov 28, 2022
1 parent a833997 commit b0413b2
Show file tree
Hide file tree
Showing 4 changed files with 421 additions and 0 deletions.
134 changes: 134 additions & 0 deletions integrationExamples/gpt/growthcode.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!--
GrowthCode Setup Example contact support@growthcode.io for more information.
-->

<html>
<head>
<script async src="../../build/dev/prebid.js"></script>
<script async src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
var FAILSAFE_TIMEOUT = 3300;
var PREBID_TIMEOUT = 1000;

var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250], [300,600]],
}
},
// Replace this object to test a new Adapter!
bids: [{
bidder: 'appnexus',
params: {
placementId: 13144370
}
}],
}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

</script>

<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function() {
googletag.pubads().disableInitialLoad();
});

pbjs.que.push(function() {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: sendAdserverRequest,
timeout: PREBID_TIMEOUT
});
pbjs.enableAnalytics({
provider: 'growthCodeAnalytics',
options: {
pid: 'TEST01',
trackEvents: [
'auctionInit',
'auctionEnd',
'bidAdjustment',
'bidTimeout',
'bidTimeout',
'bidRequested',
'bidResponse',
'setTargeting',
'requestBids',
'addAdUnits',
'noBid',
'bidWon',
'bidderDone']
}
});
pbjs.setConfig({
debugging: {
enabled: true,
bids: [{
bidder: 'appnexus',
adUnitCode: '/19968336/header-bid-tag-0',
cpm: 1.5,
adId: '111111',
ad: '<html><body><img src="https://files.prebid.org/creatives/prebid300x250.png"></body></html>'
}]
},
userSync: {
userIds: [{
name: "sharedId",
storage: {
type: "html5",
name: "_sharedID", // create a cookie with this name
expires: 365 // expires in 1 years
}
},{
name: 'growthCodeId',
params: {
pid: 'TEST01',
publisher_id: '_sharedID',
publisher_id_storage: 'html5',
}
}]
}
});
});

function sendAdserverRequest() {
if (pbjs.adserverRequestSent) return;
pbjs.adserverRequestSent = true;
googletag.cmd.push(function() {
pbjs.que.push(function() {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
}

setTimeout(function() {
sendAdserverRequest();
}, FAILSAFE_TIMEOUT);

</script>

<script>
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250], [300, 600]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads());

googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>

<body>
<h2>Prebid.js Test</h2>
<h5>Div-1</h5>
<div id='div-gpt-ad-1460505748561-0'>
<script type='text/javascript'>
googletag.cmd.push(function() { googletag.display('div-gpt-ad-1460505748561-0'); });
</script>
</div>
</body>
</html>
176 changes: 176 additions & 0 deletions modules/growthCodeAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* growthCodeAnalyticsAdapter.js - GrowthCode Analytics Adapter
*/
import { ajax } from '../src/ajax.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import * as utils from '../src/utils.js';
import CONSTANTS from '../src/constants.json';
import { getStorageManager } from '../src/storageManager.js';
import {getRefererInfo} from '../src/refererDetection.js';
import {logError, logInfo} from '../src/utils.js';

const MODULE_NAME = 'growthCodeAnalytics';
const DEFAULT_PID = 'INVALID_PID'
const ENDPOINT_URL = 'https://p2.gcprivacy.com/v1/pb/analytics'

export const storage = getStorageManager();

let sessionId = utils.generateUUID();

let trackEvents = [];
let pid = DEFAULT_PID;
let url = ENDPOINT_URL;

let eventQueue = [];

let startAuction = 0;
let bidRequestTimeout = 0;
let analyticsType = 'endpoint';

let growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}), {
track({eventType, eventData}) {
eventData = eventData ? JSON.parse(JSON.stringify(eventData)) : {};
let data = {};
if (!trackEvents.includes(eventType)) return;
switch (eventType) {
case CONSTANTS.EVENTS.AUCTION_INIT: {
data = eventData;
startAuction = data.timestamp;
bidRequestTimeout = data.timeout;
break;
}

case CONSTANTS.EVENTS.AUCTION_END: {
data = eventData;
data.start = startAuction;
data.end = Date.now();
break;
}

case CONSTANTS.EVENTS.BID_ADJUSTMENT: {
data.bidders = eventData;
break;
}

case CONSTANTS.EVENTS.BID_TIMEOUT: {
data.bidders = eventData;
data.duration = bidRequestTimeout;
break;
}

case CONSTANTS.EVENTS.BID_REQUESTED: {
data = eventData;
break;
}

case CONSTANTS.EVENTS.BID_RESPONSE: {
data = eventData;
delete data.ad;
break;
}

case CONSTANTS.EVENTS.BID_WON: {
data = eventData;
delete data.ad;
delete data.adUrl;
break;
}

case CONSTANTS.EVENTS.BIDDER_DONE: {
data = eventData;
break;
}

case CONSTANTS.EVENTS.SET_TARGETING: {
data.targetings = eventData;
break;
}

case CONSTANTS.EVENTS.REQUEST_BIDS: {
data = eventData;
break;
}

case CONSTANTS.EVENTS.ADD_AD_UNITS: {
data = eventData;
break;
}

default:
return;
}

data.eventType = eventType;
data.timestamp = data.timestamp || Date.now();

sendEvent(data);
}
});

growthCodeAnalyticsAdapter.originEnableAnalytics = growthCodeAnalyticsAdapter.enableAnalytics;

growthCodeAnalyticsAdapter.enableAnalytics = function(conf = {}) {
if (typeof conf.options === 'object') {
if (conf.options.pid) {
pid = conf.options.pid;
url = conf.options.url ? conf.options.url : ENDPOINT_URL;
} else {
logError(MODULE_NAME + ' Not a valid PartnerID')
return
}
if (conf.options.trackEvents) {
trackEvents = conf.options.trackEvents;
}
} else {
logError(MODULE_NAME + ' Invalid configuration');
return;
}

growthCodeAnalyticsAdapter.originEnableAnalytics(conf);
};

function logToServer() {
if (pid === DEFAULT_PID) return;
if (eventQueue.length > 1) {
let data = {
session: sessionId,
pid: pid,
timestamp: Date.now(),
timezoneoffset: new Date().getTimezoneOffset(),
url: getRefererInfo().page,
referer: document.referrer,
events: eventQueue
};

ajax(url, {
success: response => {
logInfo(MODULE_NAME + ' Send Data to Server')
},
error: error => {
logInfo(MODULE_NAME + ' Problem Send Data to Server: ' + error)
}
}, JSON.stringify(data), {method: 'POST', withCredentials: true})

eventQueue = [
];
}
}

function sendEvent(event) {
eventQueue.push(event);
logInfo(MODULE_NAME + 'Analytics Event: ' + event);

if (event.eventType === CONSTANTS.EVENTS.AUCTION_END) {
logToServer();
}
}

adapterManager.registerAnalyticsAdapter({
adapter: growthCodeAnalyticsAdapter,
code: 'growthCodeAnalytics'
});

growthCodeAnalyticsAdapter.logToServer = logToServer;

export default growthCodeAnalyticsAdapter;
41 changes: 41 additions & 0 deletions modules/growthCodeAnalyticsAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## GrowthCode Analytics Adapter

[GrowthCode](https://growthcode.io) offers scaled infrastructure-as-a-service to
empower independent publishers to harness data and take control of identity and
audience while rapidly aligning to industry changes and margin pressure.

## Building Prebid with GrowthCode Support

First, make sure to add the GrowthCode submodule to your Prebid.js package with:

```
gulp build --modules=growthCodeIdSystem,growthCodeAnalyticsAdapter,userId
```

The following configuration parameters are available:

```javascript
pbjs.enableAnalytics({
provider: 'growthCodeAnalytics',
options: {
pid: '<Contact GrowthCode>',
trackEvents: [
'auctionEnd',
'bidAdjustment',
'bidTimeout',
'bidRequested',
'bidResponse',
'noBid',
'bidWon',
'bidderDone']
}
});
```

| Param enableAnalytics | Scope | Type | Description | Example |
|-----------------------|----------|--------|-------------------------------------------------------------|--------------------------|
| provider | Required | String | The name of this Adapter. | `"growthCodeAnalytics"` |
| params | Required | Object | Details of module params. | |
| params.pid | Required | String | This is the Customer ID value obtained via Intimate Merger. | `"<Contact GrowthCode>"` |
| params.url | Optional | String | Custom URL for server | |
| params.trackEvents | Required | String | Name if the variable that holds your publisher ID | |
Loading

0 comments on commit b0413b2

Please sign in to comment.