Mobile Sites

From Adfonic Wiki
Jump to: navigation, search

Contents

Getting Started

To get live ads in your mobile site you just need to:


Script Tags

Use the following tag for browsers compatible with script tags such as WebKit (iOS, Android..)

<script src="http://adfonic.net/js/22222222-2222-2222-2222-222222222222"/>

Make sure you replace 22222222-2222-2222-2222-222222222222 with your Ad Slot ID.

To send additional parameters as part of the request, refer to the table below:

Parameter name Required? Format Description
s.test No 0|1 Test mode (0=false, 1=true)
t.colorScheme No blue|green|orange|purple |red|yellow The background color to use when serving enhanced text ads on high-end devices. This enables you to customize the look and feel of these ads to match your own design template.
t.constraints No name1=value1;name2=value2.. Allows you to constrain the properties of the ads that will be returned. You can override the automatic size detection for a given device by setting this to (for example) “width=300;height=50”.
u.gender No m|f The user’s gender (male or female), if known
u.dob No Number in format YYYYMMDD The user’s date of birth, if known
u.age No Integer The user’s age, if known (alternative to u.dob)
u.ageLow, u.ageHigh No Integers The user’s age range, if known (alternative to u.dob)
p.tags No Keywords in lowercase, comma-separated Additional tags to use when selecting an ad to display

The example below shows a tag, 'tennis' passed as part of the request (make sure these are correctly HTTP encoded):

<script src="http://adfonic.net/js/22222222-2222-2222-2222-222222222222?p.tags=tennis"/> 

The response should look something like:

document.write('
<!-- Banner image -->
  <a href="http://adfonic.net/ct/22222222-2222-2222-2222-222222222222/db77d46c-517d-4bed-95e7-e5fbfe11b942">
   <img border="0" alt="" src="http://as.adfonic.net/as/d517a146-fb8c-4362-85e1-340e7d04b877" width="300" height="50" />
  </a>');

Standard Tags

Standard tags are another option for mobile sites where requests are from lower end handsets:

<a href="http://adfonic.net/sc/22222222-2222-2222-2222-222222222222?r.impid=[RANDOM_ID]&r.fallback=<FallbackURL>">
    <img src="http://adfonic.net/si/22222222-2222-2222-2222-222222222222?r.impid=[RANDOM_ID]&r.fallback=<FallbackURL>&t.constraints=<Dimensions>"/>
</a>

Notes on parameters

Parameter name Format Description
r.impid (both) A large integer This will be used as the ImpressionID (numbers in img and ct request MUST be the same)
r.fallback (static-img) Any valid image URL, url-encoded This image will be served in the "no ad" case
r.fallback (static-ct) Any valid destination URL, url-encoded This URL will be redirected to in the "no ad/no impression" case

Remember to replace 22222222-2222-2222-2222-222222222222 with your Ad Slot ID.

Sample Code

The following ready-made code templates that can be cut and pasted for the following common server-side platforms:

PHP

This section is in 2 parts:

  1. Base code that needs to be included (save this as adfonic.php)
  2. Code to call the ad

Base PHP Code

<?php

/**
 * NOTE: In order for tracking cookies to be set, the ads must be requested prior to any
 * output going to the user
 * 
 * Potential additional parameters:
 * u.age - actual age
 * u.ageLow and u.ageHigh - for age range
 * u.lang - override language (default is 'en-us')
 */
class Adfonic {
	static $adfonic_ad_base = 'http://adfonic.net/ad';

	var $client_id;
	function __construct($client_id=null){
		if (isset($client_id)) {
		   $this->client_id = md5($client_id);
		}
	}	
	
	/**
	 *  Primary interface. Pass the ad identifier, any extra targeting parameters and tags
	 * @param params - name value parameters for targeting, do not url encode
	 * @return Ad content to directly embed
	 */
	function get_ad_content($ad_id,$params=array(),$tags=array()){
		$ad_url = $this->build_ad_url($ad_id,$params,$tags);
			
		$ch = curl_init($ad_url);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
		
		$output = curl_exec($ch);
		$info = curl_getinfo($ch);
		
		
		$adcontent = '';
		if ($output == false || $info['http_code'] != 200){
			$adcontent = '<!-- no ad available, received response '. $info['http_code'] . '-->';	
		}
		else {
			parse_str($output, $rvals);

			// handle "magic" quote escaping
			if (get_magic_quotes_gpc()){
				$rvals = array_map('stripslashes',$rvals);				
			}
			// WARNING: This will only work if the output hasn't started going to the user
			if (isset($rvals['trackingId'])){
				setcookie('adfonic-tracking-id',$rvals['trackingId'],time() + (3600 * 24 * 365 * 2)); // 2 years
			}
        	    
        
			
			if (isset($rvals['error'])){
				$adcontent = '<!-- no ad available, Adfonic error: ' . $rvals['error'] . '-->';
			}
			else {	
			
				$adcontent = $rvals['adContent'];
			}
		}
		
		curl_close($ch);
		
		return $adcontent;
	}
	
	/**
	 * Retrieve url for the given id and any extra parameters (tags, etc)
	 *
	 */
	function build_ad_url($ad_id,$params=array(),$tags=array()){
		$ad_url = self::$adfonic_ad_base. "/$ad_id?";

		// url params as key=value
		$u_params = array();
		
		// copy the user-supplied parameters
		foreach ($params as $k=>$v){
			$u_params[] = '$k='.urlencode($v);
		}
		
		// tracking id
		$rid = $this->get_tracking_id();
		if (isset($rid)) {		
		   $u_params[]= 'r.id='.$this->get_tracking_id();
		}
		
		// user's ip address		
		$u_params[] = 'r.ip='.$this->get_ip();
		
                // pass on all the http headers
                foreach ($_SERVER as $k=>$v) {
                    if (substr(strtolower($k),0,5) == 'http_') {
                        $k = str_replace('_','-', strtolower(substr($k,5)));
                        if ($k != 'cookie') {
                            $u_params[] = 'h.'.$k.'='.urlencode($v);
                        }
                    }
                }

		if (! empty($tags)){
			$u_params[] = "p.tags=".urlencode(join(",",$tags));
		}
		
		$query_string = join("&",$u_params);

		$ad_url .= $query_string;

		
		return $ad_url;
	}

	/**
	 * Extract tracking id from request/cookies
	 *
	 */
	function get_tracking_id(){
		if (isset($_COOKIE['adfonic-tracking-id'])){
			return $_COOKIE['adfonic-tracking-id'];
		}
		else {
			return $this->client_id;
		}
		
	}
	
	function get_ip(){
		if (isset($_SERVER['HTTP_CLIENT_IP'])){
			return $_SERVER['HTTP_CLIENT_IP'];
		}
		
		return $_SERVER['REMOTE_ADDR'];
	}
}


?>

PHP Code to Call Ad

<?php
include_once('adfonic.php');

$adfonic = new Adfonic();
$ad_content = $adfonic->get_ad_content("22222222-2222-2222-2222-222222222222");
?>
<?=$ad_content?>

Remember to replace 22222222-2222-2222-2222-222222222222 with your Ad Slot ID

JSP with JAR file

Download this JAR file and ensure that it is properly installed in your web application server. Once installed you can copy and paste the generated code into any JSP page where you wish to have an ad appear.

<%@ page import="com.adfonic.*" %>

<!-- Adfonic ad slot: NOTE have removed the ad slot description e.g. banner v MPU -->
<%
AdfonicAdClient adClient = new AdfonicAdClient();
AdfonicAdRequest adRequest = new AdfonicAdRequest();
%>
<%= adClient.getAd(request,
                   response,
                   "22222222-2222-2222-2222-222222222222",
                   adRequest) %>

Remember to replace 22222222-2222-2222-2222-222222222222 with your Ad Slot ID

In the adfonic-client.jar file, the AdfonicAdRequest class contains convenience methods exposed as bean properties for getting and setting optional request parameters. These methods are as follows:

JSP Standalone

This is an all-in-one version of the code that would otherwise be split between the adfonic-client.jar file and the JSP page. Due to its size, it's not recommended unless you don't have the ability or desire to add the JAR file to your application. In that case, simply paste the entire contents of the sample code into your JSP where you would like the ad to be placed.

<%@ page import="java.io.*" %>
<%@ page import="java.net.*" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.*" %>
<%
//==========================================================================
// Adfonic Ad Request Setup.  This process should be done once per page.
// You can pass the same parameter map to the "getAdfonicAd" method as
// many times as needed, i.e. if you would like to display multiple ads.
//==========================================================================
Map adfonicParams = new HashMap();

// Uncomment this to enable test mode
//adfonicParams.put("s.test", "1");

// If you have access to a Ad Slot ID, you should pass it in order to
// enable the most effective targeting possible
String yourUserID = null; // set this...

// Pass gender as "m" or "f" if known
//adfonicParams.put("u.gender", "m");

// Preferred method of passing age: pass date of birth as "YYYYMMDD"
SimpleDateFormat dobSdf = new SimpleDateFormat("yyyyMMdd");
//Date dateOfBirth = ...;
//adfonicParams.put("u.dob", dobSdf.format(dateOfBirth));

// Alternate method of passing age: pass the age value itself
//adfonicParams.put("u.age", String.valueOf(ageInYears));

// Another alternate method of passing age: pass an age range
//adfonicParams.put("u.ageLow", String.valueOf(ageRangeLow));
//adfonicParams.put("u.ageHigh", String.valueOf(ageRangeHigh));

// Optional language override
//adfonicParams.put("u.lang", "en-us");

// Additional tags to be used in union with tags pre-assigned to the ad space
List tags = new ArrayList();
//tags.add("sports");
//tags.add("football");
if (tags != null && !tags.isEmpty()) {
    StringBuffer tagBuf = new StringBuffer();
    for (Iterator tagIter = tags.iterator(); tagIter.hasNext(); ) {
        String tag = (String)tagIter.next();
        if (tagBuf.length() > 0) {
            tagBuf.append(',');
        }
        tagBuf.append(tag.toLowerCase());
    }
    adfonicParams.put("p.tags", tagBuf.toString());
}

// Uncomment this to control the text ad color scheme, values of
// which may be: (grey|black|blue)
//adfonicParams.put("t.colorScheme", "grey");

if (yourUserID != null && !yourUserID.equals("")) {
    // We'll pass an MD5 hash of your user ID for security
    adfonicParams.put("r.id", md5(yourUserID));
}
else {
    // Otherwise, we fall back on passing the Adfonic tracking ID
    String trackingID = getAdfonicTrackingID(request);
    if (trackingID != null) {
        adfonicParams.put("r.id", trackingID);
    }
}

// Pass the IP address
String ipAddress;
String forwardedIp = request.getHeader("X-Forwarded-For");
if (forwardedIp != null) {
    // If it has been forwarded multiple times, there will be
    // multiple IPs listed.  We only want the last one...
    int lastComma = forwardedIp.lastIndexOf(",");
    if (lastComma >= 0) {
        ipAddress = forwardedIp.substring(lastComma + 1).trim();
    }
    else {
        ipAddress = forwardedIp;
    }
}
else {
    ipAddress = request.getRemoteAddr();
}
adfonicParams.put("r.ip", ipAddress);

// Pass all HTTP request headers as "h.*" parameters
Enumeration names = request.getHeaderNames();
while (names.hasMoreElements()) {
    String name = (String)names.nextElement();
    if ("Cookie".equalsIgnoreCase(name)) {
        continue; // Don't forward cookies
    }
    else if ("Authorization".equalsIgnoreCase(name)) {
        continue; // Don't forward Basic-Auth creds
    }
    String value = request.getHeader(name);
    adfonicParams.put("h." + name.toLowerCase(), value);
}
%>

<!-- your HTML here -->

<%-- Fetch and include (inline) an Adfonic ad for a given AdSpace ID --%>
<%= getAdfonicAd(request,
                 response,
                 "137fc618-639a-486e-ab43-c95d0fb3b139",
                 adfonicParams) %>

<%!
/** Get embedded/inline ad content from Adfonic.  You may call this method
    as many times as needed per page in order to display multiple ads.
    @param adSpaceID the ID of the publisher's ad space
    @param params the targeting parameter map
*/
static String getAdfonicAd(HttpServletRequest request,
                           HttpServletResponse response,
                           String adSpaceID,
                           Map params)
{
    StringBuffer buf = new StringBuffer();
    buf.append("http://adfonic.net/ad/")
        .append(adSpaceID)
        .append("?");
    boolean firstParam = true;
    for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
        String name = (String)iter.next();
        String value = (String)params.get(name);
        if (firstParam) {
            firstParam = false;
        }
        else {
            buf.append('&');
        }
        buf.append(name)
            .append('=');
        try {
            buf.append(URLEncoder.encode(value, "utf-8"));
        }
        catch (UnsupportedEncodingException e) {
            return "<!-- No ad available, exception caught: " +
                e.getClass().getName() + ": " + e.getMessage() + " -->";
        }
    }
    String url = buf.toString();
    InputStream inputStream = null;
    try {
        HttpURLConnection conn =
            (HttpURLConnection)new URL(url).openConnection();
        // Uncomment the following lines in order to enforce timeouts
        //conn.setConnectTimeout(10000);
        //conn.setReadTimeout(30000);
        conn.setAllowUserInteraction(false);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setDoOutput(false);
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(false);
        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            // No ad available
            return "<!-- No ad available, HTTP response code: " +
                conn.getResponseCode() + " -->";
        }

        inputStream = conn.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[8192];
        int numRead;
        while ((numRead = inputStream.read(buffer)) > 0) {
            baos.write(buffer, 0, numRead);
        }
        Map responseParams = decodeParams(baos.toString());
        String trackingId = (String)responseParams.get("trackingId");
        if (trackingId != null) {
            // Cookie the user with the Adfonic tracking ID so that we can
            // more effectively target them on subsequent requests
            Cookie cookie = new Cookie("adfonic-tracking-id", trackingId);
            cookie.setMaxAge(3600 * 24 * 365 * 2); // 2 years
            response.addCookie(cookie);
        }
        String adContent = (String)responseParams.get("adContent");
        if (adContent != null) {
            return adContent;
        }
        String errorMessage = (String)responseParams.get("error");
        return "<!-- No ad available, Adfonic error: " + errorMessage + "-->";
    }
    catch (java.io.IOException e) {
        return "<!-- No ad available, exception caught: " +
            e.getClass().getName() + ": " + e.getMessage() + " -->";
    }
    finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            }
            catch (java.io.IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

static String getAdfonicTrackingID(HttpServletRequest request) {
    Cookie[] cookies = request.getCookies();
    for (int k = 0; cookies != null && k < cookies.length; ++k) {
        if ("adfonic-tracking-id".equals(cookies[k].getName())) {
            return cookies[k].getValue();
        }
    }
    return null;
}

static Map decodeParams(String encoded) {
    Map params = new HashMap();
    StringTokenizer tokenizer = new StringTokenizer(encoded, "&");
    while (tokenizer.hasMoreTokens()) {
        String nvp = tokenizer.nextToken();
        String[] toks = nvp.split("=");
        if (toks.length == 2 && toks[1].length() > 0) {
            try {
                params.put(URLDecoder.decode(toks[0], "utf-8"),
                           URLDecoder.decode(toks[1], "utf-8"));
            }
            catch (java.io.UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
    }
    return params;
}

static String md5(String key) {
    java.security.MessageDigest md;
    try {
        md = java.security.MessageDigest.getInstance("MD5");
    }
    catch (java.security.GeneralSecurityException e) {
        throw new RuntimeException(e);
    }
    byte[] digest = md.digest(key.getBytes());
    StringBuffer buf = new StringBuffer();
    for (int k = 0; k < digest.length; ++k) {
        buf.append(Integer.toHexString((digest[k] & 0xf0) >> 4));
        buf.append(Integer.toHexString(digest[k] & 0x0f));
    }
    return buf.toString().toUpperCase();
}
%>
Personal tools
Namespaces
Variants
Actions
App/Site Integration
Ad Campaign Tracking
Adfonic API
Troubleshooting
Toolbox