prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.28k stars 2.05k forks source link

How to integrate APS and Prebid.js for video? #10031

Closed spormeon closed 1 year ago

spormeon commented 1 year ago

Type of issue

potential bug, reopening from a previous issue that got closed, as now produced test pages , so you can see etc

Description

we cant get mergeConfig to work at all

Steps to reproduce

here is a test page with mergeConfig NOT working: mergeConfig is set before setConfig: https://cdn.adysis.com/VideoDemo/DemoSite/pages/mergeconfignotworking.html

here is a test page with the custom params set in setConfig, mergeConfig is set before setConfig, this works: https://cdn.adysis.com/VideoDemo/DemoSite/pages/mergeconfignotworkingparamssetinconfig.html

here is a test page with mergeConfig set after setConfig, this doesnt work and completely stops the video from even playing https://cdn.adysis.com/VideoDemo/DemoSite/pages/mergeconfignotworkingaftersetconfig.html

Test page

see above

Expected results

mergeConfig should merge the params set into setConfig

DevTools_-_cdn_adysis_com_VideoDemo_DemoSite_pages_mergeconfignotworking_html_and_mergeconfignotworkingparamssetinconfig_html_—_Prebid_Publishers__Workspace_

Actual results

nothing happens, no custom_params set

Platform details

mac, chrome, P V 7.47.0

Other information

reopening from a previous issue that got closed, as now produced test pages , so you can see etc

dgirardi commented 1 year ago

This happens because arrays are merged by concatenation.

Doing this:

pbjs.setConfig({
  video: {
    providers: [{
      divId: 'player',
      vendorCode: 2,
      // ...
   }]
 }
});

pbjs.mergeConfig({
  video: {
    providers: [{
      adServer: {
         params: {
            someparam: 'addcustomparam'
            // ...
         }
      }
    }]
  }
})

Is equivalent to:

pbjs.setConfig({
  video: {
    providers: [
       {
         divId: 'player',
         vendorCode: 2,
         // ...
       },
       {
         adServer: {
           params: {
             someparam: 'addcustomparam'
             // ...
           }
          }
       }
    ]
  }
})

which is not what you want, but also not easily fixable. mergeConfig does not know that your intention is to modify the first provider instead of just merging in more providers, and allowing that would need a more complex API.

Without knowing more about your use case, my suggestion is to do something like

const videoConfig = pbjs.getConfig('video');
Object.assign(videoConfig.providers[0], {
   adServer: {
      params: {
        someparam: 'addcustomparam'
        // ...
      }        
   }
});

pbjs.setConfig({video: videoConfig})
spormeon commented 1 year ago

after a chat with @dgirardi on slack, he thinks there maybe a some race going on that Amazon doesn't return before the ima url is getting set. The intention of this is for amazon bids, so as to call amazon and return the amazon params, push to the "video module" cust_params, so as the video module can build the AdTagUrl with amazon params added on it.
Such as these ( these are amazon test bid params):

cust_params: {
                      amznbid: 'v_testBid',
                      amznbid_sp: 'testBidSP',
                      amzndeal_sp: '',
                      amzndeals: 'testDeal3956489305171677022276867_x',
                      amzniid: 'testImpression-5200554465021677022276867',
                      amzniid_sp: 'testImpression-8448474244271677022276867',
                      amznp: 'testP',
                      amznp_sp: 'testPSP',
                      amznsz: 'x',
                      amznsz_sp: 'x',
                      testDeal3956489305171677022276867_xamzniid: 'testDealIi-5141855808061677022276867'
                  },
spormeon commented 1 year ago

@dgirardi wrote some code to try and get to work and I've tried every which way i can think of, to the point where we can get setConfig to set by uisng this:

const videoConfig = adyjs.getConfig('video');
                    Object.assign(videoConfig.providers[0], {
                        adServer: {
                            vendorCode: 'gam',
                            baseAdTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?cust_params=amzniid%3DtestImpression-1554089775921680177152353%26amznbid%3Dv_testBid%26amznp%3DtestP%26amznsz%3Dx%26amzniid_sp%3DtestImpression-1129352581991680177152353%26amznbid_sp%3DtestBidSP%26amznp_sp%3DtestPSP%26amznsz_sp%3Dx%26amzndeal_sp%3D%26amzndeals%3DtestDeal6897548601581680177152353_x%26testDeal6897548601581680177152353_xamzniid%3DtestDealIi-3586134383691680177152353',

    params: {
         ciu_sz: "fluid|728x90,fluid|300x250,fluid|180x150,fluid|120x60,fluid|88x31,fluid|300x60,fluid|300x100,fluid|320x50,fluid|468x60,fluid|300x600,fluid|160x600",
                                description_url: "%5Bdescription_url%5D",
                                impl: "s",
                                iu: "SOMETAG",
                                output: "vast",
                                sz: "1x1|48x27|96x54|162x91|175x98|180x101|185x104|194x109|195x109|196x110|200x446|201x113|208x117|220x90|240x133|250x360|288x162|292x30|300x31|300x169|300x197|300x385|300x1050|301x170|307x173|312x176|313x176|319x180|320x100|320x180|326x184|330x186|340x192|341x192|353x250|360x203|361x203|362x204|363x205|368x207|373x210|375x211|377x212|390x219|400x225|400x300|404x227|412x232|414x233|480x320|550x310|580x400|600x338|640x360|640x390|640x480|750x100|750x200|750x300|930x180|950x90|960x90|970x66|970x250|980x90|980x120|1280x720|1280x720|1600x1050|1800x1000",
                                url: "https%3A%2F%2Fgoogleads.github.io%2Fgoogleads-ima-html5%2Fvsi%2F",
                                cust_params: custParams
                            }        
                        }
                    });

 adyjs.setConfig({video: videoConfig})

you can even see setconfig in consolue:
DevTools_-_cdn_adysis_com_VideoDemo_DemoSite_pages_demitryAmazon_html

but it then stops the ima adtagurl from being built: DevTools_-_cdn_adysis_com_VideoDemo_DemoSite_pages_demitryAmazon_html_and_demitryAmazon_html_—_Prebid_Publishers__Workspace_

I also tried with a bidsBackHandler such as:

pbjs.requestBids({
    bidsBackHandler: function(bids) {
        var videoUrl = pbjs.adServers.dfp.buildVideoUrl({
            adUnit: videoAdUnit,
            params: {
                iu: '/19968336/prebid_cache_video_adunit',
                cust_params: {
                    section: "blog",
                    anotherKey: "anotherValue"
                },
                hl: "en",
                output: "xml_vast2",
                url: "https://www.example.com",
            }
        });
        invokeVideoPlayer(videoUrl);
    }
});

there is mention in the video module of the bidsbackhandler not working on render, but no clue it it doesnt work at all with video module

@karimMourra it might need your wisdom on it, as I'm completey stumped

bweiss-freestar commented 1 year ago

@spormeon are you trying to load instream or outstream?

spormeon commented 1 year ago

@bweiss-freestar its instream

fowler446 commented 1 year ago

@spormeon Is this an issue about APS or about mergeConfig? When it comes to integrating amazon APS it's as simple as taking the url that comes from dfp.buildVideoUrl and appending values for amazon. APS bids will have helper functions for encoding them. So you could get the encoded amazon kv pairs from their bid like so:

 bid.encodedQsParams || bid.helpers.encodedQsParams()

append those to your url from dfp.buildVideoUrl and you're off to the races!

I suggest you take a look at how getCustParams works in this particular module: https://github.com/prebid/Prebid.js/blob/master/modules/dfpAdServerVideo.js#L276

karimMourra commented 1 year ago

@spormeon I opened a PR adding a demo showing how to call bidsBackHandler when using the Video Module. Please let me know if this unblocks you https://github.com/prebid/Prebid.js/pull/10225/files#diff-935dda8ca4f21ee161244d8b3906abe463ac3b0a856210389c9833e60aa8af84

spormeon commented 1 year ago

@karimMourra Thanks, I'll see if I can get it working off this now

spormeon commented 1 year ago

@karimMourra we have tried to get this to work, but we cant get it to work with a "live"setup, when you turn debugging:false the videoUrl gets built but its not getting sent to GAM by the looks of it, we tried your method and the usual method from the pbjs.adServers.dfp.buildVideoUrl(options) page: https://docs.prebid.org/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html

both methods dont get sent to GAM, here is a test page so you can see. It bids, builds the videoUrl but not get sent to GAM:

https://cdn.adysis.com/VideoDemo/DemoSite/pages/BBH.html

I manged to get a bid and the videoUrl being built would def work if sent to GAM:

Google_Ad_Manager_-_Delivery_tools

spormeon commented 1 year ago

bit of an update, we can now get a bid to render when there "is a bid" from prebid and the videoUrl is built, but its not working when there is "no bid", which is whats needed, so as its still sent into GAm, for the adx to have the oportunty to take etc. Even with this rendereing when there is a bid, its still not sending intoGAM by looks: bidsBackHandlerOverride_html_—_Prebid_Publishers__Workspace_

spormeon commented 1 year ago

@karimMourra Any chance to have a look here?

karimMourra commented 1 year ago

@spormeon when there is no bid, dpf.buildVideoUrl returns null/undefined ? That doesn't sound right; you should investigate why you're not getting a valid ad tag url back from the dfp module

spormeon commented 1 year ago

@karimMourra correct, when there is no bid, "undefined" is returned, which is actually right, but your bidsbackhandler isnt pushing it to dfp, I presume because of something here: index_js_—_Prebid_js

This BBH only seems to work when there "is" a bid, where as the dfpvideomodule works when there is and isnt a bid. Which is what this should do in effect.

the undefined returned, The returned adtagurl pasted into GAM "delivery tools": Google_Ad_Manager_-_Delivery_tools

the adTagUrl built off of the page, in console: DevTools_-_cdn_adysis_com_VideoDemo_DemoSite_pages_BBH_html

spormeon commented 1 year ago

I think some of the problem might also be revolving around the "adTagUrl" is not being set here

karimMourra commented 1 year ago

@spormeon I don't understand what you're asking. If you want to implement a bidsBackHandler it's up to you to implement it in a way that works for your use case. What I've provided is just a demo, it's not meant to solve every possible issue that could be encountered in production. Also if the dfp module isn't returning an ad tag when there is no winning bid, then that sounds like a bug in the dfp module. That's unrelated to the Video Module.

spormeon commented 1 year ago

@karimMourra lets try again here, if you look at the demo page i put above, that is using the "normal dfpmodule" way of implementing a bidsbackhandler. This actually working in the respect that the "videoUrl" is returned, as its always been and as it should do. The problem is it doent "render/ push" to the player using the part of your demo code (which only works in "debugging, not in "production"

code that doesnt get the built videoUrl to the player: adyjs.videoModule.renderBid('player', videoUrl); the renderBid only seems to push bid.vasturl or bid.vastXml. I think this is whats stopping it as its not pushing adTagUrl/ baseAdTagUrl, which is only avaialble at adServer: { in the video module playlistUIvertical_html_—_Prebid_Publishers__Workspace_

How_to_integrate_APS_and_Prebid_js_for_video__·_Issue__10031_·_prebid_Prebid_js

demo page: https://cdn.adysis.com/VideoDemo/DemoSite/pages/BBH.html

code on demo page: view-source_https___cdn_adysis_com_VideoDemo_DemoSite_pages_BBH_html

VideoUrl logged in console, built by dfpmodule: DevTools_-_cdn_adysis_com_VideoDemo_DemoSite_pages_BBH_html

videoUrl built (its building correctly even when NO bid as "undefinded" is returned, you can put this in browser and see it works) https://securepubads.g.doubleclick.net/gampad/ads?env=vp&gdfp_req=1&output=vast&unviewed_position_start=1&correlator=1692034929472&sz=1x1%7C48x27%7C96x54%7C300x169%7C300x197%7C301x170%7C312x176%7C320x100%7C320x180%7C326x184%7C341x192%7C353x250%7C360x203%7C361x203%7C362x204%7C363x205%7C375x211%7C377x212%7C400x225%7C400x300%7C414x233%7C550x310%7C600x338%7C640x360%7C640x390%7C640x480%7C1280x720&url=https%3A%2F%2Fgoogleads.github.io%2Fgoogleads-ima-html5%2Fvsi%2F&iu=/1001824/Video-Corner-Units/VCU-test.com&cust_params=hb_uuid%3Dundefined%26hb_cache_id%3Dundefined%26section%3Dblog%26anotherKey%3DanotherValue&hl=en&description_url=%5Bdescription_url%5D&gdpr=1&gdpr_consent=CPv7UwAPv7UwAAKAvAENDLCsAP_AAH_AAAwIJhNX_H__bW9r8f7_aft0eY1P9_j77uQxBhfJk-4F3LvW-JwX52E7NF36tqoKmR4Eu3LBIUNlHNHUTVmwaokVryHsak2cpTNKJ6BEkHMRO2dYCF5vmxtjeQKY5_p_d3fx2D-t_dv-39z3z81Xn3dZf-_0-PCdU5-9Dfn9fRfb-9IP9_78v8v8_9_rk2_eT13_79_7_H9-f_87_QTBAJMNS4gC7MocCbQMIoUQIwrCAigUAABAMDRAQAODAp0RgE-sIkAKEUARgRAhwBRkQCAAASAJCIAJAiwQAAACAQAAgAQCIQAMDAIKACwEAgABAdAxRCgAECQgSIiIhTAgKgSCAlsqEEoLpDTCAKssAKARGwUACIJARWAAICwcAwRICViwQJcQbRAAMACAUSoVqKT00BCgmbLAAAAA.f_gAAAAAAAAA&addtl_consent=1~&us_privacy=1---

karimMourra commented 1 year ago

@spormeon you're passing in the wrong argument. renderBid expects the 2nd argument to be a bid object, not a videoUrl. You you can set your videoUrl to bid.vastUrl

spormeon commented 1 year ago

@karimMourra you mean like this? BBH2_html_—_Prebid_Publishers__Workspace_

karimMourra commented 1 year ago

Hey the line referenced by the bottom arrow is incorrect: adyjs.videoModule.renderBid('player', bid); is what you want

spormeon commented 1 year ago

@karimMourra ok, I've tried that as well and this is where it falls down, as this only works when a "bid" is returned/ made by a bidder, where as for a GAM setup to work, it need to push the whole videoUrl/ adTag/ BaseAdTag when there is "no" bid/ "a bid", thats how the dfpvideomodule works, always has, its in all the dfpvideomodule dems etc

karimMourra commented 1 year ago

@spormeon you can create a "fake" bid object in this case. try adyjs.videoModule.renderBid('player', { vastUrl: videoUrl });

spormeon commented 1 year ago

@karimMourra ah ha, bingo, works now, would never of got that. So that lets everyone use Amazon as well now. Maybe put in the docs somewhere?