Conversion Tracking

From MMwiki
Jump to: navigation, search

Contents

Page Navigation

This page contains detailed steps for implementing Conversion Tracking. We offer multiple methods to provide you with the flexibility in determining which solution fits your capabilities. We offer an SDK for iPhone, Android, and Blackberry that can be added to your application. If you are unable to include the Conversion Code library in your application, we offer the Server-to-Server methods detailed below.

Getting Started

First, we need to determine the type of conversion tracking you will need. Please take a moment to identify which option best suits your desired implementation method. The links will take you to the appropriate section of this article.

Application

  1. If you are able to implement Millennial Media's SDK into the application, please choose the OS type: iOS, Android, or Blackberry
  2. If you are unable to implement the SDK, please use the Application Server-to-Server method.

Mobile Web

  1. For conversions that occur on the Mobile Web, please use the Mobile Web Server-to-Server method.

SDK Implementations

Millennial Media is committed to making conversion tracking fast and simple for our App Developer partners. We have simplified the code that needs to be added to your application and created step by step instructions to eliminate any confusion when implementing our code. In addition, our conversion tracking solution now includes our publisher side SDK.
Now, you can easily integrate conversion tracking to evaluate and optimize the effectiveness of your ad spend. At the same time, you can begin monetizing your own valuable inventory by accessing our premium advertiser demand pool.
Only interested in tracking conversions? No problem. Our intuitive developer portal will make it easy to begin requesting ads should you decide to down the road.

How Does it work?

Simply imbed our SDK library into your application. Your application likely has several things it will try to do once it has completed launching. You just need to add our code to be included among those things. When a user launches your application, that code will run, and automatically report the event to us so that we can compare your advertising activity to your download activity and give you a positive indicator of how effective your media spend really is.
If you would like to make ad requests to Millennial Media, our SDK library allows for that as well. Simply follow the steps in our Developer Portal to begin earning money on your ad inventory.

iPhone/iPad Application Conversion Tracking

Step 1: Request a Goal ID from Millennial Media

This value is assigned uniquely to you and helps us match up your campaign activity with your application launch activity. For advertisers, your Account Executive can handle this request for you.

If you have multiple applications or goals, you should request a dedicated Goal ID for each one.

Step 2: Download Millennial Media's SDK

Please click here to sign up through our Developer's Portal and obtain the iPhone SDK. You will be asked to create a password, provide a few details, and then you will be ready to download the SDK. Only the fields with asterisks are required, and you can click "Continue without adding Apps" to skip the Add Apps screen and go directly to the Dashboard. Simply scroll over the SDK Downloads Option in the toolbar and select the iPhone SDK (iPad is the same). The download button will be right on the top of the instructions page. More step by step detail is provided on the download page as well as below. To begin monetizing your ad inventory with Millennial Media, simply click the "Manage Apps" button in the toolbar and register your apps.

Step 3: Import Library into Application

Open the iPhone/iPod-Touch window-based application where the library is going to be integrated into.
From the finder window where the libMMSDK.a file is located, drag the libMMSDK.a file into the XCode project, and drop it over the Frameworks folder as shown in the image below:

SDK1.png

A dialog box will pop up; make sure that the "Copy items into destination group’s folder" is checked as well as the "Add To Targets" option, as seen in the image below:

SDK2.png

The library file will be automatically added inside "Targets => <project name> => Link Binary With Libraries section" as well.
From the finder, drag the MMAdView.h header file into the XCode project, and drop it over the Classes folder as indicated below:

SDK3.png

A dialog will pop up; make sure that the "Copy items into destination group’s folder" is checked as well as the "Add To Targets" option.
In your application Delegate implementation file, normally called “ProjectNameAppDelegate.m”, import the MMAdView.h header.

Step 4: Conversion Tracking Class Method

Your application will typically have an app delegate and will use the applicationDidFinishLaunching method. This will allow you to track when a user starts the application for the first time. Furthermore, you may place the class method anywhere you want to track a particular conversion event. You can use our conversion tracker by simply calling the following method.

[MMAdView startSynchronousConversionTrackerWithGoalId:@"YOUR_GOAL_ID"];
About

This method starts a synchronous connection to the Millennial Media conversion tracker.

+ (void) startSynchronousConversionTrackerWithGoalId: (NSString *) goalid

Parameters

goalid: The Millennial Media Goal Id for tracking conversions for your application.

Discussion

We recommend calling this method on a background thread to prevent blocking the main thread.

Availability

v4.1.0 and later

Multiple Conversions (SDK 4.5+ Only)

If you want to track multiple conversions within the same app, you can place the above method in different sections of your app and each one will be treated as a separate conversion event. Before doing so, please make sure to request separate Goal IDs for each unique conversion event you wish to track.

Android Conversion Tracking

Step 1: Request a Goal ID from Millennial Media

This value is assigned uniquely to you and helps us match up your campaign activity with your application launch activity. For advertisers, your Account Executive can handle this request for you.

If you have multiple applications or goals, you should request a dedicated Goal ID for each one.

Step 2: Download Millennial Media's SDK

Please click here to sign up through our Developer's Portal and obtain the Android SDK. You will be asked to create a password, provide a few details, and then you will be ready to download the SDK. Only the fields with asterisks are required, and you can click "Continue without adding Apps" to skip the Add Apps screen and go directly to the Dashboard. Simply scroll over the SDK Downloads Option in the toolbar and select the Android SDK. The download button will be right on the top of the instructions page. More step by step detail is provided on the download page as well as below. To begin monetizing your ad inventory with Millennial Media, simply click the "Manage Apps" button in the toolbar and register your apps.

Step 3: MMAdView.jar

Place the MMAdView.jar into the libs directory of your Android project.

Step 4: Set the permissions

  • Add the necessary permissions to your ApplicationManifest.xml file so the library can call for ads:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Step 5: Conversion Tracking Static Method

Your application will typically have an app delegate and will use the OnCreate method. This will allow you to track when a user starts the application for the first time. Furthermore, you may place the static method anywhere you want to track a particular conversion event. To use this feature, ensure your account manager has provided a Goal ID and implement the static method below.

public static void startConversionTrackerWithGoalId(final Context context, final String goalId)

For example,

MMAdView.startConversionTrackerWithGoalId(this, "12345");
Multiple Conversions (SDK 4.5+ Only)

If you want to track multiple conversions within the same app, you can place the above method in different sections of your app and each one will be treated as a separate conversion event. Before doing so, please make sure to request separate Goal IDs for each unique conversion event you wish to track.

BlackBerry Conversion Tracking

This does not include a library. This is just source.

Step 1: Request a Goal ID from Millennial Media

This value is assigned uniquely to you and helps us match up your campaign activity with your application launch activity. For advertisers, your Account Executive can handle this request for you.

You can either ask to receive a text file with our Conversion Code and your Goal ID included, or you can simply insert the Goal ID yourself within the quotation marks where it says "INSERT_GOALID". For example, if your goal id is 12345, you would insert that value as follows within the source code.

sb.append("12345");

If you have multiple applications, you should request a dedicated Goal ID for each one.

Step 2: Main Function

Below is example on how to utilize the mmiConversionTracker class to track conversions. We have utilized the main function of the UIApplication, but this can also be used in any of your start up functions. This assumes you have the mmiConversionTracker static class embedded in your application package.

class HelloWorld extends net.rim.device.api.ui.UiApplication 
{
    public static void main(String[] args)
    {
	       mmiConversionTracker.sendNotification(<APID>, <ACID>)
        HelloWorld instance = new HelloWorld();
        instance.enterEventDispatcher();
    }  
    . . . 
}

Step 3: mmiConversionTracker Static Class

The code below provides a mmiConversionTracker static class. This static class will need to be embedded into the project as a separate class.

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.RadioInfo;

public final class mmiConversionTracker
{
    /**
     * Call the conversion tracking notification URL for the given Goal ID
     * 
     * This should be called upon application initialization.
     * 
     * @param goalid
     *- The assigned goalid
     */
    public static void sendNotification(long goalid)
    {
        StringBuffer sb = new StringBuffer();

        // Build the URL for conversion tracking
        sb.append("http://cvt.mydas.mobi/handleConversion?goalid=");
        sb.append("INSERT_GOALID");
        sb.append("&auid=");
        sb.append(DeviceInfo.getDeviceId());

        // Make the connection
        try
        {
            HttpConnection connection =(HttpConnection) Connector.open(sb.toString());
            // We will ignore the response, so just open the input stream to
            // make the request
            InputStream is = connection.openInputStream();
            is.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Notes: The Goal ID is supplied by Millennial Media. Auid is a unique identifier used by Millennial Media. For Blackberries, the code will map the User Hashed Pin to this value.

Server-to-Server

The goal of conversion matching is to find a common unique identifier that you as the advertiser/developer and Millennial Media will have access to separately. That’s why the server-to-server options for conversion tracking ask for specific items like Device ID and IP Address. Depending on where we saw the device in our network, whether it is In App or on the Mobile Web, the unique identifier that we can use to track a conversion changes. Please read each section of the implementation method you wish to use thoroughly to help you better understand why we request specific information and why this information is necessary.

Application Server-to-Server

If you are unable to include our SDK, and you want to pass the data to us directly from your server, we can support that via our API. This requires that you capture each conversion event and log it to your server. You will still need to request a Goal ID from Millennial Media.
Please note, the GOAL ID, AUID, and IP Address are required parameters. If you are submitting conversion to us in batch then we ask that you also provide the UNIX Timestamp as well via the timestamp variable. As long as you submit conversion to us in real time then the timestamp is not required. IP is required for conversion tracking outside of “application inventory”, in other words, “the mobile web”. In order to run across our whole network, we need to receive both AUID and IP Address. When passing data to our server, the call will be made to the following API.
http://cvt.mydas.mobi/handleConversion?goalid=<goal_id>&auid=<DEVICE_ID>&uip=<DEVICE_IP>&timestamp=<UNIX_Timestamp> 
When setting up the server side call to our API, the Goal ID should be hard coded, as it will always be the same. For example, if your goal id is 12345, then the call to our API would always have that value in the goal slot. See below:
http://cvt.mydas.mobi/handleConversion?goalid=12345&auid=<DEVICE_ID>&uip=<DEVICE_IP>&timestamp=<UNIX_Timestamp> 

IP Address

For conversions that occur from users that clicked on your advertisement on a mobile website, and are then directed to an app store, the IP Address must be passed to us for a conversion match to occur. If the converting device’s unique external IP Address is not provided, we will not have anything to match to the information you sent to our API, and no conversion match will occur. If for some reason you are unable to provide Millennial Media with the device’s IP Address, we will need to restrict your campaign from running on the mobile web. For more information on how to obtain a device’s IP Address, please click here.

Device ID

For devices like the iPhone, iPad, or iPod Touch the Device ID we use the UDID to match conversions, but Android devices have a couple of different identifiers that can be used to uniquely identify a device. It’s important to understand which one, and when, Millennial Media will have. Below you will find a list of the unique identifiers in the order that they should be provided. As you can see, we first attempt to acquire the DEVICE ID, and if not available we attempt to grab the ANDROID ID. If you are always sending the ANDROID ID, then a conversion would not match if we were able to acquire the DEVICE ID first since we would have two separate IDs for the device. Please try to always acquire the Device ID to ensure that no conversions are lost.
Device ID Priority
  1. Device ID
    • iOS Devices
    Every iPhone, iPad or iPod Touch contains a Unique Device Identifier (UDID), which is a sequence of 40 letters and numbers that are specific to that device and cannot be changed.
    • Android Devices
    The Device ID for Android will return an ID that is dependent on that device’s carrier. If the carrier is CDMA, then the Device ID will be the MEID (or the ESN). For GSM networks, the Device ID returned is the IMEI. These should always be the default ID that is provided for any conversion that takes place on an Android device. If the device is not tied to a carrier and does not return a DEVICE ID because it is a tablet or some other non-telephony device, then you should move on to the Android ID below.
  2. Android ID
    This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped but in regards to conversion tracking this scenario isn’t much of a concern. ANDROID_ID seems to be a good choice for a unique device identifier. There is however a downside in that it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Millennial Media falls back to the Android ID in instances where the Device ID is unavailable.
For more information on how to acquire the various Android Device IDs, please click here.

Passing Hashed IDs on Conversion Calls

Millennial Media provides a mechanism to submit hashed identifiers instead of specific device IDs. The supported hashing algorithms are MD5 and SHA1. The hashed IDs can be passed to the Conversion Tracking API using the 'hdid' query parameter. It is important that only hashed device identifiers are submitted using the 'hdid' variable. For un-hashed device identifiers, please continue to use the 'auid' variable. Any device IDs submitted using 'auid' will be hashed by our system automatically. It is assumed that any device IDs submitted using the 'hdid' variable are already hashed and will not be hashed again.
An example conversion API call using the hashed ID:
http://cvt.mydas.mobi/handleConversion?goalid=<goal_id>&hdid=<HASHED_DEVICE_ID>&uip=<DEVICE_IP>
For more information on how to hash a device ID using MD5 and SHA1, please click here.

Mobile Web Server-to-Server

If you want to pass the conversion data to us directly from your server, we can support that via our API. This requires that you capture each conversion event and log it to your server. Millennial Media will append a URID variable to the end of your destination URL upon a successful click. The URID must follow the user throughout the conversion process and when a successful conversion event occurs you must make a server to server call to our conversion tracking API with the URID included. You will still need to request a Goal ID from Millennial Media. When passing data to our server, the call will be made to the following API.
Please note, the URID and GOAL ID are required parameters. If you are submitting conversion to us in batch then we ask that you also provide the UNIX Timestamp as well via the timestamp variable. As long as you submit conversion to us in real time then the timestamp is not required.
http://cvt.mydas.mobi/handleConversion?goalid=<goal_id>&urid=<URID_ID>&timestamp=<unix_timestamp>
When setting up the server side call to our API, the Goal ID should be hard coded, as it will always be the same. For example, if your goal id is 12345, then the call to our API would always have that value in the goal slot. See below:
http://cvt.mydas.mobi/handleConversion?goalid=12345&urid=<URID_ID>&timestamp=<unix_timestamp>

How the Process Works

1. Let's say a user views your banner on a mobile site or application and the banner’s destination URL is http://m.yourmobilesite.com/home.php
2. When the user clicks on your banner, Millennial Media’s AdServer appends the URID (Unique Request ID) variable to the end of the destination URL like so:
http://m.yourmobilesite.com/home.php?mm_urid=b4ddba7cbbc7cef302937c6d8c28f4d7
*If necessary, Millennial Media is able to append the value of URID to a URL without “mm_urid=”
3. Once the user lands on your page ensure that the URID value follows that user throughout the conversion process.
4. Once a conversion has taken place, you will need to configure your server to make a call to our Conversion Tracking API via the following example call:
http://cvt.mydas.mobi/handleConversion?goalid=12345&urid=b4ddba7cbbc7cef302937c6d8c28f4d7&timestamp=1303331718

Important

The Mobile Web Server-to-Server method relies on our ability to append parameters to the destination URL. Without that ability, Mobile Web Server-to-Server conversion tracking will fail. This is important to keep in mind when using a 3rd Party click tracker for your campaign. Not all 3rd Party tracking vendors or tag formats provide the ability to append variables to the end of the click tag. If you are planning on using a 3rd party tracker with a campaign that will utilize Mobile Web Server-to-Server conversion tracking, please make sure the vendor supports this function before launching the campaign. It's equally as important that you inform your Millennial Media contact as soon as possible regarding which 3rd Party tracker you plan to work with. This will allow us to address any concerns prior to receiving the tags from you. For a list of confirmed 3rd Party trackers that support this ability, please see this section of our FAQ.

FAQ

Supported 3rd Party Tracking Vendors

The following list displays our certified 3rd party tracking vendors and whether they support parameter passing for use with Mobile Web Server-to-Server conversion tracking. Using any vendor outside of this list is not advisable and we cannot guarantee success.

Vendor Compatibility Details
DART Supports parameter passing via the Long (Static) form of the Click Tracker tag. Supported

Long (Static): http://ad.doubleclick.net/clk;123456789;87654321;i?http://m.yourwebsite.com/home.php
Unsupported
Short (Dynamic): http://ad.doubleclick.net/clk;123456789;87654321;i
Standard Tag: Wrapped in an <a href> tag.
iFrame Tag: Wrapped in an <iframe> tag.
JavaScript Tag: Wrapped in a <script> tag.

Atlas Supports parameter passing Click Tag

http://clk.atdmt.com/MRT/go/123456789/direct;wi.1;hi.1/01/

Mediamind Does NOT support parameter passing and should not be used with Mobile Web Server-to-Server conversion tracking. Unsupported
Mediaplex Supports parameter passing with additional configuration. Instructions - Screenshot of Interface for reference.
  1. Click on the Placement name.
  2. Click on the Options tab.
  3. Check the Forward checkbox.
  4. Optional - any variables you do not wish to be passed on should be specified in the Strip field (space should be used as a delimiter).
  5. Click on the Update button at the bottom of the page.
  6. Click on the placement Submit link (this can be found at either the top right corner if you are in the placement details or at the campaign level).
  7. Test and verify.
Velti Static form of standard tags support parameter passing. The Dynamic tags do not. Static

http://ad2.adinfuse.com/is/fb/12345678/web.htm?random=timestamp


IP Address

I would like to run on Mobile Web inventory, how can I obtain a user's IP Address?

Here are the different methods of obtaining a user's IP Address depending on the coding of your site. These same methods should work for applications as well. The following should only be used as a reference.
Language Code - "ip_addr" can be changed to whichever variable you prefer.
PHP @$ip_addr = $_SERVER['REMOTE_ADDR']
ASP Dim ip_addr

ip_addr = Server.URLEncode( Request.ServerVariables( "REMOTE_ADDR" ) )

JSP5 String ip_addr = request.getRemoteAddr();

ip_addr = URLEncoder.encode( ip_addr, "UTF-8" );

PERL my $ip_addr = URI::URL->new($ENV{'REMOTE_ADDR'})
Ruby On Rails ip_addr = request.env['REMOTE_ADDR']
VB.net Dim ip_addr as String = Server.URLEncode( Request.ServerVariables( "REMOTE_ADDR" ) )

Obtaining Android Device IDs

Two common identifiers are used to differ between unique Android devices: Device ID and Android ID. The following code, when implemented, will attempt to obtain the Device ID first and then move on to the Android ID if no Device ID is available.
	// Get the device ID
          auid = android.provider.Settings.Secure.ANDROID_ID + "android_id";
          tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
          if(tm != null)
          {
               try{
               auid = tm.getDeviceId();
               }
               catch (SecurityException e){
                    e.printStackTrace();
               }
               tm = null;
          }
          if(((auid == null) || (auid.length() == 0)) && (context != null))
               auid = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
          if((auid == null) || (auid.length() == 0))
               auid = null;

Hashing Device IDs

MD5

The following Java code provides one method of hashing IDs using MD5.
/**
     * <p>
     * Hashes the given plain text using the MD5 algorithm.
     * </p>
     * 
     * <p>
     * Example:
     * </p>
     * 
     * <p>
     * 098f6bcd4621d373cade4e832627b4f6
     * </p>
     * 
     * @param userId
     *            The raw user ID which must be hashed.
     * @return A String representing the MD5 hashed user.
     */
    public static String hashUserIdMD5(String userId)
    {
        String rv = null;
          
        if (userId != null)
        {
            try
            {
                // Hash the user ID
                byte[] hashBytes = null;
                MessageDigest md = MessageDigest.getInstance("MD5");
                  
                synchronized (md)
                {
                    hashBytes = md.digest(userId.getBytes());
                }
                 
                // Convert the hashed bytes into a properly formatted String
                if (hashBytes != null)
                {
                    StringBuilder sb = new StringBuilder();
                    
                    for (byte b : hashBytes)
                    {
                        String hexString = Integer.toHexString(0x00FF & b);
                        sb.append((hexString.length() == 1) ? "0" + hexString
                                                           : hexString);
                    }
                         
                    rv = sb.toString();
                }
            }
            catch (NoSuchAlgorithmException exception)
            {
                // This exception should never occur
            }
        }
         
        return rv;
    }

SHA1

The following Java code provides one method of hashing IDs using SHA1.
/**
     * <p>
     * Hashes the given plain text using the SHA-1 algorithm.
     * </p>
     *
     * <p>
     * Example:
     * </p>
     *
     * <p>
     * a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
     * </p>
     *
     * @param userId
     *            The raw user ID which must be hashed.
     * @return A String representing the SHA-1 hashed user ID.
     */
    public static String hashUserIdSHA1(String userId)
    {
        String rv = null;
          
        if (userId != null)
        {
            try
            {
                // Hash the user ID
                byte[] hashBytes = null;
                MessageDigest md = MessageDigest.getInstance("SHA1");
             
                synchronized (md)
                {
                    hashBytes = md.digest(userId.getBytes());
                }
              
                // Convert the hashed bytes into a properly formatted String
                if (hashBytes != null)
                {
                    StringBuilder sb = new StringBuilder();
              
                    for (byte b : hashBytes)
                    {
                        String hexString = Integer.toHexString(0x00FF & b);
                        sb.append((hexString.length() == 1) ? "0" + hexString
                                                           : hexString);
                    }
                 
                    rv = sb.toString();
                }
            }
            catch (NoSuchAlgorithmException exception)
            {
                // This exception should never occur
            }
        }
             
        return rv;
    }

Explanation of Parameters

What do each of the parameters of the API call represent?

Parameter Name Description Advertiser Requirement
AUID A persistent, unique ID that identifies the device. This is the primary matching component for matching app launches to our click.

This is the "Hashed Pin" for Blackberries, "Device ID" or "Android ID" for Androids, and "Unique Device ID" for iPhones.

Advertiser is responsible to capture and log the Device ID (observed from the device) upon the launch of the application.
HDID A hashed persistent, unique ID that identifies the device. This is the primary matching component for matching app launches to our click and should be used when submitting already hashed device IDs to us.

This is the "Hashed Pin" for Blackberries, hashed versions of "Device ID" or "Android ID" for Androids, and hashed "Unique Device ID" for iPhones.

Advertiser is responsible to capture, log, and hash the Device ID (observed from the device) upon the launch of the application. If you are not going to submit the already hashed device ID, please use the AUID parameter above.

We currently support MD5 and SHA1 hash strings only.

Goal ID A unique ID value assigned to Millennial Media advertisers for identification purposes. A unique Goal ID will be assigned to you upon request. A unique Goal ID should be requested for each individual conversion we are tracking.
Timestamp This represents the time of the conversion event and can be used to identify time of day trends. Should be formatted as UNIX time (in seconds). This should be assigned by your server at the time the conversion event occurs so it can be passed to us. This is only required if you are not submitting conversions to us in real time.
UIP IP Address is the numerical label that is assigned to devices for host identification and location tracking.

This is needed for matching app launches to clicks outside of in app inventory.

Advertiser is responsible to capture and log the IP Address (observed from the device) upon the launch of the application.

What is a UNIX Timestamp?

The UNIX timestamp is a way to track time as a running total of seconds. This count starts at the UNIX Epoch on January 1st, 1970. Therefore, the UNIX timestamp is merely the number of seconds between a particular date and the UNIX Epoch. This is very useful to computer systems for tracking and sorting dated information in dynamic and distributed applications both online and client side.
Personal tools
For Mobile Web Developers
Creative Services