Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added Engageya bid adapter #6109

Merged
merged 4 commits into from
Dec 21, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions modules/engageyaBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {
BANNER,
NATIVE
} from '../src/mediaTypes.js';

const {
registerBidder
} = require('../src/adapters/bidderFactory.js');
const BIDDER_CODE = 'engageya';
const ENDPOINT_URL = 'https://recs.engageya.com/rec-api/getrecs.json';
const ENDPOINT_METHOD = 'GET';

function getPageUrl() {
var pUrl = window.location.href;
if (isInIframe()) {
pUrl = document.referrer ? document.referrer : pUrl;
}
pUrl = encodeURIComponent(pUrl);
return pUrl;
}

function isInIframe() {
try {
var isInIframe = (window.self !== window.top);
} catch (e) {
isInIframe = true;
}
return isInIframe;
}

export const _getUrlVars = function(url) {
aleksatr marked this conversation as resolved.
Show resolved Hide resolved
var hash;
var myJson = {};
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
myJson[hash[0]] = hash[1];
}
return myJson;
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, NATIVE],
isBidRequestValid: function(bid) {
return bid && bid.params && bid.params.hasOwnProperty('widgetId') && bid.params.hasOwnProperty('websiteId') && !isNaN(bid.params.widgetId) && !isNaN(bid.params.websiteId);
},

buildRequests: function(validBidRequests, bidderRequest) {
var bidRequests = [];
if (validBidRequests && validBidRequests.length > 0) {
validBidRequests.forEach(function(bidRequest) {
if (bidRequest.params) {
var mediaType = bidRequest.hasOwnProperty('nativeParams') ? 1 : 2;
aleksatr marked this conversation as resolved.
Show resolved Hide resolved
var imageWidth = -1;
var imageHeight = -1;
if (bidRequest.sizes && bidRequest.sizes.length > 0) {
imageWidth = bidRequest.sizes[0][0];
imageHeight = bidRequest.sizes[0][1];
} else if (bidRequest.nativeParams && bidRequest.nativeParams.image && bidRequest.nativeParams.image.sizes) {
imageWidth = bidRequest.nativeParams.image.sizes[0];
imageHeight = bidRequest.nativeParams.image.sizes[1];
}

var widgetId = bidRequest.params.widgetId;
var websiteId = bidRequest.params.websiteId;
var pageUrl = (bidRequest.params.pageUrl && bidRequest.params.pageUrl != '[PAGE_URL]') ? bidRequest.params.pageUrl : '';
if (!pageUrl) {
pageUrl = (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : getPageUrl();
}
var bidId = bidRequest.bidId;
var finalUrl = ENDPOINT_URL + '?pubid=0&webid=' + websiteId + '&wid=' + widgetId + '&url=' + pageUrl + '&ireqid=' + bidId + '&pbtpid=' + mediaType + '&imw=' + imageWidth + '&imh=' + imageHeight;
if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprApplies && bidderRequest.consentString) {
finalUrl += '&is_gdpr=1&gdpr_consent=' + bidderRequest.consentString;
}
bidRequests.push({
url: finalUrl,
method: ENDPOINT_METHOD,
data: ''
});
}
});
}

return bidRequests;
},

interpretResponse: function(serverResponse, bidRequest) {
const bidResponses = [];
if (serverResponse.body && serverResponse.body.recs && serverResponse.body.recs.length > 0) {
var response = serverResponse.body;
var isNative = response.pbtypeId == 1;
response.recs.forEach(function(rec) {
var imageSrc = rec.thumbnail_path.indexOf('http') == -1 ? 'https:' + rec.thumbnail_path : rec.thumbnail_path;
if (isNative) {
bidResponses.push({
requestId: response.ireqId,
cpm: rec.ecpm,
width: response.imageWidth,
height: response.imageHeight,
creativeId: rec.postId,
currency: 'USD',
netRevenue: false,
ttl: 360,
native: {
title: rec.title,
body: '',
image: {
url: imageSrc,
width: response.imageWidth,
height: response.imageHeight
},
privacyLink: '',
clickUrl: rec.clickUrl,
displayUrl: rec.url,
cta: '',
sponsoredBy: rec.displayName,
impressionTrackers: [],
},
});
} else {
// var htmlTag = "<img src='https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png' style='position: absolute; left: 50%; top:50%; margin-left: -113px; margin-top:-79px;'>";
var htmlTag = '<html><div id="ENG_TAG"><a href="' + rec.clickUrl + '" target=_blank><img src="' + imageSrc + '" style="width:' + response.imageWidth + 'px;height:' + response.imageHeight + 'px;"/></a></div></html>';
var tag = rec.tag ? rec.tag : htmlTag;
bidResponses.push({
requestId: response.ireqId,
cpm: rec.ecpm,
width: response.imageWidth,
height: response.imageHeight,
creativeId: rec.postId,
currency: 'USD',
netRevenue: false,
ttl: 360,
ad: tag,
});
}
});
}

return bidResponses;
}
};

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

```
Module Name: Engageya's Bidder Adapter
Module Type: Bidder Adapter
Maintainer: reem@engageya.com
```

# Description

Module that connects to Engageya's demand sources

# Test Parameters
```
var adUnits = [
{
code: 'test-div',
mediaTypes: {
banner: {
sizes: [[300, 250]], // a display size
}
},
bids: [
{
bidder: "engageya",
params: {
widgetId: '<put here widget id>',
aleksatr marked this conversation as resolved.
Show resolved Hide resolved
websiteId: '<put here website id>',
pageUrl:[PAGE_URL]
aleksatr marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
},{
code: 'test-div',
mediaTypes: {
native: {
image: {
required: true,
sizes: [236, 202]
},
title: {
required: true,
len: 80
},
sponsoredBy: {
required: true
},
clickUrl: {
required: true
},
body: {
required: true
}
}
},
bids: [
{
bidder: "engageya",
params: {
widgetId: '<put here widget id>',
websiteId: '<put here website id>',
pageUrl:[PAGE_URL]
}
}
]
}
];
```
150 changes: 150 additions & 0 deletions test/spec/modules/engageyaBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import {expect} from 'chai';
import {spec, _getUrlVars} from 'modules/engageyaBidAdapter.js';
import * as utils from 'src/utils.js';

const ENDPOINT_URL = 'https://recs.engageya.com/rec-api/getrecs.json';

describe('engageya adapter', function() {
let bidRequests;
let nativeBidRequests;

beforeEach(function() {
bidRequests = [
{
bidder: 'engageya',
params: {
widgetId: 85610,
websiteId: 91140,
pageUrl: '[PAGE_URL]'
}
}
]

nativeBidRequests = [
{
bidder: 'engageya',
params: {
widgetId: 85610,
websiteId: 91140,
pageUrl: '[PAGE_URL]'
},
nativeParams: {
title: {
required: true,
len: 80
},
image: {
required: true,
sizes: [150, 50]
},
sponsoredBy: {
required: true
}
}
}
]
})
describe('isBidRequestValid', function () {
it('valid bid case', function () {
let validBid = {
bidder: 'engageya',
params: {
widgetId: 85610,
websiteId: 91140,
pageUrl: '[PAGE_URL]'
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});

it('invalid bid case: widgetId and websiteId is not passed', function() {
let validBid = {
bidder: 'engageya',
params: {
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(false);
})

it('invalid bid case: widget id must be number', function() {
let invalidBid = {
bidder: 'engageya',
params: {
widgetId: '157746a',
websiteId: 91140,
pageUrl: '[PAGE_URL]'
}
}
let isValid = spec.isBidRequestValid(invalidBid);
expect(isValid).to.equal(false);
})
})

describe('buildRequests', function () {
it('sends bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(bidRequests)[0];
expect(request.url).to.include(ENDPOINT_URL);
expect(request.method).to.equal('GET');
});

it('buildRequests function should not modify original bidRequests object', function () {
let originalBidRequests = utils.deepClone(bidRequests);
let request = spec.buildRequests(bidRequests);
expect(bidRequests).to.deep.equal(originalBidRequests);
});

it('buildRequests function should not modify original nativeBidRequests object', function () {
let originalBidRequests = utils.deepClone(nativeBidRequests);
let request = spec.buildRequests(nativeBidRequests);
expect(nativeBidRequests).to.deep.equal(originalBidRequests);
});

it('Request params check', function() {
let request = spec.buildRequests(bidRequests)[0];
const data = _getUrlVars(request.url)
expect(parseInt(data.wid)).to.exist.and.to.equal(bidRequests[0].params.widgetId);
expect(parseInt(data.webid)).to.exist.and.to.equal(bidRequests[0].params.websiteId);
})
})

describe('interpretResponse', function () {
let response = {recs: [
{
'ecpm': 0.0920,
'postId': '<!-- CREATIVE ID -->',
'ad': '<!-- ADS TAG -->',
'thumbnail_path': 'https://engageya.live/wp-content/uploads/2019/05/images.png'
}
],
imageWidth: 300,
imageHeight: 250,
ireqId: '1d236f7890b',
pbtypeId: 2};

it('should get correct bid response', function () {
let expectedResponse = [
{
'requestId': '1d236f7890b',
'cpm': 0.0920,
'width': 300,
'height': 250,
'netRevenue': false,
'currency': 'USD',
'creativeId': '<!-- CREATIVE ID -->',
'ttl': 700,
'ad': '<!-- ADS TAG -->'
}
];
let request = spec.buildRequests(bidRequests)[0];
let result = spec.interpretResponse({body: response}, request);
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
expect(result[0].cpm).to.not.equal(null);
expect(result[0].creativeId).to.not.equal(null);
expect(result[0].ad).to.not.equal(null);
expect(result[0].currency).to.equal('USD');
expect(result[0].netRevenue).to.equal(false);
});
})
})