Entender o modelo de acesso do Google Ads

Há dois tipos de contas do Google Ads: contas de administrador e contas de anunciante. Para uma explicação detalhada de como esses termos e outros (como conta de cliente e cliente) se relacionam, consulte Tipos de conta.

As contas de administrador podem gerenciar outras contas de administrador do Google Ads ou contas de anunciante do Google Ads. É possível vincular uma conta de anunciante a uma conta de administrador e, em seguida, gerenciar a conta de anunciante pela conta de administrador. A estrutura vinculada geral é um gráfico acíclico direcionado com contas de anunciante no nível da folha.

É possível conceder acesso a contas do Google Ads a usuários individuais ou contas de serviço. Há duas maneiras de conceder acesso a uma conta de anunciante:

  • Conceda acesso direto à conta de anunciante convidando o usuário para ela.
  • Conceda acesso indireto à conta de anunciante convidando o usuário para uma conta de administrador vinculada a ela. O usuário ganha acesso à conta de anunciante porque a conta de administrador tem acesso a todas as contas vinculadas a ela.

Também é possível atribuir funções de usuário ao convidar um usuário para gerenciar uma conta.

Considere a hierarquia de contas a seguir. Suponha que todos os usuários tenham acesso padrão.

Diagrama mostrando as contas de administrador M1, M2 e M3 vinculadas às contas de anunciante A1 a A4.

A tabela a seguir resume essa estrutura de contas.

Usuário Tem acesso direto a Tem acesso indireto a
U1, SA1 M1 M2, A1, A2, A3
U2 M2, M3 A1, A2, A3, A4
U3 A4  

ID de cliente de login

Um usuário pode ter acesso a várias hierarquias de contas. Ao fazer uma chamada de API nesses casos, é necessário especificar a conta raiz a ser usada para determinar corretamente a autorização e os níveis de acesso à conta. Para fazer isso, inclua o cabeçalho login-customer-id na solicitação de API.

A tabela a seguir usa a hierarquia de contas do exemplo anterior para mostrar quais IDs de cliente de login podem ser usados e a lista correspondente de contas para as quais é possível fazer chamadas.

Usuário ID de cliente de login a ser usado Contas para fazer chamadas de API
U1, SA1 M1 M1, M2, A1, A2, A3
U2 M2 M2, A1, A2, A3
U2 M3 M3, A1, A4
U3 A4 A4

É possível pular o cabeçalho login-customer-id se o usuário tiver acesso direto à conta do Google Ads para a qual você está fazendo chamadas. Por exemplo, não é necessário especificar o cabeçalho login-customer-id ao usar as credenciais U3 para fazer uma chamada para A4, já que os servidores do Google Ads podem determinar corretamente o nível de acesso do ID de cliente (A4).

Se você usar uma biblioteca de cliente da API Google Ads, use as configurações a seguir para especificar o cabeçalho login-customer-id.

Java

Adicione a seguinte configuração ao arquivo ads.properties.

api.googleads.loginCustomerId=INSERT_LOGIN_CUSTOMER_ID_HERE

.NET

Adicione a seguinte configuração ao inicializar o objeto GoogleAdsConfig e use-o para criar um objeto GoogleAdsClient.

GoogleAdsConfig config = new GoogleAdsConfig()
{
    // ...
    LoginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"
};
GoogleAdsClient client = new GoogleAdsClient(config);

Python

Adicione a seguinte configuração ao arquivo google-ads.yaml.

login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE

PHP

Adicione a seguinte configuração ao arquivo google_ads_php.ini.

[GOOGLE_ADS]
loginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE"

Ruby

Adicione a seguinte configuração ao arquivo google_ads_config.rb.

Google::Ads::GoogleAds::Config.new do |c|
  c.login_customer_id = 'INSERT_LOGIN_CUSTOMER_ID_HERE'
end

Crie uma instância GoogleAdsClient transmitindo o caminho para o local em que você mantém esse arquivo.

client = Google::Ads::GoogleAds::GoogleAdsClient.new(
  'path/to/google_ads_config.rb'
)

Perl

Adicione a seguinte configuração ao arquivo googleads.properties.

loginCustomerId=INSERT_LOGIN_CUSTOMER_ID_HERE

curl

Especifique o seguinte argumento de linha de comando ao executar o comando curl.

-H "login-customer-id: INSERT_LOGIN_CUSTOMER_ID_HERE"

É possível usar o CustomerService.ListAccessibleCustomers método para recuperar a lista de contas a que um usuário tem acesso direto. Essas contas podem ser usadas como valores válidos para o cabeçalho 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}" \
      

E se o método ListAccessibleCustomers não recuperar meu ID de cliente?

Se o CustomerService.ListAccessibleCustomers método não recuperou um ID de cliente que você esperava que aparecesse nos resultados, há algumas explicações possíveis.

  1. Você tem acesso ao ID de cliente, mas o acesso é emitido por uma conta de administrador principal. Por exemplo, se você chamar o ListAccessibleCustomers método com as credenciais do usuário U1 no exemplo anterior, o método retornará apenas M1 nos resultados, mesmo que U1 tenha acesso a mais contas. Para confirmar essa possibilidade, recupere a hierarquia de contas executando search ou searchStream consultas no recurso customer_client para cada uma das contas retornadas pelo método ListAccessibleCustomers. Para fazer isso, defina cada uma dessas contas como login-customer-id, conforme descrito em a seção anterior. Se você tiver acesso à conta de destino, poderá buscá-la como parte de uma das hierarquias de contas.

  2. Você está usando credenciais OAuth incorretas. O cenário mais comum é que você esteja usando as credenciais de um usuário diferente. Por exemplo, isso pode ocorrer devido à mistura acidental de credenciais de sandbox ou de desenvolvedor com credenciais de produção ou à leitura incorreta das credenciais de um usuário diferente no banco de dados ou no cache local. Uma maneira possível de solucionar este problema é usar a API Google People para recuperar o nome e o endereço de e-mail do usuário conectado e verificar se ele corresponde ao endereço de e-mail esperado.

  3. Você não tem acesso à conta. Siga o guia de acesso à conta para ter acesso à conta de cliente correta.

Papéis do usuário

A API Google Ads não tem um modelo de acesso separado nem usa escopos OAuth 2.0 separados para limitar a funcionalidade. Por exemplo, a API Google Ads usa os mesmos escopos para operações somente leitura e leitura/gravação. Em vez disso, a API Google Ads segue as mesmas funções de usuário que o Google Ads oferece suporte. Quando uma função de usuário é concedida a uma conta no nível do administrador, ela é herdada pelas contas na hierarquia. Se um usuário tiver funções conflitantes para uma determinada conta, o nível correto será resolvido pela conta login-customer-id especificada na solicitação de API.

A tabela a seguir usa a hierarquia de contas do exemplo anterior e mostra o efeito da concessão de várias funções de usuário aos usuários.

Usuário Função de usuário concedida login-customer-id Nível de acesso efetivo
SA1 Acesso padrão na conta M1 M1 Acesso padrão em M1, M2, A1, A2, A3
U2 Acesso padrão em M2
Acesso somente leitura em M3
M2 Acesso padrão em M2, A1, A2, A3
U2 Acesso padrão em M2
Acesso somente leitura em M3
M3 Acesso somente leitura em M3, A1, A4