Retrieves customers under a mcc manager and splits them according to their account_type.
Python
#!/usr/bin/env python # Copyright 2025 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. """Retrieves customers under a mcc manager and splits them according to their account_type.""" import argparse import traceback from typing import Any from google.ads.searchads360.v0.enums.types.account_level import AccountLevelTypeEnum from google.ads.searchads360.v0.services.types.search_ads360_service import SearchSearchAds360StreamRequest from google.api_core import exceptions from util_searchads360 import SearchAds360Client def _map_data(data, data_dictionary) -> None: """Inserts customer data into its corresponding dictionary using id as the key.""" if data: data_dictionary[data['id']] = data def _prepare_sub_manager_data(customer) -> dict[str, Any]: """Using the customer object, prepares sub-manager info.""" sub_manager_id = customer.sub_manager_id sub_managers_info = { 'id': sub_manager_id, 'name': customer.sub_manager_descriptive_name, 'type': AccountLevelTypeEnum.AccountLevelType.SUB_MANAGER.name, 'parent_id': customer.manager_id, } return sub_managers_info def _prepare_associate_manager_data(customer) -> dict[str, Any] | None: """Using the customer object, prepares associate-manager info.""" associate_manager_id = customer.associate_manager_id associate_manager_id_descriptive_name = str( customer.associate_manager_descriptive_name ) if not associate_manager_id_descriptive_name or associate_manager_id == 0: return None associate_manager_info = { 'id': associate_manager_id, 'name': associate_manager_id_descriptive_name, 'type': AccountLevelTypeEnum.AccountLevelType.ASSOCIATE_MANAGER.name, 'parent_id': customer.sub_manager_id, } return associate_manager_info def _prepare_client_customer_data(customer) -> dict[str, Any]: """Using the customer object, prepares client-customer info.""" client_customer_id = customer.id # Determine parent ID for the client account parent_id = ( customer.associate_manager_id or customer.sub_manager_id or customer.manager_id ) client_customer_info = { 'id': client_customer_id, 'name': customer.descriptive_name, 'type': customer.account_type.name, 'parent_id': parent_id, } return client_customer_info def _get_all_accounts_details( search_ads_360_service, client_customer_id, sub_managers_data, associate_managers_data, client_accounts_data, ) -> None: """Fetches details for a client customer and updates hierarchy maps.""" query = """ SELECT customer.id, customer.descriptive_name, customer.account_type, customer.manager_id, customer.manager_descriptive_name, customer.sub_manager_id, customer.sub_manager_descriptive_name, customer.associate_manager_id, customer.associate_manager_descriptive_name, customer.account_level FROM customer""" request = SearchSearchAds360StreamRequest() request.customer_id = client_customer_id request.query = query try: results_stream = search_ads_360_service.search_stream(request=request) for response in results_stream: for row in response.results: customer = row.customer _map_data(_prepare_sub_manager_data(customer), sub_managers_data) _map_data( _prepare_associate_manager_data(customer), associate_managers_data ) _map_data(_prepare_client_customer_data(customer), client_accounts_data) except exceptions.GoogleAPICallError as e: print( 'ERROR: An unexpected error occurred while fetching customer' f' information for {client_customer_id}.\nDetails: {e}\n' ) def _get_client_customer_ids(search_ads_360_service, customer_id) -> list[str]: """Retrieves a list of client customer IDs (if the customer is a manager). Args: search_ads_360_service: The Search Ads 360 service client. customer_id: The customer ID of the mcc manager customer. Returns: A list of client customer IDs. """ request = SearchSearchAds360StreamRequest() query = """ SELECT customer_client.id, customer_client.manager FROM customer_client WHERE customer_client.manager = False """ customer_client_ids = [] request.customer_id = customer_id request.query = query try: # Issues a search stream request. results_stream = search_ads_360_service.search_stream(request=request) for response in results_stream: for row in response.results: customer_client_ids.append(str(row.customer_client.id)) except exceptions.GoogleAPICallError as e: print( 'ERROR: An unexpected error occurred while fetching client customer IDs' f' for {customer_id}.\nDetails: {e}\n' ) return customer_client_ids def main(service_client, login_customer_id) -> None: search_ads_360_service = service_client.get_service() sub_managers_data = {} associate_managers_data = {} client_accounts_data = {} # Get all client customer IDs under the login_customer_id (MCC manager) customer_client_ids = _get_client_customer_ids( search_ads_360_service, login_customer_id ) for customer_client_id in customer_client_ids: _get_all_accounts_details( search_ads_360_service, customer_client_id, sub_managers_data, associate_managers_data, client_accounts_data, ) if __name__ == '__main__': # SearchAds360Client will read the search-ads-360.yaml configuration file in # the home directory if none is specified. search_ads_360_client = SearchAds360Client.load_from_file() parser = argparse.ArgumentParser( description=( 'Retrieves all customer_client for a mcc manager customer and runs a' ' query on each customer_client.' ) ) # Arguments to provide to run the example. parser.add_argument( '-l', '--login_customer_id', type=str, required=True, help=( 'The Search Ads 360 MCC manager login customer ID (10 digits, no' ' dashes). This can be obtained from the UI or from calling' ' ListAccessibleCustomers - ' 'https://developers.google.com/search-ads/reporting/concepts/login-customer-id.' ), ) args = parser.parse_args() search_ads_360_client.set_ids(args.login_customer_id, args.login_customer_id) try: main(search_ads_360_client, args.login_customer_id) except Exception: # pylint: disable=broad-except traceback.print_exc()
Java
// Copyright 2025 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. package sample; import com.beust.jcommander.Parameter; import com.google.ads.searchads360.v0.enums.AccountLevelTypeEnum.AccountLevelType; import com.google.ads.searchads360.v0.lib.SearchAds360Client; import com.google.ads.searchads360.v0.resources.Customer; import com.google.ads.searchads360.v0.services.SearchAds360Row; import com.google.ads.searchads360.v0.services.SearchAds360ServiceClient; import com.google.ads.searchads360.v0.services.SearchSearchAds360StreamRequest; import com.google.ads.searchads360.v0.services.SearchSearchAds360StreamResponse; import com.google.api.gax.rpc.ServerStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** Retrieves customers under a mcc manager and splits them according to their account_type. */ public class RunMccQuery { private static record AccountDetails(long id, String name, String type, long parentId) {} private static class RunMccQueryParams extends CodeSampleParams { @Parameter( names = "--loginCustomerId", required = true, description = "The Search Ads 360 MCC manager login customer ID (10 digits, no dashes). This can be" + " obtained from the UI or from calling ListAccessibleCustomers -" + " https://developers.google.com/search-ads/reporting/concepts/login-customer-id.") private String loginCustomerId; } public static void main(String[] args) { RunMccQueryParams params = new RunMccQueryParams(); params.parseArguments(args); final String loginCustomerId = params.loginCustomerId; try { // Creates a SearchAds360Client with the specified loginCustomerId. final SearchAds360Client searchAds360Client = SearchAds360Client.newBuilder() .setLoginCustomerId(loginCustomerId) .fromPropertiesFile() .build(); // Creates the Search Ads 360 Service client. SearchAds360ServiceClient client = searchAds360Client.create(); new RunMccQuery().runExample(client, loginCustomerId); } catch (Exception exception) { System.err.printf("Failed with exception: %s%n", exception); exception.printStackTrace(); System.exit(1); } } private void runExample( SearchAds360ServiceClient searchAds360ServiceClient, String loginCustomerId) { Map<Long, AccountDetails> subManagersData = new HashMap<>(); Map<Long, AccountDetails> associateManagersData = new HashMap<>(); Map<Long, AccountDetails> clientAccountsData = new HashMap<>(); List<String> customerClientIds = getClientCustomerIds(searchAds360ServiceClient, loginCustomerId); for (String customerClientId : customerClientIds) { getAllAccountsDetails( searchAds360ServiceClient, customerClientId, subManagersData, associateManagersData, clientAccountsData); } } /** Retrieves a list of client customer IDs (if the customer is a manager). */ private List<String> getClientCustomerIds( SearchAds360ServiceClient searchAds360ServiceClient, String managerCustomerId) { List<String> customerClientIds = new ArrayList<>(); String query = """ SELECT customer_client.id, customer_client.manager FROM customer_client WHERE customer_client.manager = FALSE """; SearchSearchAds360StreamRequest request = SearchSearchAds360StreamRequest.newBuilder() .setCustomerId(managerCustomerId) .setQuery(query) .build(); try { ServerStream<SearchSearchAds360StreamResponse> stream = searchAds360ServiceClient.searchStreamCallable().call(request); for (SearchSearchAds360StreamResponse response : stream) { for (SearchAds360Row row : response.getResultsList()) { customerClientIds.add(String.valueOf(row.getCustomerClient().getId())); } } } catch (Exception e) { System.err.printf( "ERROR: An unexpected error occurred while fetching client customer IDs for %s.%nDetails:" + " %s%n", managerCustomerId, e); } return customerClientIds; } /** Fetches details for a client customer and updates hierarchy maps. */ private void getAllAccountsDetails( SearchAds360ServiceClient searchAds360ServiceClient, String clientCustomerId, Map<Long, AccountDetails> subManagersData, Map<Long, AccountDetails> associateManagersData, Map<Long, AccountDetails> clientAccountsData) { String query = """ SELECT customer.id, customer.descriptive_name, customer.account_type, customer.manager_id, customer.manager_descriptive_name, customer.sub_manager_id, customer.sub_manager_descriptive_name, customer.associate_manager_id, customer.associate_manager_descriptive_name, customer.account_level FROM customer """; SearchSearchAds360StreamRequest request = SearchSearchAds360StreamRequest.newBuilder() .setCustomerId(clientCustomerId) .setQuery(query) .build(); try { ServerStream<SearchSearchAds360StreamResponse> stream = searchAds360ServiceClient.searchStreamCallable().call(request); for (SearchSearchAds360StreamResponse response : stream) { for (SearchAds360Row row : response.getResultsList()) { Customer customer = row.getCustomer(); mapData(prepareSubManagerData(customer), subManagersData); mapData(prepareAssociateManagerData(customer), associateManagersData); mapData(prepareClientCustomerData(customer), clientAccountsData); } } } catch (Exception e) { System.err.printf( "ERROR: An unexpected error occurred while fetching customer information for" + " %s.%nDetails: %s%n", clientCustomerId, e); } } /** Inserts customer data into its corresponding dictionary using id as the key. */ private void mapData(AccountDetails accountDetails, Map<Long, AccountDetails> dataCollectionMap) { if (accountDetails.id() != 0) { dataCollectionMap.put(accountDetails.id(), accountDetails); } } /** Using the customer object, prepares sub-manager info. */ private AccountDetails prepareSubManagerData(Customer customer) { return new AccountDetails( customer.getSubManagerId(), customer.getSubManagerDescriptiveName(), AccountLevelType.SUB_MANAGER.name(), customer.getManagerId()); } /** Using the customer object, prepares associate-manager info. */ private AccountDetails prepareAssociateManagerData(Customer customer) { return new AccountDetails( customer.getAssociateManagerId(), customer.getAssociateManagerDescriptiveName(), AccountLevelType.ASSOCIATE_MANAGER.name(), customer.getSubManagerId()); } /** Using the customer object, prepares client-customer info. */ private AccountDetails prepareClientCustomerData(Customer customer) { long parentId = customer.getManagerId(); if (customer.getAssociateManagerId() != 0) { parentId = customer.getAssociateManagerId(); } else if (customer.getSubManagerId() != 0) { parentId = customer.getSubManagerId(); } return new AccountDetails( customer.getId(), customer.getDescriptiveName(), customer.getAccountType().name(), parentId); } }