Generic Passback for DFP Mobile Apps

Document created by david.simerly on May 22, 2018Last modified by david.simerly on Jul 24, 2018
Version 5Show Document
  • View in full screen mode

Problem

Current app inventories that render ads on iOS/Android using DFP SDK, have no straight forward process to pass back an impression to DFP if PubMatic cannot monetize an impression. DFP does not have documentation or standard for handling this situation, so most publishers:

 

  • Move PubMatic to the bottom of stack (if other partners and AdEx are part of the auction), then serve house ads in case PubMatic defaults.
  • Fill un-served ads with AdEx mobile web demand using the javascript based GPT Passback tag, losing all app-related parameters in the process. This also treats the impression as mobile web, where app demand does not bid (not even AdEx, due to missing information).

 

Proposed Solution

The solution described below ensures that all mobile application parameters and impression custom targeting persist through Passback to DFP in order to preserve the impression's value. To achieve this, the solution leverages event notifications (called App Events), from the DFP SDK. Include ad-mob.js file to trigger app events:

 

//media.admob.com/api/v1/google_mobile_app_ads.js

 

Including this JavaScript in the PubMaitic Passback code triggers an event when there is no bid for an impression. When the SDK receives the event, it can make another ad-request (the Passback) with the same parameters. You can also include a loop to break custom criteria so that PubMatic won't process the same impression again.

 

Generic Passback Flow for Mobile App Using DFP SDK

 

 

Implementation & Setup details

The changes below demonstrate implementation in the Android and iOS DFP sample apps. Use the same techniques to implement Passback in your own app.

 

Changes Required in Android DFP SDK Code 

For the completed sample DFP Android app modified for Passback, see the Git repository.

 

Use the following steps to create the file, MyActivity.java.

 

  • Define two boolean flags as member variables:
// Flags to check and handle PubMatic Passback
private boolean mIsAppEventPubmaticPbk = false;

private boolean mIsAdLoadSuccessful = false;
  • Set AdListener on PublisherAdView instance:
    • In onAdLoaded callback, set loadSuccess flag to true and call the firePassbackRequest method (see below).
    • In onAdFailedToLoad callback, reset both flags to false.
mAdView.setAdListener(new AdListener() {
    @Override
    public void onAdLoaded() {
        super.onAdLoaded();
        /* App code ... */
        mIsAdLoadSuccessful = true;
       firePassbackRequest();
    }
    @Override
    public void onAdFailedToLoad(int errorCode) {
        super.onAdFailedToLoad(errorCode);
        // Reset both flags
        mIsAdLoadSuccessful = false;
       mIsAppEventPubmaticPbk = false;
    }
});
  • Set AppEventListener on PublisherAdView instance:
    • Check for event with key=pmpbk and value=1. On this event set PubMatic Passback flag, mIsAppEventPubmaticPbk, to true, then call the firePassbackRequest method.
mAdView.setAppEventListener(new AppEventListener() {
    @Override
    public void onAppEvent(String key, String value) {
        Log.i("BannerAdExample", "onAppEvent() Key:" + key + " Value:" + value);
        if (TextUtils.equals(key, "pmpbk") && TextUtils.equals(value, "1")) {
            // App event pmpbk with value 1 indicates PubMatic passed back
            // Set a Passback flag
            mIsAppEventPubmaticPbk = true;
          firePassbackRequest();
        }
    }
});
  • Define the firePassbackRequest method, which initiates a new request to DFP (Passback with loop breaking custom criteria):
    • When both flags are true, create a new add request containing the custom loop-breaking param, then send a request for a new ad.
/**
* Create and send new ad request adding custom targeting with PubMatic passback information
*/

private synchronized void firePassbackRequest() {
    // Send new request only when both flags are true
    if (mIsAdLoadSuccessful && mIsAppEventPubmaticPbk) {
        // Reset both flags
        mIsAdLoadSuccessful = false;
        mIsAppEventPubmaticPbk = false;
        // Create new ad request with custom targeting
        PublisherAdRequest publisherAdRequest = new PublisherAdRequest.Builder().addCustomTargeting("pmpbk", "1").build();
        Log.i("BannerAdExample", "Sending new ad request with pmpbk=1");
        // Send new ad request
        mAdView.loadAd(publisherAdRequest);
    }
}

When refreshing the DFP ad, clear the loop-breaking criteria or make a new request object so that PubMatic is included in subsequent requests.

PublisherAdRequest publisherAdRequest = new PublisherAdRequest.Builder().build();     
// Send new ad request
mAdView.loadAd(publisherAdRequest);

 

Code changes required in DFP SDK code for iOS

For the completed sample DFP iOS app modified for Passback, see the Git repository.

 

Use the following steps to create the file, MyActivity.java.

 

  • Define two boolean flags as member variables:
// Flags to check and handle PubMatic Passback
@property(nonatomic,assign) BOOL isAppEventPubmaticPbk;
@property(nonatomic,assign) BOOL isAdLoadSuccessful;
  • Implement the protocol GADAppEventDelegate and set the following in the viewdidLoad method of ViewController.m:
self.bannerView.appEventDelegate=self;
self.bannerView.delegate=self;
  • Implement the GADBannerViewDelegate methods below, designed to ensure the DFP load ad completes before initiating the Passback request.
    • Two flags ensure the ad-load and PubMatic Passback signal (pmpbk=1) are complete:
#pragma mark Ad Request Lifecycle Notifications
- (void)adViewDidReceiveAd:(GADBannerView *)bannerView
{
    self.isAdLoadSuccessful=YES;
    [self firePassbackRequest];
    NSLog(@"DFP Received Ad");
}
- (void)adView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(GADRequestError *)error
{
    NSLog(@"DFP Failed to load Ad with error %@",[error description]);
    [self resetAllFlags];
}

- (void)adView:(GADBannerView *)banner didReceiveAppEvent:(NSString *)name
      withInfo:(NSString *)info
{
    NSLog(@"Fetched Event Name %@ and Info %@",name,info);
    if([name isEqualToString:@"pmpbk"] && [info isEqualToString:@"1"])
    {
        self.isAppEventPubmaticPbk=YES;
        [self firePassbackRequest];
    } 
}
  • Define the Passback request and flag reset function:
-(void) resetAllFlags
{
    self.isAppEventPubmaticPbk=NO;
    self.isAdLoadSuccessful=NO;
}
-(void) firePassbackRequest
{
    @synchronized(self) {
        if (self.isAdLoadSuccessful && self.isAppEventPubmaticPbk) {
            self.request.customTargeting = @{@"pmpbk" : @"1"};
            [self.bannerView loadRequest:self.request];
            
            [self resetAllFlags];
        }
        
    }
}

When refreshing the DFP ad, clear the loop-breaking criteria or make a new request object so that PubMatic is included in subsequent requests.

- (IBAction)refresh:(id)sender {
    self.request = [DFPRequest request];
    [self.bannerView loadRequest:self.request];
}

 

Changes in PubMatic and DFP Ad Server

The final sections below describe a couple of changes that Publishers must make in PubMatic.

 

Passback Tag to be Trafficked in PubMatic

<script type="text/javascript" src="//media.admob.com/api/v1/google_mobile_app_ads.js"></script>
<script type="text/javascript">
admob.events.dispatchAppEvent("pmpbk", "1"); // event indicator that PubMatic doesn't have bid
</script>

 

Publisher Setup in DFP Ad Server

The only thing publisher needs to change is add negative targeting for the loop breaking key-value (pmpbk=1)in the ad-server for all PubMatic line items .

Here is a snapshot of the setup in DFP:

 

⇧ Top

Attachments

    Outcomes