Понимание модели доступа к Google Ads

Существует два типа аккаунтов Google Ads: аккаунты менеджера Google Ads и аккаунты рекламодателя Google Ads (также известные как клиентские аккаунты). Аккаунты менеджера позволяют управлять другими аккаунтами менеджера Google Ads или аккаунтами рекламодателя Google Ads. Вы можете связать аккаунт рекламодателя с аккаунтом менеджера , а затем управлять аккаунтом рекламодателя через аккаунт менеджера. Общая связанная структура представляет собой ориентированный ациклический граф, где аккаунты рекламодателей находятся на уровне листьев.

Вы можете предоставить доступ к аккаунтам Google Ads отдельным пользователям или сервисным аккаунтам. Существует два способа предоставить пользователям доступ к рекламному аккаунту:

  • Предоставьте пользователю прямой доступ к аккаунту рекламодателя, пригласив его в этот аккаунт.
  • Предоставьте пользователю косвенный доступ к аккаунту рекламодателя, пригласив его в управляющий аккаунт, связанный с этим аккаунтом. Пользователь получает доступ к аккаунту рекламодателя, поскольку управляющий аккаунт имеет доступ ко всем аккаунтам, связанным с ним.

Вы также можете назначать роли пользователям при приглашении пользователя для управления учетной записью.

Рассмотрим следующую иерархию учетных записей. Предположим, что все пользователи имеют стандартный доступ.

Диаграмма иерархии учетных записей

В следующей таблице приведена сводная информация о структуре этих счетов.

Пользователь Имеет прямой доступ Имеет косвенный доступ к
U1, SA1 М1 М2, А1, А2, А3
U2 М2, М3 А1, А2, А3, А4
U3 А4

Идентификатор клиента для входа в систему

Пользователь может иметь доступ к нескольким иерархиям учетных записей. В таких случаях при выполнении вызова API необходимо указать корневую учетную запись, которая будет использоваться для корректного определения уровней авторизации и доступа к учетной записи. Это делается путем указания заголовка login-customer-id в составе запроса API.

В следующей таблице используется иерархия учетных записей из предыдущего примера , чтобы показать, какие идентификаторы клиентов для входа в систему вы можете использовать, и соответствующий список учетных записей, к которым вы можете обращаться.

Пользователь Для входа в систему используйте идентификатор клиента. Учетные записи для выполнения вызовов API
U1, SA1 М1 М1, М2, А1, А2, А3
U2 М2 М2, А1, А2, А3
U2 М3 М3, А1, А4
U3 А4 А4

Вы можете пропустить указание заголовка login-customer-id если пользователь имеет прямой доступ к аккаунту Google Ads, к которому вы обращаетесь. Например, вам не нужно указывать заголовок login-customer-id при использовании учетных данных U3 для обращения к A4 , поскольку серверы Google Ads могут корректно определить уровень доступа по идентификатору клиента ( A4 ).

Если вы используете одну из наших клиентских библиотек, то для указания заголовка login-customer-id используйте следующие настройки.

Java

Добавьте следующую настройку в файл ads.properties .

api.googleads.loginCustomerId=INSERT_LOGIN_CUSTOMER_ID_HERE

C#

Добавьте следующий параметр при инициализации объекта GoogleAdsConfig и используйте его для создания объекта GoogleAdsClient .

GoogleAdsConfig config = new GoogleAdsConfig()
{
    ...
    LoginCustomerId = ******
};
GoogleAdsClient client = new GoogleAdsClient(config);

PHP

Добавьте следующую настройку в файл google_ads_php.ini .

[GOOGLE_ADS]
loginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"

Python

Добавьте следующие настройки в файл google-ads.yaml .

login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE

Руби

Добавьте следующую настройку в файл 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 укажите следующий аргумент командной строки.

-H "login-customer-id: LOGIN_CUSTOMER_ID"

Вы можете использовать метод 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.V23.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}"')
      

Руби

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;
}
      

локон

# Returns the resource names of customers directly accessible by the user
# authenticating the call.
#
# Variables:
#   API_VERSION,
#   DEVELOPER_TOKEN,
#   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 "developer-token: ${DEVELOPER_TOKEN}" \
--header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \
      

Что произойдет, если метод ListAccessibleCustomers не получит идентификатор моего клиента?

Если метод CustomerService.ListAccessibleCustomers не получил идентификатор клиента, который вы ожидали увидеть в результатах, этому может быть несколько объяснений.

  1. У вас есть доступ к идентификатору клиента, но доступ предоставляется через учетную запись родительского менеджера. Например, если вы вызовете метод ListAccessibleCustomers с учетными данными пользователя U1 из предыдущего примера , вы получите в результатах только M1 , даже если U1 есть доступ к большему количеству учетных записей. Чтобы подтвердить эту возможность, получите иерархию учетных записей для каждой из учетных записей, возвращаемых методом ListAccessibleCustomers . Для этого установите каждую из этих учетных записей в качестве login-customer-id, как описано в предыдущем разделе . Если у вас есть доступ к целевой учетной записи, вы сможете получить ее как часть одной из иерархий учетных записей.

  2. Вы используете неверные учетные данные OAuth. Наиболее распространенная ситуация — использование учетных данных другого пользователя. Например, это может быть связано со случайным смешиванием учетных данных тестовой среды или среды разработки с учетными данными рабочей среды, или с некорректным считыванием учетных данных другого пользователя из базы данных или локального кэша. Один из возможных способов устранения этой проблемы — использовать API Google People для получения имени и адреса электронной почты вошедшего в систему пользователя и проверки, совпадают ли они с ожидаемым адресом электронной почты.

  3. У вас нет доступа к учетной записи. Следуйте инструкциям , чтобы получить доступ к нужной учетной записи клиента.

Роли пользователей

API Google Ads не имеет собственной модели доступа и не использует отдельные области действия OAuth 2.0 для ограничения функциональности. Например, API Google Ads использует одни и те же области действия для операций только для чтения и операций чтения и записи. Вместо этого API Google Ads использует те же роли пользователей , что и Google Ads. Когда роль пользователя предоставляется учетной записи на уровне менеджера, эта роль наследуется учетными записями в иерархии. Если у пользователя есть конфликтующие роли для данной учетной записи, правильный уровень определяется учетной записью login-customer-id указанной в запросе API.

В следующей таблице используется иерархия учетных записей из предыдущего примера и показан эффект от предоставления пользователям различных ролей.

Пользователь Роль пользователя предоставлена login-customer-id Эффективный уровень доступа
СА1 Стандартный доступ по учетной записи M1 М1 Стандартный доступ на M1, M2, A1, A2, A3
U2 Стандартный доступ на M2
Доступ только для чтения на M3
М2 Стандартный доступ на M2, A1, A2, A3
U2 Стандартный доступ на M2
Доступ только для чтения на M3
М3 Доступ только для чтения на страницах M3, A1, A4.