From 295e0374703c3ad8e509a275c11f4020eeba5d0f Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Fri, 19 Jan 2024 12:47:40 +0000 Subject: [PATCH 01/45] First commit --- exads/doc/README.md | 49 ++ .../prebidJS-client-RTB-InStreamVideo.html | 226 ++++++++ .../examples/prebidJS-client-RTB-banner.html | 185 +++++++ .../examples/prebidJS-client-RTB-native.html | 216 ++++++++ .../prebidJS-client-RTB-video-banner.html | 185 +++++++ modules/exadsBidAdapter.js | 435 +++++++++++++++ modules/exadsBidAdapter.md | 286 ++++++++++ test/spec/modules/exadsBidAdapter_spec.js | 498 ++++++++++++++++++ 8 files changed, 2080 insertions(+) create mode 100644 exads/doc/README.md create mode 100644 exads/examples/prebidJS-client-RTB-InStreamVideo.html create mode 100644 exads/examples/prebidJS-client-RTB-banner.html create mode 100644 exads/examples/prebidJS-client-RTB-native.html create mode 100644 exads/examples/prebidJS-client-RTB-video-banner.html create mode 100644 modules/exadsBidAdapter.js create mode 100644 modules/exadsBidAdapter.md create mode 100644 test/spec/modules/exadsBidAdapter_spec.js diff --git a/exads/doc/README.md b/exads/doc/README.md new file mode 100644 index 00000000000..a9188b50ea9 --- /dev/null +++ b/exads/doc/README.md @@ -0,0 +1,49 @@ +# exadsBidAdapter +Exads PrebidJS Adapter + +#### In order to mantain the adapter locally: + +* Changing the adapter code that you can find into `./Prebid.js/modules/exadsBidAdapter.js` +* Updating the unit tests, they are into `./Prebid.js/test/spec/modules/exadsBidAdapter_spec.js` +* Running tlint and unit tests (to see the specific paragraph) +* Doing manual tests (to see the specific paragraph) +* Building the new version of the adapter and all modules needed: +* `gulp build --modules=consentManagement,exadsBidAdapter` +* After that you can use the prebidJS merged with our module. +* You can find it into: +* `./build/dist/prebid.js` +* Updating our examples. You can find them into: +* `./exads/examples` + +#### Lint and Unit tests +* Note: lint checks the official prebidJS rules. +* Also, to do the pull request to official prebidJS team, it is mondatory 80% or more of covarage. +* To check the coverage, type: +* `gulp test-coverage` and then +* `gulp view-coverage` + +#### Manual tests +* Copying all examples to use into the publisher test web site: `./exads/doc/README.md` +* Copying the prebidJS library containing the new changes of the adapter `./build/dist/prebid.js` +* For each example, changing `` based on the publisher web site configuration + * Note: if you need to debug the snippet code, comment the previous instruction and uncomment the `` +* Changing all params based on test scenarios (to see: `./Prebid.js/modules/exadsBidAdapter.md`) +* Navigating to the publisher web site and test it + +#### Environments (development and production) - Changes to do into the snippet code +* Set isEnabledDebug global variable (If it is true, you will be able to see logs) + +* For development environments +``` + + + + +``` +* For production environments +``` + + + + +``` diff --git a/exads/examples/prebidJS-client-RTB-InStreamVideo.html b/exads/examples/prebidJS-client-RTB-InStreamVideo.html new file mode 100644 index 00000000000..7270f41a2f4 --- /dev/null +++ b/exads/examples/prebidJS-client-RTB-InStreamVideo.html @@ -0,0 +1,226 @@ + + + + + + RTB Instream Video Prebid.js + + + + + + + + + + + + + + + + +

RTB Instream Video Prebid.js

+ + + + + + + \ No newline at end of file diff --git a/exads/examples/prebidJS-client-RTB-banner.html b/exads/examples/prebidJS-client-RTB-banner.html new file mode 100644 index 00000000000..29039820d98 --- /dev/null +++ b/exads/examples/prebidJS-client-RTB-banner.html @@ -0,0 +1,185 @@ + + + + + RTB Banner Prebid.js + + + + + + + + + +

RTB Banner Prebid.js

+ + + + + \ No newline at end of file diff --git a/exads/examples/prebidJS-client-RTB-native.html b/exads/examples/prebidJS-client-RTB-native.html new file mode 100644 index 00000000000..5a271a7ce5c --- /dev/null +++ b/exads/examples/prebidJS-client-RTB-native.html @@ -0,0 +1,216 @@ + + + + + Prebid.js + + + + + + + + +

RTB Native Prebid.js

+ + + \ No newline at end of file diff --git a/exads/examples/prebidJS-client-RTB-video-banner.html b/exads/examples/prebidJS-client-RTB-video-banner.html new file mode 100644 index 00000000000..451cb0a411f --- /dev/null +++ b/exads/examples/prebidJS-client-RTB-video-banner.html @@ -0,0 +1,185 @@ + + + + + RTB Video Banner Prebid.js + + + + + + + + + + +

RTB Video Banner Prebid.js

+ + + + + \ No newline at end of file diff --git a/modules/exadsBidAdapter.js b/modules/exadsBidAdapter.js new file mode 100644 index 00000000000..32a0d6ba08d --- /dev/null +++ b/modules/exadsBidAdapter.js @@ -0,0 +1,435 @@ +import * as utils from '../src/utils.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; + +const BIDDER = 'exadsadserver'; + +const PARTNERS = { + RTB_2_4: 'rtb_2_4' +}; + +const envParams = { + lang: '', + userAgent: '', + osName: '', + page: '', + domain: '', + language: '', + userId: '' +}; + +const adPartnerHandlers = { + [PARTNERS.RTB_2_4]: { + request: handleReqRTB2Dot4, + response: handleResRTB2Dot4, + validation: handleValidRTB2Dot4, + } +}; + +function handleReqRTB2Dot4(bid, endpointUrl, validBidRequests, bidderRequest) { + utils.logInfo(`Calling endpoint for rtb_2_4:`, endpointUrl); + const gdprConsent = getGdprConsentChoice(bidderRequest); + + // Make a dynamic bid request to the ad partner's endpoint + let bidRequestData = { + 'id': bid.bidId, // NOT bid.bidderRequestId or bid.auctionId + 'at': 1, + 'imp': [], + 'site': { + 'id': bid.params.siteId, + 'domain': envParams.domain, + 'cat': bid.params.catIab, + 'page': envParams.page, + 'keywords': bid.params.keywords + }, + 'device': { + 'ua': envParams.userAgent, + 'ip': bid.params.userIp, + 'geo': { + 'country': bid.params.country + }, + 'language': envParams.lang, + 'os': envParams.osName, + 'js': 0, + 'ext': { + 'accept_language': envParams.language + } + }, + 'user': { + 'id': bid.params.userId, + }, + 'ext': { + 'sub': 0 + } + }; + + if (gdprConsent && gdprConsent.gdprApplies) { + bidRequestData.user['ext'] = { + consent: gdprConsent.consentString + } + } + + // Banner setup + const bannerMediaType = utils.deepAccess(bid, 'mediaTypes.banner'); + if (bannerMediaType != null) { + bidRequestData.imp = bannerMediaType.sizes.map(size => { + let ext; + + if (bid.params.image_output || + bid.params.video_output) { + ext = { + image_output: bid.params.image_output ? bid.params.image_output : undefined, + video_output: bid.params.video_output ? bid.params.video_output : undefined, + } + } + + return ({ + 'id': bid.params.impressionId, + 'bidfloor': bid.params.bidfloor, + 'bidfloorcur': bid.params.bidfloorcur, + 'banner': { + 'w': size[0], + 'h': size[1], + 'mimes': bid.params.mimes ? bid.params.mimes : undefined, + ext + }, + }) + } + ); + } + const nativeMediaType = utils.deepAccess(bid, 'mediaTypes.native'); + + if (nativeMediaType != null) { + const nativeVersion = '1.2'; + + const native = { + 'native': { + 'ver': nativeVersion, + 'plcmttype': 4, + 'plcmtcnt': bid.params.native.plcmtcnt + } + }; + + native.native.assets = bidRequestData.imp = nativeMediaType.ortb.assets.map(asset => { + const newAsset = asset; + if (newAsset.img != null) { + newAsset.img.wmin = newAsset.img.h; + newAsset.img.hmin = newAsset.img.w; + } + return newAsset; + }); + + const imp = [{ + 'id': bid.params.impressionId, + 'bidfloor': bid.params.bidfloor, + 'bidfloorcur': bid.params.bidfloorcur, + 'native': { + 'request': JSON.stringify(native), + 'ver': nativeVersion + }, + }]; + + bidRequestData.imp = imp; + }; + + const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); + + if (videoMediaType != null) { + const imp = [{ + 'id': bid.params.impressionId, + 'bidfloor': bid.params.bidfloor, + 'bidfloorcur': bid.params.bidfloorcur, + 'video': { + 'mimes': bid.params.stream.video.mimes, + 'protocols': bid.params.stream.protocols, + }, + 'ext': bid.params.stream.ext + }]; + + bidRequestData.imp = imp; + } + + utils.logInfo('PAYLOAD', bidRequestData, JSON.stringify(bidRequestData)); + utils.logInfo('FINAL URL', endpointUrl); + + return makeBidRequest(endpointUrl, bidRequestData); +}; + +function handleResRTB2Dot4(serverResponse, request) { + utils.logInfo('on handleResRTB_2_4 -> request:', request); + utils.logInfo('on handleResRTB_2_4 -> request json data:', JSON.parse(request.data)); + utils.logInfo('on handleResRTB_2_4 -> serverResponse:', serverResponse); + + let bidResponses = []; + + if (serverResponse.hasOwnProperty('body') && serverResponse.body.hasOwnProperty('id')) { + utils.logInfo('Ad server response', serverResponse.body.id); + utils.logInfo('serverResponse.body.seatbid[0].bid[0]', serverResponse.body.seatbid[0].bid[0]); + + const bidRq = JSON.parse(request.data); + const requestId = serverResponse.body.id; + const bidData = serverResponse.body.seatbid[0].bid[0]; + const currency = serverResponse.body.cur; + let bidResponseAd = bidData.adm; + let pixelUrl = bidData.nurl.replace(/^http:\/\//i, 'https://'); + + const bannerInfo = utils.deepAccess(bidRq.imp[0], 'banner'); + const nativeInfo = utils.deepAccess(bidRq.imp[0], 'native'); + const videoInfo = utils.deepAccess(bidRq.imp[0], 'video'); + + let w; let h = 0; + let mediaType = ''; + const native = {}; + + if (bannerInfo != null) { + w = bidRq.imp[0].banner.w; + h = bidRq.imp[0].banner.h; + mediaType = BANNER; + } else if (nativeInfo != null) { + const reqNative = JSON.parse(bidResponseAd); + reqNative.native.assets.forEach(asset => { + if (asset.img != null) { + const imgAsset = JSON.parse(bidRq.imp[0].native.request) + .native.assets.filter(asset => asset.img != null).map(asset => asset.img); + w = imgAsset[0].w; + h = imgAsset[0].h; + native.image = { + url: asset.img.url, + height: h, + width: w + } + } else if (asset.title != null) { + native.title = asset.title.text; + } else if (asset.data != null) { + native.body = asset.data.value; + } + }); + mediaType = NATIVE; + } else if (videoInfo != null) { + mediaType = VIDEO; + } + + const bidResponse = { + requestId: requestId, + currency: currency, + ad: bidData.adm, + cpm: bidData.price, + creativeId: bidData.crid, + cid: bidData.cid, + width: w, + ttl: 360, + height: h, + netRevenue: true, + mediaType: mediaType, + nurl: pixelUrl + }; + + if (mediaType == 'native') { + native.clickUrl = bidData.adomain[0]; + bidResponse.native = native; + } + + if (mediaType == 'video') { + bidResponse.vastXml = bidData.adm; + bidResponse.width = bidData.w; + bidResponse.height = bidData.h; + } + + utils.logInfo('bidResponse->', bidResponse); + + bidResponses.push(bidResponse); + } else { + utils.logInfo('NO Ad server response ->', serverResponse.body.id); + } + + utils.logInfo('interpretResponse -> bidResponses:', bidResponses); + + return bidResponses; +} + +function makeBidRequest(url, data) { + const payloadString = JSON.stringify(data); + + return { + method: 'POST', + url: url, + data: payloadString, + } +} + +function getUrl(adPartner, bid) { + let endpointUrlMapping = { + [PARTNERS.RTB_2_4]: bid.params.endpoint + '?idzone=' + bid.params.zoneId + '&fid=' + bid.params.fid + }; + + return endpointUrlMapping[adPartner] ? endpointUrlMapping[adPartner] : 'defaultEndpoint'; +} + +function manageEnvParams() { + envParams.domain = window.location.hostname; + envParams.page = window.location.protocol + '//' + window.location.host + window.location.pathname; + envParams.lang = navigator.language; + if (envParams.lang.indexOf('-') > -1) { + envParams.lang = envParams.lang.split('-')[0]; + } + envParams.userAgent = navigator.userAgent; + if (navigator.appVersion.indexOf('Win') !== -1) { + envParams.osName = 'Windows'; + } + if (navigator.appVersion.indexOf('Mac') !== -1) { + envParams.osName = 'MacOS'; + } + if (navigator.appVersion.indexOf('X11') !== -1) { + envParams.osName = 'Unix'; + } + if (navigator.appVersion.indexOf('Linux') !== -1) { + envParams.osName = 'Linux'; + } + + let browserLanguage = navigator.language || navigator.userLanguage; + let acceptLanguage = browserLanguage.replace('_', '-'); + + envParams.language = acceptLanguage; + + utils.logInfo('Domain -> ', envParams.domain); + utils.logInfo('Page -> ', envParams.page); + utils.logInfo('Lang -> ', envParams.lang); + utils.logInfo('OS -> ', envParams.osName); + utils.logInfo('User Agent -> ', envParams.userAgent); + utils.logInfo('Primary Language -> ', envParams.language); +} + +export const imps = new Map(); + +manageEnvParams(); + +function handleValidRTB2Dot4(bid) { + const bannerInfo = bid.mediaTypes?.banner; + const nativeInfo = bid.mediaTypes?.native; + const videoInfo = bid.mediaTypes?.video; + const isValid = !!( + bid.params.endpoint && + bid.params.userIp && + bid.params.hasOwnProperty('userId') && + bid.params.zoneId && + bid.params.partner && + bid.params.fid && + bid.params.siteId && + bid.params.impressionId && + bid.params.country && + bid.params.country.length > 0 && + (bannerInfo || nativeInfo || videoInfo) && + !!(bid.params.bidfloor && bid.params.bidfloorcur) && + (nativeInfo ? !!(bid.params.native && + bid.params.native.plcmtcnt) : true) && + (videoInfo ? !!(bid.params.stream && + bid.params.stream.video && + bid.params.stream.video.mimes && + bid.params.stream.video.mimes.length > 0 && + bid.params.stream.protocols && + bid.params.stream.protocols.length > 0) : true)); + + if (!isValid) { + utils.logError('Validation Error'); + } + + return isValid; +} + +function hasValue(value) { + return ( + value !== undefined && + value !== null + ); +} + +function getGdprConsentChoice(bidderRequest) { + const hasGdprConsent = + hasValue(bidderRequest) && + hasValue(bidderRequest.gdprConsent); + + if (hasGdprConsent) { + return bidderRequest.gdprConsent; + } + + return null; +} + +export const spec = { + aliases: ['exads'], // short code + + supportedMediaTypes: [BANNER, NATIVE, VIDEO], + isBidRequestValid: function (bid) { + utils.logInfo('on isBidRequestValid -> bid:', bid); + + if (bid.bidder !== BIDDER) { + utils.logError('Validation Error', 'bidder wrong'); + return false; + } else if (!bid.params.partner) { + utils.logError('Validation Error', 'bid.params.partner missed'); + return false; + } else if (!Object.values(PARTNERS).includes(bid.params.partner)) { + utils.logError('Validation Error', 'bid.params.partner is not valid'); + return false; + } + + let adPartner = bid.params.partner; + + if (adPartnerHandlers[adPartner] && adPartnerHandlers[adPartner]['validation']) { + return adPartnerHandlers[adPartner]['validation'](bid); + } else { + // Handle unknown or unsupported ad partners + return false; + } + }, + buildRequests: function (validBidRequests, bidderRequest) { + utils.logInfo('on buildRequests -> validBidRequests:', validBidRequests); + utils.logInfo('on buildRequests -> bidderRequest:', bidderRequest); + + return validBidRequests.map(bid => { + let adPartner = bid.params.partner; + + imps.set(bid.params.impressionId, adPartner); + + let endpointUrl = getUrl(adPartner, bid); + + // Call the handler for the ad partner, passing relevant parameters + if (adPartnerHandlers[adPartner]['request']) { + return adPartnerHandlers[adPartner]['request'](bid, endpointUrl, validBidRequests, bidderRequest); + } else { + // Handle unknown or unsupported ad partners + return null; + } + }); + }, + interpretResponse: function (serverResponse, request) { + const bid = JSON.parse(request.data); + let adPartner = imps.get(bid.imp[0].id); + imps.delete(bid.imp[0].id); + + // Call the handler for the ad partner, passing relevant parameters + if (adPartnerHandlers[adPartner]['response']) { + return adPartnerHandlers[adPartner]['response'](serverResponse, request); + } else { + // Handle unknown or unsupported ad partners + return null; + } + }, + onTimeout: function (timeoutData) { + utils.logWarn(`onTimeout -> timeoutData:`, timeoutData); + }, + onBidWon: function (bid) { + utils.logInfo(`onBidWon -> bid:`, bid); + if (bid['nurl']) { + utils.triggerPixel(bid['nurl']); + } + }, + onSetTargeting: function (bid) { + utils.logInfo(`onSetTargeting -> bid:`, bid); + } +}; + +registerBidder({ + code: BIDDER, + ...spec +}); diff --git a/modules/exadsBidAdapter.md b/modules/exadsBidAdapter.md new file mode 100644 index 00000000000..605915a9144 --- /dev/null +++ b/modules/exadsBidAdapter.md @@ -0,0 +1,286 @@ +# Overview + +**Module Name**: Exads Bidder Adapter + +**Module Type**: Bidder Adapter + +**Maintainer**: info@exads.com + +# Description + +Module that connects to Exads's bidder for bids. + +### Build +``` +gulp build --modules="--modules=consentManagement,exadsBidAdapter" +``` + +### Configuration + +Use `setConfig` to instruct Prebid.js to initilize the exadsBidAdapter, as specified below. +* Set "debug" as true if you need to read logs; +* Set "gdprApplies" as true if you need to pass gdpr consent string; +* The tcString is the iabtcf consent string for gdpr; +* Uncomment the cache instruction if you need to configure a cache server (e.g. for instream video) + +``` +pbjs.setConfig({ + debug: false, + //cache: { url: "https://prebid.adnxs.com/pbc/v1/cache" }, + consentManagement: { + gdpr: { + cmpApi: 'static', + timeout: 1000000, + defaultGdprScope: true, + consentData: { + getTCData: { + tcString: consentString, + gdprApplies: false // set to true to pass the gdpr consent string + } + } + } + } +}); + +``` + +# Test Parameters + + +#### RTB Banner 2.4 + +* **zoneId** (required) - you can get it from the endpoint created after configuring the zones (integer) +* **fid** (required) - you can get it from the endpoint created after configuring the zones (string) +* **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) +* **siteId** (recommended) - unique Site ID (string) +* **banner.sizes** (required) - One array of integer - [width, height] +* **catIab** - IAB category ID (array of string) +* **userIp** (required) - IP address of the user (string)* +* **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. +* **country** - Country ISO3 +* **impressionId** (required) - unique impression ID within this bid request (string) +* **keywords** - keywords can be used to ensure ad zones get the right type of advertising. Keywords should be a string of comma-separated words +* **bidfloor** - Minimum bid for this impression (CPM) / click (CPC) and account currency, optional (float) +* **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) +* **mimes** - List of supported mime types. We support: image/jpeg, image/jpg, image/png, image/png, image/gif, image/webp, video/mp4 (string array) +* **endpoint** (required) - Exads endpoint (URL) + +##### RTB Banner 2.4 (Image) +* **image_output** - Indicates output format for image banners* (string) + +```javascript + +adUnits = + [{ code: 'postbid_iframe', // the frame where to render the creative + mediaTypes: { + banner: { + sizes: [300, 250] + } + }, + bids: [{ + bidder: 'exadsadserver', + params: { + zoneId: 12345, + fid: '829a896f011475d50da0d82cfdd1af8d9cdb07ff', + partner: 'rtb_2_4', + siteId: '123', + catIab: ['IAB17-15'], + userIp: '0.0.0.0', + userId: '1234', + country: 'IRL', + impressionId: impression_id.toString(), + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + mimes: ['image/jpg'], + image_output: 'html', + endpoint: 'https://rtb.exads.rocks/rtb.php' + } + }] + }]; +``` + +##### RTB Banner 2.4 (Video) +* **video_output** - Indicates output format for video banners* (string) + +```javascript +adUnits = + [{ code: 'postbid_iframe', // the frame where to render the creative + mediaTypes: { + banner: { + sizes: [900, 250] + } + }, + bids: [{ + bidder: 'exadsadserver', + params: { + zoneId: 12345, + fid: '829a896f011475d50da0d82cfdd1af8d9cdb07ff', + partner: 'rtb_2_4', + siteId: '123', + catIab: ['IAB17-15'], + userIp: '0.0.0.0', + userId: '1234', + country: 'IRL', + impressionId: '1234', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + mimes: ['image/jpg'], + video_output: 'html', + endpoint: 'https://rtb.exads.rocks/rtb.php' + } + }] + }]; +``` + +#### RTB 2.4 Video (Instream/OutStream/Video Slider) - VAST XML or VAST TAG (url) + +* **zoneId** (required) - you can get it from the endpoint created after configuring the zones (integer) +* **fid** (required) - you can get it from the endpoint created after configuring the zones (string) +* **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) +* **siteId** (recommended) - unique Site ID (string) +* **catIab** - IAB category ID (array of string) +* **userIp** (required) - IP address of the user (string)* +* **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. +* **country** - Country ISO3 (string) +* **impressionId** (required) - unique impression ID within this bid request (string) +* **keywords** - keywords can be used to ensure ad zones get the right type of advertising. Keywords should be a string of comma-separated words +* **bidfloor** - Minimum bid for this impression (CPM) / click (CPC) and account currency, optional (float) +* **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) +* **video.mimes** - List of supported mime types (string array) +* **context** - (recommended) - The video context, either 'instream', 'outstream'. Defaults to ‘instream’ (string) +* **protocols** - List of supported video bid response protocols (int array) +* **endpoint** (required) - Exads endpoint (URL) + +```javascript +adUnits = [{ + code: 'postbid_iframe', + mediaTypes: { + video: { + mimes: ['video/mp4'], + context: 'instream', + protocols: [3, 6] + } + }, + bids: [{ + bidder: 'exadsadserver', + params: { + zoneId: 12345, + fid: '829a896f011475d50da0d82cfdd1af8d9cdb07ff', + partner: 'rtb_2_4', + siteId: '123', + catIab: ['IAB17-15'], + userIp: '0.0.0.0', + userId: '1234', + impressionId: '1234', + stream: { + video: { + mimes: ['video/mp4'] + }, + protocols: [ + 3, + 6 + ], + ext: { + video_cta: 0 + } + }, + country: 'IRL', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + endpoint: 'https://rtb.exads.rocks/rtb.php', + } + }] +}]; +``` + +#### RTB 2.4 Native + +* **zoneId** (required) - you can get it from the endpoint created after configuring the zones (integer) +* **fid** (required) - you can get it from the endpoint created after configuring the zones (string) +* **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) +* **siteId** (recommended) - unique Site ID (string) +* **catIab** - IAB category ID (array of string) +* **userIp** (required) - IP address of the user (string)* +* **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. +* **country** - Country ISO3 (string) +* **impressionId** (required) - unique impression ID within this bid request (string) +* **keywords** - keywords can be used to ensure ad zones get the right type of advertising. Keywords should be a string of comma-separated words +* **bidfloor** - Minimum bid for this impression (CPM) / click (CPC) and account currency, optional (float) +* **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) +* **native.plcmtcnt** - The number of identical placements in this Layout (integer) +* **assets (title)** - Title object for title assets* (JSON object) + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **required** - Set to 1 if asset is required or 0 if asset is optional (integer) + * **title** + * len (required) - Maximum length of the text in the title element. (integer) +* **assets (data)** + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **data** + * **type** - Type ID of the element supported by the publisher (integer). We support: 1 (sponsored - Sponsored By message where response should contain the brand name of the sponsor), 2 (desc - Descriptive text associated with the product or service being advertised) + * **len** +* **assets (img)** + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **required** - Set to 1 if asset is required or 0 if asset is optional (integer) + * **img** + * **type** - Type ID of the image element supported by the publisher. We support: 1 (Icon image) (integer), 3 (Large image preview for the ad) (integer) + * **w** - Width of the image in pixels, optional (integer) + * **h** - Height of the image in pixels, optional (integer) + +```javascript +adUnits = [{ + code: 'postbid_iframe', + mediaTypes: { + native: { + ortb: { + assets: [{ + id: 2, + required: 1, + title: { + len: 124 + } + }, + { + id: 3, + data: { + type: 1, + len: 50 + } + }, + { + id: 1, + required: 1, + img: { + type: 3, + w: 300, + h: 300, + } + }] + } + }, + }, + bids: [{ + bidder: 'exadsadserver', + params: { + zoneId: 12345, + fid: '829a896f011475d50da0d82cfdd1af8d9cdb07ff', + partner: 'rtb_2_4', + siteId: '123', + catIab: ['IAB17-15'], + userIp: '0.0.0.0', + userId: '1234', + impressionId: '1234', + native: { + plcmtcnt: 4, + }, + country: 'IRL', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + endpoint: 'https://rtb.exads.rocks/rtb.php', + } + }] +}]; +``` \ No newline at end of file diff --git a/test/spec/modules/exadsBidAdapter_spec.js b/test/spec/modules/exadsBidAdapter_spec.js new file mode 100644 index 00000000000..8dfa88ffba8 --- /dev/null +++ b/test/spec/modules/exadsBidAdapter_spec.js @@ -0,0 +1,498 @@ +import { expect } from 'chai'; +import { spec, imps } from 'modules/exadsBidAdapter.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; + +describe('exadsBidAdapterTest', function () { + const bidder = 'exadsadserver'; + + const partners = { + RTB_2_4: 'rtb_2_4' + } + + const imageBanner = { + mediaTypes: { + banner: { + sizes: [300, 250] + } + }, + bidder: bidder, + params: { + zoneId: 5147485, + fid: '829a896f011475d505a0d89cfdd1af8d9cdb07ff', + partner: partners.RTB_2_4, + siteId: '12345', + catIab: ['IAB25-3'], + userIp: '0.0.0.0', + userId: '', + country: 'IRL', + impressionId: '123456', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + mimes: ['image/jpg'], + image_output: 'html', + endpoint: 'test.com' + } + }; + + const native = { + mediaTypes: { + native: { + ortb: { + assets: [{ + id: 3, + required: 1, + title: { + len: 124 + } + }, + { + id: 2, + data: { + type: 1, + len: 50 + } + }, + { + id: 1, + required: 1, + img: { + type: 3, + w: 300, + h: 300, + } + }] + } + }, + }, + bidder: bidder, + params: { + zoneId: 5147485, + fid: '829a896f011475d505a0d89cfdd1af8d9cdb07ff', + partner: partners.RTB_2_4, + siteId: '12345', + catIab: ['IAB25-3'], + userIp: '0.0.0.0', + userId: '', + country: 'IRL', + impressionId: '123456', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + native: { + plcmtcnt: 4, + }, + endpoint: 'test.com' + } + }; + + const instream = { + mediaTypes: { + video: { + mimes: ['video/mp4'], + protocols: [3, 6], + } + }, + bidder: bidder, + params: { + zoneId: 5147485, + fid: '829a896f011475d505a0d89cfdd1af8d9cdb07ff', + partner: partners.RTB_2_4, + siteId: '12345', + catIab: ['IAB25-3'], + userIp: '0.0.0.0', + userId: '', + country: 'IRL', + impressionId: '123456', + keywords: 'lifestyle, humour', + bidfloor: 0.00000011, + bidfloorcur: 'EUR', + stream: { + video: { + mimes: ['video/mp4'] + }, + protocols: [ + 3, + 6 + ], + ext: { + video_cta: 0 + } + }, + endpoint: 'test.com', + } + }; + + describe('bidRequestValidity', function () { + it('bidRequest with all mandatory params for banner ad-format', function () { + expect(spec.isBidRequestValid(imageBanner)).to.equal(true); + }); + + it('bidRequest with all mandatory params for native ad-format', function () { + expect(spec.isBidRequestValid(native)); + }); + + it('bidRequest with all mandatory params for instream ad-format', function () { + expect(spec.isBidRequestValid(instream)).to.equal(true); + }); + + it('bidRequest with wrong bidder code', function () { + expect(spec.isBidRequestValid({ + ...imageBanner, + bidder: 'not_exadsadserver' + })).to.eql(false); + }); + + it('bidRequest with wrong partner', function () { + expect(spec.isBidRequestValid({ + ...imageBanner, + params: { + ...imageBanner.params, + partner: 'not_rtb_2_4' + } + })).to.eql(false); + }); + + it('bidRequest without params', function () { + expect(spec.isBidRequestValid({ + bidder: bidder, + params: { } + })).to.equal(false); + }); + }); + + describe('bidRequest for banner ad-format', function () { + const bidRequests = [imageBanner]; + + it('bidRequest HTTP method', function () { + const requests = spec.buildRequests(bidRequests, {}); + requests.forEach(function(requestItem) { + expect(requestItem.method).to.equal('POST'); + }); + }); + }); + + describe('bidRequest for native ad-format', function () { + const bidRequests = [native]; + + it('bidRequest HTTP method', function () { + const requests = spec.buildRequests(bidRequests, {}); + requests.forEach(function(requestItem) { + expect(requestItem.method).to.equal('POST'); + }); + }); + }); + + describe('bidRequest for instream ad-format', function () { + const bidRequests = [instream]; + + it('bidRequest HTTP method', function () { + const requests = spec.buildRequests(bidRequests, {}); + requests.forEach(function(requestItem) { + expect(requestItem.method).to.equal('POST'); + }); + }); + }); + + describe('interpretResponse', function () { + beforeEach(() => { + imps.set('270544423272657', 'rtb_2_4'); + }); + + it('Test banner interpretResponse', function () { + const serverResponse = { + body: { + 'id': '2d2a496527398e', + 'seatbid': [ + { + 'bid': [ + { + 'id': '8f7fa506af97bc193e7bf099d8ed6930bd50aaf1', + 'impid': '270544423272657', + 'price': 0.0045000000000000005, + 'adm': '\n\n', + 'ext': { + 'btype': 1, + 'asset_mime_type': [ + 'image/jpeg', + 'image/jpg' + ] + }, + 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147485&data=TVRjd01qUXdOREU1Tm54aE5UZGxPRGhrT0dGalkyWmtNV1kzTWpsbFl6WmtZV1V3TldSa00yRTFPQS0tfDIwMjMtMTItMTIgMTM6MDM6MTZ8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg1fDUwOHw2MjYwMzg5fDg5NDUzMTczfDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwyMXwzMDB4MjUwfDF8SVRBfHwwfDR8MXwwfDY1NzhhMDY0YmE4ZjI2Ljg5MDA3NDE0MjY0MTExMDg1OHw0YzUxOWQ0ZDA0OTgyMTk2MTFjM2ZmM2Q5NzQyZmYwMHxtYW5hZ2VtZW50LmV4YWRzLnJvY2tzfDB8MHwwfDB8MmQyYTQ5NjUyNzM5OGV8MHw0MHwwfFdJTk5FUnx8MXwwLjcyfDB8MHwyfDB8MHwwfDI1MjMxMTl8LTF8MHwyNTIzOTIwfHx8fDB8MHwwfHx8fDB8MHwwfDF8MHwwfDh8MXwwfDB8MHwyfHx8MHx8T0t8Zjk4NzUzNjc4YjIyYmVkOTBlMTg5NDJmNWU1NDIyZDI-', + 'cid': '6260389', + 'crid': '89453173', + 'adomain': [ + 'test.com' + ], + 'w': 300, + 'h': 250, + 'attr': [ + 12 + ] + } + ] + } + ], + 'cur': 'USD' + } + }; + + const bidResponses = spec.interpretResponse(serverResponse, { + data: JSON.stringify({ + 'id': '2d2a496527398e', + 'at': 1, + 'imp': [ + { + 'id': '270544423272657', + 'bidfloor': 1.1e-7, + 'bidfloorcur': 'EUR', + 'banner': { + 'w': 300, + 'h': 250 + } + } + ], + 'site': { + 'id': '12345', + 'domain': 'management.exads.rocks', + 'cat': [ + 'IAB25-3' + ], + 'page': 'https://management.exads.rocks/prebidJS-client-RTB-banner.html', + 'keywords': 'lifestyle, humour' + }, + 'device': { + 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', + 'ip': '95.233.216.174', + 'geo': { + 'country': 'ITA' + }, + 'language': 'en', + 'os': 'MacOS', + 'js': 0, + 'ext': { + 'remote_addr': '', + 'x_forwarded_for': '', + 'accept_language': 'en-GB' + } + }, + 'user': { + 'id': '' + }, + 'ext': { + 'sub': 0 + } + }) + }); + + expect(bidResponses).to.be.an('array').that.is.not.empty; + + const bid = serverResponse.body.seatbid[0].bid[0]; + const bidResponse = bidResponses[0]; + + expect(bidResponse.mediaType).to.equal(BANNER); + expect(bidResponse.width).to.equal(bid.w); + expect(bidResponse.height).to.equal(bid.h); + }); + + it('Test native Ad interpretResponse', function () { + const serverResponse = { + body: { + 'id': '21dea1fc6c3e1b', + 'seatbid': [ + { + 'bid': [ + { + 'id': 'cedc93987cd4a1e08fdfe97de97482d1ecc503ee', + 'impid': '270544423272657', + 'price': 0.0045000000000000005, + 'adm': '{"native":{"link":{"url":"https:\\/\\/syndication.exads.rocks\\/click.php?d=H4sIAAAAAAAAA0WOO24DMQxEr6LGrUBJ1IelmwBGijS5gH4bb.JdG7uCkYKHj6wEDobFEI8cjNMODBkGafnc2m0_mONBv_RpdW8yXxdmYOVBIwRDwOe4zksdgKzUxkitnFQeORBaowKxVegxeLYQmFGxZuV6CDCrLmZtAyMSeZp8zDVO2ZRADrB4nIJPPhnsh8BLXONHXeraZP2OZZfbNX_tIwpY_FMxqBhU3Laa5vK5i3yZH2xrSayxzfcqzm25CB7RD2mrjVL050j3gr814Sl8ujDeenlkrR8vYzu9H_mugN9eWZHxlH2ilHVJPdH5qDAWkxIWN4UfogOxM2oBAAA-"},"eventtrackers":[{"event":1,"method":1,"url":"https:\\/\\/syndication.exads.rocks\\/cimp.php?data=TVRjd01qUXdPRE01TUh3ek5UWm1NakkyTWpnM1lqQmpPR1pqWm1SbVlUQmtNRGRoWm1VM09URXpNUS0tfC9saWJyYXJ5LzMyMTY3L2Y4NWVlODdjNGRmNWViMmNlMjdmMTBhNjRjNzlhMGUxYjY2NGVhMjMuanBnfGh0dHBzfDk1LjIzMy4yMTYuMTc0fElUQXw0MXxoYW5pbWUuY29tfDMyMTY3fDcyMDQ1NHw5MjMwOTh8NTE0NzQ4N3w1MDh8NjI2MDM5M3w4OTQ1MzE4OXwxNnwyfDB8MHwyNTh8MHwwLjV8OTB8VVNEfFVTRHwxfDF8MzR8fDF8SVRBfHx8NHwxfHx8NDQ5OTc5ZjdhY2VhZmMzZDg5NjA0ZDc0Zjg3YjdiMzR8MXwwfG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MC4wNXwxfDB8ZXhjaGFuZ2VfbmF0aXZlX2FkfDB8MHwyNTIzMTE5fC0xfDB8MjUyMzkyMHx8fDB8MHx8MHwwfDB8MHwwfDB8MXwwfHw4fDF8TW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExOS4wLjAuMCBTYWZhcmkvNTM3LjM2fHwyNHwyMnwwfDJ8MHx8fE9LfDQ3ZWFmNjZlN2RlOTFjZTkzZTExMDlkNDNmNzNmZDNl"}],"assets":[{"id":1,"title":{"text":"Title"}},{"id":2,"data":{"value":"Description"}},{"id":3,"img":{"url":"https:\\/\\/static.exads.rocks\\/library\\/32167\\/f85ee87c4df5eb2ce27f10a64c79a0e1b664ea23.jpg"}}]}}', + 'ext': { + 'btype': 1, + 'asset_mime_type': [ + 'image/jpeg', + 'image/jpg' + ] + }, + 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147487&data=TVRjd01qUXdPRE01TUh3ek5UWm1NakkyTWpnM1lqQmpPR1pqWm1SbVlUQmtNRGRoWm1VM09URXpNUS0tfDIwMjMtMTItMTIgMTQ6MTM6MTB8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg3fDUwOHw2MjYwMzkzfDg5NDUzMTg5fDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwzNHx8MXxJVEF8fDB8NHwxfDB8NjU3OGIwYzY2MDhiNjAuNzc4NjY2OTczMzI3Mzg0MzQwfDQ0OTk3OWY3YWNlYWZjM2Q4OTYwNGQ3NGY4N2I3YjM0fG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MHwyMWRlYTFmYzZjM2UxYnwwfDQwfDB8V0lOTkVSfHwxfDAuNzJ8MHwwfDJ8MHwwfDB8MjUyMzExOXwtMXwwfDI1MjM5MjB8fHx8MHwwfDB8fHx8MHwwfDB8MXwwfDB8OHwxfDB8MjJ8MHwyfHx8MHx8T0t8NmVmNGE1MTAwM2IwOGZiZGI2ZDMyOTVkNTQ2Y2U3YzM-', + 'cid': '6260393', + 'crid': '89453189', + 'adomain': [ + 'test.com' + ], + 'w': 300, + 'h': 300, + 'attr': [] + } + ] + } + ], + 'cur': 'USD' + } + }; + + const bidResponses = spec.interpretResponse(serverResponse, { + data: JSON.stringify({ + 'id': '21dea1fc6c3e1b', + 'at': 1, + 'imp': [ + { + 'id': '270544423272657', + 'bidfloor': 1.1e-7, + 'bidfloorcur': 'EUR', + 'native': { + 'request': '{"native":{"ver":"1.2","context":1,"contextsubtype":10,"plcmttype":4,"plcmtcnt":4,"assets":[{"id":1,"required":1,"title":{"len":124}},{"id":2,"data":{"type":1,"len":50}},{"id":3,"required":1,"img":{"type":3,"w":300,"h":300,"wmin":300,"hmin":300}}]}}', + 'ver': '1.2' + } + } + ], + 'site': { + 'id': '12345', + 'domain': 'management.exads.rocks', + 'cat': [ + 'IAB25-3' + ], + 'page': 'https://management.exads.rocks/prebidJS-client-RTB-native.html' + }, + 'device': { + 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', + 'ip': '95.233.216.174', + 'geo': { + 'country': 'ITA' + }, + 'language': 'en', + 'os': 'MacOS', + 'js': 0, + 'ext': { + 'remote_addr': '', + 'x_forwarded_for': '', + 'accept_language': 'en-GB' + } + }, + 'user': { + 'id': '' + }, + 'ext': { + 'sub': 0 + } + }) + }); + + expect(bidResponses).to.be.an('array').that.is.not.empty; + + const bid = serverResponse.body.seatbid[0].bid[0]; + const bidResponse = bidResponses[0]; + + expect(bidResponse.mediaType).to.equal(NATIVE); + }); + it('Test InStream Video interpretResponse', function () { + const serverResponse = { + body: { + 'id': '2218abc7ebca97', + 'seatbid': [ + { + 'bid': [ + { + 'id': 'd2d2063517b126252f56e22767c53f936ff40411', + 'impid': '270544423272657', + 'price': 0.12474000000000002, + 'adm': '\n\n \n \n exads.rocks\n \n \n \n \n \n \n 00:00:20.32\n \n \n \n \n \n \n \n \n \n \n \n \n test.com\n \n \n \n \n \n \n \n \n\n', + 'ext': { + 'btype': 1, + 'asset_mime_type': [ + 'video/mp4' + ] + }, + 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147489&data=TVRjd01qUXdPRGs0T1h3ek5EZzVOV1JqT1RjeE9XSmpaakF3TURrM05qUXpNelUwTURZek5EZzFZZy0tfDIwMjMtMTItMTIgMTQ6MjM6MDl8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg5fDUwOHw2MjYwMzk1fDg5NDUzMTkxfDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwzOXx8MXxJVEF8fDE2fDR8MXwwfDY1NzhiMzFkOGFhODk0Ljk4OTYyNTI4OTcwNDAxNzA5fGYxMTdmYjZkOGU4ZDgwNDViMGU2Y2Q0NTE4NzFkODhjfG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MHwyMjE4YWJjN2ViY2E5N3wwfDQwfDB8V0lOTkVSfHwxfDAuNzJ8MHwwfDJ8MHwwfDB8MjUyMzExOXwtMXwwfDI1MjM5MjB8fHx8MHwwfDB8fHx8MHwwfDB8MXwwfDB8OHwxfDB8MjF8MHwyfHx8MHx8T0t8MDVjNmQwNzhjZDZjYmJmNDY1ZWJlZDY2ZWQyYzViZDM-', + 'cid': '6260395', + 'crid': '89453191', + 'adomain': [ + 'test.com' + ], + 'w': 0, + 'h': 0, + 'attr': [] + } + ] + } + ], + 'cur': 'USD' + } + }; + + const bidResponses = spec.interpretResponse(serverResponse, { + data: JSON.stringify({ + 'id': '2218abc7ebca97', + 'at': 1, + 'imp': [ + { + 'id': '270544423272657', + 'video': { + 'mimes': [ + 'video/mp4' + ] + }, + 'protocols': [ + 3, + 6 + ], + 'ext': { + 'video_cta': 0 + } + } + ], + 'site': { + 'id': '12345', + 'domain': 'management.exads.rocks', + 'cat': [ + 'IAB25-3' + ], + 'page': 'https://management.exads.rocks/prebidJS-client-RTB-InStreamVideo.html', + 'keywords': 'lifestyle, humour' + }, + 'device': { + 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', + 'ip': '95.233.216.174', + 'geo': { + 'country': 'ITA' + }, + 'language': 'en', + 'os': 'MacOS', + 'js': 0, + 'ext': { + 'remote_addr': '', + 'x_forwarded_for': '', + 'accept_language': 'en-GB' + } + }, + 'user': { + 'id': '' + }, + 'ext': { + 'sub': 0 + } + }) + }); + + expect(bidResponses).to.be.an('array').that.is.not.empty; + + const bid = serverResponse.body.seatbid[0].bid[0]; + const bidResponse = bidResponses[0]; + + expect(bidResponse.mediaType).to.equal(VIDEO); + }) + }); + + describe('onBidWon', function() { + it('Should not create nurl request if bid is undefined', function() { + const result = spec.onBidWon({}); + expect(result).to.be.undefined; + }) + }); + + describe('onTimeout', function () { + it('should exists and be a function', () => { + expect(spec.onTimeout).to.exist.and.to.be.a('function'); + }); + }); +}); From 3dcb78634dcce38f83fa76d160ef4b17ab19ef62 Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Fri, 19 Jan 2024 12:50:49 +0000 Subject: [PATCH 02/45] fix: readme.md --- exads/doc/README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/exads/doc/README.md b/exads/doc/README.md index a9188b50ea9..9ce61646f9e 100644 --- a/exads/doc/README.md +++ b/exads/doc/README.md @@ -7,20 +7,17 @@ Exads PrebidJS Adapter * Updating the unit tests, they are into `./Prebid.js/test/spec/modules/exadsBidAdapter_spec.js` * Running tlint and unit tests (to see the specific paragraph) * Doing manual tests (to see the specific paragraph) -* Building the new version of the adapter and all modules needed: -* `gulp build --modules=consentManagement,exadsBidAdapter` +* Building the new version of the adapter and all modules needed: `gulp build --modules=consentManagement,exadsBidAdapter` * After that you can use the prebidJS merged with our module. -* You can find it into: -* `./build/dist/prebid.js` -* Updating our examples. You can find them into: -* `./exads/examples` +* You can find it into: `./build/dist/prebid.js` +* Updating our examples. You can find them into `./exads/examples` #### Lint and Unit tests * Note: lint checks the official prebidJS rules. * Also, to do the pull request to official prebidJS team, it is mondatory 80% or more of covarage. * To check the coverage, type: -* `gulp test-coverage` and then -* `gulp view-coverage` + * `gulp test-coverage` and then + * `gulp view-coverage` #### Manual tests * Copying all examples to use into the publisher test web site: `./exads/doc/README.md` @@ -46,4 +43,4 @@ Exads PrebidJS Adapter -``` +``` \ No newline at end of file From 30eb51e31b0c466b491e2f09a5ad6de07eda8bd6 Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Fri, 19 Jan 2024 15:25:41 +0000 Subject: [PATCH 03/45] fix: changed exads urls --- .../prebidJS-client-RTB-InStreamVideo.html | 2 +- .../examples/prebidJS-client-RTB-banner.html | 2 +- .../examples/prebidJS-client-RTB-native.html | 2 +- .../prebidJS-client-RTB-video-banner.html | 2 +- modules/exadsBidAdapter.md | 8 +++---- test/spec/modules/exadsBidAdapter_spec.js | 24 +++++++++---------- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/exads/examples/prebidJS-client-RTB-InStreamVideo.html b/exads/examples/prebidJS-client-RTB-InStreamVideo.html index 7270f41a2f4..ed873f7d49d 100644 --- a/exads/examples/prebidJS-client-RTB-InStreamVideo.html +++ b/exads/examples/prebidJS-client-RTB-InStreamVideo.html @@ -16,7 +16,7 @@ // Client Conf start // Set as true for development environments only const isEnabledDebug = false; - const exads_endpoint = 'https://rtb.exads.rocks/rtb.php'; + const exads_endpoint = 'https://your-ad-network.com/rtb.php'; const partner = 'rtb_2_4'; let zoneId = 5179865; let fid = "12f6c5316c88687e275728a8f24f8787b6c31202"; diff --git a/exads/examples/prebidJS-client-RTB-banner.html b/exads/examples/prebidJS-client-RTB-banner.html index 29039820d98..2e8acefea69 100644 --- a/exads/examples/prebidJS-client-RTB-banner.html +++ b/exads/examples/prebidJS-client-RTB-banner.html @@ -12,7 +12,7 @@ // Client Conf start // Set as true for development environments only const isEnabledDebug = false; - const exads_endpoint = 'https://rtb.exads.rocks/rtb.php'; + const exads_endpoint = 'https://your-ad-network.com/rtb.php'; const partner = 'rtb_2_4'; let zoneId = 5179861; let fid = "eeb846019c94af9409bfaaf98626a6d34c648de4"; diff --git a/exads/examples/prebidJS-client-RTB-native.html b/exads/examples/prebidJS-client-RTB-native.html index 5a271a7ce5c..f645d287a91 100644 --- a/exads/examples/prebidJS-client-RTB-native.html +++ b/exads/examples/prebidJS-client-RTB-native.html @@ -11,7 +11,7 @@ // Client Conf start // Set as true for development environments only const isEnabledDebug = true; - const exads_endpoint = 'https://rtb.exads.rocks/rtb.php'; + const exads_endpoint = 'https://your-ad-network.com/rtb.php'; let zoneId = 5179867; let fid = "1e284a9540445fad9ac9c64881569260f1aa195f"; const partner = 'rtb_2_4'; diff --git a/exads/examples/prebidJS-client-RTB-video-banner.html b/exads/examples/prebidJS-client-RTB-video-banner.html index 451cb0a411f..98ca83b7adb 100644 --- a/exads/examples/prebidJS-client-RTB-video-banner.html +++ b/exads/examples/prebidJS-client-RTB-video-banner.html @@ -12,7 +12,7 @@ // Client Conf start // Set as true for development environments only const isEnabledDebug = false; - const exads_endpoint = 'https://rtb.exads.rocks/rtb.php'; + const exads_endpoint = 'https://your-ad-network.com/rtb.php'; const partner = 'rtb_2_4'; let zoneId = 5179863; let fid = "a1891f9f74cb728ad9583e0fb0eb5feae741292c"; diff --git a/modules/exadsBidAdapter.md b/modules/exadsBidAdapter.md index 605915a9144..171c745bf8f 100644 --- a/modules/exadsBidAdapter.md +++ b/modules/exadsBidAdapter.md @@ -94,7 +94,7 @@ adUnits = bidfloorcur: 'EUR', mimes: ['image/jpg'], image_output: 'html', - endpoint: 'https://rtb.exads.rocks/rtb.php' + endpoint: 'https://your-ad-network.com/rtb.php' } }] }]; @@ -128,7 +128,7 @@ adUnits = bidfloorcur: 'EUR', mimes: ['image/jpg'], video_output: 'html', - endpoint: 'https://rtb.exads.rocks/rtb.php' + endpoint: 'https://your-ad-network.com/rtb.php' } }] }]; @@ -190,7 +190,7 @@ adUnits = [{ keywords: 'lifestyle, humour', bidfloor: 0.00000011, bidfloorcur: 'EUR', - endpoint: 'https://rtb.exads.rocks/rtb.php', + endpoint: 'https://your-ad-network.com/rtb.php', } }] }]; @@ -279,7 +279,7 @@ adUnits = [{ keywords: 'lifestyle, humour', bidfloor: 0.00000011, bidfloorcur: 'EUR', - endpoint: 'https://rtb.exads.rocks/rtb.php', + endpoint: 'https://your-ad-network.com/rtb.php', } }] }]; diff --git a/test/spec/modules/exadsBidAdapter_spec.js b/test/spec/modules/exadsBidAdapter_spec.js index 8dfa88ffba8..f31764437f9 100644 --- a/test/spec/modules/exadsBidAdapter_spec.js +++ b/test/spec/modules/exadsBidAdapter_spec.js @@ -210,7 +210,7 @@ describe('exadsBidAdapterTest', function () { 'id': '8f7fa506af97bc193e7bf099d8ed6930bd50aaf1', 'impid': '270544423272657', 'price': 0.0045000000000000005, - 'adm': '\n\n', + 'adm': '\n\n', 'ext': { 'btype': 1, 'asset_mime_type': [ @@ -218,7 +218,7 @@ describe('exadsBidAdapterTest', function () { 'image/jpg' ] }, - 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147485&data=TVRjd01qUXdOREU1Tm54aE5UZGxPRGhrT0dGalkyWmtNV1kzTWpsbFl6WmtZV1V3TldSa00yRTFPQS0tfDIwMjMtMTItMTIgMTM6MDM6MTZ8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg1fDUwOHw2MjYwMzg5fDg5NDUzMTczfDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwyMXwzMDB4MjUwfDF8SVRBfHwwfDR8MXwwfDY1NzhhMDY0YmE4ZjI2Ljg5MDA3NDE0MjY0MTExMDg1OHw0YzUxOWQ0ZDA0OTgyMTk2MTFjM2ZmM2Q5NzQyZmYwMHxtYW5hZ2VtZW50LmV4YWRzLnJvY2tzfDB8MHwwfDB8MmQyYTQ5NjUyNzM5OGV8MHw0MHwwfFdJTk5FUnx8MXwwLjcyfDB8MHwyfDB8MHwwfDI1MjMxMTl8LTF8MHwyNTIzOTIwfHx8fDB8MHwwfHx8fDB8MHwwfDF8MHwwfDh8MXwwfDB8MHwyfHx8MHx8T0t8Zjk4NzUzNjc4YjIyYmVkOTBlMTg5NDJmNWU1NDIyZDI-', + 'nurl': 'http://your-ad-network.com/', 'cid': '6260389', 'crid': '89453173', 'adomain': [ @@ -254,11 +254,11 @@ describe('exadsBidAdapterTest', function () { ], 'site': { 'id': '12345', - 'domain': 'management.exads.rocks', + 'domain': 'your-ad-network.com', 'cat': [ 'IAB25-3' ], - 'page': 'https://management.exads.rocks/prebidJS-client-RTB-banner.html', + 'page': 'https://your-ad-network.com/prebidJS-client-RTB-banner.html', 'keywords': 'lifestyle, humour' }, 'device': { @@ -306,7 +306,7 @@ describe('exadsBidAdapterTest', function () { 'id': 'cedc93987cd4a1e08fdfe97de97482d1ecc503ee', 'impid': '270544423272657', 'price': 0.0045000000000000005, - 'adm': '{"native":{"link":{"url":"https:\\/\\/syndication.exads.rocks\\/click.php?d=H4sIAAAAAAAAA0WOO24DMQxEr6LGrUBJ1IelmwBGijS5gH4bb.JdG7uCkYKHj6wEDobFEI8cjNMODBkGafnc2m0_mONBv_RpdW8yXxdmYOVBIwRDwOe4zksdgKzUxkitnFQeORBaowKxVegxeLYQmFGxZuV6CDCrLmZtAyMSeZp8zDVO2ZRADrB4nIJPPhnsh8BLXONHXeraZP2OZZfbNX_tIwpY_FMxqBhU3Laa5vK5i3yZH2xrSayxzfcqzm25CB7RD2mrjVL050j3gr814Sl8ujDeenlkrR8vYzu9H_mugN9eWZHxlH2ilHVJPdH5qDAWkxIWN4UfogOxM2oBAAA-"},"eventtrackers":[{"event":1,"method":1,"url":"https:\\/\\/syndication.exads.rocks\\/cimp.php?data=TVRjd01qUXdPRE01TUh3ek5UWm1NakkyTWpnM1lqQmpPR1pqWm1SbVlUQmtNRGRoWm1VM09URXpNUS0tfC9saWJyYXJ5LzMyMTY3L2Y4NWVlODdjNGRmNWViMmNlMjdmMTBhNjRjNzlhMGUxYjY2NGVhMjMuanBnfGh0dHBzfDk1LjIzMy4yMTYuMTc0fElUQXw0MXxoYW5pbWUuY29tfDMyMTY3fDcyMDQ1NHw5MjMwOTh8NTE0NzQ4N3w1MDh8NjI2MDM5M3w4OTQ1MzE4OXwxNnwyfDB8MHwyNTh8MHwwLjV8OTB8VVNEfFVTRHwxfDF8MzR8fDF8SVRBfHx8NHwxfHx8NDQ5OTc5ZjdhY2VhZmMzZDg5NjA0ZDc0Zjg3YjdiMzR8MXwwfG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MC4wNXwxfDB8ZXhjaGFuZ2VfbmF0aXZlX2FkfDB8MHwyNTIzMTE5fC0xfDB8MjUyMzkyMHx8fDB8MHx8MHwwfDB8MHwwfDB8MXwwfHw4fDF8TW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExOS4wLjAuMCBTYWZhcmkvNTM3LjM2fHwyNHwyMnwwfDJ8MHx8fE9LfDQ3ZWFmNjZlN2RlOTFjZTkzZTExMDlkNDNmNzNmZDNl"}],"assets":[{"id":1,"title":{"text":"Title"}},{"id":2,"data":{"value":"Description"}},{"id":3,"img":{"url":"https:\\/\\/static.exads.rocks\\/library\\/32167\\/f85ee87c4df5eb2ce27f10a64c79a0e1b664ea23.jpg"}}]}}', + 'adm': '{"native":{"link":{"url":"https:\\/\\/your-ad-network.com"},"eventtrackers":[{"event":1,"method":1,"url":"https:\\/\\/your-ad-network.com"}],"assets":[{"id":1,"title":{"text":"Title"}},{"id":2,"data":{"value":"Description"}},{"id":3,"img":{"url":"https:\\/\\/your-ad-network.com\\/32167\\/f85ee87ea23.jpg"}}]}}', 'ext': { 'btype': 1, 'asset_mime_type': [ @@ -314,7 +314,7 @@ describe('exadsBidAdapterTest', function () { 'image/jpg' ] }, - 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147487&data=TVRjd01qUXdPRE01TUh3ek5UWm1NakkyTWpnM1lqQmpPR1pqWm1SbVlUQmtNRGRoWm1VM09URXpNUS0tfDIwMjMtMTItMTIgMTQ6MTM6MTB8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg3fDUwOHw2MjYwMzkzfDg5NDUzMTg5fDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwzNHx8MXxJVEF8fDB8NHwxfDB8NjU3OGIwYzY2MDhiNjAuNzc4NjY2OTczMzI3Mzg0MzQwfDQ0OTk3OWY3YWNlYWZjM2Q4OTYwNGQ3NGY4N2I3YjM0fG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MHwyMWRlYTFmYzZjM2UxYnwwfDQwfDB8V0lOTkVSfHwxfDAuNzJ8MHwwfDJ8MHwwfDB8MjUyMzExOXwtMXwwfDI1MjM5MjB8fHx8MHwwfDB8fHx8MHwwfDB8MXwwfDB8OHwxfDB8MjJ8MHwyfHx8MHx8T0t8NmVmNGE1MTAwM2IwOGZiZGI2ZDMyOTVkNTQ2Y2U3YzM-', + 'nurl': 'http://your-ad-network.com', 'cid': '6260393', 'crid': '89453189', 'adomain': [ @@ -348,11 +348,11 @@ describe('exadsBidAdapterTest', function () { ], 'site': { 'id': '12345', - 'domain': 'management.exads.rocks', + 'domain': 'your-ad-network.com', 'cat': [ 'IAB25-3' ], - 'page': 'https://management.exads.rocks/prebidJS-client-RTB-native.html' + 'page': 'https://your-ad-network.com/prebidJS-client-RTB-native.html' }, 'device': { 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', @@ -396,14 +396,14 @@ describe('exadsBidAdapterTest', function () { 'id': 'd2d2063517b126252f56e22767c53f936ff40411', 'impid': '270544423272657', 'price': 0.12474000000000002, - 'adm': '\n\n \n \n exads.rocks\n \n \n \n \n \n \n 00:00:20.32\n \n \n \n \n \n \n \n \n \n \n \n \n test.com\n \n \n \n \n \n \n \n \n\n', + 'adm': '\n\n \n \n your-ad-network.com\n \n \n \n \n \n \n 00:00:20.32\n \n \n \n \n \n \n \n \n \n \n \n \n test.com\n \n \n \n \n \n \n \n \n\n', 'ext': { 'btype': 1, 'asset_mime_type': [ 'video/mp4' ] }, - 'nurl': 'http://rtb.exads.rocks/not.php?zid=5147489&data=TVRjd01qUXdPRGs0T1h3ek5EZzVOV1JqT1RjeE9XSmpaakF3TURrM05qUXpNelUwTURZek5EZzFZZy0tfDIwMjMtMTItMTIgMTQ6MjM6MDl8OTUuMjMzLjIxNi4xNzR8SVRBfDQxfGhhbmltZS5jb218MzIxNjd8NzIwNDU0fDkyMzA5OHw1MTQ3NDg5fDUwOHw2MjYwMzk1fDg5NDUzMTkxfDE2fDJ8MHwwfDI1OHwwfDB8MHxVU0R8VVNEfDF8MXwzOXx8MXxJVEF8fDE2fDR8MXwwfDY1NzhiMzFkOGFhODk0Ljk4OTYyNTI4OTcwNDAxNzA5fGYxMTdmYjZkOGU4ZDgwNDViMGU2Y2Q0NTE4NzFkODhjfG1hbmFnZW1lbnQuZXhhZHMucm9ja3N8MHwwfDB8MHwyMjE4YWJjN2ViY2E5N3wwfDQwfDB8V0lOTkVSfHwxfDAuNzJ8MHwwfDJ8MHwwfDB8MjUyMzExOXwtMXwwfDI1MjM5MjB8fHx8MHwwfDB8fHx8MHwwfDB8MXwwfDB8OHwxfDB8MjF8MHwyfHx8MHx8T0t8MDVjNmQwNzhjZDZjYmJmNDY1ZWJlZDY2ZWQyYzViZDM-', + 'nurl': 'http://your-ad-network.com', 'cid': '6260395', 'crid': '89453191', 'adomain': [ @@ -443,11 +443,11 @@ describe('exadsBidAdapterTest', function () { ], 'site': { 'id': '12345', - 'domain': 'management.exads.rocks', + 'domain': 'your-ad-network.com', 'cat': [ 'IAB25-3' ], - 'page': 'https://management.exads.rocks/prebidJS-client-RTB-InStreamVideo.html', + 'page': 'https://your-ad-network.com/prebidJS-client-RTB-InStreamVideo.html', 'keywords': 'lifestyle, humour' }, 'device': { From 1e83db3b47104831f086493fe6abb44aa0d83522 Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Fri, 19 Jan 2024 15:52:51 +0000 Subject: [PATCH 04/45] fix: Tools and suggestions related to the doc --- modules/exadsBidAdapter.md | 63 +++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/modules/exadsBidAdapter.md b/modules/exadsBidAdapter.md index 171c745bf8f..34ac80e6c53 100644 --- a/modules/exadsBidAdapter.md +++ b/modules/exadsBidAdapter.md @@ -283,4 +283,65 @@ adUnits = [{ } }] }]; -``` \ No newline at end of file +``` +# Tools and suggestions +This section contains some suggestions that allow to set some parameters automatically. + +### User Ip / Country +In order to detect the current user ip there are different approaches. An example is using public web services as ``` https://api.ipify.org```. + +Example of usage (to add into the publisher web sites): + +``` + +``` + +The same service gives the possibility to detect the country as well. Check the official web page about possible limitations of the free licence. + +### Impression Id +Each advertising request has to be identified uniquely by an id. +One possible approach is using a classical hash function. + +``` + +``` + +### User Id +The approach used for impression id could be used for generating a unique user id. +Also, it is recommended to store locally the id, e.g. by the browser localStorage. + +``` + +``` + From 38caa60dc84bd7f71e6c84ee8a50b241c42a81af Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Mon, 22 Jan 2024 15:30:31 +0000 Subject: [PATCH 05/45] fix: from code review --- exads/doc/README.md | 28 ++++++++++----------- modules/exadsBidAdapter.md | 50 ++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/exads/doc/README.md b/exads/doc/README.md index 9ce61646f9e..84454eba896 100644 --- a/exads/doc/README.md +++ b/exads/doc/README.md @@ -1,16 +1,16 @@ # exadsBidAdapter -Exads PrebidJS Adapter +EXADS PrebidJS Adapter #### In order to mantain the adapter locally: -* Changing the adapter code that you can find into `./Prebid.js/modules/exadsBidAdapter.js` -* Updating the unit tests, they are into `./Prebid.js/test/spec/modules/exadsBidAdapter_spec.js` -* Running tlint and unit tests (to see the specific paragraph) -* Doing manual tests (to see the specific paragraph) -* Building the new version of the adapter and all modules needed: `gulp build --modules=consentManagement,exadsBidAdapter` -* After that you can use the prebidJS merged with our module. -* You can find it into: `./build/dist/prebid.js` -* Updating our examples. You can find them into `./exads/examples` +* Change the adapter code that you can find into `./Prebid.js/modules/exadsBidAdapter.js` +* Update the unit tests, they are into `./Prebid.js/test/spec/modules/exadsBidAdapter_spec.js` +* Run tlint and unit tests (to see the specific paragraph) +* Do manual tests (to see the specific paragraph) +* Build the new version of the adapter and all modules needed: `gulp build --modules=consentManagement,exadsBidAdapter` +* After that, you can use the prebidJS, merged with our module. + * You can find it into: `./build/dist/prebid.js` +* Update our HTML examples in order to test the adapter. You can find them into `./exads/examples` #### Lint and Unit tests * Note: lint checks the official prebidJS rules. @@ -20,12 +20,12 @@ Exads PrebidJS Adapter * `gulp view-coverage` #### Manual tests -* Copying all examples to use into the publisher test web site: `./exads/doc/README.md` -* Copying the prebidJS library containing the new changes of the adapter `./build/dist/prebid.js` -* For each example, changing `` based on the publisher web site configuration +* Copy all examples to use into the publisher test website: `./exads/doc/README.md` +* Copy the prebidJS library containing the new changes of the adapter `./build/dist/prebid.js` +* For each example, change ``, based on the publisher website configuration * Note: if you need to debug the snippet code, comment the previous instruction and uncomment the `` -* Changing all params based on test scenarios (to see: `./Prebid.js/modules/exadsBidAdapter.md`) -* Navigating to the publisher web site and test it +* Change all params based on test scenarios (to see: `./Prebid.js/modules/exadsBidAdapter.md`) +* Navigate to the publisher website and test it #### Environments (development and production) - Changes to do into the snippet code * Set isEnabledDebug global variable (If it is true, you will be able to see logs) diff --git a/modules/exadsBidAdapter.md b/modules/exadsBidAdapter.md index 34ac80e6c53..9bd57b41792 100644 --- a/modules/exadsBidAdapter.md +++ b/modules/exadsBidAdapter.md @@ -8,7 +8,7 @@ # Description -Module that connects to Exads's bidder for bids. +Module that connects to EXADS' bidder for bids. ### Build ``` @@ -46,6 +46,7 @@ pbjs.setConfig({ # Test Parameters +Now you will find the different parameters to set, based on publisher website. They are optional unless otherwise specified. #### RTB Banner 2.4 @@ -53,17 +54,17 @@ pbjs.setConfig({ * **fid** (required) - you can get it from the endpoint created after configuring the zones (string) * **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) * **siteId** (recommended) - unique Site ID (string) -* **banner.sizes** (required) - One array of integer - [width, height] -* **catIab** - IAB category ID (array of string) +* **banner.sizes** (required) - one integer array - [width, height] +* **catIab** - IAB category ID (string array) * **userIp** (required) - IP address of the user (string)* * **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. * **country** - Country ISO3 * **impressionId** (required) - unique impression ID within this bid request (string) * **keywords** - keywords can be used to ensure ad zones get the right type of advertising. Keywords should be a string of comma-separated words -* **bidfloor** - Minimum bid for this impression (CPM) / click (CPC) and account currency, optional (float) -* **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) -* **mimes** - List of supported mime types. We support: image/jpeg, image/jpg, image/png, image/png, image/gif, image/webp, video/mp4 (string array) -* **endpoint** (required) - Exads endpoint (URL) +* **bidfloor** - minimum bid for this impression (CPM) / click (CPC) and account currency (float) +* **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes (string) +* **mimes** - list of supported mime types. We support: image/jpeg, image/jpg, image/png, image/png, image/gif, image/webp, video/mp4 (string array) +* **endpoint** (required) - EXADS endpoint (URL) ##### RTB Banner 2.4 (Image) * **image_output** - Indicates output format for image banners* (string) @@ -140,7 +141,7 @@ adUnits = * **fid** (required) - you can get it from the endpoint created after configuring the zones (string) * **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) * **siteId** (recommended) - unique Site ID (string) -* **catIab** - IAB category ID (array of string) +* **catIab** - IAB category ID (string array) * **userIp** (required) - IP address of the user (string)* * **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. * **country** - Country ISO3 (string) @@ -150,8 +151,8 @@ adUnits = * **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) * **video.mimes** - List of supported mime types (string array) * **context** - (recommended) - The video context, either 'instream', 'outstream'. Defaults to ‘instream’ (string) -* **protocols** - List of supported video bid response protocols (int array) -* **endpoint** (required) - Exads endpoint (URL) +* **protocols** - List of supported video bid response protocols (integer array) +* **endpoint** (required) - EXADS endpoint (URL) ```javascript adUnits = [{ @@ -202,7 +203,7 @@ adUnits = [{ * **fid** (required) - you can get it from the endpoint created after configuring the zones (string) * **partner** (required) - currently we support rtb 2.4 ("rtb_2_4") only (string) * **siteId** (recommended) - unique Site ID (string) -* **catIab** - IAB category ID (array of string) +* **catIab** - IAB category ID (string array) * **userIp** (required) - IP address of the user (string)* * **userId** (*required) - unique user ID (string). *If you cannot generate a user ID, you can leave it empty (""). The request will get a response as long as "user" object is included in the request. * **country** - Country ISO3 (string) @@ -212,20 +213,33 @@ adUnits = [{ * **bidfloorcur** - Currency for minimum bid value specified using ISO-4217 alpha codes, optional (string) * **native.plcmtcnt** - The number of identical placements in this Layout (integer) * **assets (title)** - Title object for title assets* (JSON object) - * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer): + * 1 - Image asset ID + * 2 - Title asset ID + * 3 - Description asset ID * **required** - Set to 1 if asset is required or 0 if asset is optional (integer) * **title** * len (required) - Maximum length of the text in the title element. (integer) * **assets (data)** - * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer): + * 1 - Image asset ID + * 2 - Title asset ID + * 3 - Description asset ID * **data** - * **type** - Type ID of the element supported by the publisher (integer). We support: 1 (sponsored - Sponsored By message where response should contain the brand name of the sponsor), 2 (desc - Descriptive text associated with the product or service being advertised) + * **type** - Type ID of the element supported by the publisher (integer). We support: + * 1 - sponsored - sponsored By message where response should contain the brand name of the sponsor + * 2 - desc - descriptive text associated with the product or service being advertised * **len** * **assets (img)** - * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer) 1: Image asset ID, 2: Title asset ID, 3: Description asset ID + * **id** - Unique asset ID, assigned by exchange. Typically a counter for the array (integer): + * 1 - Image asset ID + * 2 - Title asset ID + * 3 - Description asset ID * **required** - Set to 1 if asset is required or 0 if asset is optional (integer) * **img** - * **type** - Type ID of the image element supported by the publisher. We support: 1 (Icon image) (integer), 3 (Large image preview for the ad) (integer) + * **type** - Type ID of the image element supported by the publisher. We support: + * 1 - Icon image (integer) + * 3 - Large image preview for the ad (integer) * **w** - Width of the image in pixels, optional (integer) * **h** - Height of the image in pixels, optional (integer) @@ -290,7 +304,7 @@ This section contains some suggestions that allow to set some parameters automat ### User Ip / Country In order to detect the current user ip there are different approaches. An example is using public web services as ``` https://api.ipify.org```. -Example of usage (to add into the publisher web sites): +Example of usage (to add into the publisher websites): ``` -``` - +``` \ No newline at end of file From 0a4caf6046f55028a7406f515e98750ce5c62747 Mon Sep 17 00:00:00 2001 From: Giuseppe Cera Date: Mon, 22 Jan 2024 18:26:30 +0000 Subject: [PATCH 07/45] fix: from code review --- .../prebidJS-client-RTB-InStreamVideo.html | 48 ++++++++---------- .../examples/prebidJS-client-RTB-banner.html | 35 ++++++------- .../examples/prebidJS-client-RTB-native.html | 36 +++++++------- .../prebidJS-client-RTB-video-banner.html | 34 +++++++------ modules/exadsBidAdapter.js | 31 +++++------- test/spec/modules/exadsBidAdapter_spec.js | 49 +++++++++---------- 6 files changed, 113 insertions(+), 120 deletions(-) diff --git a/exads/examples/prebidJS-client-RTB-InStreamVideo.html b/exads/examples/prebidJS-client-RTB-InStreamVideo.html index ed873f7d49d..10977066f5f 100644 --- a/exads/examples/prebidJS-client-RTB-InStreamVideo.html +++ b/exads/examples/prebidJS-client-RTB-InStreamVideo.html @@ -1,17 +1,17 @@ - + - + RTB Instream Video Prebid.js - + - + - + -

RTB Instream Video Prebid.js

-