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

Conversant: Move adapter and add ccpa support #163

Merged
merged 1 commit into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions conversant/CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 2.3.0
- Added USP (CCPA) support to bidder
- Use impid for matching requests
79 changes: 79 additions & 0 deletions conversant/DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# conversant
## General Compatibility
|Feature| |
|---|---|
| Consent | Yes |
| Native Ad Support | No |
| SafeFrame Support | Yes |
| PMP Support | No |

## Browser Compatibility
| Browser | |
|--- |---|
| Chrome | Yes |
| Edge | Yes |
| Firefox | Yes |
| Internet Explorer 9 | |
| Internet Explorer 10 | Yes |
| Internet Explorer 11 | Yes |
| Safari | Yes |
| Mobile Chrome | Yes |
| Mobile Safari | Yes |
| UC Browser | |
| Samsung Internet | Yes |
| Opera | Yes |

## Adapter Information
| Info | |
|---|---|
| Partner Id | ConversantHtb |
| Ad Server Responds in (Cents, Dollars, etc) | Dollars |
| Bid Type (Gross / Net) | Net |
| GAM Key (Open Market) | ix_conv_cpm |
| GAM Key (Private Market) | ix_conv_cpm |
| Ad Server URLs | web.hb.ad.cpe.dotomi.com |
| Slot Mapping Style (Size / Multiple Sizes / Slot) | Slot |
| Request Architecture (MRA / SRA) | SRA |

## Currencies Supported
USD
## Bid Request Information
### Parameters
| Key | Required | Type | Description |
|---|---|---|---|
| | | | |

### Example
```javascript

```

## Bid Response Information
### Bid Example
```javascript

```
### Pass Example
```javascript

```

## Configuration Information
### Configuration Keys
| Key | Required | Type | Description |
|---|---|---|---|
| siteId | Yes | String | Conversant site id |
| sizes | Yes | Array of 2 element arrays | List of ad sizes |
| placementId | No | String | placement id |
| bidfloor | No | Number | Optional bid floor |
| position | No | Number | Ad position on screen |
### Example
```javascript

```

## Test Configuration
(Test configuration or methodology that can be used to retrieve & render a test creative from conversant's platform)
```javascript

```
13 changes: 13 additions & 0 deletions conversant/conversant-htb-exports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* This file contains any necessary functions that need to be exposed to the outside world.
* Things like (render functions) will be exposed by adding them to the shellInterface variable, under the partners
* profile name. This function will then be accessible through the window.headertag.ConversantHtb object.
* If necessary for backwards compatibility with old creatives, you can also add things directly to the
* window namespace here, but this is discouraged if it's not strictly needed.
*/

//? if(FEATURES.GPT_LINE_ITEMS) {
shellInterface.ConversantHtb = {
render: SpaceCamp.services.RenderService.renderDfpAd.bind(null, 'ConversantHtb')
};
//? }
166 changes: 166 additions & 0 deletions conversant/conversant-htb-system-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
'use strict';

function getPartnerId() {
return 'ConversantHtb';
}

function getStatsId() {
return 'CONV';
}

function getCallbackType() {
return 'NONE';
}

function getArchitecture() {
return 'SRA';
}

function getBidRequestRegex() {
return {
method: 'POST',
urlRegex: /web\.hb\.ad\.cpe\.dotomi\.com\/s2s\/header\/24/
};
}

function getConfig() {
return {
siteId: '108060',
xSlots: {
1: {
placementId: '54321',
sizes: [[300, 250], [180, 150]]
},
2: {
placementId: '12345',
sizes: [[120, 600]],
position: 1,
bidfloor: 0.01
}
}
};
}

function validateBidRequest(request) {
expect(request.host).toEqual('web.hb.ad.cpe.dotomi.com');

var config = getConfig();
var slotKeys = Object.keys(config.xSlots);
expect(request.body).toBeDefined();

var body = JSON.parse(request.body);
expect(body.id).toBeDefined();

slotKeys.forEach(function (value, idx) {
var slot = config.xSlots[value];
var imp = body.imp[idx];
slot.sizes.forEach(function (arr, arrIdx) {
expect(imp.banner.format[arrIdx].w).toEqual(arr[0]);
expect(imp.banner.format[arrIdx].h).toEqual(arr[1]);
});
expect(imp.displaymanager).toEqual('40834-index-client');
expect(imp.tagid).toEqual(slot.placementId);
});

expect(body.imp[1].banner.pos).toEqual(1);
expect(body.imp[1].bidfloor).toEqual(0.01);

expect(body.site.id).toEqual('108060');
expect(body.site.page).toEqual(jasmine.any(String));
expect(body.at).toEqual(1);

expect(body.device).toBeDefined();
expect(body.device.ua).toEqual(jasmine.any(String));
expect(body.regs.ext.gdpr).toEqual(jasmine.any(Number));
expect(body.user.ext.consent).toEqual(jasmine.any(String));
}

function getValidResponse(request, creative) {
var body = JSON.parse(request.body);
var response = {
seatbid: [
{
bid: [
{
adm: creative,
crid: '2101274',
impid: body.imp[0].id,
price: 2,
w: 300,
h: 250,
adomain: ['https://na13.salesforce.com'],
iurl: 'http://media.fastclick.net/win.bid',
id: 'htSlot1_0'
},
{
adm: creative,
crid: '2166499',
impid: body.imp[1].id,
price: 2,
w: 120,
h: 600,
adomain: ['https://na13.salesforce.com'],
iurl: 'http://media.fastclick.net/win.bid',
id: 'htSlot1_1'
}
]
}
],
id: '_jjzp7ar12'
};

return JSON.stringify(response);
}

function validateTargeting(targetingMap) {
expect(targetingMap).toEqual(jasmine.objectContaining({
ix_conv_cpm: jasmine.arrayContaining([jasmine.stringMatching(/300x250_\d+/), jasmine.stringMatching(/120x600_\d+/)]),
ix_conv_id: jasmine.arrayContaining([jasmine.any(String)])
}));
}

function getPassResponse(request) {
var body = JSON.parse(request.body);
var response = {
seatbid: [
{
bid: [
{
impid: body.imp[0].id,
price: 0.0000,
id: 'htSlot1_0'
},
{
impid: body.imp[1].id,
price: 0.0000,
id: 'htSlot1_1'
}
]
}
],
id: '_jjzp7ar12'
};

return JSON.stringify(response);
}

function validateBidRequestWithPrivacy(request) {
var body = JSON.parse(request.body);

expect(body.regs.ext.gdpr).toEqual(1);
expect(body.user.ext.consent).toEqual('TEST_GDPR_CONSENT_STRING');
}

module.exports = {
getPartnerId: getPartnerId,
getStatsId: getStatsId,
getCallbackType: getCallbackType,
getArchitecture: getArchitecture,
getConfig: getConfig,
getBidRequestRegex: getBidRequestRegex,
validateBidRequest: validateBidRequest,
getValidResponse: getValidResponse,
getPassResponse: getPassResponse,
validateTargeting: validateTargeting,
validateBidRequestWithPrivacy: validateBidRequestWithPrivacy
};
96 changes: 96 additions & 0 deletions conversant/conversant-htb-validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* @author: Partner
* @license: UNLICENSED
*
* @copyright: Copyright (c) 2017 by Index Exchange. All rights reserved.
*
* The information contained within this document is confidential, copyrighted
* and or a trade secret. No part of this document may be reproduced or
* distributed in any form or by any means, in whole or in part, without the
* prior written permission of Index Exchange.
*/

/**
* This file contains the necessary validation for the partner configuration.
* This validation will be performed on the partner specific configuration object
* that is passed into the wrapper. The wrapper uses an outside library called
* schema-insepctor to perform the validation. Information about it can be found here:
* https://atinux.fr/schema-inspector/.
*/

'use strict';

////////////////////////////////////////////////////////////////////////////////
// Dependencies ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

var Inspector = require('../../../libs/external/schema-inspector.js');

// Var Inspector = require('schema-inspector');

////////////////////////////////////////////////////////////////////////////////
// Main ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function partnerValidator(configs) {
var result = Inspector.validate({
type: 'object',
properties: {
siteId: {
type: 'string',
minLength: 1
},
xSlots: {
type: 'object',
properties: {
'*': {
type: 'object',
properties: {
placementId: {
type: 'string',
minLength: 1,
optional: true
},
sizes: {
type: 'array',
items: {
type: 'array',
exactLength: 2,
items: {
type: 'integer'
}
}
},
bidfloor: {
type: 'number',
optional: true
},
position: {
type: 'integer',
optional: true
}
}
}
}
},
mapping: {
type: 'object',
properties: {
'*': {
type: 'array',
items: { type: 'string' },
minLength: 1
}
}
}
}
}, configs);

if (!result.valid) {
return result.format();
}

return null;
}

module.exports = partnerValidator;
Loading