Hi
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": 
"type.googleapis.com\/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:\/\/developers.google.com\/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.
But it doesn't with my implementation of the oauth2 login
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;
}

class GoogleAuthController extends Controller
{
private $client;

public function __construct()
{
$this->client = new Google_Client();
$this->client->setClientId(env('GOOGLE_ADS_CLIENT_ID'));
$this->client->setClientSecret(env('GOOGLE_ADS_CLIENT_SECRET'));
$this->client->setRedirectUri(env('GOOGLE_ADS_REDIRECT_URI'));
$this->client->addScope('https://www.googleapis.com/auth/adwords');
}

public function login()
{
$authUrl = $this->client->createAuthUrl();
return redirect($authUrl);
}

public function callback(Request $request)
{
if (!$request->has('code')) {
return redirect()->route('login')->withErrors('Authorization failed.');
}
$accessToken = $this->client->fetchAccessTokenWithAuthCode($request->get(
'code'));
session([
'google_ads_access_token' => $accessToken
]);
return redirect()->route('keywordurls');
}

public function logout()
{
session()->forget('google_ads_access_token');
return redirect()->route('login');
}
}

class EfGoogleAds
{

public $serviceClient = null;
public $fieldServiceClient = null;
private GoogleAdsClient $googleAdsClient;
public function __construct()
{
$this->setGoogleAdsClient();
$this->serviceClient = $this->googleAdsClient->getGoogleAdsServiceClient();
$this->fieldServiceClient = $this->googleAdsClient->
getGoogleAdsFieldServiceClient();
}

private function setGoogleAdsClient()
{
$oAuth2Credential = (new OAuth2TokenBuilder())
->withClientId(env('GOOGLE_ADS_CLIENT_ID'))
->withClientSecret(env('GOOGLE_ADS_CLIENT_SECRET'))
->withRefreshToken(session('google_ads_access_token')['access_token']) // 
Use the stored refresh token
->build();

$this->googleAdsClient = (new GoogleAdsClientBuilder())
->withDeveloperToken(env('GOOGLE_ADS_DEVELOPER_TOKEN'))
->withOAuth2Credential($oAuth2Credential)
->build();
}

public function getGoogleAdsClient(): GoogleAdsClient{
return $this->googleAdsClient;
}
}

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
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/d1b9c90b-6766-4279-885d-4847e0cdc33dn%40googlegroups.com.

Reply via email to