Microsoft Advertising APIs
Request and Download a Keyword Performance Report in Perl

The following code sample shows how to request and retrieve a keyword performance report by using Perl.

# For release code, use the following SOAP::Lite statement.
#use SOAP::Lite ( +maptype => {} );
# For debugging code, use the following SOAP::Lite statement.
use SOAP::Lite ( +trace => all, maptype => {} );

use LWP::Simple;
use File::Basename;
use strict;

eval
{
    my $username = "username";
    my $password = "password";
    my $devToken = "devtoken";
    my $appToken = "apptoken";
    my $customerAccountId = "customerid";
    my $customerId = "customerid";
    my $accountId = 123456;
    my $zipFile = "c:\\temp\\KeywordPerformanceReport.zip";
    
    # Use either the sandbox or the production URI.
    # This example is for the sandbox URI.
    my $URI = "https://sandboxapi.microsoft.com/V6";
    # The following commented-out line contains the production URI.
    #my $URI = "https://adcenterapi.microsoft.com/V6";
    
    # The Microsoft adCenter API namespace.
    my $xmlns = "https://adcenter.microsoft.com/v6";
    
    # The proxy for the reporting Web service.
    my $reportingProxy = $URI."/Reporting/ReportingService.svc?wsdl";
    
    # The common data-type namespace.
    my $namespaceArrays =
        "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
    
    # The service operation that will be called.
    my $action = 'SubmitGenerateReport';
    
    # The Web service.
    my $reportingService = SOAP::Lite->new(
        uri => $URI, 
        proxy => $reportingProxy, 
        on_action => ( sub { return $action } ));
    $reportingService->autotype(0);
    $reportingService->multirefinplace(1);
    $reportingService->readable(1);
    
    my $ReportRequest = CreateKeywordPerformanceReportRequest(
        'My Keyword Report',
        $accountId);
    
    my $reportRequestId;
    
    # Assemble the service operation parameters.
    my @header = CreateV6Header(
        $username,
        $password,
        $devToken,
        $appToken,
        $customerAccountId,
        $customerId);
    
    my @params =
    (
        @header,
        $ReportRequest
    );
    
    # Make the adCenter API call.
    my $methodQueueReport = SOAP::Data->name
    (
        $action."Request"
    )->attr({xmlns => $xmlns});
    
    my $response = $reportingService->call(
        $methodQueueReport => @params);
    
    # Check for errors.
    if ($response->fault) 
    {
        print "$action failed.\n";
        
        # Display the fault code and the fault string.
        print $response->faultcode, " ", $response->faultstring, "\n";
        
        # Display any ApiFault faults.
        if($response->match("//ApiFaultDetail"))
        {
            # Display the adCenter tracking ID.
            my $trackingId = $response->valueof("
                //ApiFaultDetail/TrackingId");
            print "TrackingId: $trackingId\n";
            
            # Display adCenter operation errors.
            my @operationErrors = $response->valueof(
                "//ApiFaultDetail/OperationErrors/OperationError");
            foreach my $operationError (@operationErrors)
            {
                print 
                    "Operation error ($operationError->{Code}) encountered.";
                print "$operationError->{Message}\n";        
            }
        }
        
        # Display any AdApiFault faults.
        elsif($response->match("//AdApiFaultDetail"))
        {
            # Display the adCenter tracking ID.
            my $trackingId = $response->valueof(
                "//AdApiFaultDetail/TrackingId");
            print "TrackingId: $trackingId\n";
            
            # Display adCenter operation errors.
            my @adApiErrors = $response->valueof(
                "//AdApiFaultDetail/Errors/AdApiError");
            foreach my $adApiError (@adApiErrors)
            {
                print "Ad API error ($adApiError->{Code}) encountered. ";
                print "$adApiError->{Message}\n";        
            }
        }
    }
    else
    {
        print "Successful call to $action.\n";
    
        # Display the adCenter tracking ID.
        my $trackingId = $response->valueof(
            '//ApiCallTrackingData/TrackingId');
        print "TrackingId: $trackingId\n";
        
        my $reportId = $response->valueof('//ReportRequestId');
        $reportRequestId = $reportId;
        
        RetrieveReport($reportId, $zipFile);
    }
    
    sub CreateV6Header
    {
        # Method parameters.
        my (
            $username,
            $password,
            $devtoken,
            $apptoken,
            $customeraccountid,
            $customerid) = @_;
        
        # Initialize the application token.
        my $AppToken = SOAP::Header->name
        (
            "ApplicationToken"=>$apptoken
        )->attr({xmlns => $xmlns});
        
        # Initialize the developer token.
        my $DevToken =SOAP::Header->name
        (
            "DeveloperToken"=>$devtoken
        )->attr({xmlns => $xmlns});
        
        # Initialize the user name.
        my $UserName =SOAP::Header->name
        (
            "UserName"=>$username
        )->attr({xmlns => $xmlns});
        
        # Initialize the password.
        my $Password =SOAP::Header->name
        (
            "Password"=>$password
        )->attr({xmlns => $xmlns});
        
        # Initialize the customer account ID.
        my $CustomerAccountId =SOAP::Header->name
        (
            "CustomerAccountId"=>$customeraccountid
        )->attr({xmlns => $xmlns});
        
        # Initialize the customer ID.
        my $CustomerId =SOAP::Header->name
        (
            "CustomerId"=>$customerid
        )->attr({xmlns => $xmlns});
        
        # Assemble the header parameters.
        my @headerParams =
        (
            $AppToken,
            $CustomerAccountId,
            $CustomerId,
            $DevToken,
            $Password,
            $UserName, 
        );
        
        return @headerParams;
    }

    
    # This subroutine creates the keyword performance report request.
    # Some of the data is passed in to the subroutine, but the majority
    # of it is hard-coded.
    sub CreateKeywordPerformanceReportRequest
    {
        my ($nameOfReport, $accountForReport) = @_;
        
        # Request an XML report.
        my $format = SOAP::Data->name("Format" => "Xml");
    
        # Use the English language.
        my $language = SOAP::Data->name("Language" => "English");
        
        # Specify the report name.
        my $reportName = SOAP::Data->name(
            "ReportName" => $nameOfReport);
        
        # Allow partial data to be returned.
        my $returnOnlyCompleteData = SOAP::Data->name(
            "ReturnOnlyCompleteData" => "false");
        
        # Specify the report aggregation.
        my $aggregation = SOAP::Data->name("Aggregation" => "Monthly");
        
        # Specify the time frame of the report. For this example, it is
        # the last six months.
        my $time = SOAP::Data->name("Time" => \SOAP::Data->value
        (
            #SOAP::Data->name("CustomDateRangeEnd" => ""),
            #SOAP::Data->name("CustomDateRangeStart" => ""),
            #SOAP::Data->name("CustomDates" => ""),
            SOAP::Data->name("PredefinedTime" => "LastSixMonths")
        ));
        
        # Specify the account that the report is for.
        my $accountIds = SOAP::Data->name("AccountIds" =>
            \SOAP::Data->value
        (
            SOAP::Data->name("int")->value(
                $accountForReport)->uri($namespaceArrays)
        ));
        
        my $scope = SOAP::Data->name("Scope" =>
            \SOAP::Data->value($accountIds));
    
        # Specify the columns that will be in the report.
        my $columns = SOAP::Data->name("Columns" => \SOAP::Data->value
        (
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "AccountName"),
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "CampaignName"),
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "Keyword"),
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "TimePeriod"),
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "Impressions"),
            SOAP::Data->name(
                "KeywordPerformanceReportColumn" => "Conversions"),
        ));
        
        # Specify the filter for the report. The report request 
        # in this example specifies only the search ads that were
        # displayed in the United States.
        my $filter = SOAP::Data->name("Filter" => \SOAP::Data->value
        (
            SOAP::Data->name("AdDistribution" => "Search"),
            #SOAP::Data->name("DeliveredMatchType" => ""),
            #SOAP::Data->name("Keywords" => ""),
            SOAP::Data->name("LanguageAndRegion" => "UnitedStates")
        ));
        
        # Create the report request object.
        my $request = SOAP::Data->name("ReportRequest" =>
            \SOAP::Data->value
        (
            $format,
            $language,
            $reportName,
            $returnOnlyCompleteData,
            $aggregation,
            $columns,
            $filter,
            $scope,
            $time
        ));
    
        # Set the request attributes.
        $request->attr
        ({
            'i:type' => 'KeywordPerformanceReportRequest',
            'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'
        });
        
        return $request;
    }
    
    
    # This subroutine calls the PollGenerateReport service operation.
    sub GetReportStatus
    {
        my $reportRequestId=$_[0];
        
        my @header = CreateV6Header(
            $username,
            $password,
            $devToken,
            $appToken,
            $customerAccountId,
            $customerId);
        
        # This is important because the on_action property of the Web
        # service uses a reference to this global variable. If you
        # don't change the global variable, the wrong service operation
        # might be called.
        $action = "PollGenerateReport";
        
        my @params =
        (
            @header,
            SOAP::Data->name("ReportRequestId" => $reportRequestId)
        );
        
        my $methodGetReportStatus = SOAP::Data->name(
            $action.'Request')->attr({xmlns => $xmlns});
        my $response = $reportingService->call(
            $methodGetReportStatus => @params);
    
        if ($response->fault) 
        {
            print "$action failed.\n";
            
            # Display the fault code and the fault string.
            print $response->faultcode,
                " ",
                $response->faultstring, "\n";
        
            # Display the adCenter tracking ID.
            my $trackingId =
                $response->valueof("//ApiFaultDetail/TrackingId");
            print "TrackingId: $trackingId\n";
            
            # Display adCenter operation errors.
            my @operationErrors = $response->valueof(
                "//ApiFaultDetail/OperationErrors/OperationError");
            foreach my $operationError (@operationErrors)
            {
                print
                "Operation error ($operationError->{Code}) encountered. ";
                
                print "$operationError->{Message}\n";        
            }
        }
        else
        {
            print "Successful call to $action.\n";
        }
    
        return $response;
    }
    
    # This subroutine retrieves a requested report. This subroutine
    # will work for any type of report. The only parameter needed for
    # the subroutine is the report request identifier.
    sub RetrieveReport
    {
        my ($reportRequestId, $zipFileName) = @_;
        my $polling = 1;
        my $waitMinutes = 1;
        my $content = "";
    
        while ($polling)
        {
            my $response = GetReportStatus($reportRequestId);
            my $status = $response->valueof('//Status');
            print "Status: $status \n\r";
            
            if ($status =~ /Success/)
            {
                # Get the URL of the report to download.
                my $downloadUrl = $response->valueof(
                    '//ReportDownloadUrl');
                print "Downloading From : $downloadUrl\n\r";
    
                # Download the content of the zipped report.
                unless (defined ($content = get($downloadUrl)))
                {
                    die;
                }
    
                # Make sure that the .zip file destination directory
                # exists.
                my $dirname = dirname($zipFileName);
                mkdir($dirname);
                
                # Open the .zip file for writing and in binary mode.
                open(ZIPFILE, ">", $zipFileName);
                binmode(ZIPFILE);
                
                # Write the report contents to the .zip file.
                print(ZIPFILE $content);
                close(ZIPFILE);
                
                $polling = 0;
            }
            
            if (!($status =~ /Pending/))
            {
                $polling = 0;
            }
    
            if($polling)
            {
                # Wait a while before getting the status again.
                sleep($waitMinutes * 60);
            }
        }
    
        return $content;
    }
    
};
warn $@ if $@;
Page view tracker