Cập nhật bằng cách sử dụng mặt nạ tại hiện trường

Trong API Google Ads, quá trình cập nhật được thực hiện bằng cách sử dụng mặt nạ trường (field mask). Mặt nạ trường liệt kê tất cả các trường bạn dự định thay đổi trong quá trình cập nhật và mọi trường được chỉ định không có trong mặt nạ trường sẽ bị bỏ qua, ngay cả khi được gửi đến máy chủ.

Trình trợ giúp mặt nạ cho trường (field mask)

Bạn nên dùng hàm trợ giúp field_mask có trong gói google.api_core để tạo mặt nạ cho trường (field mask). Phương thức này chấp nhận 2 đối tượng protobuf và trả về một đối tượng mặt nạ trường có trường list chứa tất cả các trường khác nhau giữa 2 đối tượng.

Nếu None được truyền dưới dạng tham số đầu tiên, thì danh sách mặt nạ trường sẽ chỉ chứa tất cả các trường trên đối tượng protobuf thứ hai không được đặt thành giá trị mặc định.

Sau khi tạo xong, đối tượng mặt nạ cho trường (field mask) phải được sao chép vào đối tượng thao tác sẽ được gửi đến máy chủ:

Dưới đây là ví dụ về cách cập nhật chiến dịch:

from google.api_core import protobuf_helpers
from google.ads.googleads.client import GoogleAdsClient

# Retrieve a GoogleAdsClient instance.
client = GoogleAdsClient.load_from_storage()
# Create a new campaign operation.
campaign_operation = client.get_type('CampaignOperation')
# Retrieve a new campaign object from its update field.
campaign = campaign_operation.update
# Mutate the campaign.
campaign.network_settings.target_search_network.value = False

# Create a field mask using the updated campaign.
# The field_mask helper is only compatible with raw protobuf message
# instances, which we can access using the ._pb attribute.
field_mask = protobuf_helpers.field_mask(None, campaign._pb)

# Copy the field_mask onto the operation's update_mask field.
client.copy_from(campaign_operation.update_mask, field_mask)

Trước tiên, chúng ta sẽ tạo một đối tượng CampaignOperation trống. Sau đó, chúng ta đặt truy xuất đối tượng Chiến dịch trống từ đối tượng đó. Sau đó, chúng tôi cập nhật đối tượng chiến dịch đó và tạo một mặt nạ trường (field mask) mới, so sánh mặt nạ đó với None. Thao tác này sẽ tạo ra danh sách mặt nạ trường chỉ chứa trường network_settings.target_search_network đã được thay đổi.

Dưới đây là ví dụ về cách cập nhật một chiến dịch hiện có. Ở đây, chúng tôi giả định tập lệnh đã được cung cấp tham số resource_name. Đây là tên tài nguyên hợp lệ cho chiến dịch và là customer_id hợp lệ:

import proto

from google.api_core import protobuf_helpers
from google.ads.googleads.client import GoogleAdsClient

# Retrieve a GoogleAdsClient instance.
client = GoogleAdsClient.load_from_storage()
# Retrieve an instance of the GoogleAdsService.
googleads_service = client.get_service('GoogleAdsService')

# Search query to retrieve campaign.
query = f"""
    SELECT
      campaign.network_settings.target_search_network,
      campaign.resource_name
    FROM campaign
    WHERE campaign.resource_name = {resource_name}"""

# Submit a query to retrieve a campaign instance.
response = googleads_service.search_stream(customer_id=customer_id, query=query)

# Iterate over results to retrieve the campaign.
for batch in response:
    for row in batch.results:
        initial_campaign = row.campaign

# Create a new campaign operation.
campaign_operation = client.get_type('CampaignOperation')
# Set the copied campaign object to a variable for easy reference.
updated_campaign = campaign_operation.update
# Copy the retrieved campaign into the new campaign.
# Here we use the proto.Message.copy_from method because of its simple
# compatibility with the protobuf message instances, which are wrapped
# by the proto-plus library.
proto.Message.copy_from(updated_campaign, initial_campaign)
# Mutate the new campaign.
updated_campaign.network_settings.target_search_network = False

# Create a field mask using the updated campaign.
field_mask = protobuf_helpers.field_mask(
    initial_campaign._pb, updated_campaign._pb
)

# Copy the field mask onto the operation's update_mask field.
# Note that the client's copy_from  method is designed to work with both native
# messages and messages wrapped by proto-plus, so it works here for the
# update_mask, even though it's an instance of the native message class
# google.protobuf.field_mask_pb2.FieldMask.
client.copy_from(campaign_operation.update_mask, field_mask)

Với chiến lược này, updated_campaign sẽ chia sẻ tất cả các trường giống như initial_campaign đã được truy xuất từ API, cụ thể là tên tài nguyên. Mặt nạ trường (field mask) đã tạo sẽ cho API biết rằng chỉ cần thay đổi trường network_settings.target_search_network.