I'm trying to replicate the GetAccountHieararchy.php example on my Laravel application and I keep getting this aparently very common permissions error but I can't see whats the problem:
{ "message": "The caller does not have permission", "code": 7, "status": "PERMISSION_DENIED", "details": [ { "@type": "
\/google.ads.googleads.v13.errors.GoogleAdsFailure", "errors": [ { "errorCode": { "authorizationError": "USER_PERMISSION_DENIED" }, "message": "User doesn't have permission to access customer. Note: If you're accessing a client customer, the manager's customer id must be set in the 'login-customer-id' header. See https:\/\/
\/google-ads\/api\/docs\/concepts\/call-structure#cid" } ], "requestId": "HvUJs9KXJuoUXsX1rySSZg" } ] }
Using a refresh token generated with the playground app and then placing it in th google_ads_php.ini works.
Is there something wrong or missing here? I see in the playground some parameters in the first step that I don't see here. This is not my implementation I'm just looking to understand and fix the permissions issue here.
class MCCHierarchy
{
public function all()
{
$efGoogleAds = new EfGoogleAds();
return $this->createCustomerClientHierarchy($efGoogleAds);
}
private function createCustomerClientHierarchy(EfGoogleAds $efGoogleAds)
{
// First, fetch the list of accessible customers
$outputArray = $this->getAccessibleCustomers($efGoogleAds->getGoogleAdsClient());
$selects = ['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', 'customer_client.status']; $wheres = [
['customer_client.level', '= 1'],
['customer_client.status', '= "ENABLED"'],
['customer_client.manager', '= true']
];
// Now, we fetch subClients againsts each customer
foreach ($outputArray as $key => $mccClient) {
try{
$subAccountsStreamReport = new StreamReportGoogleAds('customer_client', $efGoogleAds->serviceClient, intval($mccClient['clientId']), $selects, $wheres, '');
}catch(\Google\ApiCore\ApiException $e){
Log::error('Client id failing: '.$mccClient['clientId']);
if (isset($e->getMetadata()[0]["errors"][0]["errorCode"]["authorizationError"]) && $e->getMetadata()[0]["errors"][0]["errorCode"]["authorizationError"] === 'CUSTOMER_NOT_ENABLED') {
// The customer account can't be accessed because it is not yet enabled or has been deactivated.
// You may want to log this or handle differently in your application.
continue;
} else {
throw $e;
}
}
$subClientArray = [];
$subClientIdsArray = [];
try{
foreach ($subAccountsStreamReport->stream->iterateAllElements() as $subAccount) {
$customerClient = $subAccount->getCustomerClient();
$subClientArray[] = [
'clientName' => $customerClient->getDescriptiveName(),
'clientId' => $customerClient->getId(),
'manager' => $customerClient->getManager(),
'clientStatus' => CustomerStatus::name($customerClient->getStatus())
];
$subClientIdsArray[] = [
"subClientName" => $customerClient->getDescriptiveName(),
"subClientId" => $customerClient->getId()
];
}
}catch(\Google\Ads\GoogleAds\Lib\V13\GoogleAdsException $e){
Log::error('Client id failing in second loop: '.$mccClient['clientId']);
throw $e;
}
$outputArray[$key]['subClients'] = $subClientArray;
$outputArray[$key]['subClientsIds'] = json_encode($subClientIdsArray);
}
//dd($outputArray);
return $outputArray;
}
/**
* Retrieves a list of accessible customers with the provided set up credentials.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @return int[] the list of customer IDs
*/
private function getAccessibleCustomers(GoogleAdsClient $googleAdsClient): array
{
$outputArray = [];
// Issues a request for listing all customers accessible by this authenticated Google
// account.
$customerServiceClient = $googleAdsClient->getCustomerServiceClient();
$accessibleCustomers = $customerServiceClient->listAccessibleCustomers(['customer.status' => 'ENABLED']);
foreach ($accessibleCustomers->getResourceNames() as $customerResourceName) {
$customer = CustomerServiceClient::parseName($customerResourceName)['customer_id'];
$outputArray[] = [
'clientName' => $customerResourceName,
'clientId' => intval($customer),
];
}
return $outputArray;
}