Tracking

As soon as you're bidding, you can start tracking! We'll show you how to do this now, guiding you through the process of writing impression, click and match interceptors.

Write the impression interceptor

Impression, click, and match interceptors are very similar to bid interceptors; they reuse much of the same API. Impression interceptors will be invoked when your bidder receives the ImpressionRequest generated by your creative's snippet when it is loaded in the user's browser. In our first exercise, the impression interceptor will simply log the value of the ad's winning price.

Making this code run will have some extra prerequisites:

  • The Bid for an ad needs an impression URL in the snippet; the price parameter of the URL should be set using the DoubleClick %%WINNING_PRICE%% macro.
  • In the Project settings, Step 3: Configure Doubleclick integration, besides the interceptor class name, you must fill in the Encryption Key and Integrity Key.
  • In the zone that contains the bidder, you must set a hostname for the bidder (or its load balancer), and have DNS A-records pointing to their IPs.

To make it more concrete, here is the sample code that you can use in a bid interceptor to generate a third-party ad:

chain.response().addBid(Bid.newBuilder()
    .setId(imp.getId())
    .setImpid(imp.getId())
    .setPrice(0.99)
    .setAdm("<a target='_blank' href='%%CLICK_URL_UNESC%%%{${OB_CLICK_URL}}%'>\n"
          + "<img src='http://content.com/creative?id=ABCD'>\n"
          + "<img src='${OB_IMPRESSION_URL}'>\n"
          + "</a>")
    .addAdomain("landing.com")
    .addExtension(ObExt.bidImpressionParameter, ObExt.UrlParameter.newBuilder()
        .setName(PriceName.DEFAULT).setValue(DoubleClickMacros.WINNING_PRICE.key()).build())
    .addExtension(ObExt.bidClickParameter, ObExt.UrlParameter.newBuilder()
        .setName("ad_url").setValue("%{${OB_AD_CLICKTHROUGH_URL}}%").build()));

In the bid's snippet, Open Bidder's macro ${OB_IMPRESSION_URL} depends on the zone's hostname— which is why registering it is mandatory to process impressions and clicks even though you could skip this configuration for simple bidding tests. This URL will also have a price parameter, which will be used to extract the coded price sent by the exchange. The %{...}% delimiters, that you can use in both the snippet and impression/click parameters, will URL-encode its contents.

Specifying Open Bidder macros

Open Bidder provides several macros that can be used to insert callbacks and other information, such as certain fields from the ad (like the clickthrough URL in the example above), in the snippets. You could then use a few snippet templates, instead of building each snippet programmatically at every request. Check the enums OpenRtbMacros (part of the OpenRTB standard), and SnippetMacros (Open Bidder-specific macros). Notice that for some macros, the expanded value can also depend on bidder configuration such as the zone's hostname.

The expanded snippet may still contain exchange-specific macros; these will not be processed by Open Bidder, so the exchange will expand them in the usual way. For DoubleClick Ad Exchange, check DoubleClickMacros. In both cases, these enums are more type-safe, you can invoke their key() method to obtain the macro string. But you can also embed macro keys directly in snippets and bid parameters.

Writing the click interceptor

The final step in ad tracking is handling clicks. In order to create a click interceptor you must implement the ClickInterceptor interface. You can extract parameters that your bid interceptors included in the click URL produced by the ${OB_CLICK_URL} macro from the request.

One of the tasks performed by click interceptors is setting the redirect location. Usually, you'll set the redirect location as a click URL's parameter, using URL encoding. The click interceptor can extract this parameter (as in the ad_url in the code below), and call ClickResponse.setRedirectLocation(). Open Bidder's click request receiver will make an HTTP redirect to that location, so you only need to write the interceptor.

Pixel matching

Pixel Matching is an optional feature that is used to associate a Google User ID with a cookie. Once you have this match, you can use information associated with the cookie to adjust bidding logic— e.g. for remarketing. Match tables, which are essentially a mapping of Google User IDs to cookies, should be used to store these matches. For DoubleClick Ad Exchange, we recommend that you let Google host your match table rather than implement this yourself. When your pixel (or tag) is placed on a publisher page, it will cause a MatchRequest to be sent to your bidder, which will handle that with the custom MatchInterceptor chain you provide.

Write the match interceptor

If you would like to write a custom match interceptor, implement the MatchInterceptor interface. In the example below, we implement DoubleClickMatchInterceptor in order to have easier access to data specific to Ad Exchange. Looking at the sample below, you may notice that the structure is very similar to that of impression and click interceptors. Unlike impression and click requests, the MatchInterceptor will receive a parameter which will provide an ID that can be used to match the user to your cookie. In subsequent BidRequests, this can be used to identify the user.

Interceptor unit test

Unit testing impression or click interceptors is similar to unit testing bid interceptors. Like bid interceptors, they have some useful test-scope utilities. You can check their features by viewing the ImpressionTestUtil and ClickTestUtil classes directly.

Send feedback about...

Open Bidder (Beta)