Monday, June 27, 2011

Android advertising - incorporating JumpTap, Part 1

Ok. The time has come to figure out how to incoporate Jumptap into my app. Let's look at the emails they sent out:

Ok, here's the main one:


Setup your mobile site/app to display ads and start earning money:
1. Log-in to your account. (http://www.jumptap.com)
2. Add a site/app to your Jumptap account.
3. Install ad code. We provide you with the sample code needed to display ads. You simply integrate it into your site/app.
4. Site approval. In 1-2 days you will receive an email confirming if your site has been approved. Once approved, your site will be ready to display ads!


I've done #1 and #2. So, now the question becomes - how to install the ad code? Where is all this sample code they speak of? A link guys, a link. I know you're busy and all...

Anyway, let's go to the site.

It's tough to actually get their site - all sorts of articles and whatnot come first. However, this url looks promising:

https://support.jumptap.com/index.php/Publisher_integration_guide

Let's take a look:

Jumptap's tapLink system provides a single interface for mobile operators and publishers to retrieve display ads from the Jumptap ad network.

This page applies to the current version of the tapLink API - version 2.9.

This wiki page describes how publishers and mobile operators retrieve banner ads via the tapLink API.

// ok.


Ad Request API

The tapLink API allows mobile web publishers and application developers to request display ads via a server-side call mechanism.

To request an ad, the publishing server makes a server-to-server invocation of the Jumptap Ad Service via a REST-style web-interface.

The resultant XHTML markup is then displayed in the end user's browser page or application.

// ok.


Requesting an ad

Ad requests to tapLink must be made on a just-in-time basis; in other words, an ad should be requested as the page on which the ad will be displayed is being built.

// ok

tapLink does not support pre-fetching of advertising for future display.

Ad requests to the Jumptap API comprise:

A simple HTTP GET request of the form:

http://a.jumptap.com/a/ads?

// ok

HTTP headers forwarded from the originating handset.

// Ok, I think.

The XJT-UserId header.

// How do I get that?


Structuring the GET Request

Starting with the base URI, add the required request parameters plus any optional parameters that you can provide.

Note that:

Parameter/value pairs are separated from each other with the '&' character.


The order of the parameter/value pairs in the query string is not important.

All parameter values must be URL-encoded.
// how? I'm sure they will suggest it. Java certainly has that capability.

It is not necessary to pass parameters for values that you are already sending as headers.
For example, if you are sending the user-agent header from the device, you do not need to pass the ua parameter.

// how do I know if I'm doing that?

You do not need to pass the same parameters with every request.
For example, if postal code is only available on particular pages of your site, then the requests from those pages would include "&pc=&country=" whereas requests from other pages would not.

// That's good.

Do not pass a null value or an empty string for parameters for which you do not have values. Instead, leave such parameters out of the query string altogether.

// ok

The template of an ad request containing all possible parameters is below. Note that this is not actually a valid request as it does not contain any values for the defined parameters.

http://a.jumptap.com/a/ads?v=&pub=&site=&spot=&a=&url=&ua=&gateway-ip&client-ip=&operator=&l=&ll=&pc=&country=&u=&hid=&mt-gender=&mt-age=&mt-hhi=

// ok.


Passing Client Headers
In order to perform various functions including handset identification, operator/carrier resolution, geographic targeting, and frequency capping, the HTTP headers from the originating (handset) client must be passed along with each ad request.

With a few specific exceptions, all headers – including the Accept* headers – should be forwarded to Jumptap. The following headers should be explicitly excluded:

Host:
Keep-Alive:
Connection:
Cookie:
Cache-Control:
Content-Length:

// I guess they will show us how to do this with sample code.


Passing the XJT-UserId Header
In order to allow taplink to identify and track unique users on your site, tapLink issues a cookie containing a unique user ID. This unique ID is passed to / from tapLink via the XJT-UserId header.

// so, it's basically a header for the cookie.

For more information regarding how to set and send the cookie, please refer to The tapLink Cookie.


Passing IPs
tapLink uses IP addresses to determine several pieces of information about an ad request, including:

The mobile operator from whose network the ad request was made. This allows advertisers to carrier-target their campaigns.

// no problem.

The country from which the ad request was made. This allows advertisers to country-target their campaigns.

// sure.

If you are able to forward device headers with the ad request and you have the ability to modify the headers, then you will need to manipulate the x-forwarded-for header as if you were a proxy:

// oh...
// What's this "x-forwarded-for" header?

If the x-forwarded-for header is present in the headers from the device and has a non-zero length then append "," to the end of it prior to forwarding it Jumptap.

// Well, ok, I'm not sure how this all works yet. How am I going to intercept all
// this stuff.


If x-forwarded-for has a zero-length or is not present in the headers from the device, then set it to "" without the comma.

// Set it? if it's not there, then what do I set? This is getting steep very quickly...


If you are able to forward device headers with the ad request but you cannot modify the headers, then:

// Condition 2. Ah, I see; the ad request is what you generate for Jumptap.

Forward the x-forwarded-for header as-is to Jumptap
Include the client-ip parameter in the query string of the ad request and set it to "".

// Am I picking up the client IP with Java code?

If you are not able to forward device headers, then:

Include the gateway-ip parameter in the query string of the ad request and set it to the x-forwarded-for header from the device.

Include the client-ip parameter in the query string of the ad request and set it to "".

// Ok. This is really detailed. I guess it's good, but I'm hoping a lot of this will
// be handled by the sample code.

In all cases above, refers to the IP address of the client invoking you. This IP which can be obtained from the HTTP implementation you are using.


// I thought the IP was carried in the IP header.

For more information regarding the x-forwarded-for header, please refer to Wikipedia: http://en.wikipedia.org/wiki/x-forwarded-for.

// Here we go:

The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer. This is a non-RFC-standard request field which was introduced by the Squid caching proxy server's developers.


// Ok, so, this is how they get the ip. But since I'm sending from the device directly
// on the network, how does the ip work? Is the ip a public ip? Is it ipv4 or ipv6?
// Certainly the device doesn't have its own pulic ip address, unless it's ipv6.

Required Request Information

Parameter HTTP Header Required Description

gateway-ip x-forwarded-for Y A series of IPs associated with the ad request.

Please refer to the Passing IPs section above for further detail.

// Ok, they covered this.

hid Y The unique device hardware ID.

This parameter is only required for iPhone and Android applications, not mobile web sites.

// why not mobile web apps?

This parameter is used for conversion tracking and is necessary in order to determine campaign coverage.



Example of iPhone (40-character alphanumeric value):

483a269b72ab8bc5d4a5fe0659c90f4808ce615b

Example of Android (16-character alphanumeric value): 20014303ca716d69

// ok.

l Accept-Language Y The user’s preferred language. Valid values are the ISO-639-1 2 letter language codes. http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes


// ok. I hope they don't make me look this up...anyway, the 2-letter code is en per the link.


pub Y Your publisher alias as assigned by Jumptap.

// ok. Do I have one yet?

site Y A site alias assigned by Jumptap.

// ok. Do I have one yet?

spot Y An ad spot alias assigned by Jumptap.

// how do I get that?
url Y/N The URL of the page requesting the ad.

// how does an app have a url?
Note that this is not the Referer header (which may reference the previous page), but is rather the URL of the page on which the ad will be displayed.
The value of this parameter must be encoded.
This parameter is required for requests from mobile web sites, but not for requests from applications.

// right.
ua User-Agent Y The user-agent of the handset making the request.

tapLink uses this to identify the handset making the request thus allowing us to serve handset-targeted campaigns and to insure that the correct size ad is returned.
When using the ua parameter, the value must be encoded; do not encode the user-agent HTTP header.
For Opera Mini, the user agent of the handset is passed in the X-OperaMini-Phone-UA header. If you are passing the user agent in the ua parameter, this is the value you must use for Opera Mini requests. If you are passing the request headers, Jumptap will automatically resolve the handset for Opera Mini requests.

// That's ensure, no insure. What's opera mini? The opera browser on the handset?
// How does the interaction with jumptap work? Am I somehow going through a browser
// or something? I don't get it yet.




Optional Request Information
Parameter HTTP Header Required Description

a N Indicates whether adult ads are allowed to be returned in response to the ad request.
By default, adult ads are not returned; they must be specifically requested by the publisher.

Valid values include:
"notallowed" - indicates that adult ads may not be returned. This is the default value for the parameter.
"allowed" - indicates that adult ads may be returned; note that the returned ad may or may not be adult.
"only" - indicates that only adult ads should be returned.

// ok, we can ignore that. This is a family app.



client-ip N The IP Address of the device requesting the ad. This is used by tapLink and our Ad Providers for Carrier/Gateway targeting. Please refer to the Passing IPs section above for further detail.

// ok, we covered that above.

country Y/N The two letter ISO country code of the originating user’s request. http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
Country should be passed only if the country of the user originating the ad request is definitively known; it should not be set for a static value for all of your requests.
If country is not included in the request, Jumptap will automatically determine the country based on the user or gateway IP.


The country parameter is required if the postal code (pc) parameter is passed.
If you are passing latitude/longitude, then the country parameter should not be passed.

// Let Jumptap handle that.


ll N Latitude/Longitude
Latitude and longitude must be comma-separated.
The value of this parameter must be encoded.
Example, ll=42.369%2C-71.075
Latitude/Longitude is preferred to and supersedes the postal code and country parameters.

// Hmmm...I could grab that with the GPS function. It will make the ads more tailored.

mt-age N The user's age in years, if known. Valid values include any integer from 1-199.

// No, I'm not going to make the user enter that.

mt-gender N The user's gender, if known. Valid values are 'm' or 'f'

// no.

mt-hhi N The user's household income in thousands, if known.

// no

Valid values include
000_015
Where household income is less than $15,000
015_020
Where household income is $15,000-$19,999
020_030
Where household income is $20,000-$29,999
030_040
Where household income is $30,000-$39,999
040-050
Where household income is $40,000-$49,999
050-075
Where household income is $50,000-$74,999
075-100
Where household income is $75,000-$99,999
100_125
Where household income is $100,000-$124,999
125_150
Where household income is $125,000-$149,999
150_OVER
Where household income is $150,000 or higher

// no

operator N For publishers having on-deck instances of their sites, this parameter should be used to indicate the on-deck mobile operator.
This parameter should be passed only for on-deck instances for which the operator/carrier is definitively known.
For off-deck requests, Jumptap will determine the operator based on request header and gateway IP information.

See Valid Operators for a list of valid operators.


// I don't even know what on-deck/off-deck means yet. I'll ignore it for now.

pc N Postal code


If you are passing latitude/longitude, then the pc parameter should not be passed.
The value of this parameter must be encoded.
If postal code is included in the request, the country parameter is required.
Example: pc=02141&country=us

// ignore for now.

q N For search sites or applications, pass the search terms using the q ("query") parameter.


The value of this parameter should be encoded.

// not a search app.

Referer N The Referer HTTP header.
Note that this is not the URL of the page making the request but rather the previous page.
There is not currently a parameter that corresponds to the Referer header.

// well I guess we don't need to worry about that one.

u ClientID
x-up-subno
x-msisdn
XID
etc


N Unique id of the end-user. tapLink uses this identifier for frequency capping.
Different mobile operators use different headers to pass user information, and as such, we strongly recommend that you forward the device's HTTP headers so that tapLink can determine which header contains the user ID.
Only in cases in which you cannot pass headers should you create your own algorithm to determine which header contains the user ID.

In the specific case in which you are unable to forward the device headers and you cannot create an algorithm to check for user ID within the various possible parameters and your site requires a login, you may pass the hashed login ID in the u parameter.

Please note that the value that you pass in must be unique for each user, but should be consistent for each request from the same user.

// Let's hope we can forward the headers for now. Android runs on a lot of devices.


v Y Version of the Jumptap tapLink API. Currently 'v29' (Version 2.9).


// ok.


Common Errors
HTTP Headers

Not passing HTTP headers.

// let's pass them.

Passing the publishing server's HTTP headers rather than those of the handset.

// Ok. How do I distinguish/retrieve the handset headers?

User-agent

Not encoding the user-agent when passing it in the ua parameter.

// ok.

Double-encoding the user-agent when passing it in the ua parameter.

// ok.

Passing the user-agent of the publisher server rather than the handset.


// ok.

Latitude / Longitude

Not comma-separating the latitude and longitude values.
Not encoding the latitude,longitude.

// ok

Postal Code

Not encoding the postal code.
Not including the country parameter when the postal code is passed.

// ok

Country

Passing a static value with every ad request.
Passing the complete name of the country rather than the two-digit code.

// ok

Display Errors

Not accounting for an empty ad response (e.g. not collapsing the placeholder when no ad is returned).

// ok.

In an iPhone app, not accounting for both supported ad sizes: 300 x 50, 320 x 50.

// ok.

In any application, not setting aside enough vertical space for the banner

// ok.


Response Format
Ads returned from tapLink are valid XHTML. There are a number of benefits to XHTML, each of which makes your inventory more valuable to advertisers:

Using XHTML allows us to accommodate the richer ad units that advertisers are now requesting, including Javascript and rich media ads for those handsets that support them.

// That's good.

Using XHTML allows us to introduce tracking pixels to our ad responses.

// ok.

Using XHTML allows us to introduce additional ad types and functionality in the future without requiring a modification to your integration.

// That's definitely good.


Adding Style Information
Style information can be added to the response by wrapping it in div tags. Common style changes include centering the banner, centering the text below a banner, and changing the color of text below a banner.

// Ok. Man, this sounds complicated. Admob is supposed to be really easy.


Handling the Response
Ad responses are to be displayed in-whole, without modification. Parsing or otherwise modifying the response may lead to unexpected and / or undesired behavior. For example, parsing the image and click may cause you to ignore tracking pixels also contained in the response, thus rendering your site ineligible for third-party tracked campaigns.


// ok.


Handling the Response
Ad responses are to be displayed in-whole, without modification. Parsing or otherwise modifying the response may lead to unexpected and / or undesired behavior. For example, parsing the image and click may cause you to ignore tracking pixels also contained in the response, thus rendering your site ineligible for third-party tracked campaigns.





Banner Type Example Handsets Notes
iPhone Interstitial Apple iPhone / iTouch
Dimensions: 320 x 415 pixels
Supported file types: .gif, .png, .jpg

// I forgot what Interstitial means...between levels, something like that.

iPhone Optimized Banner Apple iPhone / iTouch
Dimensions: 320 x 50 pixels
Supported file types: .gif, .png, .jpg

// Ok, we're not on iPhone yet anyway.

X-Large Banner
Apple iPhone/iTouch
Google G1
Nokia E70
Palm Treo 700p
Dimensions: 300 x 50 pixels
Supported file types: .gif, .png, .jpg


// ok. What's G1? It must run Android.

Large Banner
LG VX-8500 Chocolate
Samsung MM-A900
Dimensions: 216 x 36 pixels
Supported file types: .gif, .png, .jpg

// Ok, funny how they get very specific on the phones. Do I have to worry
// about this?

Medium Banner
LG VX-8000
Motorola RAZRs
Motorola ROKR E1
Dimensions: 168 x 28 pixels
Supported file types: .gif, .png, .jpg
Small Banner
Motorola V195
Dimensions: 120 x 20 pixels
Supported file types: .gif, .png, .jpg


Call-to-action text for banners
All
Dimensions:
24 characters X-Large
18 characters Large
12 characters Medium
10 characters Small
Supported: text, accented characters


Sample Responses

Standard Text Banner

(Couldn't post the html)


HTTP Status Codes
Status Code Description
200 Response indicating that the request completed successfully.
201 This response code is returned when activity reporting events are logged successfully with tapLink.
400 A bad request status is send when not all the required parameters are provided or if any one of the required parameters contains an invalid parameter.
401 Sent when incorrect credentials are sent with the request.
403 Sent when IP restrictions are in effect.
404 Sent when the ad spot or ad provider does not exist.
500 Sent when there is an unexpected server-side error.
503 Sent when the service is currently unavailable.


// Standard error codes.


Timeouts
The publisher is responsible for dealing with errors returned from tapLink. The publisher is also responsible for setting the appropriate socket, connection and read/idle timeout values on their client application to protect themselves from a possible tapLink outage.

The publisher should work with Jumptap to determine the proper timeout values and retry policy based on the type of application the publisher has developed. Setting these timeouts will vary depending on the underlying HTTP client library implementation.

// This whole thing looks pretty complicated. Work with Jumptap?

Ok. That's an kind of in-depth view of what's involved in the interface, and
gives a good background. But, what about sample code? I'm concerned about the possible complexity. We'll tackle that in our next post.

No comments:

Post a Comment