i have a laravel project which uses the google ads api, and i am attempting 
to make a select from the `customer_client` table but getting unanticipated 
results.

of the four initial customers that i get in `runExample` by calling 
`getAccessibleCustomers`, one should be a manager account with several 
customers 'under' it. 

however, when i run this code, i only see the top level customers. the 
heirarchy is flat.

my code is below and is a mostly copy-paste job from the example google 
code at:
https://developers.google.com/google-ads/api/docs/account-management/get-account-hierarchy

the main differences, i believe, is in my construction of the oauthToken 
and googleAdsClient.

any assistance or insight is greatly appreciated!

<?php
namespace App\Libs;

require_once(__DIR__."/../../vendor/autoload.php");

use DB;
use Exception;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V12\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V12\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V12\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\V12\GoogleAdsServerStreamDecorator;
use Google\Ads\GoogleAds\V12\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V12\Resources\CustomerClient;
use Google\Ads\GoogleAds\V12\Services\CustomerServiceClient;
use Google\Ads\GoogleAds\V12\Services\GoogleAdsRow;
use Google\ApiCore\ApiException;

class GoogleAds {

    /**
     * The results from the example code
     */
    private static $rootCustomerClients = [];

    /**
     * Main
     */
    public function getGoogleAdsCustomersTest(bool $resetCache = false)
    {
        /**
         * Hard codes of values of OAuth2TokenBuilder and 
GoogleAdsClientBuilder. 
         * Normally stored in db. 
         */
        $clientId = "<client id>.apps.googleusercontent.com";
        $clientSecret = "<client secret>";
        $refreshToken = "<refresh token>";
        $developerToken = "<developer token>";

        /**
         * Create oauth with values, not fromFile()
         */
        $oauthToken = (new \Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder())
            ->withClientId($clientId)
            ->withClientSecret($clientSecret)
            ->withRefreshToken($refreshToken)
            ->build();


        /**
         * Create googleAdsClient with values, not fromFile()
         */
        $googleAdsClient = (new 
\Google\Ads\GoogleAds\Lib\V12\GoogleAdsClientBuilder())
            ->withOAuth2Credential($oauthToken)
            ->withDeveloperToken($this->developerToken)
            ->build();

        self::runExample($googleAdsClient);
    }

    /**
     * runExample
     */
    public static function runExample(GoogleAdsClient $googleAdsClient) {

        $rootCustomerIds = [];
        $rootCustomerIds = self::getAccessibleCustomers($googleAdsClient);

        $allHierarchies = [];
        $accountsWithNoInfo = [];

        // Constructs a map of account hierarchies.
        foreach ($rootCustomerIds as $rootCustomerId) {
            $customerClientToHierarchy = 
self::createCustomerClientToHierarchy($rootCustomerId);
            if (is_null($customerClientToHierarchy)) {
                $accountsWithNoInfo[] = $rootCustomerId;
            } else {
                $allHierarchies += $customerClientToHierarchy;
            }
        }

        // Prints the IDs of any accounts that did not produce hierarchy 
information.
        if (!empty($accountsWithNoInfo)) {
            print
                'Unable to retrieve information for the following accounts 
which are likely '
                . 'either test accounts or accounts with setup issues. 
Please check the logs for '
                . 'details:' . PHP_EOL;
            foreach ($accountsWithNoInfo as $accountId) {
                print $accountId . PHP_EOL;
            }
            print PHP_EOL;
        }

        // Prints the hierarchy information for all accounts for which 
there is hierarchy info
        // available.
        foreach ($allHierarchies as $rootCustomerId => 
$customerIdsToChildAccounts) {
            printf(
                "The hierarchy of customer ID %d is printed below:%s",
                $rootCustomerId,
                PHP_EOL
            );
            self::printAccountHierarchy(
                self::$rootCustomerClients[$rootCustomerId],
                $customerIdsToChildAccounts,
                0
            );
            print PHP_EOL;
        }
    }

    /**
     * getAccessibleCustomers
     */
    private static function getAccessibleCustomers(GoogleAdsClient 
$googleAdsClient): array
    {
        $accessibleCustomerIds = [];
        // Issues a request for listing all customers accessible by this 
authenticated Google
        // account.
        $customerServiceClient = 
$googleAdsClient->getCustomerServiceClient();
        $accessibleCustomers = 
$customerServiceClient->listAccessibleCustomers();

        print 'No manager customer ID is specified. The example will print 
the hierarchies of'
            . ' all accessible customer IDs:' . PHP_EOL;
        foreach ($accessibleCustomers->getResourceNames() as 
$customerResourceName) {
            $customer = 
CustomerServiceClient::parseName($customerResourceName)['customer_id'];
            print $customer . PHP_EOL;
            $accessibleCustomerIds[] = intval($customer);
        }
        print PHP_EOL;

        return $accessibleCustomerIds;
    }

    /**
     * Prints the specified account's hierarchy using recursion.
     *
     * @param CustomerClient $customerClient the customer client whose info 
will be printed and
     *     its child accounts will be processed if it's a manager
     * @param array $customerIdsToChildAccounts a map from customer IDs to 
child
     *     accounts
     * @param int $depth the current depth we are printing from in the
     *     account hierarchy
     */
    private static function printAccountHierarchy(
        CustomerClient $customerClient,
        array $customerIdsToChildAccounts,
        int $depth)
    {
        if ($depth === 0) {
            print 'Customer ID (Descriptive Name, Currency Code, Time 
Zone)' . PHP_EOL;
        }
        $customerId = $customerClient->getId();
        print str_repeat('-', $depth * 2);
        printf(
            " %d ('%s', '%s', '%s')%s",
            $customerId,
            $customerClient->getDescriptiveName(),
            $customerClient->getCurrencyCode(),
            $customerClient->getTimeZone(),
            PHP_EOL
        );

        // Recursively call this function for all child accounts of 
$customerClient.
        if (array_key_exists($customerId, $customerIdsToChildAccounts)) {
            foreach ($customerIdsToChildAccounts[$customerId] as 
$childAccount) {
                self::printAccountHierarchy($childAccount, 
$customerIdsToChildAccounts, $depth + 1);
            }
        }
    }

    /**
     * Create heirarchy
     */
    private static function createCustomerClientToHierarchy(int 
$rootCustomerId): ?array {
        // Creates a GoogleAdsClient with the specified login customer ID. 
See
        // 
https://developers.google.com/google-ads/api/docs/concepts/call-structure#cid 
for more
        // information.
        // Generate a refreshable OAuth2 credential for authentication.

        /**
         * Hard codes of values of OAuth2TokenBuilder and 
GoogleAdsClientBuilder. 
         * Normally stored in db. 
         */
        $clientId = "<client id>.apps.googleusercontent.com";
        $clientSecret = "<client secret>";
        $refreshToken = "<refresh token>";
        $developerToken = "<developer token>";

        /**
         * Create oauth with values, not fromFile()
         */
        $oauthToken = (new \Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder())
            ->withClientId($clientId)
            ->withClientSecret($clientSecret)
            ->withRefreshToken($refreshToken)
            ->build();
        // Construct a Google Ads client configured from a properties file 
and the
        // OAuth2 credentials above.

        /**
         * Create googleAdsClient with values, not fromFile()
         */
        $googleAdsClient = (new 
\Google\Ads\GoogleAds\Lib\V12\GoogleAdsClientBuilder())
            ->withOAuth2Credential($oauthToken)
            ->withDeveloperToken($developerToken)
            ->withLoginCustomerId($rootCustomerId)
            ->build();

        // Creates the Google Ads Service client.
        $googleAdsServiceClient = 
$googleAdsClient->getGoogleAdsServiceClient();
        // Creates a query that retrieves all child accounts of the manager 
specified in search
        // calls below.
        $query = 'SELECT customer_client.client_customer, 
customer_client.level,'
            . ' customer_client.manager, customer_client.descriptive_name,'
            . ' customer_client.currency_code, customer_client.time_zone,'
            . ' customer_client.id FROM customer_client WHERE 
customer_client.level <= 1';

        $rootCustomerClient = null;
        // Adds the root customer ID to the list of IDs to be processed.
        $managerCustomerIdsToSearch = [$rootCustomerId];

        // Performs a breadth-first search algorithm to build an 
associative array mapping
        // managers to their child accounts ($customerIdsToChildAccounts).
        $customerIdsToChildAccounts = [];

        while (!empty($managerCustomerIdsToSearch)) {
            $customerIdToSearch = array_shift($managerCustomerIdsToSearch);
            // Issues a search request by specifying page size.
            /** @var GoogleAdsServerStreamDecorator $stream */
            try {
                $stream = $googleAdsServiceClient->searchStream( 
$customerIdToSearch, $query);

                // Iterates over all elements to get all customer clients 
under the specified customer's
                // hierarchy.
                foreach ($stream->iterateAllElements() as $googleAdsRow) {
                    /** @var GoogleAdsRow $googleAdsRow */
                    $customerClient = $googleAdsRow->getCustomerClient();

                    // Gets the CustomerClient object for the root customer 
in the tree.
                    if ($customerClient->getId() === $rootCustomerId) {
                        $rootCustomerClient = $customerClient;
                        self::$rootCustomerClients[$rootCustomerId] = 
$rootCustomerClient;
                    }

                    // The steps below map parent and children accounts. 
Continue here so that managers
                    // accounts exclude themselves from the list of their 
children accounts.
                    if ($customerClient->getId() === $customerIdToSearch) {
                        continue;
                    }

                    // For all level-1 (direct child) accounts that are a 
manager account, the above
                    // query will be run against them to create an 
associative array of managers to
                    // their child accounts for printing the hierarchy 
afterwards.
                    $customerIdsToChildAccounts[$customerIdToSearch][] = 
$customerClient;
                    // Checks if the child account is a manager itself so 
that it can later be processed
                    // and added to the map if it hasn't been already.
                    if ($customerClient->getManager()) {
                        // A customer can be managed by multiple managers, 
so to prevent visiting
                        // the same customer multiple times, we need to 
check if it's already in the
                        // map.
                        $alreadyVisited = array_key_exists(
                            $customerClient->getId(),
                            $customerIdsToChildAccounts
                        );
                        if (!$alreadyVisited && $customerClient->getLevel() 
=== 1) {
                            array_push($managerCustomerIdsToSearch, 
$customerClient->getId());
                        }
                    }
                }
            } // try
            catch(\Exception $e) {
            }
        } // while

        return is_null($rootCustomerClient) ? null
            : [$rootCustomerClient->getId() => $customerIdsToChildAccounts];
    }

}

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
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 
"Google Ads API and AdWords 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/b04bbd83-ff52-459c-9b7d-abff6c9cfb98n%40googlegroups.com.

Reply via email to