Prebid Mobile Extensions

This document describes extensions available when using the the Prebid Mobile SDK. These are implemented server-side which means there are no further client side dependencies.

To get started using the Prebid Mobile SDK along with Relevant Yield, please read: Setting up Prebid Mobile in HB Manager

Setting arbitrary bid parameters.

Some bid parameters like keywords are dynamic and might depend on individual user etc. In this case they can't be setup in Yield the normal way but must be supplied via the App code.

For this purpose a special context data ext_merge_json is used that should be set using the addContextData() function in the Prebid Mobile ad unit. This should be a stringified JSON object containing the bid parameters per bidder you want to merge with the settings provided by Yield.

The following example using hypothetical JavaScript syntax shows how to set up keywords with bidder appnexus (Xandr):

BannerAdUnit adUnit = new BannerAdUnit(...);
...
const object = {
  "appnexus": {
    "keywords": [
      { "key": "some_key", "value": ["some_value"] },
      { "key": "other_key", "value": ["other_value"] },
    ],
  },
// add other bidder(s) here
};
adUnit.addContextData("ext_merge_json", JSON.stringify(object));

Notice: The ext_merge_json context data will be removed immediately after being parsed on the server. This ensures it won't be read by other bid adapters etc.

Other extensions

Some other Relevant-specific functionality can also be controlled via the ext_merge_json object described above. To do this there is a special key relevant that can be added to the object - containing these settings. Example:

BannerAdUnit adUnit = new BannerAdUnit(...);
...
const object = {
"appnexus": { /** bid paramters */ },
"rubicon": { /** bid paramters */ },
"relevant": { // Relevant specific settings
    "skip_imp_format": true, // Use dimensions specified in Yield instead of in App
},
};
adUnit.addContextData("ext_merge_json", JSON.stringify(object));

The following settings exists:

  • skip_imp_format - Use dimensions specified in Yield instead of in the App. This means that the dimensions used will not be the dimension(s) specified when setting up a BannerAdUnit object. Instead the dimensions in the Placement Type in Yield will be used. This makes it possible to change the dimensions for placements without updating the App.

Android example helper class

Below is an example of an helper-class for the Android Prebid Mobile SDK that can be used to set keywords in Xandr and to enable the skip_imp_format setting (see above).

package org.prebid.mobile.app;

import org.prebid.mobile.AdUnit;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import java.util.Arrays;
import java.util.Map;

/**
 * Custom bid parameters can be merged in the 'imp' object created for an ad unit. The bidder
 * "relevant" is a special object that can contain custom settings.
 *
 * This is done by setting the context data "ext_merge_json" to a JSON-string.
 * Example using "JavaScript syntax":
 *
 * const object = {
 *   "appnexus": {
 *     "keywords": [
 *       { "key": "some_key", "value": ["some_value"] },
 *       { "key": "other_key", "value": ["other_value"] },
 *     ],
 *   },
 *   "relevant": {
 *     "skip_imp_format": true, // Use dimensions specified in Yield instead of in App
 *   },
 * };
 * adUnit.addContextData("ext_merge_json", JSON.stringify(object));
 *
 * This example-class is used to add such data in a couple of specific ways.
 *
 * Example usage:
 *
 * RelevantData relevantData = new RelevantData();
 * Map<String,String> kws = new HashMap<String,String>();
 * kws.put("some_key", "some_value");
 * kws.put("other_key", "other_value");
 * try {
 *   relevantData.addXandrKeywords(kws);
 *   relevantData.setSkipImpFormat();
 *   relevantData.apply(adUnit);
 * } catch (JSONException e) {
 *   e.printStackTrace();
 * }
 *
 */
class RelevantData {
    private JSONObject ext = new JSONObject();

    private JSONObject objByPath(String[] path) throws JSONException {
        JSONObject res = ext;
        for (String p: path) {
            JSONObject next = res.has(p) ? res.getJSONObject(p) : null;
            if (next == null) {
                next = new JSONObject();
                res.put(p, next);
            }
            res = next;
        }
        return res;
    }

    private JSONArray arrByPath(String[] path) throws JSONException {
        String name = path[path.length - 1];
        JSONObject obj = objByPath(Arrays.copyOf(path, path.length - 1));
        JSONArray res = obj.has(name) ? obj.getJSONArray(name) : null;
        if (res == null) {
            res = new JSONArray();
            obj.put(name, res);
        }
        return res;
    }

    private JSONObject objByName(String name) throws JSONException {
        return objByPath(new String[]{name});
    }

    public void addXandrKeywords(Map<String, String> keywords) throws JSONException {
        JSONArray kws = arrByPath(new String[]{"appnexus", "keywords"});
        for (String key : keywords.keySet()) {
            JSONObject kvObj = new JSONObject();
            JSONArray kvValues = new JSONArray();
            kvValues.put(keywords.get(key));
            kvObj.put("key", key);
            kvObj.put("value", kvValues);
            kws.put(kvObj);
        }
    }

    public void setSkipImpFormat() throws JSONException {
        objByName("relevant").put("skip_imp_format", true);
    }

    public void apply(AdUnit adUnit) {
        adUnit.addContextData("ext_merge_json", ext.toString());
    }
}