Существует два типа аккаунтов Google Рекламы: управляющие аккаунты и аккаунты рекламодателей. Подробную информацию о том, как эти и другие термины (например, "Клиентский аккаунт" и "Клиент") связаны между собой, можно найти в статье Типы аккаунтов.
Управляющие аккаунты могут управлять другими управляющими аккаунтами Google Рекламы или аккаунтами рекламодателей Google Рекламы. Вы можете связать аккаунт рекламодателя с управляющим аккаунтом и управлять им через управляющий аккаунт. Общая структура связанных аккаунтов представляет собой направленный ациклический граф, в котором аккаунты рекламодателей находятся на уровне конечных узлов.
Вы можете предоставить доступ к аккаунтам Google Рекламы отдельным пользователям или сервисным аккаунтам. Предоставить пользователям доступ к аккаунту рекламодателя можно двумя способами:
- Предоставьте пользователю прямой доступ к аккаунту рекламодателя, пригласив его в этот аккаунт.
- Предоставьте пользователю косвенный доступ к аккаунту рекламодателя, пригласив его в управляющий аккаунт, связанный с этим аккаунтом. Пользователь получает доступ к аккаунту рекламодателя, поскольку управляющий аккаунт имеет доступ ко всем связанным с ним аккаунтам.
Вы также можете назначать роли пользователей, когда приглашаете их управлять аккаунтом.
Рассмотрим следующую иерархию аккаунтов. Предположим, что у всех пользователей стандартный доступ.

В таблице ниже приведена сводная информация о структуре аккаунта.
| Пользователь | Имеет прямой доступ к | Имеет косвенный доступ к |
|---|---|---|
| U1, SA1 | M1 | M2, A1, A2, A3 |
| U2 | M2, M3 | A1, A2, A3, A4 |
| U3 | A4 |
Идентификатор клиента для входа
У пользователя может быть доступ к нескольким иерархиям аккаунтов. При вызове API в таких случаях необходимо указать корневой аккаунт, чтобы правильно определить уровни авторизации и доступа к аккаунту. Для этого добавьте в запрос к API заголовок login-customer-id.
В таблице ниже на основе иерархии аккаунтов из предыдущего примера показано, какие идентификаторы клиентов для входа можно использовать и к каким аккаунтам можно выполнять вызовы.
| Пользователь | Идентификатор клиента для входа | Аккаунты, к которым выполняются вызовы API |
|---|---|---|
| U1, SA1 | M1 | M1, M2, A1, A2, A3 |
| U2 | M2 | M2, A1, A2, A3 |
| U2 | M3 | M3, A1, A4 |
| U3 | A4 | A4 |
Вы можете не указывать заголовок login-customer-id, если у пользователя есть прямой доступ к аккаунту Google Рекламы, к которому вы обращаетесь. Например, вам не нужно указывать заголовок login-customer-id при использовании учетных данных U3 для вызова A4, поскольку серверы Google Рекламы могут правильно определить уровень доступа по идентификатору клиента (A4).
Если вы используете клиентскую библиотеку Google Ads API, укажите заголовок login-customer-id в настройках.
Java
Добавьте в файл ads.properties следующий параметр:
api.googleads.loginCustomerId=INSERT_LOGIN_CUSTOMER_ID_HERE
.NET
Добавьте следующую настройку при инициализации объекта GoogleAdsConfig и используйте ее для создания объекта GoogleAdsClient.
GoogleAdsConfig config = new GoogleAdsConfig()
{
// ...
LoginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"
};
GoogleAdsClient client = new GoogleAdsClient(config);
Python
Добавьте в файл google-ads.yaml следующий параметр:
login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE
PHP
Добавьте в файл google_ads_php.ini следующий параметр:
[GOOGLE_ADS]
loginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"
Ruby
Добавьте в файл google_ads_config.rb следующий параметр:
Google::Ads::GoogleAds::Config.new do |c|
c.login_customer_id = 'INSERT_LOGIN_CUSTOMER_ID_HERE'
end
Создайте экземпляр GoogleAdsClient, передав путь к файлу.
client = Google::Ads::GoogleAds::GoogleAdsClient.new(
'path/to/google_ads_config.rb'
)
Perl
Добавьте в файл googleads.properties следующий параметр:
loginCustomerId=INSERT_LOGIN_CUSTOMER_ID_HERE
curl
При выполнении команды curl укажите следующий аргумент командной строки:
-H "login-customer-id: INSERT_LOGIN_CUSTOMER_ID_HERE"Чтобы получить список аккаунтов, к которым у пользователя есть прямой доступ, используйте метод CustomerService.ListAccessibleCustomers.
Эти аккаунты можно использовать в качестве допустимых значений для заголовка login-customer-id.
Java
private void runExample(GoogleAdsClient client) { // Optional: Change credentials to use a different refresh token, to retrieve customers // available for a specific user. // // UserCredentials credentials = // UserCredentials.newBuilder() // .setClientId("INSERT_OAUTH_CLIENT_ID") // .setClientSecret("INSERT_OAUTH_CLIENT_SECRET") // .setRefreshToken("INSERT_REFRESH_TOKEN") // .build(); // // client = client.toBuilder().setCredentials(credentials).build(); try (CustomerServiceClient customerService = client.getLatestVersion().createCustomerServiceClient()) { ListAccessibleCustomersResponse response = customerService.listAccessibleCustomers( ListAccessibleCustomersRequest.newBuilder().build()); System.out.printf("Total results: %d%n", response.getResourceNamesCount()); for (String customerResourceName : response.getResourceNamesList()) { System.out.printf("Customer resource name: %s%n", customerResourceName); } } }
C#
public void Run(GoogleAdsClient client) { // Get the CustomerService. CustomerServiceClient customerService = client.GetService(Services.V25.CustomerService); try { // Retrieve the list of customer resources. string[] customerResourceNames = customerService.ListAccessibleCustomers(); // Display the result. foreach (string customerResourceName in customerResourceNames) { Console.WriteLine( $"Found customer with resource name = '{customerResourceName}'."); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
PHP
public static function runExample(GoogleAdsClient $googleAdsClient) { $customerServiceClient = $googleAdsClient->getCustomerServiceClient(); // Issues a request for listing all accessible customers. $accessibleCustomers = $customerServiceClient->listAccessibleCustomers(new ListAccessibleCustomersRequest()); print 'Total results: ' . count($accessibleCustomers->getResourceNames()) . PHP_EOL; // Iterates over all accessible customers' resource names and prints them. foreach ($accessibleCustomers->getResourceNames() as $resourceName) { /** @var string $resourceName */ printf("Customer resource name: '%s'%s", $resourceName, PHP_EOL); } }
Python
def main(client: GoogleAdsClient) -> None: customer_service: CustomerServiceClient = client.get_service( "CustomerService" ) accessible_customers: ListAccessibleCustomersResponse = ( customer_service.list_accessible_customers() ) result_total: int = len(accessible_customers.resource_names) print(f"Total results: {result_total}") resource_names: List[str] = accessible_customers.resource_names for resource_name in resource_names: # resource_name is implicitly str print(f'Customer resource name: "{resource_name}"')
Ruby
def list_accessible_customers() # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google::Ads::GoogleAds::GoogleAdsClient.new accessible_customers = client.service.customer.list_accessible_customers().resource_names accessible_customers.each do |resource_name| puts "Customer resource name: #{resource_name}" end end
Perl
sub list_accessible_customers { my ($api_client) = @_; my $list_accessible_customers_response = $api_client->CustomerService()->list_accessible_customers(); printf "Total results: %d.\n", scalar @{$list_accessible_customers_response->{resourceNames}}; foreach my $resource_name (@{$list_accessible_customers_response->{resourceNames}}) { printf "Customer resource name: '%s'.\n", $resource_name; } return 1; }
curl
# Returns the resource names of customers directly accessible by the user # authenticating the call. # # Variables: # API_VERSION, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # curl -f --request GET \ "https://googleads.googleapis.com/v${API_VERSION}/customers:listAccessibleCustomers" \ --header "Content-Type: application/json" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \
Что делать, если метод ListAccessibleCustomers не возвращает идентификатор клиента?
Если метод CustomerService.ListAccessibleCustomers не вернул идентификатор клиента, который должен был быть в результатах, этому может быть несколько объяснений.
У вас есть доступ к идентификатору клиента, но он предоставлен через родительский управляющий аккаунт. Например, если вы вызовете метод
ListAccessibleCustomersс учетными данными пользователяU1из предыдущего примера, то в результатах будет толькоM1, хотя у пользователяU1есть доступ к большему количеству аккаунтов. Чтобы подтвердить эту возможность, получите иерархию аккаунтов, выполнив запросыsearchилиsearchStreamк ресурсуcustomer_clientдля каждого из аккаунтов, возвращенных методомListAccessibleCustomers. Для этого задайте каждый из этих аккаунтов в качествеlogin-customer-id, как описано в предыдущем разделе. Если у вас есть доступ к целевому аккаунту, вы можете получить его в рамках одной из иерархий аккаунтов.Вы используете неправильные учетные данные OAuth. Чаще всего это происходит, когда вы используете учетные данные другого пользователя. Например, это может произойти, если вы случайно перепутаете учетные данные песочницы или разработчика с учетными данными рабочей среды или неправильно прочитаете учетные данные другого пользователя из базы данных или локального кеша. Один из возможных способов устранения этой проблемы – использовать Google People API, чтобы получить имя и адрес электронной почты вошедшего в систему пользователя и проверить, совпадает ли он с ожидаемым адресом электронной почты.
У вас нет доступа к аккаунту. Чтобы получить доступ к нужному аккаунту клиента, следуйте руководству по доступу к аккаунту.
Роли пользователей
У Google Ads API нет собственной модели доступа и отдельных областей действия OAuth 2.0 для ограничения функциональности. Например, в Google Ads API используются одни и те же области действия для операций чтения и записи. Вместо этого в Google Ads API используются те же роли пользователей, что и в Google Рекламе. Если роль пользователя назначена на уровне управляющего аккаунта, она наследуется всеми аккаунтами в иерархии. Если у пользователя есть конфликтующие роли в определенном аккаунте, правильный уровень определяется аккаунтом login-customer-id, указанным в запросе к API.
В таблице ниже используется иерархия аккаунтов из предыдущего примера и показано, как предоставление различных ролей влияет на пользователей.
| Пользователь | Роль пользователя предоставлена | login-customer-id | Действующий уровень доступа |
|---|---|---|---|
| SA1 | Стандартный доступ к аккаунту M1 | M1 | Стандартный доступ на M1, M2, A1, A2, A3 |
| U2 |
Стандартный доступ к M2 Доступ только для чтения к M3 |
M2 | Стандартный доступ на M2, A1, A2, A3 |
| U2 |
Стандартный доступ к M2 Доступ только для чтения к M3 |
M3 | Доступ только для чтения на устройствах M3, A1 и A4 |