Posts tagged with python

Hi I'm trying to connect an python script with google ads api.

I have: Ads Account manager with developer_token and the the account level is in "Test Account" Google ads api -> enabled.

service account added to the api and with file service.json and email like service_acc@project.iam.gserviceaccount.com

google-ads.yaml with

json_key_file_path: 'service.json' impersonated_email: 'service_acc@project.iam.gserviceaccount.com' use_proto_plus: True developer_token: 'developer_token' 

client_ads_id (supuse to be in ads.google.com in help -> customer Id) 10 digits without

I can access client api with client = googleads.client.GoogleAdsClient.load_from_storage() with no error.

Then I try to create a user list with

user_list_service_client = client.get_service("UserListService") user_list_operation = client.get_type("UserListOperation") user_list = user_list_operation.create user_list.name = list_name user_list.description = description user_list.crm_based_user_list.upload_key_type = (    client.enums.CustomerMatchUploadKeyTypeEnum.CONTACT_INFO         ) user_list.membership_life_span = 365 response = user_list_service_client.mutate_user_lists(             customer_id=customer_id, operations=[user_list_operation]         ) 

In the last line I get an error:

errors {   error_code {     authentication_error: NOT_ADS_USER   }   message: "User in the cookie is not a valid Ads user." } 

and in the middle of the exception I got

status = StatusCode.UNAUTHENTICATED 

I don't know how to link the client ads account with the api service account.

I've try to:

  1. The service account is not linked to the ads client. (I've invited to service_acc@project.iam.gserviceaccount.com but... obviously it doesn't arrive and doesn't accept the invitation automatically)
  2. In this doc talk about impersonate, and don't know how to do it

A Google Ads user with permissions on the Google Ads account you want to access. Google Ads does not support using service accounts without impersonation

I may be doing it the wrong way but I want, at first, to extract keyword traffic information like I did with TrafficEstimationService in the (now deprecated) AdWords API. My code looks like this (with some edits here and there):

# [... some initialization (clients, service accounts, etc.) bits here] # fetch an instance of the Google Ads client gc = GoogleAdsClient.load_from_storage(gads_credentials_file, version="v10") # fetch an instance of the Google Ads service gs = gc.get_service("GoogleAdsService") # fetch an instance of the Geo Target Constant service gtcs = gc.get_service("GeoTargetConstantService").geo_target_constant_path # fetch an instance of the keyword plan idea service ks = gc.get_service("KeywordPlanIdeaService") # build the initial search request rq = gc.get_type("GenerateKeywordIdeasRequest") rq.customer_id = gads_account_id.replace("-", '') rq.geo_target_constants = [gtcs(get_location_id(gads_country))] rq.keyword_plan_network = (gc.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH_AND_PARTNERS) rq.language = gs.language_constant_path(get_language_id(gads_language)) rq.keyword_annotation = gc.enums.KeywordPlanKeywordAnnotationEnum if len(gads_keywords) > 0:     rq.keyword_seed.keywords.extend(gads_keywords) # generate keyword ideas keyword_ideas = ks.generate_keyword_ideas(request=rq) rows = [] for idea in keyword_ideas:     rows.append({         "date": r,         "text": idea.text,         "competition_value": idea.keyword_idea_metrics.competition.name,         "avg_monthly_searches": idea.keyword_idea_metrics.avg_monthly_searches     }) 

So far, so good. I can specify location and language and (of course) they keywords to look for. At the end of this request, I have something like this (just printing the first list item):

{'date': '2022-08-09', 'text': 'zapatos', 'competition_value': 'MEDIUM', 'avg_monthly_searches': 301000} 

The problem I have is I have been requested to ensure the match type is EXACT but looking at both the documentation and the source code for KeywordPlanIdeaService there is no trace of this parameter. That's why I assume I'm doing it wrong (or maybe I'm lacking something here). In any case, I'm a bit lost.

Can you tell me how can I specify this (if it can be done) or an alternate way to accomplish this?

client_id, client_secret, developer_token = settings.CLIENT_ID, settings.CLIENT_SECRET, settings.DEVELOPER_TOKEN credentials = oauth2.GoogleRefreshTokenClient(     client_id,     client_secret,     login_user.refresh_token ) client = GoogleAdsClient(credentials, settings.DEVELOPER_TOKEN) click_conversion = client.get_type("ClickConversion") conversion_action_service = client.get_service("ConversionActionService") click_conversion.conversion_action = (     conversion_action_service.conversion_action_path(         client_id, company.conversion_name     ) ) click_conversion.gclid = deal.gclid click_conversion.conversion_value = float(deal.deal_value if deal.deal_value else 0) click_conversion.conversion_date_time = make_aware(datetime.now()).strftime('%Y%m%d %H%M%S %z') conversion_upload_service = client.get_service("ConversionUploadService") request = client.get_type("UploadClickConversionsRequest") request.customer_id = client_id request.conversions.append(click_conversion) request.partial_failure = True conversion_upload_response = (     conversion_upload_service.upload_click_conversions(         request=request,     ) ) 

Does anyone know why I'm getting the above error when trying to Upload Clicks to google ads? got this in the logs:

Request made: ClientCustomerId: xxxxxx-xxxxx.apps.googleusercontent.com, Host: googleads.googleapis.com, Method: /google.ads.googleads.v11.services.ConversionUploadService/UploadClickConversions, RequestId: None, IsFault: True, FaultMessage: Getting metadata from plugin failed with error: 'GoogleRefreshTokenClient' object has no attribute 'before_request'

customer_service = client.get_service("CustomerService") app_list = customer_service.list_accessible_customers().resource_names def customer_query(client, customer_id):     ga_service = client.get_service("GoogleAdsService")     query = """         SELECT             customer.descriptive_name,             customer.currency_code         FROM customer         LIMIT 1"""     request = client.get_type("SearchGoogleAdsRequest")     request.customer_id = customer_id     request.query = query     response = ga_service.search(request=request)     customer = list(response)[0].customer     return customer for entry in app_list:     customer_id = entry.split('/')[1]     entry = customer_query(client, customer_id)     formatted_entry = {'customer_id': customer_id, 'name': entry.descriptive_name, 'currency': entry.currency_code}     apps.append(formatted_entry) return apps 

This seems really convoluted and I'm having to pass around a lot more data than I'd like. Surely there should be a way to just request the details.

I'm trying to get campaign information with Google ADS API. The sample code snippet I used is from the official googleads github repo.

import argparse import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException _DEFAULT_PAGE_SIZE = 1000 # [START get_campaigns_by_label] def main(client, customer_id, label_id, page_size):     """Demonstrates how to retrieve all campaigns by a given label ID.     Args:         client: An initialized GoogleAdsClient instance.         customer_id: A client customer ID str.         label_id: A label ID to use when searching for campaigns.         page_size: An int of the number of results to include in each page of             results.     """     ga_service = client.get_service("GoogleAdsService")     # Creates a query that will retrieve all campaign labels with the     # specified label ID.     query = f"""         SELECT             campaign.id,             campaign.name,             label.id,             label.name          FROM campaign_label          WHERE label.id = "{label_id}"          ORDER BY campaign.id"""     # Retrieves a google.api_core.page_iterator.GRPCIterator instance     # initialized with the specified request parameters.     request = client.get_type("SearchGoogleAdsRequest")     request.customer_id = customer_id     request.query = query     request.page_size = page_size     iterator = ga_service.search(request=request)     # Iterates over all rows in all pages and prints the requested field     # values for the campaigns and labels in each row. The results include     # the campaign and label objects because these were included in the     # search criteria.     for row in iterator:         print(             f'Campaign found with ID "{row.campaign.id}", name '             f'"{row.campaign.name}", and label "{row.label.name}".'         ) if __name__ == "__main__":     # GoogleAdsClient will read the google-ads.yaml configuration file in the     # home directory if none is specified.     googleads_client = GoogleAdsClient.load_from_storage(version="v10")     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.",     )     parser.add_argument(         "-l",         "--label_id",         type=str,         required=True,         help="A label ID associated with a campaign.",     )     args = parser.parse_args()     try:         main(             googleads_client,             args.customer_id,             args.label_id,             _DEFAULT_PAGE_SIZE,         )     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) 

When I run the above .py file, I get the following error.

ValueError: Specified Google Ads API version "v10" does not exist. Valid API versions are: "v8", "v7", "v6" 

But when I change the version on "GoogleAdsClient.load_from_storage(version="v10")" to v8, this time I get the following error.

Request made: ClientCustomerId: XXXXXXX, Host: googleads.googleapis.com, Method: /google.ads.googleads.v8.services.GoogleAdsService/Search, RequestId: XXXXXXXXX,IsFault: True, FaultMessage:  Version v8 is deprecated. Requests to this version will be blocked. 

By the way, I'm sure the google-ads package is up to date. Previously, I ran the following.

pip uninstall google-ads pip install google-ads 

Thanks in advance for your help.