Extensiones de ubicación de Google Ads

Para crear extensiones de ubicación de Google Ads, debes crear un Perfil de Negocio y propagarlo con las direcciones de todas las ubicaciones de tu empresa. Luego, asocia el Perfil de Negocio con tu feed de extensiones de ubicación para crearlas.

Perfil de Negocio

El Perfil de Negocio es el repositorio central de las ubicaciones de tu empresa en todos los productos de Google. No debe preocuparse por sincronizar las ubicaciones de su Perfil de Negocio y las extensiones de ubicación de Google Ads. Solo realice la configuración por única vez de los objetos de feed obligatorios. Google Ads mantendrá sus extensiones de ubicación sincronizadas automáticamente con los datos más recientes de tu Perfil de Negocio.

Existen dos maneras de crear ubicaciones en el Perfil de Negocio.

  1. Puedes usar la IU del Perfil de Negocio para crear tus ubicaciones. Si sigues este enfoque, puedes ir directamente a vincular las ubicaciones a tus anuncios con la API de Google Ads.
  2. Puedes usar la API del Perfil de Negocio para crear ubicaciones de empresa de manera programática.

Cómo trabajar con la API del Perfil de Negocio

Para comenzar a usar la API del Perfil de Negocio, visita su página principal. Recomendamos utilizar cuentas comerciales en lugar de cuentas personales para las ubicaciones vinculadas a Google Ads. Si usas una cuenta comercial, puedes compartir el acceso con otros usuarios sin tener que compartir los detalles de tu cuenta personal.

Para crear ubicaciones de la empresa de manera programática con la API del Perfil de Negocio,

  1. Primero, descarga una biblioteca cliente. Sigue la guía de configuración básica para crear credenciales de OAuth y trabajar con la API del Perfil de Negocio.

  2. Usa la API del Perfil de Negocio para enumerar todas las cuentas que posees o de las que tienes derechos de administración. Selecciona la cuenta con la que trabajarás.

  3. Usa la API del Perfil de Negocio para crear las ubicaciones.

Cómo crear un feed de extensiones de ubicación nuevo vinculado a su Perfil de Negocio

Para crear un nuevo feed de extensiones de ubicación, primero crea un objeto Feed. Realiza una operación FeedService.MutateFeeds de create para crear el feed. El fragmento de código se muestra a continuación.

Java

// Creates a feed that will sync to the Business Profile account. Do not add FeedAttributes to
// this object as Google Ads will add them automatically because this will be a system generated
// feed.
Feed.Builder businessProfileFeed =
    Feed.newBuilder()
        .setName("Business Profile feed #" + getPrintableDateTime())
        // Configures the location feed populated from Business Profile Locations.
        .setPlacesLocationFeedData(placesLocationFeedData)
        // Since this feed's feed items will be managed by Google,
        // you must set its origin to GOOGLE.
        .setOrigin(FeedOrigin.GOOGLE);

FeedOperation operation = FeedOperation.newBuilder().setCreate(businessProfileFeed).build();
      

C#

private static string CreateBusinessProfileFeed(GoogleAdsClient client, long customerId,
    string businessProfileEmailAddress, string businessAccountId,
    string businessProfileAccessToken)
{
    // Optional: Delete all existing location extension feeds. This is an optional step,
    // and is required for this code example to run correctly more than once.
    // 1. Google Ads only allows one location extension feed per email address.
    // 2. A Google Ads account cannot have a location extension feed and an affiliate
    // location extension feed at the same time.
    DeleteLocationExtensionFeeds(client, customerId);

    // Get the FeedServiceClient.
    FeedServiceClient feedService = client.GetService(Services.V13.FeedService);

    // Creates a feed that will sync to the Business Profile account specified by
    // businessProfileEmailAddress. Do not add FeedAttributes to this object as Google Ads
    // will add them automatically because this will be a system generated feed.
    Feed businessProfileFeed = new Feed()
    {
        Name = "Business Profile feed #" + ExampleUtilities.GetRandomString(),

        PlacesLocationFeedData = new PlacesLocationFeedData()
        {
            EmailAddress = businessProfileEmailAddress,
            // If the EmailAddress is for a Business Profile manager instead of the
            // Business Profile account owner, then set BusinessAccountId to the Google+
            // Page ID of a location for which the manager has access. This information is
            // available through the Business Profile API. See
            // https://developers.google.com/my-business/reference/rest/v4/accounts.locations#locationkey
            // for details.
            BusinessAccountId = string.IsNullOrEmpty(businessAccountId) ?
                null : businessAccountId,
            // Used to filter Business Profile listings by labels. If entries exist in
            // label_filters, only listings that have at least one of the labels set are
            // candidates to be synchronized into FeedItems. If no entries exist in
            // label_filters, then all listings are candidates for syncing.
            LabelFilters = { "Stores in New York" },
            // Sets the authentication info to be able to connect Google Ads to the
            // Business Profile account.
            OauthInfo = new OAuthInfo()
            {
                HttpMethod = "GET",
                HttpRequestUrl = GOOGLE_ADS_SCOPE,
                HttpAuthorizationHeader = $"Bearer {businessProfileAccessToken}"
            },
        },
        // Since this feed's feed items will be managed by Google,
        // you must set its origin to GOOGLE.
        Origin = FeedOrigin.Google
    };

    FeedOperation operation = new FeedOperation()
    {
        Create = businessProfileFeed
    };

    // Adds the feed.
    MutateFeedsResponse response =
        feedService.MutateFeeds(customerId.ToString(), new[] { operation });

    // Displays the results.
    string businessProfileFeedResourceName = response.Results[0].ResourceName;
    Console.WriteLine($"Business Profile feed created with resource name: " +
        $"{businessProfileFeedResourceName}.");
    return businessProfileFeedResourceName;
}
      

PHP

private static function createFeed(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    string $businessProfileEmail,
    string $businessProfileAccessToken,
    string $businessAccountIdentifier
) {

    $businessProfileFeed = new Feed([
        'name' => 'Business Profile feed #' . Helper::getPrintableDatetime(),
        'origin' => FeedOrigin::GOOGLE,
        'places_location_feed_data' => new PlacesLocationFeedData([
            'email_address' => $businessProfileEmail,
            'business_account_id' => $businessAccountIdentifier,
            // Used to filter Business Profile listings by labels. If entries exist in
            // label_filters, only listings that have at least one of the labels set are
            // candidates to be synchronized into FeedItems. If no entries exist in
            // label_filters, then all listings are candidates for syncing.
            'label_filters' => ['Stores in New York'],
            // Sets the authentication info to be able to connect Google Ads to the Business
            // Profile account.
            'oauth_info' => new OAuthInfo([
                'http_method' => 'GET',
                'http_request_url' => self::GOOGLE_ADS_SCOPE,
                'http_authorization_header' => 'Bearer ' . $businessProfileAccessToken
            ])

        ])
    ]);
    // Creates a feed operation.
    $feedOperation = new FeedOperation();
    $feedOperation->setCreate($businessProfileFeed);

    // Issues a mutate request to add the feed and print its information.
    // Since it is a system generated feed, Google Ads will automatically:
    // 1. Set up the feed attributes on the feed.
    // 2. Set up a feed mapping that associates the feed attributes of the feed with the
    //    placeholder fields of the LOCATION placeholder type.
    $feedServiceClient = $googleAdsClient->getFeedServiceClient();
    $response = $feedServiceClient->mutateFeeds(
        $customerId,
        [$feedOperation]
    );
    $businessProfileFeedResourceName = $response->getResults()[0]->getResourceName();
    printf(
        "Business Profile feed created with resource name: '%s'.%s",
        $businessProfileFeedResourceName,
        PHP_EOL
    );

    return $businessProfileFeedResourceName;
}
      

Python

feed_operation = client.get_type("FeedOperation")
business_profile_feed = feed_operation.create
business_profile_feed.name = f"Business Profile Feed #{uuid4()}"
# Configure the location feed populated from Business Profile Locations.
business_profile_feed.places_location_feed_data.email_address = (
    business_profile_email
)

if business_account_id is not None:
    business_profile_feed.places_location_feed_data.business_account_id = (
        business_account_id
    )

# Used to filter Business Profile listings by labels. If entries exist in
# label_filters, only listings that have at least one of the labels set are
# candidates to be synchronized into FeedItems. If no entries exist in
# label_filters, then all listings are candidates for syncing.
business_profile_feed.places_location_feed_data.label_filters.append(
    "Stores in New York"
)

# Set the authentication info to be able to connect Google Ads to the
# Business Profile account.
business_profile_feed.places_location_feed_data.oauth_info.http_method = (
    "GET"
)
business_profile_feed.places_location_feed_data.oauth_info.http_request_url = (
    DEFAULT_OAUTH2_SCOPE
)
business_profile_feed.places_location_feed_data.oauth_info.http_authorization_header = (
    f"Bearer {business_profile_access_token}"
)
# Since this feed's feed items will be managed by Google, you must set its
# origin to GOOGLE.
business_profile_feed.origin = client.enums.FeedOriginEnum.GOOGLE

# Optional: Delete all existing location extension feeds. This is an
# optional step, and is required for this code example to run correctly
# more than once; Google Ads only allows one location extension feed
# per email address, and a Google Ads account cannot have a location
# extension feed and an affiliate location extension feed at the same
# time.
delete_location_extension_feeds(client, customer_id)

# Add the feed. Since it is a system generated feed, Google Ads will
# automatically:
# 1. Set up the FeedAttributes on the feed.
# 2. Set up a FeedMapping that associates the FeedAttributes of the feed
#   with the placeholder fields of the LOCATION placeholder type.
feed_response = feed_service.mutate_feeds(
    customer_id=customer_id, operations=[feed_operation]
)
feed_resource_name = feed_response.results[0].resource_name
print(
    "Business Profile feed created with resource name "
    f"'{feed_resource_name}'."
)
      

Ruby

def create_feed(
  client,
  customer_id,
  business_profile_email_address,
  business_profile_access_token,
  business_account_identifier)
  # Creates a feed operation.
  operation = client.operation.create_resource.feed do |feed|
    feed.name = "Business Profile feed #{(Time.new.to_f * 1000).to_i}"
    feed.origin = :GOOGLE
    feed.places_location_feed_data = client.resource.places_location_feed_data do |data|
      data.email_address = business_profile_email_address
      data.business_account_id = business_account_identifier
      data.label_filters << "Stores in New York"
      data.oauth_info = client.resource.o_auth_info do |oauth|
        oauth.http_method = "GET"
        oauth.http_request_url = "https://www.googleapis.com/auth/adwords"
        oauth.http_authorization_header = "Bearer #{business_profile_access_token}"
      end
    end
  end

  # Issues a mutate request to add the feed and print its information.
  # Since it is a system generated feed, Google Ads will automatically:
  # 1. Set up the feed attributes on the feed.
  # 2. Set up a feed mapping that associates the feed attributes of the feed with the
  #    placeholder fields of the LOCATION placeholder type.
  response = client.service.feed.mutate_feeds(
    customer_id: customer_id,
    operations: [operation],
  )

  # Prints out the Business Profile feed resource name.
  business_profile_feed_resource_name = response.results.first.resource_name
  puts "Business Profile feed created with resource name: #{business_profile_feed_resource_name}"

  business_profile_feed_resource_name
end
      

Perl

# Create a feed that will sync to the Business Profile account specified by
# $business_profile_email. Do not add FeedAttributes to this object as Google Ads
# will add them automatically because this will be a system generated feed.
my $business_profile_feed = Google::Ads::GoogleAds::V13::Resources::Feed->new(
  {
    name => "Business Profile feed #" . uniqid(),
    # Configure the location feed populated from Business Profile Locations.
    placesLocationFeedData =>
      Google::Ads::GoogleAds::V13::Resources::PlacesLocationFeedData->new({
        emailAddress      => $business_profile_email,
        businessAccountId => $business_profile_account_id,
        # Used to filter Business Profile listings by labels. If entries exist in
        # label_filters, only listings that have at least one of the labels set are
        # candidates to be synchronized into FeedItems. If no entries exist in
        # label_filters, then all listings are candidates for syncing.
        labelFilters => ["Stores in New York"],
        # Set the authentication info to be able to connect Google Ads to the
        # Business Profile account.
        oauthInfo => Google::Ads::GoogleAds::V13::Resources::OAuthInfo->new({
            httpMethod     => "GET",
            httpRequestUrl =>
              Google::Ads::GoogleAds::Constants::DEFAULT_OAUTH2_SCOPE,
            httpAuthorizationHeader => "Bearer " .
              $business_profile_access_token
          })}
      ),
    # Since this feed's feed items will be managed by Google, you must set its
    # origin to GOOGLE.
    origin => GOOGLE
  });
      

Debe propagar los siguientes campos que son específicos de los feeds de extensiones de ubicación:

Atributo Obligatoria Descripción
origin Dado que el sistema genera el feed de extensiones de ubicación, debes configurar el campo origin en GOOGLE.
attributes No No especifiques ningún attributes para el feed. Google Ads los creará automáticamente porque este es un feed generado por el sistema.
places_location_feed_data Si establece el atributo places_location_feed_data en un objeto PlacesLocationFeedData en su feed, le indicará a Google Ads lo siguiente:
  • Vincula tus cuentas de Perfil de Negocio y Google Ads.
  • Cree atributos de feed automáticamente para su feed.
  • Crea automáticamente un tipo de criterio FeedMapping LOCATION_EXTENSION_TARGETING.
  • (Opcional) Limita el conjunto de ubicaciones que Google Ads sincroniza desde tu Perfil de Negocio.

Atributos de PlacesLocationFeedData

Atributo Obligatoria Descripción
email_address La dirección de correo electrónico de tu propietario o uno de sus administradores del Perfil de Negocio. Debe coincidir con la dirección de correo electrónico que se proporcionó en oauth_info.
oauth_info Información de OAuth2 que otorga a tu cuenta de Google Ads acceso a tu Perfil de Negocio. Si no estás familiarizado con OAuth2, primero lee la guía de autenticación.
business_account_id No El ID de la cuenta de la empresa administrada cuyas ubicaciones se utilizarán. Si usas la API del Perfil de Negocio, puedes obtener este ID de la parte account_id de name de Account. De lo contrario, puedes copiar la parte LOCATION_GROUP_ID de la sección Información del grupo de ubicaciones del grupo por ubicación especificado.
business_name_filter No Nombre de la empresa que se sincronizará con Google Ads.
category_filters No Categorías de las fichas que se sincronizarán con Google Ads
label_filters No Etiquetas de las fichas que se sincronizarán con Google Ads.

Atributo oauth_info de PlacesLocationFeedData

Atributo Valor Descripción
http_method GET El método HTTP para obtener información de autorización.
http_request_url https://www.googleapis.com/auth/adwords El permiso de OAuth que la API de Google Ads usa para autorizar tus solicitudes a un Perfil de Negocio.
http_authorization_header Bearer OAUTH_ACCESS_TOKEN El encabezado de autorización que contiene el token de acceso de OAuth que otorga permiso a tu cuenta de Google Ads para leer datos de tu cuenta del Perfil de Negocio. En lugar de OAUTH_ACCESS_TOKEN, sustituye un token de acceso generado a partir de credenciales de OAuth por el http_request_url de la PlacesLocationFeedData y un permiso que coincida con http_request_url.

Espere a que el feed esté listo

Una vez que se cree el Feed, Google Ads creará los atributos del feed y FeedMapping. Luego, se propagarán los contenidos del feed mediante la creación de los objetos FeedItem que corresponden a las ubicaciones en el Perfil de Negocio.

Debes esperar hasta que se cree la FeedMapping para garantizar que el feed esté configurado de forma correcta y que se pueda usar en los próximos pasos. Para ello, intenta recuperar el FeedMapping del feed relevante, con placeholder_type igual a LOCATION.

Java

try (FeedServiceClient feedServiceClient =
    googleAdsClient.getLatestVersion().createFeedServiceClient()) {
  // Adds the feed. Since it is a system generated feed, Google Ads will automatically:
  // 1. Set up the FeedAttributes on the feed.
  // 2. Set up a FeedMapping that associates the FeedAttributes of the feed
  // with the placeholder fields of the LOCATION placeholder type.
  MutateFeedsResponse response =
      feedServiceClient.mutateFeeds(Long.toString(customerId), ImmutableList.of(operation));
  String businessProfileFeedResourceName = response.getResults(0).getResourceName();
  System.out.printf(
      "Business Profile feed created with resource name: %s%n",
      businessProfileFeedResourceName);
      

C#

private static FeedMapping GetBusinessProfileFeedMapping(GoogleAdsClient client,
    long customerId, string businessProfileFeedResourceName)
{
    // Get the GoogleAdsService.
    GoogleAdsServiceClient googleAdsService = client.GetService(
        Services.V13.GoogleAdsService);

    // Create the query.
    string query = $"SELECT feed_mapping.resource_name, feed_mapping.status FROM " +
        $"feed_mapping WHERE feed_mapping.feed = '{businessProfileFeedResourceName}' and " +
        $"feed_mapping.status = ENABLED and feed_mapping.placeholder_type = LOCATION" +
        $" LIMIT 1";

    // Issue a search request.
    PagedEnumerable<SearchGoogleAdsResponse, GoogleAdsRow> result =
        googleAdsService.Search(customerId.ToString(), query);

    // Display the results.
    GoogleAdsRow googleAdsRow = result.FirstOrDefault();
    return (googleAdsRow == null) ? null : googleAdsRow.FeedMapping;
}
      

PHP

// Issues a mutate request to add the feed and print its information.
// Since it is a system generated feed, Google Ads will automatically:
// 1. Set up the feed attributes on the feed.
// 2. Set up a feed mapping that associates the feed attributes of the feed with the
//    placeholder fields of the LOCATION placeholder type.
$feedServiceClient = $googleAdsClient->getFeedServiceClient();
$response = $feedServiceClient->mutateFeeds(
    $customerId,
    [$feedOperation]
);
$businessProfileFeedResourceName = $response->getResults()[0]->getResourceName();
printf(
    "Business Profile feed created with resource name: '%s'.%s",
    $businessProfileFeedResourceName,
    PHP_EOL
);

return $businessProfileFeedResourceName;
      

Python

# Add the feed. Since it is a system generated feed, Google Ads will
# automatically:
# 1. Set up the FeedAttributes on the feed.
# 2. Set up a FeedMapping that associates the FeedAttributes of the feed
#   with the placeholder fields of the LOCATION placeholder type.
feed_response = feed_service.mutate_feeds(
    customer_id=customer_id, operations=[feed_operation]
)
feed_resource_name = feed_response.results[0].resource_name
print(
    "Business Profile feed created with resource name "
    f"'{feed_resource_name}'."
)
      

Ruby

# Issues a mutate request to add the feed and print its information.
# Since it is a system generated feed, Google Ads will automatically:
# 1. Set up the feed attributes on the feed.
# 2. Set up a feed mapping that associates the feed attributes of the feed with the
#    placeholder fields of the LOCATION placeholder type.
response = client.service.feed.mutate_feeds(
  customer_id: customer_id,
  operations: [operation],
)

# Prints out the Business Profile feed resource name.
business_profile_feed_resource_name = response.results.first.resource_name
puts "Business Profile feed created with resource name: #{business_profile_feed_resource_name}"

business_profile_feed_resource_name
      

Perl

# Add the feed. Since it is a system generated feed, Google Ads will automatically:
# 1. Set up the FeedAttributes on the feed.
# 2. Set up a FeedMapping that associates the FeedAttributes of the feed with the
#    placeholder fields of the LOCATION placeholder type.
my $feeds_response = $api_client->FeedService()->mutate({
    customerId => $customer_id,
    operations => [$feed_operation]});

my $feed_resource_name = $feeds_response->{results}[0]{resourceName};

printf "Business Profile feed created with resource name: '%s'.\n",
  $feed_resource_name;
      

Si el FeedMapping aún no está disponible, reintenta las llamadas con una política de retirada exponencial hasta que el Feed esté listo.

Java

try (CustomerFeedServiceClient customerFeedServiceClient =
    googleAdsClient.getLatestVersion().createCustomerFeedServiceClient()) {

  // After the completion of the Feed ADD operation above the added feed will not be available
  // for usage in a CustomerFeed until the sync between the Google Ads and Business Profile
  // accounts
  // completes. The loop below will retry adding the CustomerFeed up to ten times with an
  // exponential back-off policy.
  String addedCustomerFeed = null;
  int numberOfAttempts = 0;
  do {
    numberOfAttempts++;
    try {
      MutateCustomerFeedsResponse customerFeedsResponse =
          customerFeedServiceClient.mutateCustomerFeeds(
              Long.toString(customerId), ImmutableList.of(customerFeedOperation));
      addedCustomerFeed = customerFeedsResponse.getResults(0).getResourceName();
      System.out.printf("Customer feed created with resource name: %s%n", addedCustomerFeed);
    } catch (GoogleAdsException gae) {
      // Waits using exponential backoff policy.
      long sleepSeconds = (long) Math.scalb(5, numberOfAttempts);

      // Exits the loop early if sleepSeconds grows too large in the event that
      // MAX_CUSTOMER_FEED_ADD_ATTEMPTS is set too high.
      if (sleepSeconds > (long) Math.scalb(5, 10)) {
        break;
      }

      System.out.printf(
          "Attempt #%d to add the CustomerFeed was not successful. "
              + "Waiting %d seconds before trying again.%n",
          numberOfAttempts, sleepSeconds);
      Thread.sleep(sleepSeconds * 1000);
    }
  } while (numberOfAttempts < MAX_CUSTOMER_FEED_ADD_ATTEMPTS && addedCustomerFeed == null);
      

C#

private static void WaitForBusinessProfileFeedToBeReady(GoogleAdsClient client,
    long customerId, string businessProfileFeedResourceName)
{
    int numAttempts = 0;
    while (numAttempts < MAX_FEEDMAPPING_RETRIEVAL_ATTEMPTS)
    {
        // Once you create a feed, Google's servers will setup the feed by creating feed
        // attributes and feedmapping. Once the feedmapping is created, it is ready to be
        // used for creating customer feed.
        // This process is asynchronous, so we wait until the feed mapping is created,
        // peforming exponential backoff.
        FeedMapping feedMapping = GetBusinessProfileFeedMapping(client,
            customerId, businessProfileFeedResourceName);

        if (feedMapping == null)
        {
            numAttempts++;
            int sleepSeconds = (int)(5 * Math.Pow(2, numAttempts));
            Console.WriteLine($"Checked: #{numAttempts} time(s). Business Profile feed " +
                $"is not ready yet. Waiting {sleepSeconds} seconds before trying again.");
            Thread.Sleep(sleepSeconds * 1000);
        }
        else
        {
            Console.WriteLine($"Business Profile Feed {businessProfileFeedResourceName} " +
                $"is now ready.");
            return;
        }
    }
    throw new RpcException(new Status(StatusCode.DeadlineExceeded,
        $"Business Profile Feed is not ready after {MAX_FEEDMAPPING_RETRIEVAL_ATTEMPTS} " +
        $"retries."));
}
      

PHP

// After the completion of the feed ADD operation above the added feed will not be available
// for usage in a customer feed until the sync between the Google Ads and Business Profile
// accounts completes. The loop below will retry adding the customer feed up to ten times
// with an exponential back-off policy.
$numberOfAttempts = 0;
$addedCustomerFeed = null;
$customerFeedServiceClient = $googleAdsClient->getCustomerFeedServiceClient();
do {
    $numberOfAttempts++;
    try {
        // Issues a mutate request to add a customer feed and print its information if the
        // request succeeded.
        $addedCustomerFeed = $customerFeedServiceClient->mutateCustomerFeeds(
            $customerId,
            [$customerFeedOperation]
        );
        printf(
            "Customer feed created with resource name: '%s'.%s",
            $addedCustomerFeed->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    } catch (GoogleAdsException $googleAdsException) {
        // Waits using exponential backoff policy.
        $sleepSeconds = self::POLL_FREQUENCY_SECONDS * pow(2, $numberOfAttempts);
        // Exits the loop early if $sleepSeconds grows too large in the event that
        // MAX_CUSTOMER_FEED_ADD_ATTEMPTS is set too high.
        if (
            $sleepSeconds > self::POLL_FREQUENCY_SECONDS
            * pow(2, self::MAX_CUSTOMER_FEED_ADD_ATTEMPTS)
        ) {
            break;
        }
        printf(
            "Attempt #%d to add the customer feed was not successful."
            . " Waiting %d seconds before trying again.%s",
            $numberOfAttempts,
            $sleepSeconds,
            PHP_EOL
        );
        sleep($sleepSeconds);
    }
} while (
    $numberOfAttempts < self::MAX_CUSTOMER_FEED_ADD_ATTEMPTS
    && is_null($addedCustomerFeed)
);
      

Python

# Create a CustomerFeed operation and configure the CustomerFeed to
# associate the feed with this customer for the LOCATION placeholder
# type.

# OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at
# the Campaign level.

# OPTIONAL: Create an AdGroupFeed for even more fine grained control
# over which feed items are used at the AdGroup level.
customer_feed_operation = client.get_type("CustomerFeedOperation")
customer_feed = customer_feed_operation.create
customer_feed.feed = feed_resource_name
customer_feed.placeholder_types.append(
    client.enums.PlaceholderTypeEnum.LOCATION
)
# The function string "IDENTITY(true)" will enable this feed.
true_operand = client.get_type("Operand")
true_operand.constant_operand.boolean_value = True
customer_feed.matching_function.left_operands.append(true_operand)
customer_feed.matching_function.function_string = "IDENTITY(true)"
customer_feed.matching_function.operator = (
    client.enums.MatchingFunctionOperatorEnum.IDENTITY
)

customer_feed_response = customer_feed_service.mutate_customer_feeds(
    customer_id=customer_id, operations=[customer_feed_operation]
)
print(
    "Customer feed created with resource name "
    f"'{customer_feed_response.results[0].resource_name}'."
)
      

Ruby

# After the completion of the feed ADD operation above the added feed will
# not be available for usage in a customer feed until the sync between the
# Google Ads and Business Profile accounts completes. The loop below will
# retry adding the customer feed up to ten times with an exponential back-off
# policy.
number_of_attempts = 0
added_customer_feed = nil
customer_feed_service_client = client.service.customer_feed

loop do
  number_of_attempts += 1
  begin
    # Issues a mutate request to add a customer feed and print its information
    # if the request succeeded.
    response = customer_feed_service_client.mutate_customer_feeds(
      customer_id: customer_id,
      operations: [operation]
    )
    puts "Customer feed created with resource name: " \
      "#{response.results.first.resource_name}"
  rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
    # Waits using exponential backoff policy
    sleep_seconds = POLL_FREQUENCY_SECONDS * (2 ** number_of_attempts)
    puts "Attempt #{number_of_attempts} to add the customer feed was " \
      "not successful. Waiting #{sleep_seconds} seconds before trying again."
    sleep sleep_seconds
  end
  break if number_of_attempts >= MAX_CUSTOMER_FEED_ADD_ATTEMPTS || added_customer_feed
end
      

Perl

# After the completion of the Feed ADD operation above the added feed will not be available
# for usage in a CustomerFeed until the sync between the Google Ads and Business Profile
# accounts completes. The loop below will retry adding the CustomerFeed up to ten times with an
# exponential back-off policy.
my $customer_feed_service       = $api_client->CustomerFeedService();
my $customer_feed_resource_name = undef;
my $number_of_attempts          = 0;

while ($number_of_attempts < MAX_CUSTOMER_FEED_ADD_ATTEMPTS) {
  $number_of_attempts++;

  my $customer_feeds_response = eval {
    $customer_feed_service->mutate({
      customerId => $customer_id,
      operations => [$customer_feed_operation],
    });
  };

  if ($@) {
    # Wait using exponential backoff policy.
    my $sleep_seconds = 5 * (2**$number_of_attempts);

    # Exit the loop early if $sleep_seconds grows too large in the event that
    # MAX_CUSTOMER_FEED_ADD_ATTEMPTS is set too high.
    if ($sleep_seconds > 5 * (2**10)) {
      last;
    }

    printf "Attempt #%d to add the CustomerFeed was not successful. " .
      "Waiting %d seconds before trying again.\n",
      $number_of_attempts, $sleep_seconds;

    sleep($sleep_seconds);
  } else {
    $customer_feed_resource_name =
      $customer_feeds_response->{results}[0]{resourceName};

    printf "Customer feed created with resource name: '%s'.\n",
      $customer_feed_resource_name;

    last;
  }
}
      

Asociar el feed con el cliente

Una vez que el feed esté listo, puedes asociarlo con un cliente creando un CustomerFeed. Luego, realiza una operación CustomerFeedService.MutateCustomerFeeds de create para completar la vinculación.

Se deben configurar los siguientes campos de CustomerFeed.

Atributo Valor Descripción
feed Es el nombre del recurso del feed. El nombre del recurso del feed que se creó en el paso anterior.
placeholder_types LOCATION Indica que este feed propaga las extensiones de ubicación del cliente conectado.
matching_function IDENTITY(true) para marcar este feed como habilitado y IDENTITY(false) para marcarlo como inhabilitado. Consulta Estrategias de filtrado para obtener más detalles.

Java

// Adds a CustomerFeed that associates the feed with this customer for
// the LOCATION placeholder type.
CustomerFeed customerFeed =
    CustomerFeed.newBuilder()
        .setFeed(businessProfileFeedResourceName)
        .addPlaceholderTypes(PlaceholderType.LOCATION)
        // Creates a matching function that will always evaluate to true.
        .setMatchingFunction(
            MatchingFunction.newBuilder()
                .addLeftOperands(
                    Operand.newBuilder()
                        .setConstantOperand(
                            ConstantOperand.newBuilder().setBooleanValue(true).build())
                        .build())
                .setFunctionString("IDENTITY(true)")
                .setOperator(MatchingFunctionOperator.IDENTITY)
                .build())
        .build();

CustomerFeedOperation customerFeedOperation =
    CustomerFeedOperation.newBuilder().setCreate(customerFeed).build();
      

C#

private static void CreateCustomerFeed(GoogleAdsClient client, long customerId,
    string businessProfileFeedResourceName)
{
    // Get the CustomerFeedService.
    CustomerFeedServiceClient customerFeedService = client.GetService(
        Services.V13.CustomerFeedService);

    // Adds a CustomerFeed that associates the feed with this customer for
    // the LOCATION placeholder type.
    CustomerFeed customerFeed = new CustomerFeed()
    {
        Feed = businessProfileFeedResourceName,
        PlaceholderTypes = { PlaceholderType.Location },
        MatchingFunction = new MatchingFunction()
        {
            LeftOperands =
            {
                new Operand()
                {
                    ConstantOperand = new ConstantOperand()
                    {
                        BooleanValue = true
                    }
                }
            },
            // Specify the function string as IDENTITY(true) to mark this feed as enabled.
            FunctionString = "IDENTITY(true)",
            Operator = MatchingFunctionOperator.Identity
        },
    };

    CustomerFeedOperation operation = new CustomerFeedOperation()
    {
        Create = customerFeed
    };

    MutateCustomerFeedsResponse customerFeedsResponse =
        customerFeedService.MutateCustomerFeeds(
            customerId.ToString(), new[] { operation });

    // Displays the result.
    string addedCustomerFeed = customerFeedsResponse.Results[0].ResourceName;
    Console.WriteLine($"Customer feed created with resource name: {addedCustomerFeed}.");
    return;
}
      

PHP

private static function createCustomerFeed(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    string $businessProfileFeedResourceName
) {
    // Creates a customer feed that associates the feed with this customer for the LOCATION
    // placeholder type.
    $customerFeed = new CustomerFeed([
        'feed' => $businessProfileFeedResourceName,
        'placeholder_types' => [PlaceholderType::LOCATION],
        // Creates a matching function that will always evaluate to true.
        'matching_function' => new MatchingFunction([
            'left_operands' => [new Operand([
                'constant_operand' => new ConstantOperand(['boolean_value' => true])
            ])],
            'function_string' => 'IDENTITY(true)',
            'operator' => MatchingFunctionOperator::IDENTITY
        ])
    ]);
    // Creates a customer feed operation.
    $customerFeedOperation = new CustomerFeedOperation();
    $customerFeedOperation->setCreate($customerFeed);

    // After the completion of the feed ADD operation above the added feed will not be available
    // for usage in a customer feed until the sync between the Google Ads and Business Profile
    // accounts completes. The loop below will retry adding the customer feed up to ten times
    // with an exponential back-off policy.
    $numberOfAttempts = 0;
    $addedCustomerFeed = null;
    $customerFeedServiceClient = $googleAdsClient->getCustomerFeedServiceClient();
    do {
        $numberOfAttempts++;
        try {
            // Issues a mutate request to add a customer feed and print its information if the
            // request succeeded.
            $addedCustomerFeed = $customerFeedServiceClient->mutateCustomerFeeds(
                $customerId,
                [$customerFeedOperation]
            );
            printf(
                "Customer feed created with resource name: '%s'.%s",
                $addedCustomerFeed->getResults()[0]->getResourceName(),
                PHP_EOL
            );
        } catch (GoogleAdsException $googleAdsException) {
            // Waits using exponential backoff policy.
            $sleepSeconds = self::POLL_FREQUENCY_SECONDS * pow(2, $numberOfAttempts);
            // Exits the loop early if $sleepSeconds grows too large in the event that
            // MAX_CUSTOMER_FEED_ADD_ATTEMPTS is set too high.
            if (
                $sleepSeconds > self::POLL_FREQUENCY_SECONDS
                * pow(2, self::MAX_CUSTOMER_FEED_ADD_ATTEMPTS)
            ) {
                break;
            }
            printf(
                "Attempt #%d to add the customer feed was not successful."
                . " Waiting %d seconds before trying again.%s",
                $numberOfAttempts,
                $sleepSeconds,
                PHP_EOL
            );
            sleep($sleepSeconds);
        }
    } while (
        $numberOfAttempts < self::MAX_CUSTOMER_FEED_ADD_ATTEMPTS
        && is_null($addedCustomerFeed)
    );

    if (is_null($addedCustomerFeed)) {
        throw new \RuntimeException(
            'Could not create the customer feed after ' . self::MAX_CUSTOMER_FEED_ADD_ATTEMPTS
            . ' attempts. Please retry the customer feed ADD operation later.'
        );
    }
}
      

Python

# After the completion of the Feed ADD operation above the added feed
# will not be available for usage in a CustomerFeed until the sync
# between the Google Ads and Business Profile accounts completes.
# This process is asynchronous, so we wait until the feed mapping is
# created, performing exponential backoff.
customer_feed_resource_name = None
number_of_attempts = 0

while number_of_attempts < MAX_CUSTOMER_FEED_ADD_ATTEMPTS:
    feed_mapping = get_business_profile_feed_mapping(
        client, customer_id, feed_resource_name
    )

    if feed_mapping is None:
        number_of_attempts += 1
        sleep_seconds = 5 * (2 ** number_of_attempts)

        print(
            f"Attempt #{number_of_attempts} was not successful. "
            f"Waiting {sleep_seconds}s before trying again."
        )

        time.sleep(sleep_seconds)
    else:
        customer_feed_resource_name = feed_mapping.resource_name
        print(f"Business Profile feed {feed_resource_name} is now ready.")
        break
      

Ruby

def create_customer_feed(
  client,
  customer_id,
  business_profile_feed_resource_name)
  # Creates a customer feed operation.
  operation = client.operation.create_resource.customer_feed do |cf|
    cf.feed = business_profile_feed_resource_name
    cf.placeholder_types << :LOCATION
    cf.matching_function = client.resource.matching_function do |m|
      m.left_operands << client.resource.operand do |op|
        op.constant_operand = client.resource.constant_operand do |co|
          co.boolean_value = true
        end
      end
      m.function_string = "IDENTITY(true)"
      m.operator = :IDENTITY
    end
  end

  # After the completion of the feed ADD operation above the added feed will
  # not be available for usage in a customer feed until the sync between the
  # Google Ads and Business Profile accounts completes. The loop below will
  # retry adding the customer feed up to ten times with an exponential back-off
  # policy.
  number_of_attempts = 0
  added_customer_feed = nil
  customer_feed_service_client = client.service.customer_feed

  loop do
    number_of_attempts += 1
    begin
      # Issues a mutate request to add a customer feed and print its information
      # if the request succeeded.
      response = customer_feed_service_client.mutate_customer_feeds(
        customer_id: customer_id,
        operations: [operation]
      )
      puts "Customer feed created with resource name: " \
        "#{response.results.first.resource_name}"
    rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
      # Waits using exponential backoff policy
      sleep_seconds = POLL_FREQUENCY_SECONDS * (2 ** number_of_attempts)
      puts "Attempt #{number_of_attempts} to add the customer feed was " \
        "not successful. Waiting #{sleep_seconds} seconds before trying again."
      sleep sleep_seconds
    end
    break if number_of_attempts >= MAX_CUSTOMER_FEED_ADD_ATTEMPTS || added_customer_feed
  end

  if added_customer_feed.nil?
    raise "Could not create the customer feed after #{MAX_CUSTOMER_FEED_ADD_ATTEMPTS} " \
      "attempts. Please retry the customer feed ADD operation later."
  end
end
      

Perl

# Add a CustomerFeed that associates the feed with this customer for the LOCATION
# placeholder type.
my $customer_feed = Google::Ads::GoogleAds::V13::Resources::CustomerFeed->new(
  {
    feed             => $feed_resource_name,
    placeholderTypes => LOCATION,
    # Create a matching function that will always evaluate to true.
    matchingFunction =>
      Google::Ads::GoogleAds::V13::Common::MatchingFunction->new({
        leftOperands => [
          Google::Ads::GoogleAds::V13::Common::Operand->new({
              constantOperand =>
                Google::Ads::GoogleAds::V13::Common::ConstantOperand->new({
                  booleanValue => "true"
                })})
        ],
        functionString => "IDENTITY(true)",
        operator       => IDENTITY
      })});