Hi All,

  Every day we almost spend 10K+ dollar in Google Ads in order to advertise 
our APPs in the whole world.
  
  In business side, our App operation team want to analysis the advertising 
effect about the different country current and history performance of every 
App.
  
  We need make the advertising strategy about which country can offer us 
high quality users recently.
  
  We know that there are country performance reports of the account cost in 
the Google Ads backstage, but we want history data in order to analysis the 
data.
  
  So we decide to get the country performance report and store them in our 
own database.
  
  We found that the 'Location' and 'Geo' API can realize this idea, but 
both of them have some issues.
  
  The issue situation is :
  
  1. When we call the 'Location' API, we can almost get all account cost 
data. 
  
     The cost of every account is almost as same as the report of Google 
Ads backstage. It only has no more than 1% error rate and we can accept it.
 
We have a location-country dimension table. Through this table, we can 
transfer the location to country.
 
But, when we drill down the data to location level, we found that a lot of 
account have the issue situation that the location is '--'. Correct cost 
and meanless location.
 
Example: We use one account to spend 1K in US and 2K in India and 3K in 
Japan. When we see the data through 'Location' API, the data maybe is 1k in 
US and 5K in '--'.

     With this return data, we can not have a view about the advertising 
performance of country.
 
  2. When we call the 'Geo' API, the country field won't be '--' and the 
cost of account is correct.
  
     But, a lot of account is missing.
 
If we can have 10 accounts data from 'Location' API, maybe we can only have 
3-5 accounts data from 'Geo' API in same time period.
 


  We have no idea about how to solve these problems.Our target is just to 
get one correct cost report of all account and all country everyday.
  
  
----------------------------------------------------------------------------------------------------------------------------------------------------------

The following is the result date of calling the 2 APIs :

account_id information:
  $mcc = '945-959-2387';
  $account_id = '9929989200';

1. The information from 'location' API
relative parameter :
            $report_type = 'CAMPAIGN_LOCATION_TARGET_REPORT';
            $fields      = array('Impressions', 'Clicks', 'Conversions', 
'Cost', 'Date', 'ExternalCustomerId', 'CampaignId', 'Id');
            $report_name = 'adwords_location_report';

The log from 'location' API:
  [2019-07-23 17:40:53] AW_REPORT_DOWNLOADER.INFO: 
clientCustomerId=9929989200 Teebik (AwApi-PHP, googleads-php-lib/40.0.0, 
PHP/7.1.7, GuzzleHttp/6.2.1, curl/7.29.0) "POST 
/api/adwords/reportdownload/v201809 HTTP/1.1" Status: 200   
  bool(true)

The return data from 'location' API

  cat /tmp/adwords_location_report_LAST_30_DAYS.csv 
  Impressions,Clicks,Conversions,Cost,Day,Customer ID,Campaign ID,Location
  1,1,0.00,170000,2019-07-09,9929989200,2038668410, --
  1,1,0.00,50000,2019-06-29,9929989200,2038668902, --
  1,0,0.00,0,2019-07-03,9929989200,2038668902, --
  1,0,0.00,0,2019-07-01,9929989200,2038668410, --
  1,0,0.00,0,2019-07-10,9929989200,2038668902, --
  2,0,0.00,0,2019-07-09,9929989200,2039512296, --
  1,0,0.00,0,2019-06-26,9929989200,2038668410, --
  1,0,0.00,0,2019-07-15,9929989200,2038668902, --


2. The information from 'geo' API

relative parameter :
      $report_type = 'GEO_PERFORMANCE_REPORT';
            $fields      = array('Impressions', 'Clicks', 'Conversions', 
'Cost', 'Date', 'ExternalCustomerId', 'CountryCriteriaId');
            $report_name = 'adwords_geo_report';


The return data from 'geo' API
  head  /tmp/adwords_geo_report_LAST_30_DAYS.csv 
  Impressions,Clicks,Conversions,Cost,Day,Customer ID,Country/Territory
  1,0,0.00,0,2019-07-20,9929989200,2462
  3,0,0.00,0,2019-07-16,9929989200,2462
  1,0,0.00,0,2019-07-03,9929989200,2462
  4,0,0.00,0,2019-07-12,9929989200,2462
  1,0,0.00,0,2019-07-04,9929989200,2554
  2,0,0.00,0,2019-07-14,9929989200,2462
  1,0,0.00,0,2019-06-27,9929989200,2462
  1,0,0.00,0,2019-07-11,9929989200,2462
  2,0,0.00,0,2019-06-28,9929989200,2462

---------------------------------------------------------------------------------------------------------------------------
  

The following is our PHP code.


//$mcc = '945-959-2387';
$mccConfigPath = "/tmp/adsapi_php.ini";
$customerId = '9929989200';
$date_range_type = 'LAST_30_DAYS';
$report_type = 'geo';

downloadReport($mccConfigPath, $customerId, $date_range_type, 
$report_type));

    
    public function downloadReport($mccConfigPath, $customerId, 
$date_range_type, $report_type)
    {
        if ($report_type == 'geo') {
            $report_type = 'GEO_PERFORMANCE_REPORT';
            $fields      = array('Impressions', 'Clicks', 'Conversions', 
'Cost', 'Date', 'ExternalCustomerId', 'CountryCriteriaId','CampaignId');
            $report_name = 'adwords_geo_report';
            $file_path   = '/tmp/adwords_geo_report_' . $date_range_type . 
'.csv';
        }  elseif ($report_type == 'location') {

            // 
https://developers.google.com/adwords/api/docs/appendix/reports/campaign-location-target-report
 
            // Id = location
            $report_type = 'CAMPAIGN_LOCATION_TARGET_REPORT';
            $fields      = array('Impressions', 'Clicks', 'Conversions', 
'Cost', 'Date', 'ExternalCustomerId', 'CampaignId', 'Id');
            $report_name = 'adwords_location_report';
            $file_path   = '/tmp/adwords_location_report_' . 
$date_range_type . '.csv';
        } else {
            $report_type = 'ACCOUNT_PERFORMANCE_REPORT';
            $fields      = array('Impressions', 'Clicks', 'Conversions', 
'Cost', 'Date', 'ExternalCustomerId');
            $report_name = 'adwords_account_report';
            $file_path   = '/tmp/adwords_account_report_' . 
$date_range_type . '.csv';
        }

        return $this->downloadCriteriaReport($mccConfigPath, $customerId, 
$report_type, $fields, $report_name, $date_range_type, 'CSV', $file_path, 
FALSE, TRUE, TRUE);
    }



    
    
    public function downloadCriteriaReport($mccConfigPath, $customerId, 
$reportType, $fields, $reportName, $dateRangeType, $downloadFormat, 
$filePath, $includeZeroImpressions = FALSE, $skipReportHeader = FALSE, 
$skipReportSummary = FALSE)
    {
        $filterErrMessage = array(
            "503 Service Unavailable",
            "500 Internal Server Error",
            "502 Bad Gateway",
            "Temporary problem with the server. Please retry the request 
after a few moments",
            "AuthorizationError.CUSTOMER_NOT_ACTIVE",  // 
https://ads-developers.googleblog.com/2018/03/changes-to-inactive-adwords-accounts.html
            "looks like we got no XML document",  // 
https://stackoverflow.com/questions/4313952/soap-looks-like-we-got-no-xml-document
        );

        try {
            // Construct an API session for the client customer ID 
specified in the
            // configuration file.
            /** @var AdWordsSessionBuilder $sessionBuilder */
            $sessionBuilder = 
F::$f->Helper_AdwordsSession->getMccSessionBuilder($mccConfigPath);

            // Create selector.
            $selector = new Selector();
            $selector->setFields($fields);

            // Create report definition.
            $reportDefinition = new ReportDefinition();
            $reportDefinition->setSelector($selector);
            $reportDefinition->setReportName($reportName);
            $reportDefinition->setDateRangeType($dateRangeType);
            $reportDefinition->setReportType($reportType);
            $reportDefinition->setDownloadFormat($downloadFormat);

            // Construct an API session for the specified client customer 
ID.
            $customerSession = 
$sessionBuilder->withClientCustomerId($customerId)->build();
            $reportDownloader = new ReportDownloader($customerSession);

            $retryCount = 0;
            $doContinue = true;
            do {
                $retryCount++;
                try {
                    // Optional: If you need to adjust report settings just 
for this one
                    // request, you can create and supply the settings 
override here.
                    // Otherwise, default values from the configuration file
                    // (adsapi_php.ini) are used.
                    $reportSettingsOverride = (new 
ReportSettingsBuilder())->includeZeroImpressions($includeZeroImpressions)->skipReportSummary($skipReportSummary)->skipReportHeader($skipReportHeader)->build();
                    $reportDownloadResult = 
$reportDownloader->downloadReport($reportDefinition, 
$reportSettingsOverride);
                    $reportDownloadResult->saveToFile($filePath);
                    $doContinue = false;
                } catch (ApiException $e) {
                    // echo 'error with download report, retry. error 
message:' . $e->getMessage() . PHP_EOL;
                    log_message('error with download report, retry. error 
message:' . $e->getMessage(), LOG_ERR);

                    // If this is a server error, retry up to the defined 
maximum number
                    // of retries.
                    if ($e->getErrors() === null && $retryCount < 
self::MAX_RETRIES) {
//                        F::$f->Helper_Monitor->addCacheLog('API warning 
with download report, warning message:' . $e->getMessage());
                        log_message('warning with download report, retry. 
error message:' . $e->getMessage(), LOG_ERR);
                        $sleepTime = $retryCount * self::BACKOFF_FACTOR;
                        sleep($sleepTime);
                    } else {
                        $errMessage = $e->getMessage();
                        // If the error message include the following 
information, Skip

                        $isSkip = false;
                        foreach($filterErrMessage as $temp) {
                            if (stripos($errMessage, $temp) !== false) {
                                $isSkip = true;
                                break;
                            }
                        }

                        if (!$isSkip) {
                            F::$f->Helper_Monitor->addCacheLog('API error 
with download report, error message: ' . $e->getMessage());
                        }
                        log_message('error with download report, exit. 
error message:' . $e->getMessage(), LOG_ERR);
                        return false;
                    }
                }
            } while ($doContinue === true);
        } catch (Exception $e) {
            echo 'error with download report, retry. error message:' . 
$e->getMessage() . PHP_EOL;
            F::$f->Helper_Monitor->addCacheLog('API error with download 
report, error message:' . $e->getMessage());
            log_message('error with download 
report,customerId:'.$customerId.'. error message:' . $e->getMessage(), 
LOG_ERR);
            return FALSE;
        }
        return TRUE;
    }


<?php
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * Date: 2016/3/15
 * Time: 12:36
 */
class Helper_AdwordsSession
{
    /**
     * @param $mccConfigPath
     * @return AdWordsSessionBuilder
     */
    public function getMccSessionBuilder($mccConfigPath)
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new 
OAuth2TokenBuilder())->fromFile($mccConfigPath)->build();
        // See: AdWordsSessionBuilder for setting a client customer ID that 
is
        // different from that specified in your adsapi_php.ini file.
        $sessionBuilder = (new 
AdWordsSessionBuilder())->fromFile($mccConfigPath)->withOAuth2Credential($oAuth2Credential);

        return $sessionBuilder;
    }
} 
  
  
  Looking forward for your help.
  
  Best regards.

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog:
https://googleadsdeveloper.blogspot.com/
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~

You received this message because you are subscribed to the Google
Groups "AdWords API and Google Ads API Forum" group.
To post to this group, send email to adwords-api@googlegroups.com
To unsubscribe from this group, send email to
adwords-api+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"AdWords API and Google Ads API Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to adwords-api+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/adwords-api/a8581400-7291-4aca-b1f9-a8cc51f21a5e%40googlegroups.com.

Reply via email to