Posts tagged with php

I have been having trouble trying to figure out how to set a range of dates for a given lineItem using the google ads php client library. Basically, what I want to do is make a line item to be available for a specified start date and an end date but no success. In their example they have this snippet:

$lineItem->setStartDateTimeType(StartDateTimeType::IMMEDIATELY); $lineItem->setEndDateTime(             AdManagerDateTimes::fromDateTime(                 new DateTime('+1 month', new DateTimeZone('America/New_York'))             )         ); 

They're setting a start date for the line item to IMMEDIATELY, and and end date to 1 month from the time of creation. I tried passing to AdManagerDateTimes::fromDateTimeString a valid ISO 8601 string and no luck (GAM spits an error). Tried creating a DateTime() instance and passing it to the code above, nothing. I'm not too experienced in php and maybe this is way easier than i think it is but I'm stuck.

Any tips please? Thank you

I am trying to create a new campaing using google ads api with php client library. And simply getting this error. I will post whole php code here since I don't really know what this error is about. The console outputs the following:

[2022-02-22T18:00:13.039301+03:00] google-ads.WARNING: Request made: Host: "googleads.googleapis.com", Method: "/google.ads.googleads.v10.services.CampaignBudgetService/MutateCampaignBudgets", CustomerId: 9445807394, RequestId: "ozBYeKzMcMLizUbsO0r8_w", IsFault: 1, FaultMessage: "["The operation is not allowed for the given context."]" [2022-02-22T18:00:13.042848+03:00] google-ads.NOTICE: Request ------- Method Name: /google.ads.googleads.v10.services.CampaignBudgetService/MutateCampaignBudgets Host: googleads.googleapis.com Headers: {     "x-goog-api-client": "gl-php\/7.4.27 gccl\/14.0.0 gapic\/14.0.0 gax\/1.11.4 grpc\/1.43.0 rest\/1.11.4",     "x-goog-request-params": "customer_id=9445807394",     "developer-token": "REDACTED",     "login-customer-id": "6165712462" } Request: {"customerId":"9445807394","operations":[{"create":{"name":"Test Budget #2022-02-22T18:00:12.342+03:00","amountMicros":"500000","deliveryMethod":"STANDARD"}}]} Response ------- Headers: {     "request-id": "ozBYeKzMcMLizUbsO0r8_w",     "date": "Tue, 22 Feb 2022 15:00:12 GMT",     "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" } Fault ------- Status code: 3 Details: Request contains an invalid argument. Failure: {"errors":[{"errorCode":{"contextError":"OPERATION_NOT_PERMITTED_FOR_CONTEXT"},"message":"The operation is not allowed for the given context.","location":{"fieldPathElements":[{"fieldName":"operations","index":0}]}}],"requestId":"ozBYeKzMcMLizUbsO0r8_w"} Request with ID 'ozBYeKzMcMLizUbsO0r8_w' has failed. Google Ads failure details:         context_error: The operation is not allowed for the given context 

The code is as follows:

<?php /**  * Copyright 2018 Google LLC  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *     https://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */     namespace Google\Ads\GoogleAds\Examples\BasicOperations;          require __DIR__ . '/vendor/autoload.php';          use GetOpt\GetOpt;     use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;     use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;     use Google\Ads\GoogleAds\Examples\Utils\Helper;     use Google\Ads\GoogleAds\Lib\V10\GoogleAdsClient;     use Google\Ads\GoogleAds\Lib\V10\GoogleAdsClientBuilder;     use Google\Ads\GoogleAds\Lib\V10\GoogleAdsException;     use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;     use Google\Ads\GoogleAds\V10\Common\ManualCpc;     use Google\Ads\GoogleAds\V10\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;     use Google\Ads\GoogleAds\V10\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod;     use Google\Ads\GoogleAds\V10\Enums\CampaignStatusEnum\CampaignStatus;     use Google\Ads\GoogleAds\V10\Errors\GoogleAdsError;     use Google\Ads\GoogleAds\V10\Resources\Campaign;     use Google\Ads\GoogleAds\V10\Resources\Campaign\NetworkSettings;     use Google\Ads\GoogleAds\V10\Resources\CampaignBudget;     use Google\Ads\GoogleAds\V10\Services\CampaignBudgetOperation;     use Google\Ads\GoogleAds\V10\Services\CampaignOperation;     use Google\ApiCore\ApiException;          /** This example adds new campaigns to an account. */     class AddCampaigns{         private const CUSTOMER_ID = '9445807394';         private const NUMBER_OF_CAMPAIGNS_TO_ADD = 2;              public static function main(){             // Either pass the required parameters for this example on the command line, or insert them             // into the constants above.             $options = (new ArgumentParser())->parseCommandArguments([                 ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT             ]);                  // Generate a refreshable OAuth2 credential for authentication.             $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();                  // Construct a Google Ads client configured from a properties file and the             // OAuth2 credentials above.             $googleAdsClient = (new GoogleAdsClientBuilder())                 ->fromFile()                 ->withOAuth2Credential($oAuth2Credential)                 ->build();                  try {                 self::runExample(                     $googleAdsClient,                     $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID                 );             } catch (GoogleAdsException $googleAdsException) {                 printf(                     "Request with ID '%s' has failed.%sGoogle Ads failure details:%s",                     $googleAdsException->getRequestId(),                     PHP_EOL,                     PHP_EOL                 );                 foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {                     /** @var GoogleAdsError $error */                     printf(                         "\t%s: %s%s",                         $error->getErrorCode()->getErrorCode(),                         $error->getMessage(),                         PHP_EOL                     );                 }                 exit(1);             } catch (ApiException $apiException) {                 printf(                     "ApiException was thrown with message '%s'.%s",                     $apiException->getMessage(),                     PHP_EOL                 );                 exit(1);             }         }              /**          * Runs the example.          *          * @param GoogleAdsClient $googleAdsClient the Google Ads API client          * @param int $customerId the customer ID          */         public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId){             // Creates a single shared budget to be used by the campaigns added below.             $budgetResourceName = self::addCampaignBudget($googleAdsClient, $customerId);                  // Configures the campaign network options.             $networkSettings = new NetworkSettings([                 'target_google_search' => true,                 'target_search_network' => true,                 'target_content_network' => false,                 'target_partner_search_network' => false             ]);                  $campaignOperations = [];             for ($i = 0; $i < self::NUMBER_OF_CAMPAIGNS_TO_ADD; $i++) {                 // Creates a campaign.                 // [START add_campaigns_1]                 $campaign = new Campaign([                     'name' => 'Test #' . Helper::getPrintableDatetime(),                     'advertising_channel_type' => AdvertisingChannelType::SEARCH,                     // Recommendation: Set the campaign to PAUSED when creating it to prevent                     // the ads from immediately serving. Set to ENABLED once you've added                     // targeting and the ads are ready to serve.                     'status' => CampaignStatus::PAUSED,                     // Sets the bidding strategy and budget.                     'manual_cpc' => new ManualCpc(),                     'campaign_budget' => $budgetResourceName,                     // Adds the network settings configured above.                     'network_settings' => $networkSettings,                     // Optional: Sets the start and end dates.                     'start_date' => date('Ymd', strtotime('+1 day')),                     'end_date' => date('Ymd', strtotime('+1 month'))                 ]);                 // [END add_campaigns_1]                      // Creates a campaign operation.                 $campaignOperation = new CampaignOperation();                 $campaignOperation->setCreate($campaign);                 $campaignOperations[] = $campaignOperation;             }                  // Issues a mutate request to add campaigns.             $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();             $response = $campaignServiceClient->mutateCampaigns($customerId, $campaignOperations);                  printf("Added %d campaigns:%s", $response->getResults()->count(), PHP_EOL);                  foreach ($response->getResults() as $addedCampaign) {                 /** @var Campaign $addedCampaign */                 print "{$addedCampaign->getResourceName()}" . PHP_EOL;             }         }              /**          * Creates a new campaign budget in the specified client account.          *          * @param GoogleAdsClient $googleAdsClient the Google Ads API client          * @param int $customerId the customer ID          * @return string the resource name of the newly created budget          */         // [START add_campaigns]         private static function addCampaignBudget(GoogleAdsClient $googleAdsClient, int $customerId){             // Creates a campaign budget.             $budget = new CampaignBudget([                 'name' => 'Test Budget #' . Helper::getPrintableDatetime(),                 'delivery_method' => BudgetDeliveryMethod::STANDARD,                 'amount_micros' => 500000             ]);                  // Creates a campaign budget operation.             $campaignBudgetOperation = new CampaignBudgetOperation();             $campaignBudgetOperation->setCreate($budget);                  // Issues a mutate request.             $campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();             $response = $campaignBudgetServiceClient->mutateCampaignBudgets(                 $customerId,                 [$campaignBudgetOperation]             );                  /** @var CampaignBudget $addedBudget */             $addedBudget = $response->getResults()[0];             printf("Added budget named '%s'%s", $addedBudget->getResourceName(), PHP_EOL);                  return $addedBudget->getResourceName();         }         // [END add_campaigns]     }          AddCampaigns::main(); 

How to fix this error? Or what is it about?

I have created my service account, following the Google documentation as best I can. I created a JSON Key File and have used it successfully to create and refresh my access token, but when I try to call the Google Ads API using that access token I get a 401 with the message "User in the cookie is not a valid Ads user."

I am using a PHP cURL request, not the Google Client library.

My suspicion is that I have something set up incorrectly somewhere between the Master Ad account, the service account and the project in the Google Cloud Console, but I am finding the documentation confusing and unhelpful.

I submitted a question to the Google Ads API google group, and the support person said that my setup looked OK, but also admitted that he cannot see all of it from his end.

I have created the following pieces of the puzzle:
Google Ads Master Account
Developer Token
Project in Google Cloud Console
Service Account in Project
Private Key for Service Account
Set email of Master Ads Account to role of Owner of Service Account
Enabled Domain-Wide Delegation for the Service Account with scope "https://www.googleapis.com/auth/adwords"
Requested and received Access Token with the private key in the JSON file

Please let me know what extra details I should provide to get my issue resolved. Thanks in advance.

Edit:

This the converted curl code it prints this error it's relating to A Outh 2.0 I used both Client ID and client secret and same error { "error": { "code": 401, "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" } }

   $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, 'https://googleads.googleapis.com/v9/customers/(8519781266):generateKeywordIdeas');        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch, CURLOPT_POST, 1);        curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n\n\"keywordSeed\": {\n    \"keywords\": [\n    \"cofee\"\n  ]\n  }\n}");                $headers = array();        $headers[] = 'Content-Type: application/json';        $headers[] = 'Login-Customer-Id: (2260416591)';        $headers[] = 'Developer-Token: (z2sb0uyekDzkMbiyNpAImg';        $headers[] = 'Authorization: Bearer (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)';        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);                $result = curl_exec($ch);        if (curl_errno($ch)) {            echo 'Error:' . curl_error($ch);        }        print_r($result) ;        curl_close($ch);         

This curl command code with my google's data

curl -i --request POST https://googleads.googleapis.com/v9/customers/(8519781266):generateKeywordIdeas \ --header "Content-Type: application/json" \ --header "login-customer-id: (2260416591)" \ --header "developer-token: (z2sb0uyekDzkMbiyNpAImg" \ --header "Authorization: Bearer (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)" \ --data '{ "keywordSeed": {     "keywords": [     "cofee"   ]   } }' 

This's the curl command line

curl -i --request POST https://googleads.googleapis.com/v9/customers/(ACCOUNT NUMBER):generateKeywordIdeas \ --header "Content-Type: application/json" \ --header "login-customer-id: (MCC ID)" \ --header "developer-token: (DEVELOPER TOKEN" \ --header "Authorization: Bearer (ACCESS TOKEN)" \ --data '{ "keywordSeed": {     "keywords": [     "cofee"   ]   } }' 

and it prints this error

 C:\Users\MostafaEzzat>curl -i --request POST https://googleads.googleapis.com/v9/customers/(8519781266):generateKeywordIdeas \ HTTP/1.0 411 Length Required Content-Type: text/html; charset=UTF-8 Referrer-Policy: no-referrer Content-Length: 1564 Date: Sat, 01 Jan 2022 18:14:44 GMT <!DOCTYPE html> <html lang=en>   <meta charset=utf-8>   <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">   <title>Error 411 (Length Required)!!1</title>   <style>     *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}   </style>   <a href=//www.google.com/><span id=logo aria-label=Google></span></a>   <p><b>411.</b> <ins>That’s an error.</ins>   <p>POST requests require a <code>Content-length</code> header.  <ins>That’s all we know.</ins> curl: (6) Could not resolve host: \ C:\Users\MostafaEzzat>--header "Content-Type: application/json" \ '--header' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>--header "login-customer-id: (2260416591)" \ '--header' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>--header "developer-token: (z2sb0uyekDzkMbiyNpAImg" \ '--header' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>--header "Authorization: Bearer (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)" \ '--header' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>--data '{ '--data' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat> C:\Users\MostafaEzzat>"keywordSeed": { '"keywordSeed":' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>    "keywords": [ '"keywords":' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>    "cofee" '"cofee"' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>  ] ']' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>  } '}' is not recognized as an internal or external command, operable program or batch file. C:\Users\MostafaEzzat>}' 

so I don't know honestly how to convert to Curl PHP and parse combine and all the parameters which is in this link https://developers.google.com/google-ads/api/rest/reference/rest/v9/KeywordPlanHistoricalMetrics

I'm making Web Application for Extracting data from Youtube Videos then analyze it and find the best keywords

All I need is finding the best keywords from Keywords Planner of Google depends on the volume search i did extract the youtube video data, I followed this library https://github.com/googleads/googleads-php-lib

I have Clientid, Clientsecret and Developer Token After I installed the library successfully and tried to test GetCampaigns() class, I get this Error

Fatal error: Uncaught InvalidArgumentException: All of 'clientId', 'clientSecret', and 'refreshToken' must be set when using installed/web application flow. in C:\xampp\htdocs\seosystem\googleads-php-lib\src\Google\AdsApi\Common\OAuth2TokenBuilder.php:225 Stack trace: #0 C:\xampp\htdocs\seosystem\googleads-php-lib\src\Google\AdsApi\Common\OAuth2TokenBuilder.php(173): Google\AdsApi\Common\OAuth2TokenBuilder->validate() #1 C:\xampp\htdocs\seosystem\googleads-php-lib\examples\AdWords\v201809\BasicOperations\GetCampaigns.php(81): Google\AdsApi\Common\OAuth2TokenBuilder->build() #2 C:\xampp\htdocs\seosystem\googleads-php-lib\examples\AdWords\v201809\BasicOperations\GetCampaigns.php(90): Google\AdsApi\Examples\AdWords\v201809\BasicOperations\GetCampaigns::main() #3 C:\xampp\htdocs\seosystem\index.php(4): require_once('C:\\xampp\\htdocs...') #4 {main} thrown in C:\xampp\htdocs\seosystem\googleads-php-lib\src\Google\AdsApi\Common\OAuth2TokenBuilder.php on line 225 

I went to OAuth2TokenBuilder and replaced and still get the same Error Message no worries i'll change the key later

 private $clientId ='847786194979-n0udvkdi41r9fd5arlma6gadlm2kueot.apps.googleusercontent.com'; private $clientSecret ='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'; private $refreshToken ='Af8L57gifnGl1b4M324_Tg'; 

and this's the whole file

<?php /**  * Copyright 2016 Google Inc. All Rights Reserved.  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *     http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ namespace Google\AdsApi\Common; use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Auth\Credentials\UserRefreshCredentials; use InvalidArgumentException; /**  * Builds OAuth2 access token fetchers.  *  * @see FetchAuthTokenInterface  */ final class OAuth2TokenBuilder implements AdsBuilder{     private $configurationLoader;     private $jsonKeyFilePath;     private $scopes;     private $impersonatedEmail;     private $clientId ='847786194979-n0udvkdi41r9fd5arlma6gadlm2kueot.apps.googleusercontent.com';     private $clientSecret ='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';     private $refreshToken ='Af8L57gifnGl1b4M324_Tg';     public function __construct(){         $this->configurationLoader = new ConfigurationLoader();     }     /**      * Reads configuration settings from the specified filepath. The filepath is      * optional, and if omitted, it will look for the default configuration      * filename in the home directory of the user running PHP.      *      * @see AdsBuilder::DEFAULT_CONFIGURATION_FILENAME      *      * @param string $path the filepath      * @return OAuth2TokenBuilder this builder populated from the configuration      * @throws InvalidArgumentException if the configuration file could not be      *     found      */     public function fromFile($path = null){         if ($path === null) {             $path = self::DEFAULT_CONFIGURATION_FILENAME;         }         return $this->from($this->configurationLoader->fromFile($path));     }     /**      * @see AdsBuilder::from()      */     public function from(Configuration $configuration){         $this->jsonKeyFilePath = $configuration->getConfiguration('jsonKeyFilePath', 'OAUTH2');         $this->scopes = $configuration->getConfiguration('scopes', 'OAUTH2');         $this->impersonatedEmail = $configuration->getConfiguration('impersonatedEmail', 'OAUTH2');         $this->clientId = $configuration->getConfiguration('clientId', 'OAUTH2');         $this->clientSecret = $configuration->getConfiguration('clientSecret', 'OAUTH2');         $this->refreshToken = $configuration->getConfiguration('refreshToken', 'OAUTH2');         return $this;     }     /**      * Includes an absolute path to an OAuth2 JSON key file when using service      * account flow. Required and only applicable when using service account flow.      *      * @param string|null $jsonKeyFilePath      * @return OAuth2TokenBuilder this builder      */     public function withJsonKeyFilePath($jsonKeyFilePath){         $this->jsonKeyFilePath = $jsonKeyFilePath;         return $this;     }     /**      * Includes OAuth2 scopes. Required and only applicable when using service      * account flow.      *      * @param string|null $scopes a space-delimited list of scopes      * @return OAuth2TokenBuilder this builder      */     public function withScopes($scopes){         $this->scopes = $scopes;         return $this;     }     /**      * Includes an email of account to impersonate when using service account      * flow. Optional and only applicable when using service account flow.      *      * @param string|null $impersonatedEmail      * @return OAuth2TokenBuilder this builder      */     public function withImpersonatedEmail($impersonatedEmail){         $this->impersonatedEmail = $impersonatedEmail;         return $this;     }     /**      * Includes an OAuth2 client ID. Required when using installed application or      * web application flow.      *      * @param string|null $clientId      * @return OAuth2TokenBuilder this builder      */     public function withClientId($clientId){         $this->clientId = $clientId;         return $this;     }     /**      * Includes an OAuth2 client secret. Required when using installed application      * or web application flow.      *      * @param string|null $clientSecret      * @return OAuth2TokenBuilder this builder      */     public function withClientSecret($clientSecret){         $this->clientSecret = $clientSecret;         return $this;     }     /**      * Includes an OAuth2 refresh token. Required when using installed application      * or web application flow.      *      * @param string|null $refreshToken      * @return OAuth2TokenBuilder this builder      */     public function withRefreshToken($refreshToken){         $this->refreshToken = $refreshToken;         return $this;     }     /**      * @see AdsBuilder::build()      */     public function build(){         $this->defaultOptionals();         $this->validate();         if ($this->jsonKeyFilePath !== null) {             return new ServiceAccountCredentials(                 $this->scopes,                 $this->jsonKeyFilePath,                 $this->impersonatedEmail             );         } else {             return new UserRefreshCredentials(                 null,                 [                     'client_id' => $this->clientId,                     'client_secret' => $this->clientSecret,                     'refresh_token' => $this->refreshToken                 ]             );         }     }     /**      * @see AdsBuilder::defaultOptionals()      */     public function defaultOptionals(){         // Nothing to default for this builder.     }     /**      * @see AdsBuilder::validate()      */     public function validate(){         if (($this->jsonKeyFilePath !== null || $this->scopes !== null)             && ($this->clientId !== null || $this->clientSecret !== null                 || $this->refreshToken !== null)) {             throw new InvalidArgumentException(                 'Cannot have both service account '                 . 'flow and installed/web application flow credential values set.'             );         }         if ($this->jsonKeyFilePath !== null || $this->scopes !== null) {             if ($this->jsonKeyFilePath === null || $this->scopes === null) {                 throw new InvalidArgumentException(                     'Both \'jsonKeyFilePath\' and '                     . '\'scopes\' must be set when using service account flow.'                 );             }         } elseif ($this->clientId === null             || $this->clientSecret === null             || $this->refreshToken === null) {             throw new InvalidArgumentException(                 'All of \'clientId\', '                 . '\'clientSecret\', and \'refreshToken\' must be set when using '                 . 'installed/web application flow.'             );         }     }     /**      * Gets the JSON key file path.      *      * @return string|null      */     public function getJsonKeyFilePath(){         return $this->jsonKeyFilePath;     }     /**      * Gets the scopes.      *      * @return string|null      */     public function getScopes(){         return $this->scopes;     }     /**      * Gets the impersonated email.      *      * @return string|null      */     public function getImpersonatedEmail(){         return $this->impersonatedEmail;     }     /**      * Gets the client ID.      *      * @return string|null      */     public function getClientId(){         return $this->clientId;     }     /**      * Gets the client secret.      *      * @return string|null      */     public function getClientSecret(){         return $this->clientSecret;     }     /**      * Gets the refresh token.      *      * @return string|null      */     public function getRefreshToken(){         return $this->refreshToken;     } }