forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dailymotion Bid Adaptor: initial release (prebid#10970)
* Dailymotion Bid Adaptor: initial release * .md file lint issue resolved * Dailymotion Bid Adaptor: build bidder request based on param with fallbacks * Dailymotion Bid Adaptor: support video metadata * Dailymotion Bid Adaptor: add support for sending adUnitCode * Dailymotion Bid Adaptor: add support for sending startDelay * feat(LEO-528): Allow multiple IAB categories in video metadata The same way as we can have an array of IAB categories level 1 in the ORTB request, this PR introduces an array for the IAB categories level 2. To be forward compatible with level [2.2](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%202.2.tsv) and [3.0](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%203.0.tsv) specifications, the category IDs should be sent as strings. * Dailymotion bid adapter: Clarify the video metadata to provide in each player context * Dailymotion bid adapter: Move API key to bid params * Dailymotion bid adapter: Verify API key is string Co-authored-by: Rumesh <[email protected]> * Dailymotion bid adapter: Move API key to bid params (fix tests) * Dailymotion Bid Adaptor: add gpp support and get coppa from request * Dailymotion Bid Adaptor: fix lint error * Dailymotion Bid Adaptor: add iabcat1 and fallback to ortb2 for iabcat2 * Dailymotion Bid Adaptor: get iabcats from ortb2.site.content.data --------- Co-authored-by: Kevin Siow <[email protected]> Co-authored-by: Aditi Chaudhary <[email protected]> Co-authored-by: Sébastien Millet <[email protected]> Co-authored-by: Rumesh <[email protected]>
- Loading branch information
Showing
3 changed files
with
648 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import { registerBidder } from '../src/adapters/bidderFactory.js'; | ||
import { VIDEO } from '../src/mediaTypes.js'; | ||
import { deepAccess } from '../src/utils.js'; | ||
|
||
/** | ||
* Get video metadata from bid request | ||
* | ||
* @param {BidRequest} bidRequest A valid bid requests that should be sent to the Server. | ||
* @return video metadata | ||
*/ | ||
function getVideoMetadata(bidRequest, bidderRequest) { | ||
const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video', {}); | ||
const videoBidderParams = deepAccess(bidRequest, 'params.video', {}); | ||
|
||
const videoParams = { | ||
...videoAdUnit, | ||
...videoBidderParams, // Bidder Specific overrides | ||
}; | ||
|
||
// Store as object keys to ensure uniqueness | ||
const iabcat1 = {}; | ||
const iabcat2 = {}; | ||
|
||
deepAccess(bidderRequest, 'ortb2.site.content.data', []).forEach((data) => { | ||
if ([4, 5, 6, 7].includes(data?.ext?.segtax)) { | ||
(Array.isArray(data.segment) ? data.segment : []).forEach((segment) => { | ||
if (typeof segment.id === 'string') { | ||
// See https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy | ||
// Only take IAB cats of taxonomy V1 | ||
if (data.ext.segtax === 4) iabcat1[segment.id] = 1; | ||
// Only take IAB cats of taxonomy V2 or higher | ||
if ([5, 6, 7].includes(data.ext.segtax)) iabcat2[segment.id] = 1; | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
const videoMetadata = { | ||
description: videoParams.description || '', | ||
duration: videoParams.duration || 0, | ||
iabcat1: Object.keys(iabcat1), | ||
iabcat2: Array.isArray(videoParams.iabcat2) | ||
? videoParams.iabcat2 | ||
: Object.keys(iabcat2), | ||
id: videoParams.id || '', | ||
lang: videoParams.lang || '', | ||
private: videoParams.private || false, | ||
tags: videoParams.tags || '', | ||
title: videoParams.title || '', | ||
topics: videoParams.topics || '', | ||
xid: videoParams.xid || '', | ||
}; | ||
|
||
return videoMetadata; | ||
} | ||
|
||
export const spec = { | ||
code: 'dailymotion', | ||
gvlid: 573, | ||
supportedMediaTypes: [VIDEO], | ||
|
||
/** | ||
* Determines whether or not the given bid request is valid. | ||
* The only mandatory parameter for a bid to be valid is the API key. | ||
* Other parameters are optional. | ||
* | ||
* @return boolean True if this is a valid bid, and false otherwise. | ||
*/ | ||
isBidRequestValid: function (bid) { | ||
return typeof bid?.params?.apiKey === 'string' && bid.params.apiKey.length > 10; | ||
}, | ||
|
||
/** | ||
* Make a server request from the list of valid BidRequests (that already passed the isBidRequestValid call) | ||
* | ||
* @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. | ||
* @param {BidderRequest} bidderRequest | ||
* @return ServerRequest Info describing the request to the server. | ||
*/ | ||
buildRequests: (validBidRequests = [], bidderRequest) => validBidRequests.map(bid => ({ | ||
method: 'POST', | ||
url: 'https://pb.dmxleo.com', | ||
data: { | ||
bidder_request: { | ||
gdprConsent: { | ||
apiVersion: bidderRequest?.gdprConsent?.apiVersion || 1, | ||
consentString: bidderRequest?.gdprConsent?.consentString || '', | ||
// Cast boolean in any case (eg: if value is int) to ensure type | ||
gdprApplies: !!bidderRequest?.gdprConsent?.gdprApplies, | ||
}, | ||
refererInfo: { | ||
page: bidderRequest?.refererInfo?.page || '', | ||
}, | ||
uspConsent: bidderRequest?.uspConsent || '', | ||
gppConsent: { | ||
gppString: deepAccess(bidderRequest, 'gppConsent.gppString') || | ||
deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), | ||
applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') || | ||
deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), | ||
}, | ||
}, | ||
config: { | ||
api_key: bid.params.apiKey | ||
}, | ||
// Cast boolean in any case (value should be 0 or 1) to ensure type | ||
coppa: !!deepAccess(bidderRequest, 'ortb2.regs.coppa'), | ||
request: { | ||
adUnitCode: bid.adUnitCode || '', | ||
auctionId: bid.auctionId || '', | ||
bidId: bid.bidId || '', | ||
mediaTypes: { | ||
video: { | ||
playerSize: bid.mediaTypes?.[VIDEO]?.playerSize || [], | ||
api: bid.mediaTypes?.[VIDEO]?.api || [], | ||
startDelay: bid.mediaTypes?.[VIDEO]?.startdelay || 0, | ||
}, | ||
}, | ||
sizes: bid.sizes || [], | ||
}, | ||
video_metadata: getVideoMetadata(bid, bidderRequest), | ||
}, | ||
options: { | ||
withCredentials: true, | ||
crossOrigin: true, | ||
}, | ||
})), | ||
|
||
/** | ||
* Map the response from the server into a list of bids. | ||
* As dailymotion prebid server returns an entry with the correct Prebid structure, | ||
* we directly include it as the only bid in the response. | ||
* | ||
* @param {*} serverResponse A successful response from the server. | ||
* @return {Bid[]} An array of bids which were nested inside the server. | ||
*/ | ||
interpretResponse: serverResponse => serverResponse?.body ? [serverResponse.body] : [], | ||
}; | ||
|
||
registerBidder(spec); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: Dailymotion Bid Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: [email protected] | ||
``` | ||
|
||
# Description | ||
|
||
Dailymotion prebid adapter. | ||
|
||
# Configuration options | ||
|
||
Before calling this adapter, you need to set at least the API key in the bid parameters: | ||
|
||
```javascript | ||
const adUnits = [ | ||
{ | ||
bids: [{ | ||
bidder: 'dailymotion', | ||
params: { | ||
apiKey: 'fake_api_key' | ||
} | ||
}] | ||
} | ||
]; | ||
``` | ||
|
||
`apiKey` is your publisher API key. For testing purpose, you can use "dailymotion-testing". | ||
|
||
# Test Parameters | ||
|
||
By setting the following bid parameters, you'll get a constant response to any request, to validate your adapter integration: | ||
|
||
```javascript | ||
const adUnits = [ | ||
{ | ||
bids: [{ | ||
bidder: 'dailymotion', | ||
params: { | ||
apiKey: 'dailymotion-testing' | ||
} | ||
}] | ||
} | ||
]; | ||
``` | ||
|
||
Please note that failing to set these will result in the adapter not bidding at all. | ||
|
||
# Sample video AdUnit | ||
|
||
To allow better targeting, you should provide as much context about the video as possible. | ||
There are two ways of doing this depending on if you're using Dailymotion player or a third party one. | ||
|
||
If you are using the Dailymotion player, you should only provide the video `xid` in your ad unit, example: | ||
|
||
```javascript | ||
const adUnits = [ | ||
{ | ||
bids: [{ | ||
bidder: 'dailymotion', | ||
params: { | ||
apiKey: 'dailymotion-testing' | ||
} | ||
}], | ||
code: 'test-ad-unit', | ||
mediaTypes: { | ||
video: { | ||
api: [2, 7], | ||
context: 'instream', | ||
playerSize: [ [1280, 720] ], | ||
startDelay: 0, | ||
xid: 'x123456' // Dailymotion infrastructure unique video ID | ||
}, | ||
} | ||
} | ||
]; | ||
``` | ||
|
||
This will automatically fetch the most up-to-date information about the video. | ||
If you provide any other metadata in addition to the `xid`, they will be ignored. | ||
|
||
If you are using a third party video player, you should not provide any `xid` and instead fill the following members: | ||
|
||
```javascript | ||
const adUnits = [ | ||
{ | ||
bids: [{ | ||
bidder: 'dailymotion', | ||
params: { | ||
apiKey: 'dailymotion-testing', | ||
video: { | ||
description: 'overriden video description' | ||
} | ||
} | ||
}], | ||
code: 'test-ad-unit', | ||
mediaTypes: { | ||
video: { | ||
api: [2, 7], | ||
context: 'instream', | ||
description: 'this is a video description', | ||
duration: 556, | ||
iabcat2: ['6', '17'], | ||
id: '54321', | ||
lang: 'FR', | ||
playerSize: [ [1280, 720] ], | ||
private: false, | ||
startDelay: 0, | ||
tags: 'tag_1,tag_2,tag_3', | ||
title: 'test video', | ||
topics: 'topic_1, topic_2', | ||
}, | ||
} | ||
} | ||
]; | ||
``` | ||
|
||
Each of the following video metadata fields can be added in mediaTypes.video or bids.params.video. | ||
If a field exists in both places, it will be overridden by bids.params.video. | ||
|
||
* `description` - Video description | ||
* `duration` - Video duration in seconds | ||
* `iabcat2` - List of IAB category IDs from the [2.0 taxonomy](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%202.0.tsv) | ||
* `id` - Video unique ID in host video infrastructure | ||
* `lang` - ISO 639-1 code for main language used in the video | ||
* `private` - True if video is not publicly available | ||
* `tags` - Tags for the video, comma separated | ||
* `title` - Video title | ||
* `topics` - Main topics for the video, comma separated | ||
* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player) | ||
|
||
# Integrating the adapter | ||
|
||
To use the adapter with any non-test request, you first need to ask an API key from Dailymotion. Please contact us through **[email protected]**. | ||
|
||
You will then be able to use it within the bid parameters before making a bid request. | ||
|
||
This API key will ensure proper identification of your inventory and allow you to get real bids. |
Oops, something went wrong.