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

Bids Response hook #303

Closed
bszekely1 opened this issue Jun 12, 2020 · 7 comments · Fixed by #304
Closed

Bids Response hook #303

bszekely1 opened this issue Jun 12, 2020 · 7 comments · Fixed by #304
Assignees
Milestone

Comments

@bszekely1
Copy link
Contributor

bszekely1 commented Jun 12, 2020

Type of issue

Intent to implement

Description

The intent of this ticket is to provide publishers a hook for bid responses and expose an object containing all the prebid bid keys to the publisher. Today the Prebid SDK controls the request builder for the ad server, inferring either GAM or Mopub. The problems with our approach are the following:

  • Publishers are not able to add custom keys to send to the ad server
  • Rendering in ads in ad servers other than GAM and Mopub is not possible
  • It is not possible to support in-stream in the current iteration

Goals

  • Provide a method to pass bidder keys to publishers
  • Provide an event hook to indicate bids are returned

Proposed Design

Existing flow

Prebid SDK Fetch Demand Current

  1. Publisher App invokes Prebid SDK, passing context settings, calling fetchDemand for ads
  2. Prebid SDK calls PBS for demand
  3. Prebid Server performs calls to bid adapter endpoints
  4. Bid adapters respond back with bids
  5. Prebid Server responds back to Prebid Server with all eligible bids
  6. Prebid SDK attaches bids to the request builder object of ad server SDK using inflection to determine which ad server is integrated (either GAM or Mopub)
  7. App invokes a request ads in the ad server SDK with prebid attributes in the request builder object
  8. Ad server SDK calls ad server endpoint for an ad
  9. Ad server responds to ad server SDK with ad
  10. Ad server SDK creates a webview to render Prebid Universal Creative
  11. PUC fetches ad from the PBS Cache endpoint
  12. PUC displays ad

3rd Party Ad Server

Prebid SDK Fetch Demand Callback 3rd Party Ad Server Support

  1. Publisher App invokes Prebid SDK, passing context settings, calling fetchDemand for ads
  2. Prebid SDK calls PBS for demand
  3. Prebid Server performs calls to bid adapter endpoints
  4. Bid adapters respond back with bids
  5. Prebid Server responds back to Prebid Server with all eligible bids
  6. Prebid SDK passes a dictionary of keys (bids) back to the app using the callback of fetchDemand
  7. App invokes a request ads in the 3rd party ad server SDK attaching any prebid key values in the request builder object
  8. Ad server SDK calls ad server endpoint for an ad
  9. Ad server responds to ad server SDK with ad
  10. Ad server SDK creates a webview to render Prebid Universal Creative
  11. PUC fetches ad from the PBS Cache endpoint
  12. PUC displays ad

Instream Video Support

Prebid SDK Fetch Demand Callback Instream Support

  1. Publisher App invokes Prebid SDK, passing context settings, calling fetchDemand for ads
  2. Prebid SDK calls PBS for demand
  3. Prebid Server performs calls to bid adapter endpoints
  4. Bid adapters respond back with bids
  5. Prebid Server responds back to Prebid Server with all eligible bids
  6. Prebid SDK passes bidder keys back to publisher, sending keys to the video player
  7. Video player makes requests to the ad server for a vast object, containing Prebid bid keys
  8. Ad server SDK calls ad server endpoint for an ad
  9. Ad server responds to ad server SDK with ad
  10. Ad Server SDK passes VAST object to video player
  11. Video player renders VAST object
  12. VAST fetches Prebid VAST object for ad
  13. Ad is displayed

Requirements

  1. Publishers must be able to render ads as they do today to prevent any breaking changes
  2. Publisher should use the existing fetchDemand object to express new method of receiving targeting keys
  3. Publisher should signal to the Prebid SDK when to supply the targeting keys vs the standard flow, otherwise the default behavior is to use inflection, where no keys are provided to publisher
  4. If targeting keys are requested, Prebid SDK must not use inflection to add bidder keys to the publisher ad server
  5. If targeting keys are requested, the keys should be contained in an immutable object to mitigate the risk the publisher can modify keys, causing render issues
    • The publisher can still make a copy of this immutable object, however it would have to be intentional with purpose
  6. To support a third party ad server, the publisher would be required to configure / setup line items in the publisher ad server containing the Prebid Universal Creative to render the ad

Technical proposal

A proof of concept was created in PR 304. The summary of the PR is the following:

Current fetchDemand

func fetchDemand(completion: @escaping(_ result: ResultCode) -> Void)
  • If publisher wants Prebid SDK to handle passing keys to ad server, they can call fetchDemand as they do today
  • Only GAM an Mopub are supported

New fetchDemand

func fetchDemand(completion: @escaping(_ result: ResultCode, _ kvResultDict: [String : String]?) -> Void)
  • New fetch will be the same function as before but with a targetingDict object specifying the publisher would like access to the keys
  • Publisher would manual controls to pass keys to any ad server, where they can modify keys or suppress keys from going to the ad server
  • Can support any ad server the publisher opts to use

Example

func loadMPRewardedVideo() {
    let adUnit = RewardedVideoAdUnit(configId: "1001-1")
    adUnit.fetchDemand { [weak self] (resultCode: ResultCode, targetingDict: [String : String]?) in
        print("Prebid demand fetch for mopub \(resultCode.name())")
        
        guard let targetingDict = targetingDict else {
            return
        }
        
        let keywords = Utils.shared.convertDictToMoPubKeywords(dict: targetingDict)
        MPRewardedVideo.loadAd(withAdUnitID: "46d2ebb3ccd340b38580b5d3581c6434", keywords: keywords, userDataKeywords: nil, location: nil, mediationSettings: nil)
    }
}

In-Scope

Out of Scope

Prebid SDK Changes

Prebid Server OpenRTB Changes

N/A

Prebid Server Changes

Other information

@yoalex5 yoalex5 linked a pull request Jun 19, 2020 that will close this issue
@anwzhang
Copy link
Contributor

Since we already use a minimal set of targeting keywords to make universal creative to work, we should not let publishers to modify the returned keys. We could provide a immutable class that only allows adding extra keys.

However, looking PR 199 in Android, it already solves this problem...

@yoalex5
Copy link
Collaborator

yoalex5 commented Jul 7, 2020

@anwzhang

Since Prebid SDK is not a final point(the final point is ad server SDK as AdManager or MoPub), Prebid SDK can not guarantee that Key/Values will not be modified.

Publisher is able to modify custom parameters using ad server SDK.
For example:

iOS:

adUnit.fetchDemand(adObject: self.amRequest) { [weak self] (resultCode: ResultCode) in
    
    //add key/value
    self?.amRequest.customTargeting?["myKey"] = "my value"
    
    //change value
    self?.amRequest.customTargeting?["hb_size"] = "new size"
    
    //remove key/value
    self?.amRequest.customTargeting?.removeValue(forKey: "hb_size")
    
    //remove all
    self?.amRequest.customTargeting?.removeAll()
    
    print("Prebid demand fetch for AdManager \(resultCode.name())")
    self?.amBanner.load(self?.amRequest)
}

Android:

adUnit.fetchDemand(request, new OnCompleteListener() {
    @Override
    public void onComplete(ResultCode resultCode) {

        //add key/value
        request.getCustomTargeting().putString("myKey", "my value");

        //change value
        request.getCustomTargeting().putString("hb_size", "new size");

        //remove key/value
        request.getCustomTargeting().remove("hb_size");

        //remove all
        request.getCustomTargeting().clear();

        DemoActivity.this.resultCode = resultCode;
        amBanner.loadAd(request);
        refreshCount++;
    }
});

What do you think ?

@bszekely1
Copy link
Contributor Author

@yoalex5 After discussing in our PMC meeting today, we all agreed to keep the bidder keys in an immutable object to mitigate the risk of the publisher accidentally modifying them. They can still take the extra step to copy the object to modify keys however this would be an extra step the publisher would have to perform and would need to be intentional.

I have updated the requirements of the ticket to require an immutable object.

@yoalex5
Copy link
Collaborator

yoalex5 commented Aug 3, 2020

targetingDict is immutable object

@anwzhang
Copy link
Contributor

Hi @yoalex5, which targetingDict are you referring to?

@yoalex5
Copy link
Collaborator

yoalex5 commented Aug 12, 2020

Hello @anwzhang

adUnit.fetchDemand { [weak self] (resultCode: ResultCode, targetingDict: [String : String]?) in 

}

@anwzhang
Copy link
Contributor

Looks good to me.

@bszekely1 bszekely1 added this to the 1.8 milestone Sep 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants