Mutaciones masivas

Para mutar varios tipos de recursos en una sola solicitud o enviar todas las mutaciones a un extremo unificado, usa GoogleAdsService.Mutate. Para obtener la lista completa de operaciones admitidas, consulta la referencia de MutateOperation.

Operaciones de mutación

Cada MutateGoogleAdsRequest acepta un MutateOperation repetido en su campo mutate_operations:

  • Operaciones de modificación de recursos (todas las versiones admitidas): Cada entrada puede especificar una sola operación create, update o remove para un tipo de recurso.
  • Operaciones de acción (versión 23 y posteriores): Cada entrada también puede especificar una operación de acción, como book_campaigns_operation o quote_campaigns_operation (en la versión 22, MutateOperation solo admite operaciones de mutación de recursos).

Para crear entidades dependientes (como una campaña y un grupo de anuncios) en una sola llamada a GoogleAdsService.Mutate, crea dos entradas de MutateOperation (una que contenga un CampaignOperation y otra que contenga un AdGroupOperation). Asigna un nombre de recurso temporal con un ID negativo (como customers/CUSTOMER_ID/campaigns/-1) a la campaña para que la operación del grupo de anuncios pueda hacer referencia a ella en la misma solicitud:

Python

import uuid

campaign_budget_service = client.get_service("CampaignBudgetService")
campaign_service = client.get_service("CampaignService")
googleads_service = client.get_service("GoogleAdsService")

campaign_budget_resource_name = campaign_budget_service.campaign_budget_path(
    customer_id, budget_id
)
temp_campaign_resource_name = campaign_service.campaign_path(customer_id, "-1")

mutate_operation1 = client.get_type("MutateOperation")
campaign = mutate_operation1.campaign_operation.create
campaign.resource_name = temp_campaign_resource_name
campaign.name = f"Bulk Mutate Campaign #{uuid.uuid4()}"
campaign.advertising_channel_type = (
    client.enums.AdvertisingChannelTypeEnum.SEARCH
)
campaign.status = client.enums.CampaignStatusEnum.PAUSED
campaign.manual_cpc = client.get_type("ManualCpc")
campaign.campaign_budget = campaign_budget_resource_name
campaign.contains_eu_political_advertising = (
    client.enums.EuPoliticalAdvertisingStatusEnum.DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
)

mutate_operation2 = client.get_type("MutateOperation")
ad_group = mutate_operation2.ad_group_operation.create
ad_group.name = "Bulk Mutate Ad Group"
ad_group.campaign = temp_campaign_resource_name
ad_group.status = client.enums.AdGroupStatusEnum.ENABLED

response = googleads_service.mutate(
    customer_id=customer_id,
    mutate_operations=[mutate_operation1, mutate_operation2],
)

for op_response in response.mutate_operation_responses:
    result_type = op_response._pb.WhichOneof("response")
    result = getattr(op_response, result_type)
    print(f"Created {result_type}: {result.resource_name}")

Ruby

campaign_budget_resource_name =
  client.path.campaign_budget(customer_id, budget_id)
temp_campaign_resource_name =
  client.path.campaign(customer_id, -1)

mutate_operation1 = client.operation.mutate do |m|
  m.campaign_operation = client.operation.create_resource.campaign do |c|
    c.resource_name = temp_campaign_resource_name
    c.name = "Bulk Mutate Campaign #{(Time.new.to_f * 1000).to_i}"
    c.advertising_channel_type = :SEARCH
    c.status = :PAUSED
    c.manual_cpc = client.resource.manual_cpc
    c.campaign_budget = campaign_budget_resource_name
    c.contains_eu_political_advertising = :DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
  end
end

mutate_operation2 = client.operation.mutate do |m|
  m.ad_group_operation = client.operation.create_resource.ad_group do |ag|
    ag.name = "Bulk Mutate Ad Group"
    ag.campaign = temp_campaign_resource_name
    ag.status = :ENABLED
  end
end

response = client.service.google_ads.mutate(
  customer_id: customer_id,
  mutate_operations: [mutate_operation1, mutate_operation2]
)

response.mutate_operation_responses.each do |op_response|
  result = op_response.send(op_response.response)
  puts "Created #{op_response.response}: #{result.resource_name}"
end

Atomicidad y falla parcial

De forma predeterminada, las operaciones en una solicitud de GoogleAdsService.Mutate se ejecutan de forma atómica: todas las operaciones se realizan correctamente juntas, o bien falla toda la solicitud si alguna operación contiene un error.

Al igual que los servicios de recursos individuales, este endpoint admite las siguientes opciones:

  • Falla parcial (partial_failure = true): Confirma las operaciones válidas y devuelve errores para las operaciones fallidas en partial_failure_error.
  • Modo de validación (validate_only = true): Verifica si hay errores en las operaciones sin confirmar los cambios en la cuenta:
    • Operaciones de modificación de recursos: Solo devuelve errores de validación y omite los resultados.
    • Operaciones de acción (versión 23 y posteriores): Devuelve el resultado de la acción (como quote_campaigns_result o book_campaigns_result) cuando la validación se realiza correctamente. Si se producen errores de validación, el resultado de la acción se omite de MutateOperationResponse (aunque es posible que se devuelva una cotización en ErrorDetails.reservation_error_details). Ten en cuenta que quote_campaigns_operation requiere validate_only = true y partial_failure = false.