به‌روزرسانی بااستفاده از پوشش‌های فیلد

در Google Ads API، به‌روزرسانی‌ها بااستفاده از ماسک فیلد انجام می‌شود. پوشش فیلد همه فیلدهایی را که قصد دارید با به‌روزرسانی تغییر دهید فهرست می‌کند و هر فیلد مشخص‌شده‌ای که در پوشش فیلد نباشد نادیده گرفته می‌شود، حتی اگر به سرور ارسال شده باشد.

FieldMaskUtil

روش توصیه‌شده برای تولید ماسک‌های فیلد، استفاده از ابزار کمکی ماسک فیلد داخلی است که جزئیات خاصی را پنهان می‌کند و به شما امکان می‌دهد با نظارت بر تغییراتی که در فیلدهای نهاد ایجاد می‌کنید، ماسک‌های فیلد را به‌طور خودکار تولید کنید.

مثال زیر نشان می‌دهد که چگونه می‌توان یک پوشش فیلد برای به‌روزرسانی یک کمپین ایجاد کرد:

campaign = client.resource.campaign
campaign.resource_name = client.path.campaign(customer_id, campaign_id)

mask = client.field_mask.with campaign do
  campaign.status = :PAUSED
  campaign.network_settings = client.resource.network_settings do |ns|
    ns.target_search_network = false
  end
end

کد ابتدا یک شیء Campaign خالی ایجاد می‌کند، سپس نام منبع آن را تنظیم می‌کند تا به میانای برنامه‌سازی کاربردی اطلاع دهد که پویش درحال به‌روزرسانی است.

این مثال از روش client.field_mask.with در پویش برای شروع بلوک دربرگیرنده به‌روزرسانی‌ها استفاده می‌کند. در پایان این بلوک، ابزار کمکی وضعیت فعلی پویش را پس‌از بلوک با وضعیت اولیه پویش قبل‌از بلوک مقایسه می‌کند و به‌طور خودکار ماسک فیلدی تولید می‌کند که فیلدهای تغییریافته را فهرست می‌کند. می‌توانید آن ماسک فیلد را به عملیات ارائه دهید وقتی آن را برای تماس جهش به این صورت می‌سازید:

operation = client.operation.campaign
operation.update = campaign
operation.update_mask = mask

این روش زمانی توصیه می‌شود که درحال ساختن عملیاتی پیچیده هستید و می‌خواهید کنترل دقیقی بر هر مرحله داشته باشید. اما در بیشتر موارد، می‌توانید نام منبع (یا نمونه منبع موجود) را به روش کارخانه کتابخانه Ruby ارسال کنید:

campaign_resource_name = client.path.campaign(customer_id, campaign_id)

operation =
  client.operation.update_resource.campaign(campaign_resource_name) do |c|
    c.status = :PAUSED
    c.network_settings = client.resource.network_settings do |ns|
      ns.target_search_network = false
    end
  end

When given a resource name string, this method automatically creates a new campaign resource with resource_name populated, constructs the field mask based on changes you make within the block, builds the update operation, and returns the final operation with update and update_mask already populated. همچنین می‌توانید به‌جای رشته نام منبع، یک نمونه اولیه Campaign موجود را ارسال کنید تا وضعیت شروع پویش را مشخص کنید. این الگو برای همه منابعی که از عملیات به‌روزرسانی پشتیبانی می‌کنند کار می‌کند.

ایجاد دستی ماسک فیلد

برای ایجاد ماسک فیلد از ابتدا بدون استفاده از ابزارهای کمکی کتابخانه، یک Google::Protobuf::FieldMask ایجاد کنید، آرایه‌ای پرشده با نام‌های همه فیلدهایی که قصد تغییر آن‌ها را دارید بسازید، و آرایه را به فیلد paths ماسک فیلد اختصاص دهید:

mask = Google::Protobuf::FieldMask.new
mask.paths = ['status', 'name']

به‌روزرسانی فیلدهای پیام و زیرفیلدهای آن‌ها

فیلدهای MESSAGE می‌توانند فیلدهای فرعی داشته باشند (مثل MaximizeConversions که سه فیلد فرعی دارد: target_cpa_micros، cpc_bid_ceiling_micros، و cpc_bid_floor_micros)، یا می‌توانند هیچ فیلد فرعی‌ای نداشته باشند (مثل ManualCpm).

فیلدهای پیام بدون زیرفیلدهای تعریف‌شده

هنگام به‌روزرسانی فیلد MESSAGE که با هیچ زیرفیلدی تعریف نشده است، از FieldMaskUtil برای تولید پوشش فیلد استفاده کنید، همان‌طور که قبلاً ارائه شد.

فیلدهای پیام با زیرفیلدهای تعریف‌شده

هنگام به‌روزرسانی فیلد MESSAGE که با زیرفیلدها تعریف شده است، بدون اینکه صریحاً هیچ‌یک از زیرفیلدها را در آن پیام تنظیم کنید، باید هریک از زیرفیلدهای MESSAGE تغییرپذیر را به‌صورت دستی به FieldMask اضافه کنید، مشابه مثال قبلی که ماسک فیلد را از ابتدا ایجاد کرد.

یک مثال رایج، به‌روزرسانی استراتژی پیشنهاد قیمت پویش بدون تنظیم هیچ‌یک از فیلدها در استراتژی پیشنهاد قیمت جدید است. مثال زیر نشان می‌دهد چگونه پویشی را به‌روز کنید تا از استراتژی پیشنهاد قیمت MaximizeConversions استفاده کند بدون اینکه هیچ‌کدام از زیرفیلدها را در استراتژی پیشنهاد قیمت تنظیم کنید.

برای این مثال، استفاده از مقایسه داخلی FieldMaskUtil به هدف موردنظر نمی‌رسد.

کد زیر ماسک فیلدی تولید می‌کند که شامل maximize_conversions است. بااین‌حال، Google Ads API برای جلوگیری از پاک شدن تصادفی فیلدها، این رفتار را مجاز نمی‌داند و خطای FieldMaskError.FIELD_HAS_SUBFIELDS را ایجاد می‌کند.

# Creates a campaign with the proper resource name.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
end

# Update the maximize conversions field within the update block, so it's
# captured in the field mask.
operation = client.operation.update_resource.campaign(campaign) do |c|
  c.maximize_conversions = client.resource.maximize_conversions
end

# Sends the operation in a mutate request that results in a
# FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
# be included in a field mask.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)
# Create the operation directly from the campaign's resource name. Don't do
# anything in the block so that the field mask starts empty. You can modify
# other fields in this block, except the message field intended to have a
# blank subfield.
campaign_resource_name = client.path.campaign(customer_id, campaign_id)
operation = client.operation.update_resource.campaign(campaign_resource_name) {}

# Manually add the maximize conversions subfield to the field mask so the API
# knows to clear it.
operation.update_mask.paths << 'maximize_conversions.target_cpa_micros'

# This operation succeeds.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)

پاک کردن فیلدها

برخی‌از فیلدها را می‌توان به‌طور صریح پاک کرد. مشابه مثال قبلی، باید این فیلدها را به‌طور صریح به ماسک فیلد اضافه کنید. برای مثال، فرض کنید پویشی دارید که از استراتژی پیشنهاد قیمت MaximizeConversions استفاده می‌کند و فیلد target_cpa_micros با مقداری بزرگ‌تر از 0 تنظیم شده است.

در proto3، تنظیم کردن فیلد اسکالر غیر اختیاری روی مقدار پیش‌فرض آن (0) با تنظیم‌نشده باقی گذاشتن آن در نمونه پیام جدید تفاوتی ندارد. درنتیجه، FieldMaskUtil به‌جای maximize_conversions.target_cpa_micros، maximize_conversions را به ماسک فیلد اضافه می‌کند که باعث بروز خطای FieldMaskError.FIELD_HAS_SUBFIELDS می‌شود.

# Create a campaign object representing the campaign you want to change.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
end

# The field mask in this operation includes 'maximize_conversions',
# but not 'maximize_conversions.target_cpa_micros', so it results in an
# error.
operation = client.operation.update_resource.campaign(campaign) do |c|
  c.maximize_conversions = client.resource.maximize_conversions do |mc|
    mc.target_cpa_micros = 0
  end
end

# Operation fails because the field mask is invalid.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)
# Create a campaign including the maximize conversions fields right away, since
# they are manually added to the field mask.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
  c.maximize_conversions = client.resource.maximize_conversions do |mc|
    mc.target_cpa_micros = 0
  end
end

# Create the operation with an empty field mask. You can add a block here with
# other changes that are automatically added to the field mask.
operation = client.operation.update_resource.campaign(campaign) {}

# Add the field to the field mask so the API knows to clear it.
operation.update_mask.paths << 'maximize_conversions.target_cpa_micros'

# Operation succeeds because the correct field mask is specified.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)

توجه داشته باشید که رویکرد مقایسه خودکار برای فیلدهایی که به‌عنوان optional در میان‌گیرهای پروتکل Google Ads API تعریف شده‌اند، طبق انتظار عمل می‌کند. چون target_cpa_micros فیلد optional در MaximizeConversions نیست، برای پاک کردن آن باید صریحاً مسیر را به update_mask.paths افزود.