Skip to content

Commit

Permalink
New Bidder:tapnative (prebid#12322)
Browse files Browse the repository at this point in the history
* New Bidder:tapnative

* removed duplicate
  • Loading branch information
pranavsheth authored Oct 11, 2024
1 parent 176660f commit 4cc7d25
Show file tree
Hide file tree
Showing 4 changed files with 526 additions and 3 deletions.
105 changes: 102 additions & 3 deletions libraries/audUtils/bidderUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import {
logError
} from '../../src/utils.js';

// Declare native assets
const NATIVE_ASSETS = [
{ id: 1, required: 1, title: { len: 100 } }, // Title
{ id: 2, required: 1, img: { type: 3, w: 300, h: 250 } }, // Main image
{ id: 3, required: 0, data: { type: 1, len: 140 } }, // Body
{ id: 4, required: 1, data: { type: 2 } }, // Sponsored by
{ id: 5, required: 1, icon: { w: 50, h: 50 } }, // Icon
{ id: 6, required: 1, data: { type: 12, len: 15 } } // Call to action
];
// Function to get Request
export const getBannerRequest = (bidRequests, bidderRequest, ENDPOINT) => {
let request = [];
Expand Down Expand Up @@ -34,6 +43,7 @@ export const getBannerRequest = (bidRequests, bidderRequest, ENDPOINT) => {
if (bidderRequest?.uspConsent) {
deepSetValue(req, 'regs.ext.us_privacy', bidderRequest.uspConsent);
}
req.MediaType = getMediaType(bidReq);
request.push(req);
});
// Return the array of request
Expand All @@ -48,6 +58,15 @@ export const getBannerRequest = (bidRequests, bidderRequest, ENDPOINT) => {
}
// Function to get Response
export const getBannerResponse = (bidResponse, mediaType) => {
return formatResponse(bidResponse, mediaType);
}
// Function to get NATIVE Response
export const getNativeResponse = (bidResponse, bidRequest, mediaType) => {
const assets = JSON.parse(JSON.parse(bidRequest.data)[0].imp[0].native.request).assets;
return formatResponse(bidResponse, mediaType, assets);
}
// Function to format response
const formatResponse = (bidResponse, mediaType, assets) => {
let responseArray = [];
if (bidResponse) {
try {
Expand All @@ -61,14 +80,28 @@ export const getBannerResponse = (bidResponse, mediaType) => {
response.height = bidReq.h;
response.ad = bidReq.adm;
response.meta = {
advertiserDomains: bidReq.adomain
advertiserDomains: bidReq.adomain,
primaryCatId: bidReq.cat || [],
attr: bidReq.attr || []
};
response.creativeId = bidReq.crid;
response.netRevenue = false;
response.currency = 'USD';
response.ttl = 300;
response.dealId = bidReq.dealId;
response.mediaType = mediaType;
if (mediaType == 'native') {
let nativeResp = JSON.parse(bidReq.adm).native;
let nativeData = {
clickUrl: nativeResp.link.url,
impressionTrackers: nativeResp.imptrackers
};
nativeResp.assets.forEach(asst => {
let data = getNativeAssestData(asst, assets);
nativeData[data.key] = data.value;
});
response.native = nativeData;
}
responseArray.push(response);
});
}
Expand All @@ -78,13 +111,18 @@ export const getBannerResponse = (bidResponse, mediaType) => {
}
return responseArray;
}
// Function to get imp
// Function to get imp based on Media Type
const getImpDetails = (bidReq) => {
let imp = {};
if (bidReq) {
imp.id = bidReq.bidId;
imp.bidfloor = getFloorPrice(bidReq);
imp.banner = getBannerDetails(bidReq);
if (bidReq.mediaTypes.native) {
let assets = { assets: NATIVE_ASSETS };
imp.native = { request: JSON.stringify(assets) };
} else if (bidReq.mediaTypes.banner) {
imp.banner = getBannerDetails(bidReq);
}
}
return imp;
}
Expand Down Expand Up @@ -137,3 +175,64 @@ const getUserDetails = (bidReq) => {
}
return user;
}
// Function to get asset data for response
const getNativeAssestData = (params, assets) => {
let response = {};
if (params.title) {
response.key = 'title';
response.value = params.title.text;
}
if (params.data) {
response.key = getAssetData(params.id, assets);
response.value = params.data.value;
}
if (params.img) {
response.key = getAssetImageDataType(params.id, assets);
response.value = {
url: params.img.url,
height: params.img.h,
width: params.img.w
}
}
return response;
}
// Function to get asset data types based on id
const getAssetData = (paramId, asset) => {
let resp = '';
for (let i = 0; i < asset.length; i++) {
if (asset[i].id == paramId) {
switch (asset[i].data.type) {
case 1 : resp = 'sponsored';
break;
case 2 : resp = 'desc';
break;
case 12 : resp = 'cta';
break;
}
}
}
return resp;
}
// Function to get image type based on the id
const getAssetImageDataType = (paramId, asset) => {
let resp = '';
for (let i = 0; i < asset.length; i++) {
if (asset[i].id == paramId) {
switch (asset[i].img.type) {
case 1 : resp = 'icon';
break;
case 3 : resp = 'image';
break;
}
}
}
return resp;
}
// Function to get Media Type
const getMediaType = (bidReq) => {
if (bidReq.mediaTypes.native) {
return 'native';
} else if (bidReq.mediaTypes.banner) {
return 'banner';
}
}
41 changes: 41 additions & 0 deletions modules/tapnativeBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
BANNER,
NATIVE
} from '../src/mediaTypes.js';
import {
registerBidder
} from '../src/adapters/bidderFactory.js';
import {
getBannerRequest,
getBannerResponse,
getNativeResponse,
} from '../libraries/audUtils/bidderUtils.js';

const ENDPOINT = 'https://rtb-east.tapnative.com/hb';
// Export const spec
export const spec = {
code: 'tapnative',
supportedMediaTypes: [BANNER, NATIVE],
// Determines whether or not the given bid request is valid
isBidRequestValid: function(bidParam) {
return !!(bidParam.params.placement_id);
},
// Make a server request from the list of BidRequests
buildRequests: function(bidRequests, serverRequest) {
// Get Requests based on media types
return getBannerRequest(bidRequests, serverRequest, ENDPOINT);
},
// Unpack the response from the server into a list of bids.
interpretResponse: function(serverResponse, serverRequest) {
let bidderResponse = {};
const mType = JSON.parse(serverRequest.data)[0].MediaType;
if (mType == BANNER) {
bidderResponse = getBannerResponse(serverResponse, BANNER);
} else if (mType == NATIVE) {
bidderResponse = getNativeResponse(serverResponse, serverRequest, NATIVE);
}
return bidderResponse;
}
}

registerBidder(spec);
61 changes: 61 additions & 0 deletions modules/tapnativeBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Overview

```
Module Name: Tapnative Bidder Adapter
Module Type: Bidder Adapter
Maintainer: support@tapnative.com
```

# Description

Tapnative currently supports the BANNER and NATIVE type ads through prebid js

Module that connects to tapnative's demand sources.

# Test Request
```
var adUnits = [
{
code: 'display-ad',
mediaTypes: {
banner: {
sizes: [[300, 250]],
}
}
bids: [
{
bidder: 'tapnative',
params: {
placement_id: 111520, // Required parameter
width: 300, // Optional parameter
height: 250, // Optional parameter
bid_floor: 0.5 // Optional parameter
}
}
]
},
{
code: 'native-ad-container',
mediaTypes: {
native: {
title: { required: true, len: 100 },
image: { required: true, sizes: [300, 250] },
sponsored: { required: false },
clickUrl: { required: true },
desc: { required: true },
icon: { required: false, sizes: [50, 50] },
cta: { required: false }
}
},
bids: [
{
bidder: 'tapnative',
params: {
placement_id: 111519, // Required parameter
bid_floor: 1 // Optional parameter
}
}
]
}
];
```
Loading

0 comments on commit 4cc7d25

Please sign in to comment.