التعديلات باستخدام أقنعة الحقول

في 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 proto حالي بدلاً من سلسلة اسم المورد لتحديد الحالة الأولية للحملة. يعمل هذا النمط مع جميع الموارد التي تتيح عملية التعديل.

إنشاء قناع حقل يدويًا

لإنشاء قناع حقل من البداية بدون استخدام أدوات المكتبة، أنشئ 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 إلى قناع الحقل بدلاً من maximize_conversions.target_cpa_micros، ما يؤدي إلى حدوث خطأ 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 في Protocol Buffers لواجهة Google Ads API. لأنّ target_cpa_micros ليس حقل optional في MaximizeConversions، يجب إلحاق المسار بـ update_mask.paths بشكل صريح لمسحه.