Omniture API: Pulling Campaign Tracking Code Click-Throughs programatically

This is the process I used to pull campaign tracking code click throughs programatically through the Omniture Reporting API. While you can start with code, I found it to be much more productive to use Omniture’s API Explorer to figure out exactly what I wanted first. The API Explorer is nice because it shows you the available methods  with their parameters and gives you immediate feedback as to whether it worked or not. The first section below goes through the API Explorer. The second half contains the code I wrote and is specific to C# and Visual Studio 2010.

Access to the API

First, you need web service access to Omniture. This creates a Share Secret key which is used instead of your password when making API calls. The username passed to the API is a combination of your company and your Omniture username: :.  Your username and shared key should look something like this:

  • Username: jdoe:Company
  • Shared Secret: 728275238473afe875ae398fea323ad3

 

API Explorer

You’ll want to verify that your username and shared secret actually work. The best way to do that is with the API Explorer. Enter your username and shared secret in the first section.

/images/legacy/2012-04-10_142911.png

In the next section, choose "Company" for the API and "GetTokenCount" for the Method. This is a great Method to start with because it doesn’t require any parameters. Click "Get Response".

/images/legacy/2012-04-10_143825.png

The response shows up in a box below. If there are any problems, the error will appear here. If all is well, you’ll see the data you requested. In this case, we asked for the Token Count and got back 9978. Omniture gives you an allotment of API tokens. Each call you make (regardless of the response size) consumes 1 token.

/images/legacy/2012-04-10_143320.png

Now that we know that we can successfully access the API, the next step is figuring out the API calls you want to use and the parameters that they take. In my case, I wanted to get a Ranked Report containing the number of Click-throughs for each Campaign Tracking Code. The Report API documentation explains most of the parameter fields and options. I selected "Report" for the API, and "GetRankedReport" for the Method. This populates the parameter section with a template for all possible options (it can be a bit overwhelming, but fortunately, you don’t need most of it most of the time).

/images/legacy/2012-04-10_144729.png

After quite a bit of trial and error, I ended up with this:

/images/legacy/2012-04-10_145725.png

Which results in this response:

/images/legacy/2012-04-10_150038.png

Once you figure out how to pull the data you need through the API explorer, it’s time to move on to the code.

 

The Code (Visual Studio 2010 specific)

Omniture has created guides for a number of different platforms. You can search for them on the Omniture Developer Connection. In my case, I’m building the project in Visual Studio 2010, which has a guide and some libraries that Omniture created. I followed steps 1-4 of the guide to get started as they are. Their API client class follows the request structure you used in the API Explorer pretty closely. You need to create a reportDescription object within which you will put the parameters you need.

I decided to create an Extension method to populate the reportDescription object for me. Here it is:

public static class reportDescriptionExtensions
{
    public static reportDescription PopulateWith(this reportDescription reportDescription, string reportSuite, string startDate, string endDate, string filter, int top, int startingWith)
    {
        reportDescription.reportSuiteID = reportSuite;
        reportDescription.dateFrom = startDate;
        reportDescription.dateTo = endDate;
        reportDescription.metrics = new reportDefinitionMetric[]
            {
                new reportDefinitionMetric() { id = "instances" }
            };
        reportDescription.elements = new reportDefinitionElement[]
            {
                new reportDefinitionElement()
                {
                    id = "trackingCode",
                    search = new reportDefinitionSearch()
                    {
                        type = reportDefinitionSearchType.and,
                        keywords = new string[] { filter }
                    },
                    top = top,
                    startingWith = startingWith,
                }
            };

        return reportDescription;
    }
}

Note that the reportDescription object is created outside of this method and is passed in. I’ve both hardcoded some of the values and passed in others as arguments. I ended up adding in a few extra parameters that I didn’t have in the API Explorer example above: I added a search and split the results into pages (top & startWith). Note how the values and structure here are pretty close to what we had in the API Explorer.

Here is the client I created to pull down the report and convert it to my own reporting format. I’ll break each section down below.

public class SiteCatalystClient
{
    private string url;
    private string username;
    private string password;
    private int top;

    public SiteCatalystClient(string url, string username, string password)
    {
        this.url = url;
        this.username = username;
        this.password = password;
        top = 10000;
    }

    public ClickthroughReport GetClickThroughsReport(string reportSuite, string filter, string startDate, string endDate)
    {
        using (var client = OmnitureWebServicePortTypeClient.getClient(username, password, url))
        {
            ((CustomBinding)client.Endpoint.Binding).Elements.Find<TransportBindingElement>().MaxReceivedMessageSize = int.MaxValue;
            var startingWith = 0;
            var report = new ClickthroughReport();
            var executionCount = 0;

            do
            {
                var trackingCodeReportDescription = new reportDescription().PopulateWith(reportSuite, startDate, endDate, filter, top, startingWith);
                var reportResponse = client.ReportGetRankedReport(trackingCodeReportDescription);

                foreach (var dataPoint in reportResponse.report.data)
                {
                    report.AddRecord(new ClickthroughReportRecord()
                    {
                        Name = dataPoint.name,
                        ClickThroughs = (int)dataPoint.counts[0]
                    });
                }

                startingWith += top;

                if (reportResponse.report.data.Count() < top) break;
            } while (++executionCount < 10);

            return report;
        }
    }
}

Let’s break this down. The constructor takes the API url (https://api.omniture.com/admin/1.3/), username (the combined username from above), and password (shared secret). I also set top to the number of records I want to fetch each time.

public SiteCatalystClient(string url, string username, string password)
{
    this.url = url;
    this.username = username;
    this.password = password;
    top = 10000;
}

The only method that this class has at this time is to pull the Compaign Tracking code click-throughs. It takes the reportSuite, filter (filters on the actual tracking code to narrow the results down), and startDate and endDate. It returns a ClickthroughReport object which is my own object I use elsewhere in my project.

public ClickthroughReport GetClickThroughsReport(string reportSuite, string filter, string startDate, string endDate)

Next I instantiate the client that Omniture provided in the library we downloaded earlier, then I overrode the MaxReceivedMessageSize to the largest possible value. This sets how large the messages can be coming back from Omniture. The messages for my reports were quite large, so I just set this limit as high as it could go.

using (var client = OmnitureWebServicePortTypeClient.getClient(username, password, url))
{
    ((CustomBinding)client.Endpoint.Binding).Elements.Find<TransportBindingElement>().MaxReceivedMessageSize = int.MaxValue;

Then I set starting values for startingWith and executionCount and create my ClickthroughReport object which I will return from this method.

var startingWith = 0;
var report = new ClickthroughReport();
var executionCount = 0;</pre>

We go into a do while loop. Our result set is paged, so each time through the loop pulls the next range of data. I have it limited to 10 loops though because I don’t want this report to run for too long.

do
{
    ///.....
} while (++executionCount &lt; 10);</pre>

I create the reportDescription object (this was provided in the Omniture library) and populate it with my extension method, PopulateWith, that I showed above.

var trackingCodeReportDescription = new reportDescription().PopulateWith(reportSuite, startDate, endDate, filter, top, startingWith);

Now we finally get to the actual API call. We give it the reportDescription object we just created.

var reportResponse = client.ReportGetRankedReport(trackingCodeReportDescription);

The reportResponse object contains a property called report which contains a property called data. Data is an array with the values we want. I loop through each item and place it in to my own report record object:

foreach (var dataPoint in reportResponse.report.data)
{
    report.AddRecord(new ClickthroughReportRecord()
    {
        Name = dataPoint.name,
        ClickThroughs = (int)dataPoint.counts[0]
    });
}

The last little bit is to increment the record we’ll start with next time and break out of the loop if we’re at the end of the result set.

startingWith += top;

if (reportResponse.report.data.Count() < top) break;

I return my report object which is essentially just a list of campaign codes with their corresponding click-through values.