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

add adot bidder adapter #4949

Merged
merged 2 commits into from
Apr 7, 2020
Merged

add adot bidder adapter #4949

merged 2 commits into from
Apr 7, 2020

Conversation

mlequain
Copy link
Contributor

@mlequain mlequain commented Mar 9, 2020

Type of change

  • New bidder adapter

Description of change

Add adot bidder adapter

  • test parameters for validating bids
{
  bidder: 'adot',
  params: {
    placementId: 'adot_prebidjs_integration'
  }
}

Be sure to test the integration with your adserver using the Hello World sample page.

  • contact email of the adapter’s maintainer: [email protected]
  • official adapter submission

For any changes that affect user-facing APIs or example code documented on http://prebid.org, please provide:

Copy link
Collaborator

@jsnellbaker jsnellbaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mlequain

Thank you for submitting this new adapter. There are a few things that I observed that need to be initially addressed since they're causing errors or aren't supported by the Prebid.js project.

Can you please take a look when you can?

Thanks!

const NET_REVENUE = true;
// eslint-disable-next-line no-template-curly-in-string
const AUCTION_PRICE = '${AUCTION_PRICE}';
const OUTSTREAM_VIDEO_PLAYER_URL = 'http://adserver.adotmob.com/video/player.min.js';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This host path should be secure.

Comment on lines 29 to 47
function isObject(value) {
return (value !== null) && (typeof (value) === 'object') && !isArray(value);
}

function isArray(value) {
return Array.isArray(value);
}

function isString(value) {
return (typeof (value) === 'string');
}

function isNumber(value) {
return (typeof (value) === 'number');
}

function isBoolean(value) {
return (typeof (value) === 'boolean');
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these functions can be found in the src/utils.js file under similar names. It may ideal (and save some space in your adapter) to use those instead.

Comment on lines 53 to 66
function groupBy(values, key) {
const groups = values.reduce((acc, value) => {
const groupId = value[key];

if (!acc[groupId]) acc[groupId] = [];
acc[groupId].push(value);

return acc;
}, {});

return Object
.entries(groups)
.map(([id, values]) => ({id, key, values}));
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a similar function available in the src/utils.js, could you review that function to see if it would meet your needs here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function in the src/utils.js does not format the values the same way unfortunately. Do you want me to rename the method to avoid confusion ?

Comment on lines +110 to +112
return isArray(mediaSize) &&
(mediaSize.length === 2) &&
mediaSize.every(size => (isNumber(size) && size >= 0));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a function in the src/utils.js named isArrayOfNums that I believe basically the same type of check here. Perhaps you could use it instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with isArrayOfNums is that it does not check if the value is superior to 0.

const base = {bidId, adUnitCode, container: params.video && params.video.container};

const imps = Object
.entries(mediaTypes)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property is not supported in IE11. Is there an alternative you can use instead?

if (!isObject(bid.ext)) return false;
if (!isObject(bid.ext.adot)) return false;
if (!isString(bid.ext.adot.media_type)) return false;
if (!BID_SUPPORTED_MEDIA_TYPES.includes(bid.ext.adot.media_type)) return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see earlier note.

if (!bid.adm && !bid.nurl) return false;
if (bid.adm) {
if (!isString(bid.adm)) return false;
if (!bid.adm.includes(AUCTION_PRICE)) return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see earlier note.

}
if (bid.nurl) {
if (!isString(bid.nurl)) return false;
if (!bid.nurl.includes(AUCTION_PRICE)) return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see earlier note.

const allowedBidderCodes = [this.code];

return isObject(adUnit) &&
allowedBidderCodes.includes(adUnit.bidder) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see earlier note.

Comment on lines 2 to 4
import { executeRenderer } from 'src/Renderer';
import * as utils from 'src/utils';
import { spec } from 'modules/adotBidAdapter';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include the .js extension on these imports as well (eg. src/Renderer.js).

@mlequain
Copy link
Contributor Author

@jsnellbaker I've updated the code to address the issues you mentioned in your previous comment.

Let me know if there is anything that I missed or if you want me to change anything else.

@stale
Copy link

stale bot commented Mar 26, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Mar 26, 2020
@jsnellbaker jsnellbaker removed the stale label Mar 26, 2020
Copy link
Collaborator

@jsnellbaker jsnellbaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mlequain

Sorry for the delay here; thank you for making the updates. I looked through again, and it looks better. There is another function that needs to be updated because it's not available in IE11. I made a suggestion for an alternative, please see the comment below.

Additionally, when I tried to test the adapter with the params provided in the description - the endpoint didn't appear to be returning a response. The endpoint returned a 204 No Content response.

I copied the request payload in case that may be a factor:

{"id":"1693a3242bca91","imp":[{"id":"2540029fc5df2c_0_0","banner":{"format":[{"w":300,"h":250}],"w":300,"h":250,"pos":0},"pmp":{"deals":[{"id":"adot_prebidjs_integration"}]}},{"id":"2540029fc5df2c_0_1","banner":{"format":[{"w":300,"h":600}],"w":300,"h":600,"pos":0},"pmp":{"deals":[{"id":"adot_prebidjs_integration"}]}}],"site":{"page":"http://test.localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true","domain":"test.localhost:9999","name":"test.localhost:9999"},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36","language":"en-US"},"user":null,"regs":null,"at":1,"ext":{"adot":{"adapter_version":"v1.0.0"},"should_use_gzip":true}}

Can you please take a look? We need to have a valid test bid to verify new adapters to ensure the end-to-end workflow is working properly.

In addition, you have some example test params for native and both video (outstream and instream) that I can use to test?

Please let me know if you have any questions about the above. Thanks!

Comment on lines 427 to 428
const openRTBImpression = serverRequest.data.imp.find(imp => imp.id === impressionId);
const internalImpression = serverRequest._adot_internal.impressions.find(imp => imp.impressionId === impressionId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The find function isn't directly supported in IE11. There is an alternative polyfill you can import to use instead.

The import path would look like:

import find from 'core-js/library/fn/array/find.js';

You can refer to the appnexusBidAdapter.js to see some examples of how it's used (like here).

@mlequain
Copy link
Contributor Author

mlequain commented Apr 3, 2020

Hi @jsnellbaker

Sorry for the late reply.

I've updated the code to remove the calls to find and use the polyfill instead, let me know if everything is OK.

Below you'll find the adUnits you can use to test the video (outstream & instream) as well as the native.

Instream adUnit

const adUnit = {
    code: 'test-div',
    mediaTypes: {
        video: {
            context: 'instream',
            playerSize: [[300, 250]]
        }
    },
    bids: [{
        bidder: 'adot',
        params: {
            video: {
                mimes: ['video/mp4'],
                minDuration: 5,
                maxDuration: 35,
                protocols: [2, 3],
                instreamContext: 'pre-roll'
            },
            placementId: 'adot_prebidjs_integration'
        }
    }]
}

Outstream adUnit

const adUnit = {
    code: 'test-div',
    mediaTypes: {
        video: {
            context: 'outstream',
            playerSize: [[300, 250]]
        }
    },
    bids: [{
        bidder: 'adot',
        params: {
            video: {
                mimes: ['video/mp4'],
                minDuration: 5,
                maxDuration: 35,
                protocols: [2, 3]
            },
            placementId: 'adot_prebidjs_integration'
        }
    }]
}

Native adUnit

const adUnit = {
    code: 'test-div',
    mediaTypes: {
        native: {
                image: {
                    required: false,
                    sizes: [100, 50]
                },
                title: {
                    required: false,
                    len: 140
                },
                sponsoredBy: {
                    required: false
                },
                clickUrl: {
                    required: false
                },
                body: {
                    required: false
                },
                icon: {
                    required: false,
                    sizes: [50, 50]
                }
        }
    },
    bids: [{
        bidder: 'adot',
        params: {
    	    placementId: 'adot_prebidjs_integration'
        }
    }]
}

@jsnellbaker
Copy link
Collaborator

Hi @mlequain

Thanks for providing the updated information. I checked through each of the mediaTypes.

Please see below for my feedback:

  • Banner > working fine.
  • Instream > it appears that the created bid does not have its vastXml and/or vastUrl populated. I did observe there was a key named adUrl with what looked like a vastUrl value. If that is the ad payload, this should be assigned to the vastUrl field instead. In its current state, the bid is getting rejected by Prebid since it doesn't have the expected vast properties defined.
  • Outstream > it appears that the bid information was being passed to the bid's renderer. I didn't physically see the player appear on the page, but that may just be the page itself. If you're sure the outstream code works in your test pages, then this is fine.
  • Native > I'm not seeing a bid return from the endpoint (response is just a 204 No Content). I have copied the request payload for review:
{"id":"1116802233e543","imp":[{"id":"2dc85247667e9_0","native":{"request":"{\"assets\":[]}"},"pmp":{"deals":[{"id":"adot_prebidjs_integration"}]}}],"site":{"page":"http://test.localhost:9999/integrationExamples/gpt/demo_native.html?pbjs_debug=true","domain":"test.localhost:9999","name":"test.localhost:9999"},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36","language":"en-US"},"user":null,"regs":null,"at":1,"ext":{"adot":{"adapter_version":"v1.0.0"},"should_use_gzip":true}}

Can you take a look to see why the native bid isn't returning and about the feedback on the instream?

@mlequain
Copy link
Contributor Author

mlequain commented Apr 6, 2020

Hi @jsnellbaker

I have updated the code to make sure we either return a vastUrl or a vastXml for all the video bids, the instream video should now be returning a valid prebid ad.

The outstream video is working fine on my end.

I managed to bid on the native ad using your bid request, let me know if it's working on your end as well.

@jsnellbaker
Copy link
Collaborator

@mlequain

Thanks for the follow-up. I retested the video instream and saw it was working.

However, I tried the native test again, but I'm still not seeing a bid return.

I noticed the sample params had an extra native object under the mediaTypes. When I removed that, I saw the native asset data was properly added to the imp[0].native.request.assets (where before it wasn't). But this didn't appear to help return a bid.

I have copied the updated request payload below, can you take a look and advise?

{"id":"1d746d3476ea1e","imp":[{"id":"2ba0032f0a9c5a_0","native":{"request":"{\"assets\":[{\"id\":3,\"required\":false,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":50}},{\"id\":1,\"required\":false,\"title\":{\"len\":140}},{\"id\":4,\"required\":false,\"data\":{\"type\":1}},{\"id\":5,\"required\":false,\"data\":{\"type\":2}},{\"id\":2,\"required\":false,\"img\":{\"type\":1,\"wmin\":50,\"hmin\":50}}]}"},"pmp":{"deals":[{"id":"adot_prebidjs_integration"}]}}],"site":{"page":"http://test.localhost:9999/integrationExamples/gpt/demo_native.html?pbjs_debug=true","domain":"test.localhost:9999","name":"test.localhost:9999"},"device":{"ua":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1","language":"en-US"},"user":null,"regs":null,"at":1,"ext":{"adot":{"adapter_version":"v1.0.0"},"should_use_gzip":true}}

@mlequain
Copy link
Contributor Author

mlequain commented Apr 7, 2020

@jsnellbaker

I have updated the adapter documentation and my previous comment to fix the mistake in the native snippet.

I have also updated some targeting parameters on my end and I'm seeing bids for the native ad using your bid request.

Let me know if everything is working on your end.

Thanks a lot

@jsnellbaker
Copy link
Collaborator

@mlequain Thanks for the additional update, I am getting a native bid back now. LGTM

@jsnellbaker jsnellbaker merged commit 73d5861 into prebid:master Apr 7, 2020
@mlequain
Copy link
Contributor Author

mlequain commented Apr 7, 2020

@jsnellbaker Thanks a lot for your help !

rjvelicaria pushed a commit to openx/Prebid.js that referenced this pull request Apr 9, 2020
* add adot bidder adapter

* remove promises and other methods to ensure IE11 compatibility and remove duplicate code

Co-authored-by: Maxime Lequain <[email protected]>
iggyfisk pushed a commit to happypancake/Prebid.js that referenced this pull request Jun 22, 2020
* add adot bidder adapter

* remove promises and other methods to ensure IE11 compatibility and remove duplicate code

Co-authored-by: Maxime Lequain <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants