フィールド マスクを使用した更新

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 オブジェクトを作成してから、更新するキャンペーンの API に通知するリソース名を設定します。

この例では、キャンペーンで client.field_mask.with メソッドを使用して、更新を含むブロックを開始します。このブロックの最後に、ユーティリティはブロックの後のキャンペーンの現在のステータスとブロックの前のキャンペーンの初期ステータスを比較し、変更されたフィールドを列挙するフィールド マスクを自動的に生成します。そのフィールド マスクは、以下のように、オペレーション作成時にオペレーションに指定できます。

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

複雑なオペレーションを行って各ステップを細かく制御する場合は、この方法をおすすめします。ただし、ほとんどの場合は、よりシンプルな Ruby ライブラリ ユーティリティを使用できます。

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

このメソッドは、新しい空のキャンペーン リソースを自動的に作成し、ブロック内で行った変更に基づいてフィールド マスクを作成し、更新オペレーションをビルドして、updateupdate_mask がすでに入力された最終オペレーションを返します。campaign メソッドにキャンペーンを渡して、キャンペーンの開始状態を指定することもできます。このパターンは、更新オペレーションをサポートするすべてのリソースで機能します。

マスクを手動で作成する

ライブラリ ユーティリティを使用せずにフィールド マスクをゼロから作成するには、まず Google::Protobuf::FieldMask を作成し、変更するすべてのフィールドの名前が入力された配列を作成して、最後にフィールド マスクの path フィールドに配列を代入します。

mask = Google::Protobuf::FieldMask.new
mask.path = ["status", "name"]

メッセージ フィールドとそのサブフィールドの更新

MESSAGE フィールドには、サブフィールドを含めることも(例: target_cpa_microscpc_bid_ceiling_microscpc_bid_floor_micros の 3 つを持つ MaximizeConversions)、まったく持たない(ManualCpm など)こともできます。

サブフィールドが定義されていないメッセージ フィールド

どのサブフィールドでも定義されていない MESSAGE フィールドを更新する場合は、前述のように FieldMaskUtil を使用してフィールド マスクを生成します。

サブフィールドが定義されたメッセージ フィールド

メッセージのサブフィールドを明示的に設定せずにサブフィールドで定義された MESSAGE フィールドを更新する場合は、フィールド マスクをゼロから作成した前述の例と同様に、変更可能なMESSAGE サブフィールドを手動で FieldMask に追加する必要があります。

一般的な例としては、新しい入札戦略のフィールドを設定せずにキャンペーンの入札戦略を更新する場合があります。次の例は、入札戦略のサブフィールドを設定せずに、MaximizeConversions 入札戦略を使用するようにキャンペーンを更新する方法を示しています。

この例では、FieldMaskUtil の組み込み比較では意図した目標を達成できません。

次のコードは、maximize_conversions を含むフィールド マスクを生成します。ただし、誤ってフィールドをクリアして FieldMaskError.FIELD_HAS_SUBFIELDS エラーが発生するのを防ぐため、Google Ads API ではこの動作が許可されていません。

# 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 will result 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],
)

次のコードは、サブフィールドを設定せずに MaximizeConversions 入札戦略を使用するようにキャンペーンを適切に更新する方法を示しています。

# Create the operation directly from the campaign's resource name. Don't do
# anything in the block so that the field mask is empty. You could modify other
# fields in this block, just not the message field that is intended to have a
# blank subfield. We'll add that below.
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 より大きい値が設定されているとします。

次のコードが実行されます。ただし、maximize_conversions.target_cpa_micros はフィールド マスクに追加されないため、target_cpa_micros フィールドに変更は行われません。

# 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 will include 'maximize_conversions',
# but not 'maximize_conversions.target_cpa_micros', so it will result 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 will fail since field mask is incorrect.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

次のコードは、MaximizeConversions 入札戦略で target_cpa_micros フィールドを適切にクリアする方法を示しています。

# Create a campaign including the maximize conversions fields right away, since
# we're going to manually add them 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 may add a block here with
# other changes that will automatically get 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 will succeed since we specified the correct field mask.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

「正しくない」コードは、Google Ads API の protocol buffersoptional として定義されているフィールドに対して意図したとおりに機能します。しかし、target_cpa_microsoptional フィールドではないため、「正しくない」コードでは、target_cpa フィールドをクリアするように入札戦略が更新されません。