Skip to content

Commit

Permalink
Lucead Bid Adapter: Support Single Request Architecture mode + enhanc…
Browse files Browse the repository at this point in the history
…ed reporting + updated PAAPI auction config
  • Loading branch information
aymeric45 committed May 13, 2024
1 parent 37ab555 commit 378b0a1
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 113 deletions.
138 changes: 82 additions & 56 deletions modules/luceadBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import {fetch} from '../src/ajax.js';

const bidderCode = 'lucead';
const bidderName = 'Lucead';
let baseUrl = 'https://lucead.com';
let staticUrl = 'https://s.lucead.com';
let companionUrl = 'https://cdn.jsdelivr.net/gh/lucead/prebid-js-external-js-lucead@master/dist/prod.min.js';
let endpointUrl = 'https://prebid.lucead.com/go';
const defaultCurrency = 'EUR';
const defaultTtl = 500;
const aliases = ['adliveplus'];
const defaultRegion = 'eu';
const domain = 'lucead.com'
let baseUrl = `https://${domain}`;
let staticUrl = `https://s.${domain}`;
let endpointUrl = baseUrl;
let companionUrl = 'https://cdn.jsdelivr.net/gh/lucead/prebid-js-external-js-lucead@master/dist/prod.min.js';

function isDevEnv() {
return location.hash.includes('prebid-dev') || location.href.startsWith('https://ayads.io/test');
return location.hash.includes('prebid-dev');
}

function isBidRequestValid(bidRequest) {
Expand All @@ -27,11 +29,14 @@ export function log(msg, obj) {
}

function buildRequests(bidRequests, bidderRequest) {
const region = bidRequests[0]?.params?.region || defaultRegion;
endpointUrl = `https://${region}.${domain}`;

if (isDevEnv()) {
baseUrl = location.origin;
staticUrl = baseUrl;
companionUrl = `${staticUrl}/dist/prebid-companion.js`;
endpointUrl = `${baseUrl}/go`;
endpointUrl = `${baseUrl}`;
}

log('buildRequests', {
Expand All @@ -50,73 +55,91 @@ function buildRequests(bidRequests, bidderRequest) {
getUniqueIdentifierStr,
ortbConverter,
deepSetValue,
is_sra: true,
region,
};

loadExternalScript(companionUrl, bidderCode, () => window.ayads_prebid && window.ayads_prebid(companionData));
loadExternalScript(companionUrl, bidderCode, () => {
const fn = window.lucead_prebid;
return fn && fn(companionData);
});

return bidRequests.map(bidRequest => ({
return {
method: 'POST',
url: `${endpointUrl}/prebid/sub`,
url: `${endpointUrl}/go/prebid/sra`,
data: JSON.stringify({
request_id: bidderRequest.bidderRequestId,
domain: location.hostname,
bid_id: bidRequest.bidId,
sizes: bidRequest.sizes,
media_types: bidRequest.mediaTypes,
fledge_enabled: bidderRequest.fledgeEnabled,
enable_contextual: bidRequest?.params?.enableContextual !== false,
enable_pa: bidRequest?.params?.enablePA !== false,
params: bidRequest.params,
bid_requests: bidRequests.map(bidRequest => {
return {
bid_id: bidRequest.bidId,
sizes: bidRequest.sizes,
media_types: bidRequest.mediaTypes,
placement_id: bidRequest.params.placementId,
};
}),
}),
options: {
contentType: 'text/plain',
withCredentials: false
},
}));
};
}

function interpretResponse(serverResponse, bidRequest) {
// @see required fields https://docs.prebid.org/dev-docs/bidder-adaptor.html
const response = serverResponse.body;
const bidRequestData = JSON.parse(bidRequest.data);

const bids = response.enable_contextual !== false ? [{
requestId: response?.bid_id || '1', // bid request id, the bid id
cpm: response?.cpm || 0,
width: (response?.size && response?.size?.width) || 300,
height: (response?.size && response?.size?.height) || 250,
currency: response?.currency || defaultCurrency,
ttl: response?.ttl || defaultTtl,
creativeId: response.ssp ? `ssp:${response.ssp}` : (response?.ad_id || '0'),
netRevenue: response?.netRevenue || true,
ad: response?.ad || '',
const response = serverResponse?.body;
const bidRequestData = JSON.parse(bidRequest?.data);

const bids = (response?.bids || []).map(bid => ({
requestId: bid?.bid_id || '1', // bid request id, the bid id
cpm: bid?.cpm || 0,
width: (bid?.size && bid?.size?.width) || 300,
height: (bid?.size && bid?.size?.height) || 250,
currency: bid?.currency || defaultCurrency,
ttl: bid?.ttl || defaultTtl,
creativeId: bid?.ssp ? `ssp:${bid.ssp}` : `${bid?.ad_id || 0}:${bid?.ig_id || 0}`,
netRevenue: bid?.net_revenue || true,
ad: bid?.ad || '',
meta: {
advertiserDomains: response?.advertiserDomains || [],
advertiserDomains: bid?.advertiser_domains || [],
},
}] : null;

log('interpretResponse', {serverResponse, bidRequest, bidRequestData, bids});

if (response.enable_pa === false) { return bids; }

const fledgeAuctionConfig = {
seller: baseUrl,
decisionLogicUrl: `${baseUrl}/js/ssp.js`,
interestGroupBuyers: [baseUrl],
perBuyerSignals: {},
auctionSignals: {
size: bidRequestData.sizes ? {width: bidRequestData?.sizes[0][0] || 300, height: bidRequestData?.sizes[0][1] || 250} : null,
},
};
}));

const fledgeAuctionConfigs = [{bidId: response.bid_id, config: fledgeAuctionConfig}];
log('interpretRespoonetagnse', {serverResponse, bidRequest, bidRequestData, bids});

if (response?.enable_pa === false) { return bids; }

const paapi = response.bids.map(bid => ({
bidId: bid?.bid_id,
config: {
seller: baseUrl,
decisionLogicUrl: `${baseUrl}/js/ssp.js`,
interestGroupBuyers: [baseUrl],
requestedSize: bid?.size,
auctionSignals: {
size: bid?.size,
},
perBuyerSignals: {
[baseUrl]: {
prebid_paapi: true,
prebid_bid_id: bid?.bid_id,
prebid_request_id: bidRequestData.request_id,
placement_id: bid.placement_id,
// floor,
is_sra: true,
endpoint_url: endpointUrl,
},
}
}
}));

return {bids, fledgeAuctionConfigs};
return {bids, paapi};
}

function report(type = 'impression', data = {}) {
function report(type, data) {
// noinspection JSCheckFunctionSignatures
return fetch(`${endpointUrl}/report/${type}`, {
return fetch(`${endpointUrl}/go/report/${type}`, {
body: JSON.stringify(data),
method: 'POST',
contentType: 'text/plain'
Expand All @@ -128,20 +151,23 @@ function onBidWon(bid) {

let data = {
bid_id: bid?.bidId,
placement_id: bid?.params ? bid?.params[0]?.placementId : 0,
placement_id: bid.params ? (bid?.params[0]?.placementId || '0') : '0',
spent: bid?.cpm,
currency: bid?.currency,
};

if (bid.creativeId) {
if (bid.creativeId.toString().startsWith('ssp:')) {
data.ssp = bid.creativeId.split(':')[1];
if (bid?.creativeId) {
const parts = bid.creativeId.toString().split(':');

if (parts[0] === 'ssp') {
data.ssp = parts[1];
} else {
data.ad_id = bid.creativeId;
data.ad_id = parts[0]
data.ig_id = parts[1]
}
}

return report(`impression`, data);
return report('impression', data);
}

function onTimeout(timeoutData) {
Expand Down
41 changes: 26 additions & 15 deletions modules/luceadBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@ Maintainer: prebid@lucead.com

Module that connects to Lucead demand source to fetch bids.

# Test Parameters
# Params type definition

```typescript
type Params = {
placementId: string;
region?: 'eu' | 'us' | 'ap';
};
```
const adUnits = [
{
code: 'test-div',
sizes: [[300, 250]],
bids: [
{
bidder: 'lucead',
params: {
placementId: '2',
}
}
]
}
];

# Test Parameters

```javascript
const adUnits=[
{
code:'test-div',
sizes:[[300,250]],
bids:[
{
bidder:'lucead',
params:{
placementId:'2',
region:'us', // optional: 'eu', 'us', 'ap'
}
}
]
}
];
```
Loading

0 comments on commit 378b0a1

Please sign in to comment.