Skip to content

Commit 781b6df

Browse files
committedJan 13, 2025
Mobkoi Bidder Adapter: Initialise implementation
1 parent 8b5d33e commit 781b6df

File tree

3 files changed

+544
-0
lines changed

3 files changed

+544
-0
lines changed
 

‎modules/mobkoiBidAdapter.js

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
2+
import { registerBidder } from '../src/adapters/bidderFactory.js';
3+
import { BANNER } from '../src/mediaTypes.js';
4+
import { _each, replaceMacros, deepAccess, deepSetValue, logError } from '../src/utils.js';
5+
6+
const BIDDER_CODE = 'mobkoi';
7+
/**
8+
* !IMPORTANT: This value must match the value in mobkoiAnalyticsAdapter.js
9+
* The name of the parameter that the publisher can use to specify the ad server endpoint.
10+
*/
11+
const PARAM_NAME_AD_SERVER_BASE_URL = 'adServerBaseUrl';
12+
/**
13+
* The list of ORTB response fields that are used in the macros. Field
14+
* replacement is self-implemented in the adapter. Use dot-notated path for
15+
* nested fields. For example, 'ad.ext.adomain'. For more information, visit
16+
* https://www.npmjs.com/package/dset and https://www.npmjs.com/package/dlv.
17+
*/
18+
const ORTB_RESPONSE_FIELDS_SUPPORT_MACROS = ['adm', 'nurl', 'lurl'];
19+
20+
export const converter = ortbConverter({
21+
context: {
22+
netRevenue: true,
23+
ttl: 30,
24+
},
25+
request(buildRequest, imps, bidderRequest, context) {
26+
const ortbRequest = buildRequest(imps, bidderRequest, context);
27+
const prebidBidRequest = context.bidRequests[0];
28+
29+
ortbRequest.id = utils.getOrtbId(prebidBidRequest);
30+
31+
return ortbRequest;
32+
},
33+
bidResponse(buildPrebidBidResponse, ortbBidResponse, context) {
34+
utils.replaceAllMacrosInPlace(ortbBidResponse, context);
35+
36+
const prebidBid = buildPrebidBidResponse(ortbBidResponse, context);
37+
utils.addCustomFieldsToPrebidBidResponse(prebidBid, ortbBidResponse);
38+
return prebidBid;
39+
},
40+
});
41+
42+
export const spec = {
43+
code: BIDDER_CODE,
44+
supportedMediaTypes: [BANNER],
45+
46+
isBidRequestValid(bid) {
47+
if (!deepAccess(bid, 'ortb2.site.publisher.id')) {
48+
logError('The "ortb2.site.publisher.id" field is required in the bid request.' +
49+
'Please set it via the "config.ortb2.site.publisher.id" field with pbjs.setBidderConfig.'
50+
);
51+
return false;
52+
}
53+
54+
return true;
55+
},
56+
57+
buildRequests(prebidBidRequests, prebidBidderRequest) {
58+
const adServerEndpoint = utils.getAdServerEndpointBaseUrl(prebidBidderRequest) + '/bid';
59+
60+
return {
61+
method: 'POST',
62+
url: adServerEndpoint,
63+
options: {
64+
contentType: 'application/json',
65+
},
66+
data: converter.toORTB({
67+
bidRequests: prebidBidRequests,
68+
bidderRequest: prebidBidderRequest
69+
}),
70+
};
71+
},
72+
73+
interpretResponse(serverResponse, customBidRequest) {
74+
if (!serverResponse.body) return [];
75+
76+
const responseBody = {...serverResponse.body, seatbid: serverResponse.body.seatbid};
77+
const prebidBidResponse = converter.fromORTB({
78+
request: customBidRequest.data,
79+
response: responseBody,
80+
});
81+
return prebidBidResponse.bids;
82+
},
83+
};
84+
85+
registerBidder(spec);
86+
87+
export const utils = {
88+
89+
/**
90+
* !IMPORTANT: Make sure the implementation of this function matches getAdServerEndpointBaseUrl
91+
* in both adapters.
92+
* Obtain the Ad Server Base URL from the given Prebid object.
93+
* @param {*} bid Prebid Bidder Request Object or Prebid Bid Response/Request
94+
* or ORTB Request/Response Object
95+
* @returns {string} The Ad Server Base URL
96+
* @throws {Error} If the ORTB ID cannot be found in the given
97+
*/
98+
getAdServerEndpointBaseUrl (bid) {
99+
const ortbPath = `site.publisher.ext.${PARAM_NAME_AD_SERVER_BASE_URL}`;
100+
const prebidPath = `ortb2.${ortbPath}`;
101+
102+
const adServerBaseUrl =
103+
deepAccess(bid, prebidPath) ||
104+
deepAccess(bid, ortbPath);
105+
106+
if (!adServerBaseUrl) {
107+
throw new Error('Failed to find the Ad Server Base URL in the given object. ' +
108+
`Please set it via the "${prebidPath}" field with pbjs.setBidderConfig.\n` +
109+
'Given Object:\n' +
110+
JSON.stringify(bid, null, 2)
111+
);
112+
}
113+
114+
return adServerBaseUrl;
115+
},
116+
117+
/**
118+
* !IMPORTANT: Make sure the implementation of this function matches utils.getPublisherId in
119+
* both adapters.
120+
* Extract the publisher ID from the given object.
121+
* @param {*} prebidBidRequestOrOrtbBidRequest
122+
* @returns string
123+
* @throws {Error} If the publisher ID is not found in the given object.
124+
*/
125+
getPublisherId: function (prebidBidRequestOrOrtbBidRequest) {
126+
const ortbPath = 'site.publisher.id';
127+
const prebidPath = `ortb2.${ortbPath}`;
128+
129+
const publisherId =
130+
deepAccess(prebidBidRequestOrOrtbBidRequest, prebidPath) ||
131+
deepAccess(prebidBidRequestOrOrtbBidRequest, ortbPath);
132+
133+
if (!publisherId) {
134+
throw new Error(
135+
'Failed to obtain publisher ID from the given object. ' +
136+
`Please set it via the "${prebidPath}" field with pbjs.setBidderConfig.\n` +
137+
'Given object:\n' +
138+
JSON.stringify(prebidBidRequestOrOrtbBidRequest, null, 2)
139+
);
140+
}
141+
142+
return publisherId;
143+
},
144+
145+
/**
146+
* !IMPORTANT: Make sure the implementation of this function matches utils.getOrtbId in
147+
* mobkoiAnalyticsAdapter.js.
148+
* We use the bidderRequestId as the ortbId. We could do so because we only
149+
* make one ORTB request per Prebid Bidder Request.
150+
* The ID field named differently when the value passed on to different contexts.
151+
* @param {*} bid Prebid Bidder Request Object or Prebid Bid Response/Request
152+
* or ORTB Request/Response Object
153+
* @returns {string} The ORTB ID
154+
* @throws {Error} If the ORTB ID cannot be found in the given object.
155+
*/
156+
getOrtbId(bid) {
157+
const ortbId =
158+
// called bidderRequestId in Prebid Request
159+
bid.bidderRequestId ||
160+
// called seatBidId in Prebid Bid Response Object
161+
bid.seatBidId ||
162+
// called ortbId in Interpreted Prebid Response Object
163+
bid.ortbId ||
164+
// called id in ORTB object
165+
(Object.hasOwn(bid, 'imp') && bid.id);
166+
167+
if (!ortbId) {
168+
throw new Error('Unable to find the ORTB ID in the bid object. Given Object:\n' +
169+
JSON.stringify(bid, null, 2)
170+
);
171+
}
172+
173+
return ortbId;
174+
},
175+
176+
/**
177+
* Append custom fields to the prebid bid response. so that they can be accessed
178+
* in various event handlers.
179+
* @param {*} prebidBidResponse
180+
* @param {*} ortbBidResponse
181+
*/
182+
addCustomFieldsToPrebidBidResponse(prebidBidResponse, ortbBidResponse) {
183+
prebidBidResponse.ortbBidResponse = ortbBidResponse;
184+
prebidBidResponse.ortbId = ortbBidResponse.id;
185+
},
186+
187+
replaceAllMacrosInPlace(ortbBidResponse, context) {
188+
const macros = {
189+
// ORTB macros
190+
AUCTION_PRICE: ortbBidResponse.price,
191+
AUCTION_IMP_ID: ortbBidResponse.impid,
192+
AUCTION_CURRENCY: ortbBidResponse.cur,
193+
AUCTION_BID_ID: context.bidderRequest.auctionId,
194+
195+
// Custom macros
196+
BIDDING_API_BASE_URL: utils.getAdServerEndpointBaseUrl(context.bidderRequest),
197+
CREATIVE_ID: ortbBidResponse.crid,
198+
CAMPAIGN_ID: ortbBidResponse.cid,
199+
ORTB_ID: ortbBidResponse.id,
200+
PUBLISHER_ID: deepAccess(context, 'bidRequest.ortb2.site.publisher.id') || deepAccess(context, 'bidderRequest.ortb2.site.publisher.id')
201+
};
202+
203+
_each(ORTB_RESPONSE_FIELDS_SUPPORT_MACROS, ortbField => {
204+
deepSetValue(
205+
ortbBidResponse,
206+
ortbField,
207+
replaceMacros(deepAccess(ortbBidResponse, ortbField), macros)
208+
);
209+
});
210+
},
211+
}

‎modules/mobkoiBidAdapter.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Overview
2+
3+
Module Name: Mobkoi Bidder Adapter
4+
Module Type: Bidder Adapter
5+
Maintainer: platformteam@mobkoi.com
6+
7+
# Description
8+
9+
Module that connects to Mobkoi Ad Server
10+
11+
### Supported formats:
12+
- Banner
13+
14+
# Test Parameters
15+
```js
16+
const adUnits = [
17+
{
18+
code: 'banner-ad',
19+
mediaTypes: {
20+
banner: { sizes: [300, 200] },
21+
},
22+
bids: [
23+
{
24+
bidder: 'mobkoi',
25+
},
26+
],
27+
},
28+
];
29+
30+
pbjs.que.push(function () {
31+
pbjs.setBidderConfig({
32+
bidders: ['mobkoi'],
33+
config: {
34+
ortb2: {
35+
site: {
36+
publisher: {
37+
id: 'module-test-publisher-id',
38+
ext: {
39+
adServerBaseUrl: 'https://adserver.dev.mobkoi.com',
40+
},
41+
},
42+
},
43+
},
44+
},
45+
});
46+
47+
pbjs.addAdUnits(adUnits);
48+
});
49+
```

0 commit comments

Comments
 (0)
Failed to load comments.