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 [email protected]
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/adwords-api/d1b9c90b-6766-4279-885d-4847e0cdc33dn%40googlegroups.com.