Posts tagged with google-oauth

My Google OAuth refresh token expires after one hour, even though both my OAuth and Google Ads API applications are verified and approved.

  • Both OAuth and Google Ads API apps are verified and approved.
  • Created a new client_credentials.json file after approval.
  • Using the provided Laravel example for the PHP Google Ads API.
  • Added the developer token with basic access and populated clientId and clientSecret in the google_ads_php.ini file.

For the refresh token i used command ~/go/bin/oauth2l fetch --credentials CLIENT_SECRET.json --scope adwords to obtain a refresh token. And added this token to google_ads_php.ini too.

Despite these steps, I consistently encounter a "token has been expired or revoked" error after 60 minutes.

I've set up an OAuth2 web project as well as a Service Account. Both IDs have been added with domain-wide delegation with the adwords scope in my Google Workspace.

I have a Google Ads Manager account with a Developer Key (it's in test mode, if that matters?). The email I'm trying to authenticate with for either method is an Admin in the domain and on the relevant Ads Manager and Ads accounts.

No matter what I do, I get the following error.

{     "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https:\/\/developers.google.com\/identity\/sign-in\/web\/devconsole-project.",     "code": 16,     "status": "UNAUTHENTICATED",     "details": [         {             "@type": "type.googleapis.com\/google.ads.googleads.v16.errors.GoogleAdsFailure",             "errors": [                 {                     "errorCode": {                         "authenticationError": "OAUTH_TOKEN_HEADER_INVALID"                     },                     "message": "Oauth token HTTP header is malformed."                 }             ],             "requestId": "9QCN5RO9mRkmS1ULtDAKMA"         }     ] } 

If I try to use the service account email as the impersonateEmail parameter, I get a NOT_ADS_USER. I've invited it to the Ads Manager account, but am not sure how to accept that invite. I think it would result in the same OAUTH_TOKEN_HEADER_INVALID, anyways.

This is within a Laravel project.

$oauth2 = (new OAuth2TokenBuilder())                 ->withClientId(config('google.client_id'))                 ->withClientSecret(config('google.client_secret'))                 ->withRefreshToken(config('googleads.refresh_token'))                 ->build(); 
$oauth2 = (new OAuth2TokenBuilder())                 ->withJsonKeyFilePath(realpath(config('google.service.file')))                 ->withScopes('https://www.googleapis.com/auth/adwords')                 ->withImpersonatedEmail(config('googleads.impersonated_email'))                 ->build(); 

What's strange is that, using either OAuth2Token instance, I can run fetchAuthToken(), and I see that the object gets its access_token. I can also see in Google\ApiCore\CredentialsWrapper::getAuthorizationHeaderCallback that it is added as the authorization Bearer token.

Here's how my GoogleAdsClient is built:

$this->client = (new GoogleAdsClientBuilder())                 ->withOAuth2Credential($oauth2)                 ->withDeveloperToken(config('google.developer_key'))                 ->usingGapicV2Source(true)                 ->build(); 

And here's the request that fails with the OAUTH_TOKEN_HEADER_INVALID:

$requestArgs = [             // Set the language resource using the provided language ID.             'language' => $this->getLanguageConstant(),             'customer_id' => $this->getCustomerId(),             // Add the resource name of each location ID to the request. - currently an empty array             'geo_target_constants' => $this->getGeoTargetConstants(),             // Set the network. To restrict to only Google Search, change the parameter below to             'keyword_plan_network' => KeywordPlanNetwork::GOOGLE_SEARCH,         ] + $requestOptionalArgs;         $response = $ideaClient->generateKeywordIdeas(             new GenerateKeywordIdeasRequest($requestArgs)         ); 

I've been going in circles on this for over a day. Thank you in advance!

I have generated developer_token, access_token and refresh token with googleads read permission. While using in code using google-ads-api I am getting below error.

Code:

from google.ads.googleads.client import GoogleAdsClient googleads_client = GoogleAdsClient.load_from_storage(path="./googleads.yaml", version="v14") 

Error:

  googleads_client = GoogleAdsClient.load_from_storage(path="./googleads.yaml", version="v14") 

I followed this tutorial to generate developer token, access token and refresh_token.

Here is permissions in the app and during authorization screenshot

I've made a script that runs on the Google Ads API. The project on console.cloud.google.com is configured as "External" and "In Testing". The script I'm talking about needs to be run daily on a cron job. Issue is, every week I have to get a new refresh token manually, which is unnecessary in my opinion. So, is there a way to get a new refresh token without needing a user pressing "Continue" and "Accept", i.e. verifying that they allow access to Google Ads? Or does that only happen when I Publish my app on console.cloud.google.com?

So far, I either put the refresh token into the script and it works or (in another script) I use the refresh token to cURL into https://oauth2.googleapis.com/token to get an access token.

I'm attempting to cURL the Google Ads API with the following PHP code:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://googleads.googleapis.com/v14/customers/[CUSTOMER_ID]:generateKeywordHistoricalMetrics'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, [     'developer-token: [DEVELOPER_TOKEN',     'login-customer-id: [LOGIN_CUSTOMER_ID]',     'Authorization: Bearer [???????]',     'Accept: application/json',     'Content-Type: application/json', ]); curl_setopt($ch, CURLOPT_POSTFIELDS, '{"historicalMetricsOptions":{"yearMonthRange":{"start":{"month":"JUNE","year":2022},"end":{"month":"MAY","year":2023}}},"keywords":[""]}'); $response = curl_exec($ch); curl_close($ch); 

And the response is:

{   "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"   } } 

What I believe the issue to be is on the "Authentication" field. So far, I've put the following in that field(and failed each time):

  1. OAUTH 2 Client ID
  2. OAUTH 2 Client Secret
  3. OAUTH 2 Refresh Token, that works for another Google Ads project I've made
  4. Developer token

So, I could appreciate any and all help, since I'm running out of ideas and don't know what to do.