Posts tagged with google-api

I'm using oAuth2.0 flow to work with Google Ads API. I ran in a problem today that when doing an API Request I'm getting the following 401 error:

UNAUTHENTICATED: 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. 

On the headers of each google ads request I add

   {"Content-Type", "application/json"},    {"Accept", "application/json"},    {"User-Agent", "Mozilla/5.0 (Macintosh; ..."},    {"Authorization", "Bearer $ACCESS_TOKEN"},    {"developer-token", "$DEVELOPER_TOKEN"},    {"login-customer-id", "$LOGIN_CUSTOMER_ID"} 

I've already tried to generate a new access_token, since my automatically process of generating new access_tokens when the current one expired could be failing, but it wasn't the case. I managed to create a new valid access token and it continues to give the same error. The scope used when fist granted permissions to the app was "https://www.googleapis.com/auth/adwords".

Did anyone fall into the same problem?

I am using a Google Ads php library (https://github.com/googleads/googleads-php-lib) to manage my own google ads account, following Google's instructions here (https://developers.google.com/adwords/api/docs/guides/first-api-call)

(I've actually been doing this for many years without a problem, but I recently switched over to using a different project in the Google Cloud Platform, so I had to update my credentials and get a new refresh token)

To get a new refresh token, I ran the php script called GetRefreshTokenWithoutIniFile.php (which allows me to grant offline access and retrieve a new refresh token, which I store in a file auth.ini for future use).

The refresh token last for a few days, before I see this error:

{     "error" : "invalid_grant",     "error_description" : "Token has been expired or revoked." } 

I have been using the above method for years and the refresh token has never expired. However, it now seems to expire every couple of days. I am certainly not 'running out' of refresh tokens (I only request one), and the user is not revoking access (the user is me). For that reason, these similar answers don't help me:

Any more ideas?

I want to use Google Ads API with service account I managed to create a session using this Java code configuration:

ClassLoader classLoader = this.getClass().getClassLoader();         File configFile = new File(classLoader.getResource("ads.properties").getFile());         GoogleAdsClient googleAdsClient = GoogleAdsClient.newBuilder()                 .fromEnvironment()                 .fromPropertiesFile(configFile)                 .build();         GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient(); 

I want to use this connection to make a request using this code:

AdWordsSession session = null;         try {             // Generate a refreshable OAuth2 credential.             Credential oAuth2Credential = new OfflineCredentials.Builder()                             .forApi(Api.ADWORDS)                             .fromFile()                             .build()                             .generateCredential();             // Construct an AdWordsSession.             session =                     new AdWordsSession.Builder().fromFile().build();         } catch (ConfigurationLoadException cle) {             System.err.printf(                     "Failed to load configuration from the %s file. Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, cle);             return;         } catch (ValidationException ve) {             System.err.printf(                     "Invalid configuration in the %s file. Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, ve);             return;         } catch (OAuthException oe) {             System.err.printf(                     "Failed to create OAuth credentials. Check OAuth settings in the %s file. "                             + "Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, oe);             return;         }         AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();         try {             runExample(adWordsServices, session);         } catch (ApiException apiException) {             System.err.println("Request failed due to ApiException. Underlying ApiErrors:");             if (apiException.getErrors() != null) {                 int i = 0;                 for (ApiError apiError : apiException.getErrors()) {                     System.err.printf("  Error %d: %s%n", i++, apiError);                 }             }         } catch (RemoteException re) {             System.err.printf(                     "Request failed unexpectedly due to RemoteException: %s%n", re);         } 

AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Get the TrafficEstimatorService. TrafficEstimatorServiceInterface trafficEstimatorService = adWordsServices.get(session, TrafficEstimatorServiceInterface.class);

Full source: https://developers.google.com/adwords/api/docs/samples/java/basic-operations

Do you know how I can use service account into the above code?

I'm trying to get reports for my google ads and display them on a dashboard for easier viewing and monitoring.

I've gone through the whole process to authenticate my account. I got all the keys needed. Everything works up until the query is run. See code below copied from Google ads API examples

#!/usr/bin/env python # Copyright 2020 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. """This example illustrates how to get all campaigns. To add campaigns, run add_campaigns.py. """ import argparse import sys from google.ads.google_ads.client import GoogleAdsClient from google.ads.google_ads.errors import GoogleAdsException def main(client, customer_id):     ga_service = client.get_service("GoogleAdsService", version="v6")     query = """         SELECT campaign.id, campaign.name         FROM campaign         ORDER BY campaign.id"""     # Issues a search request using streaming.     response = ga_service.search_stream(customer_id, query=query)     try:         for batch in response:             for row in batch.results:                 print(                     f"Campaign with ID {row.campaign.id} and name "                     f'"{row.campaign.name}" was found.'                 )     except GoogleAdsException as ex:         print(             f'Request with ID "{ex.request_id}" failed with status '             f'"{ex.error.code().name}" and includes the following errors:'         )         for error in ex.failure.errors:             print(f'\tError with message "{error.message}".')             if error.location:                 for field_path_element in error.location.field_path_elements:                     print(f"\t\tOn field: {field_path_element.field_name}")         sys.exit(1) if __name__ == "__main__":     # GoogleAdsClient will read the google-ads.yaml configuration file in the     # home directory if none is specified.     google_ads_client = GoogleAdsClient.load_from_storage()     parser = argparse.ArgumentParser(         description="Lists all campaigns for specified customer."     )     # The following argument(s) should be provided to run the example.     parser.add_argument(         "-c",         "--customer_id",         type=str,         required=True,         help="The Google Ads customer ID.",     )     args = parser.parse_args()     main(google_ads_client, args.customer_id) 

Nothing gets printed to my console. When I print out print(response) i get <google.api_core.grpc_helpers._StreamingResponseIterator object at 0x7fb7dcaaf3d0>

I get no errors, tracebacks nothing. This is what my console looks like (hiding customer_id):

Im building an app with google ads api using a service account auth flow (server to server).

The problem: the auth part is not working... I keep getting a 401 error.

Sample of the request:

const request = require('request'); .... request({   'method': 'GET',   'url': 'https://googleads.googleapis.com/v6/customers/XXXXXXXX',   'headers': {     'Authorization': 'Bearer XXXXXXXX',     'developer-token': 'XXXXXXXX',     'Content-Type': 'application/json'   } }) ... 

or

curl --location --request GET 'https://googleads.googleapis.com/v6/customers/XXXXXXXX' \ --header 'Authorization: Bearer XXXXXXXX' \ --header 'developer-token: XXXXXXXX' \ --header 'Content-Type: application/json' 

[ERROR] Response from google ads api:

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

I cant seem to find out why Im getting this authentication error.

What I have tried:

  1. Following this guide step by step -> https://developers.google.com/google-ads/api/docs/oauth/service-accounts
  2. Using the python library -> https://github.com/googleads/googleads-python-lib
  3. Using the google ads API with REST (no library)
  4. On localhost server
  5. On the production server (the www.g-suite.com domain linked to the account)

Whatever method or environment I try, it results in the same error.

Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential 

Steps I have implemented:

  • Created a google ads manager account
  • Generated a valid developer token for that account
  • Created project in Google cloud platform
  • Opened a service account inside the project
  • Created a private key for the service account
  • Granting impersonation abilities in the G Suite domain for this scope: https://www.googleapis.com/auth/adwords
  • Enabled domain-wide delegation on the service account
  • Generated the access token with the key json file.

Generating the access token:

const { google } = require('googleapis'); const getAccessToken = async () => {     const SCOPES = ['https://www.googleapis.com/auth/adwords'];     const authClient = new google.auth.GoogleAuth({         keyFile: './pathtokeyfile.json',         scopes: SCOPES,     });     const token = await authClient.getAccessToken();     return token; }; 

I am surely missing something, but am not sure what it is..

Will be super grateful if someone can share a solution!! thanks champs 👍