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

در 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

وقتی رشته نام منبعی ارائه شود، این روش به‌طور خودکار منبع پویش جدیدی با resource_name پرشده ایجاد می‌کند، ماسک فیلد را براساس تغییراتی که در بلوک ایجاد می‌کنید می‌سازد، عملیات به‌روزرسانی را می‌سازد، و عملیات نهایی را با update و update_mask ازپیش پرشده برمی‌گرداند. همچنین می‌توانید به‌جای رشته نام منبع، یک نمونه اولیه 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» برای جلوگیری از پاک کردن تصادفی فیلدها و تولید خطای 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 اضافه کنید.