Skip to content

Commit

Permalink
Eight Pod Bid / Analytics Adapter : initial release (prebid#11260)
Browse files Browse the repository at this point in the history
* eight pod init

* fix mocks

* specify eightPodAnalyticAdapter tests

* update Event import
  • Loading branch information
GreDiSe authored May 2, 2024
1 parent 8c72bc2 commit 5cfae1b
Show file tree
Hide file tree
Showing 6 changed files with 815 additions and 0 deletions.
186 changes: 186 additions & 0 deletions modules/eightPodAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import {logError, logInfo} from '../src/utils.js';
import {ajax} from '../src/ajax.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import { EVENTS } from '../src/constants.js';
import adapterManager from '../src/adapterManager.js';
import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'
import {getStorageManager} from '../src/storageManager.js';

const analyticsType = 'endpoint';
const MODULE_NAME = `eightPod`;
const MODULE = `${MODULE_NAME}AnalyticProvider`;

/**
* Custom tracking server that gets internal events from EightPod's ad unit
*/
const trackerUrl = 'https://demo.8pod.com/tracker/track';

export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME})

const {
BID_WON
} = EVENTS;

export let queue = [];
export let context;

/**
* Create eightPod Analytic adapter
*/
let eightPodAnalytics = Object.assign(adapter({ analyticsType }), {
/**
* Execute on bid won - setup basic settings, save context about EightPod's bid. We will send it with our events later
*/
track({ eventType, args }) {
switch (eventType) {
case BID_WON:
if (args.bidder === 'eightPod') {
eightPodAnalytics.setupPage(args);
context = makeContext(args);
break;
}
}
},

/**
* Execute on bid won - subscribe on events from adUnit
*/
setupPage() {
eightPodAnalytics.eventSubscribe();
queue = getEventFromLocalStorage();
},
/**
* Subscribe on internal ad unit tracking events
*/
eventSubscribe() {
window.addEventListener('message', async (event) => {
const data = event?.data;

if (!data?.detail?.name) {
return;
}

trackEvent(data);
});

// Send queue of event every 10 seconds
setInterval(sendEvents, 10_000);
},
resetQueue() {
queue = [];
},
getContext() {
return context;
}
});

/**
* Create context of event, who emits it
*/
function makeContext(args) {
const params = args?.params?.[0];
return {
bidId: args.seatBidId,
variantId: args.creativeId || 'variantId',
campaignId: 'campaignId',
publisherId: params.publisherId,
placementId: params.placementId,
};
}

/**
* Create event, add context and push it to queue
*/
export function trackEvent(event) {
if (!event.detail) {
return;
}
const fullEvent = {
context: eightPodAnalytics.getContext(),
eventType: event.detail.type,
eventClass: 'adunit',
timestamp: new Date().getTime(),
eventName: event.detail.name,
payload: event.detail.payload
};

addEvent(fullEvent);
}

/**
* Push event to queue, save event list in local storage
*/
function addEvent(eventPayload) {
queue.push(eventPayload);
storage.setDataInLocalStorage(`EIGHT_POD_EVENTS`, JSON.stringify(queue), null);
}

/**
* Gets previously saved event that has not been sent
*/
function getEventFromLocalStorage() {
const storedEvents = storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage('EIGHT_POD_EVENTS') : null;

if (storedEvents) {
return JSON.parse(storedEvents);
} else {
return [];
}
}

/**
* Send event to our custom tracking server and reset queue
*/
function sendEvents() {
eightPodAnalytics.eventsStorage = queue;

if (queue.length) {
try {
sendEventsApi(queue, {
success: () => {
resetLocalStorage();
eightPodAnalytics.resetQueue();
},
error: (e) => {
logError(MODULE, 'Cant send events', e);
}
})
} catch (e) {
logError(MODULE, 'Cant send events', e);
}
}
}

/**
* Send event to our custom tracking server
*/
function sendEventsApi(eventList, callbacks) {
ajax(trackerUrl, callbacks, JSON.stringify(eventList));
}

/**
* Remove saved events in success scenario
*/
const resetLocalStorage = () => {
storage.setDataInLocalStorage(`EIGHT_POD_EVENTS`, JSON.stringify([]), null);
}

// save the base class function
eightPodAnalytics.originEnableAnalytics = eightPodAnalytics.enableAnalytics;
eightPodAnalytics.eventsStorage = [];

// override enableAnalytics so we can get access to the config passed in from the page
eightPodAnalytics.enableAnalytics = function (config) {
eightPodAnalytics.originEnableAnalytics(config);
logInfo(MODULE, 'init', config);
};

/**
* Register Analytics Adapter
*/
adapterManager.registerAnalyticsAdapter({
adapter: eightPodAnalytics,
code: MODULE_NAME
});

export default eightPodAnalytics;
19 changes: 19 additions & 0 deletions modules/eightPodAnalyticsAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Overview
Module Name: 8pod Analytics by 8Pod

Module Type: Analytics Adapter

Maintainer: bianca@8pod.com

# Description

Analytics adapter for prebid provided by 8pod. It gets events from eightPod's ad unit and send it to our tracking server to improve user experience.
Please, use it ONLY with eightPodBidAdapter.

# Analytics Adapter configuration example

```
{
provider: 'eightPod'
}
```
Loading

0 comments on commit 5cfae1b

Please sign in to comment.