-
Notifications
You must be signed in to change notification settings - Fork 406
Creative Configuration
In this document we will describe the CreativeConfiguration
class and how to use it in your own exchange connector:
When using or implementing a new exchange connector, most exchanges (at least OpenRTB-compliant exchanges), are asking for specific values in the BidResponse
you have to send back. For example, in every Bid
, most exchanges are asking for either the nurl
for win-notification or adm
for XHTML markup fields. These fields are not global to the campaign but specific to the creative that was used to bid.
Configuration of creative-specific fields like adm
or nurl
are powered by the CreativeConfiguration
class. This class is mainly used by the exchange connectors to override the getCreativeCompatibility()
function.
CreativeConfiguration
is a simple class that does not know about the various fields that are required by the exchange at the creative-level (see Exchange specific configuration).
TypedCreativeConfiguration<CreativeData>
is a generic (templated) class that you should use to parse and store your fields. To use it, first declare a struct
where all your creative data will be stored:
class MyExchangeConnector : public OpenRTBExchangeConnector {
public:
/* ... */
struct CreativeInfo {
std::vector<std::string> adm;
std::string nurl;
std::string adm;
};
};
Then, declare a TypedCreativeConfiguration
with your creative data struct. The common usage pattern in RTBKit is to create a typedef
of the full TypedCreativeConfiguration
type to make it easy to use:
typedef TypedCreativeConfiguration<CreativeInfo> MyExchangeCreativeConfiguration;
MyExchangeCreativeConfiguration config;
Once you've declared your creative configuration, you can initialize it by registering fields that need to be populated inside your creative. First, you have to initialize your creative configuration by giving it a name. This name will be used by the CreativeConfiguration
class to retrieve the providerConfig
of the creative:
MyExchangeConnector::MyExchangeConnector(
std::string name, std::shared_ptr<ServiceProxies> proxies)
: OpenRTBExchangeConnector(std::move(name), std::move(proxies))
, config("myexchange")
{
init();
}
By giving it the name "myexchange"
, all the fields must be put in the "myexchange"
section of the creative's providerConfig
.
Now, we can start adding some fields:
void MyExchangeConnector::init() {
config.addField(
"adomain",
[](const Json::Value& value, CreativeInfo& info) {
Datacratic::jsonDecode(value, info.adomain);
}).required();
config.addField(
"adm",
[](const Json::Value& value, CreativeInfo& info) {
Datacratic::jsonDecode(value, info.adm);
}).snippet().required();
config.addField(
"nurl",
[](const Json::Value& value, CreativeInfo& info) {
Datacratic::jsonDecode(value, info.nurl);
}).snippet();
}
As you can see, addField
takes two parameters:
* The first one is the name of the field that should be in the providerConfig
:
* The second is a callback of the form void(const Json::Value&, CreativeInfo&)
that will be called to parse the field.
Here, we just call Datacratic::jsonDecode
to decode and store the field in the right place in your CreativeInfo
struct. Based on the type of the field, jsonDecode
will automatically decode the right type (array for a vector, string for a string, ...).
Some fields can be marked required()
while others can be marked snippet()
. To understand what snippet()
means, let's jump to the next section.
Note that you can also mark a field optional()
if you want. By default, all fields are optional.
When sending back bids to the exchange, you usually need to include information in some of the fields that are only known at runtime and not during configuration. For example, in the adm
or nurl
field, you usually have to include the bid request id as well as the impression id to later re-conciliate with a potential WIN.
Some exchanges have built-in macros that they expand when receiving your response like ${AUCTION_PRICE} for the final win price. RTBKit on its turn offers a bunch of macros that you can use in your fields. Such fields must be marked as snippet()
when initialization your creative configuration.
All the macros are then expanded by the ExchangeConnector
when sending the response back to the exchange.
You will find below the list of all the macros provided by RTBKit and what they expand to at runtime:
Macro | Expansion | Example |
---|---|---|
%{exchange} | Name of the exchange connector | rubicon |
%{creative.id} | ID of the creative | 1 |
%{creative.name} | Name of the creative | android_300x200 |
%{creative.width} | Width of the creative | 300 |
%{creative.height} | Height of the creative | 200 |
%{bidrequest.id} | ID of the bidrequest | 164208 |
%{bidrequest.user.id} | ID of the user | VpC0f8AoJ64AAA..PIIAAABZ |
%{bidrequest.publisher.id} | ID of the publisher | 178697 |
%{bidrequest.timestamp} | The timestamp (seconds since epoch) of the bidrequest | 1462802300 |
%{response.account} | The account used to bid | hello:world |
%{imp.id} | The id of the impression | 1 |
In addition to macros, RTBKit provides a bunch of filters to "transform" the output of the macro:
Filter | Description | Example |
---|---|---|
lower | Lowercase the content of the macro | rubicon |
upper | Uppercase the content of the macro | RUBICON |
urlencode | Encode a string like an URL | http%3A%2F%2Fnews.google.com%2F |
Filters are specified after the name of the macro, separated by #
:
%{exchange#upper}
- Getting Started
- Pull Request Guidelines
- Coding Standards
- Demo Stack
- How to compile static filters test
- RTBkit Binary Package
- Architecture
- Bid Request Lifecycle
- ZooKeeper Nodes
- Load Shedding
- Banker
- Post Auction Loop State Machine
- Post-Auction Loop Sharding
- ZMQ Endpoints