Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dgkeyword Rtd Provider: add new real-time data submodule #6410

Merged
merged 9 commits into from
May 26, 2021
1 change: 1 addition & 0 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
],
"rtdModule": [
"browsiRtdProvider",
"dgkeywordRtdProvider",
"geoedgeRtdProvider",
"haloRtdProvider",
"jwplayerRtdProvider",
Expand Down
132 changes: 132 additions & 0 deletions modules/dgkeywordRtdProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* This module adds dgkeyword provider to the real time data module
* The {@link module:modules/realTimeData} module is required
* The module will get keywords from 1plux profile api.
* This module can work only with AppNexusBidAdapter.
* @module modules/dgkeywordProvider
* @requires module:modules/realTimeData
*/

import * as utils from '../src/utils.js';
import { ajax } from '../src/ajax.js';
import { submodule } from '../src/hook.js';
import { getGlobal } from '../src/prebidGlobal.js';

/**
* get keywords from api server. and set keywords.
* @param {Object} reqBidsConfigObj
* @param {function} callback
* @param {Object} moduleConfig
* @param {Object} userConsent
*/
export function getDgKeywordsAndSet(reqBidsConfigObj, callback, moduleConfig, userConsent) {
const URL = 'https://mediaconsortium.profiles.tagger.opecloud.com/api/v1?url=';
const PROFILE_TIMEOUT_MS = 1000;
const timeout = (moduleConfig && moduleConfig.params && moduleConfig.params.timeout && Number(moduleConfig.params.timeout) > 0) ? Number(moduleConfig.params.timeout) : PROFILE_TIMEOUT_MS;
const url = (moduleConfig && moduleConfig.params && moduleConfig.params.url) ? moduleConfig.params.url : URL + encodeURIComponent(window.location.href);
const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits;
let isFinish = false;
utils.logMessage('[dgkeyword sub module]', adUnits, timeout);
let setKeywordTargetBidders = getTargetBidderOfDgKeywords(adUnits);
if (setKeywordTargetBidders.length <= 0) {
utils.logMessage('[dgkeyword sub module] no dgkeyword targets.');
callback();
} else {
utils.logMessage('[dgkeyword sub module] dgkeyword targets:', setKeywordTargetBidders);
utils.logMessage('[dgkeyword sub module] get targets from profile api start.');
ajax(url, {
success: function(response) {
const res = JSON.parse(response);
if (!isFinish) {
utils.logMessage('[dgkeyword sub module] get targets from profile api end.');
if (res) {
let keywords = {};
if (res['s'] != null && res['s'].length > 0) {
keywords['opeaud'] = res['s'];
}
if (res['t'] != null && res['t'].length > 0) {
keywords['opectx'] = res['t'];
}
if (Object.keys(keywords).length > 0) {
const targetBidKeys = {}
for (let bid of setKeywordTargetBidders) {
// set keywords to params
bid.params.keywords = keywords;
if (!targetBidKeys[bid.bidder]) {
targetBidKeys[bid.bidder] = true;
}
}

// set keywrods to ortb2
let addOrtb2 = {};
utils.deepSetValue(addOrtb2, 'site.keywords', keywords);
utils.deepSetValue(addOrtb2, 'user.keywords', keywords);
const ortb2 = {ortb2: addOrtb2};
getGlobal().setBidderConfig({ bidders: Object.keys(targetBidKeys), config: ortb2 });
}
}
isFinish = true;
}
callback();
},
error: function(errorStatus) {
// error occur
utils.logError('[dgkeyword sub module] profile api access error.', errorStatus);
callback();
}
}, null, {
withCredentials: true,
contentType: 'application/json',
});
setTimeout(function () {
if (!isFinish) {
// profile api timeout
utils.logInfo('[dgkeyword sub module] profile api timeout. [timeout: ' + timeout + 'ms]');
isFinish = true;
}
callback();
}, timeout);
}
}

/**
* get all bidder which hava {dgkeyword: true} in params
* @param {Object} adUnits
*/
export function getTargetBidderOfDgKeywords(adUnits) {
let setKeywordTargetBidders = [];
for (let adUnit of adUnits) {
for (let bid of adUnit.bids) {
if (bid.params && bid.params['dgkeyword'] === true) {
delete bid.params['dgkeyword'];
setKeywordTargetBidders.push(bid);
}
}
}
return setKeywordTargetBidders;
}

/** @type {RtdSubmodule} */
export const dgkeywordSubmodule = {
/**
* used to link submodule with realTimeData
* @type {string}
*/
name: 'dgkeyword',
/**
* get data and send back to realTimeData module
* @function
* @param {string[]} adUnitsCodes
*/
getBidRequestData: getDgKeywordsAndSet,
init: init,
};

function init(moduleConfig) {
return true;
}

function registerSubModule() {
submodule('realTimeData', dgkeywordSubmodule);
}
registerSubModule();
35 changes: 35 additions & 0 deletions modules/dgkeywordRtdProvider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Overview

Module Name: Digital Garage Keyword Module
Module Type: Rtd Provider
Maintainer: [email protected]
Remarks: This module can work only with AppNexusBidAdapter.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this line. Better documentation is needed here. I don't understand what your module does or how pubs are supposed to use it.

At a high level, RTD modules MUST be setting data in standard locations by default -- not bidder-specific locations. It is ok to also set data in bidder-specific params, but that should be considered secondary.

So please try again and describe the different use cases for this module, including how pubs interact with it and where the data ends up in the bidrequest/adunit object.

## Integration

1) Compile the Digital Garage Keyword Module and Appnexus Bid Adapter into your Prebid build:

```
gulp build --modules="dgkeywordRtdProvider,appnexusBidAdapter,..."
```

2) Use `setConfig` to instruct Prebid.js to initilize the dgkeyword module, as specified below.

## Configuration

This module is configured as part of the `realTimeData.dataProviders`

```javascript
var DGKEYWORD_TIMEOUT = 1000;
pbjs.setConfig({
realTimeData: {
auctionDelay: DGKEYWORD_TIMEOUT,
dataProviders: [{
name: 'dgkeyword',
waitForIt: true,
params: {
timeout: DGKEYWORD_TIMEOUT
}
}]
}
});
```
Loading