ショッピング リスティング グループを使用すると、商品をグループに分割できます。 これは、UI では「商品 グループ」と呼ばれます。複数のディメンションを使用してグループ化することで、商品を含めたり除外したりすることができます。
以下のツリーを考えてみましょう。最初のレベルでは、商品は状態によって「New」、「Used」、「Other」に分けられています。2 番目のレベルでは、状態が「Other」の商品がブランド別に「CoolBrand」、「CheapBrand」などに分類されています。

ツリーの各ノードは、ListingGroupType で定義される子区分またはユニットのいずれかです。子区分はツリーに新しいレベルを追加し、ユニットはツリーの葉として機能します。各子区分は完全に分割されている必要があるため、「Other」のノードが必ず必要となります。この例では Root と商品状態: (Other)のノードが子区分です。子区分とユニットで構成されるこのツリー構造により、ユニットレベルで入札を設定でき、すべての商品がツリー内の唯一のユニットノードに分類されることが保証されます。
入札単価を設定できるのは、関連付けられた ListingGroupInfo.type が UNIT の AdGroupCriterion のみです。
AdGroupCriterion の negative がデフォルトの false に設定され、ListingGroupInfo.type
が UNIT に設定されている場合、広告グループの入札戦略で条件レベルの入札単価(個別クリック単価など)が必要な場合は、入札単価を指定する必要があります。たとえば、AdGroupCriterion
の cpc_bid_micros フィールドを設定する必要があります。正の UNIT
ノードに必要な入札単価を指定しないと、エラーが発生します。
ListingGroupInfo.type が SUBDIVISION の場合、AdGroupCriterion
に入札単価を設定することはできません。AdGroupCriterion の negative が true
に設定されている場合、除外であるため入札単価は適用されません。
ノードは ListingGroupInfo
クラスのオブジェクトであり、ノードがユニットか子区分かを示す
ListingGroupType フィールドを含んでいます。AdGroupCriterion の ListingGroupInfo を listing_group に設定すると、AdGroup にリンクされます。
ツリーを有効にするには、少なくとも 1 つのユニットノードが必要です。そのユニットはルートノードとすることができ、この場合「すべての商品」区分となります。有効なリスティング グループ ツリーを作成するまで、広告は配信されません。
個別クリック単価を設定する
設定できるのは、ユニットノードのみです。cpc_bid_microsAdGroupCriterion下位区分ノードで設定しようとするとエラーが発生して失敗します。
リスティングの項目
ListingGroupInfo には、複数のディメンション タイプのうちの 1 つを含む ListingDimensionInfo である case_value
があります。ListingGroupInfo は、商品に関連付けられている値(オファー
ID、ブランド、商品の状態など)を表します。利用可能な ListingDimensionInfo タイプについて詳しくは、リファレンス ドキュメントをご覧ください。
下位区分の子ノードは、同じ ListingDimensionInfo サブタイプの case_value を保持している必要があります。Root
ノードのみ case_value を保持しません。
また、各下位区分には、適切なタイプの「空」の case_value を必ず設定する必要があります。この子は、その
ListingDimensionInfo の「その他すべての値」を表すため、通常「Other 」と呼ばれます。
詳しくは、リスティング グループ ツリーの最初のレベルを追加する次のコード スニペットをご覧ください。
Java
private void runExample( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, boolean replaceExistingTree) { // 1) Optional: Removes the existing listing group tree, if it already exists on the ad group. if (replaceExistingTree) { removeListingGroupTree(googleAdsClient, customerId, adGroupId); } // Creates a list of ad group criterion to add.q List<AdGroupCriterionOperation> operations = new ArrayList<>(); // 2) Constructs the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = createListingGroupSubdivisionRoot(customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as part of the // criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.getResourceName(); operations.add(AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionRoot).build()); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() .setProductCondition( ProductConditionInfo.newBuilder().setCondition(ProductCondition.NEW).build()) .build(), 200_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionNew).build()); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() .setProductCondition( ProductConditionInfo.newBuilder().setCondition(ProductCondition.USED).build()) .build(), 100_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionUsed).build()); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = createListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() // All sibling nodes must have the same dimension type, even if they don't contain a // bid. // parent .setProductCondition(ProductConditionInfo.newBuilder().build()) .build()); // Gets the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as part of the // criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.getResourceName(); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionOther).build()); // 4) Constructs the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().setValue("CoolBrand").build()) .build(), 900_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandCoolBrand).build()); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().setValue("CheapBrand").build()) .build(), 10_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandCheapBrand).build()); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().build()) .build(), 50_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandOther).build()); // Issues a mutate request to add the ad group criterion to the ad group. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().creat<eAdGroupCriterionServiceClie>nt()) { ListMutateAdGroupCriterionResult mutateAdGroupCriteriaResults = adGroupCriterionServiceClient .mutateAdGroupCriteria(Long.toString(customerId), operations) .getResultsList(); for (MutateAdGroupCriterionResult mutateAdGroupCriterionResult : mutateAdGroupCriteriaResults) { System.out.printf( "Added ad group criterion for listing group with resource name: '%s'%n", ceName()); } } } AddShoppingProductListingGroupTree.java
C#
public void Run(GoogleAdsClient client, long customerId, long adGroupId, bool replaceExistingTree) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V25.AdGroupCriterionService); try { // 1) Optional: Remove the existing listing group tree, if it already exists on the // ad group. if (replaceExistingTree) { RemoveListingGroupTree(client, customerId, adGroupId); } // Create a list of ad group criterion to add List<AdGroupCriterionOperation> operations = new List<AdGroupCriterionOperation>(); // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = CreateListingGroupSubdivisionRoot( customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionRoot }); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.New } }, 200_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionNew }); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.Used } }, 100_000L ); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionUsed }); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = CreateListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { // All sibling nodes must have the same dimension type, even if they // don't contain a bid. ProductCondition = new ProductConditionInfo() } ); // Get the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionOther }); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CoolBrand" } }, 900_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCoolBrand }); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CheapBrand" } }, 10_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCheapBrand }); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() }, 50_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandOther }); // Issues a mutate request to add the ad group criterion to the ad group. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); // Display the results. foreach (MutateAdGroupCriterionResult mutateAdGroupCriterionResult in response.Results) { Console.WriteLine("Added ad group criterion for listing group with resource " + $"name: '{mutateAdGroupCriterionResult.ResourceName}."); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {iteLine($"Request ID: {e.RequestId}"); throw; } }AddShoppingProductListingGroupTree.cs
PHP
public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId, bool $replaceExistingTree ) { // 1) Optional: Remove the existing listing group tree, if it already exists on the ad // group. if ($replaceExistingTree === 'true') { self::removeListingGroupTree($googleAdsClient, $customerId, $adGroupId); } // Create a list of ad group criteria to add. $operations = []; // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) $adGroupCriterionRoot = self::createListingGroupSubdivision($customerId, $adGroupId); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as part of the // criterion ID. $adGroupCriterionResourceNameRoot = $adG>roupCriterionRoot-getResourceName(); $operations[] = new AdGroupCriterionOpe>ration(['create' = $adGroupCriterionRoot]); // 3) Construct the listing group unit nodes for NEW, USED and other. // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 $adGroupCriterionConditionNew = self::createListingGroupUnitBiddable( $customerId, $adGroupId, $adGroupCriterionResourceNameRoot, new ListingDimensionInfo([ > 'product_condition' = new ProductConditionIn>fo( ['condition' = ProductCondition::PBNEW] ) ]), 200000 ); $operations[] => new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionNew]); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 $adGroupCriterionConditionUsed = self::createListingGroupUnitBiddable( $customerId, $adGroupId, $adGroupCriterionResourceNameRoot, new Listin>gDimensionInfo([ 'product_condition' >= new ProductConditionInfo( ['condition' = ProductCondition::USED] ) ]), 100000 > ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionUsed]); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) $adGroupCriterionConditionOther = self::createListingGroupSubdivision( $customerId, $adGroupId, $adGroupCriterionResourceNameRoot, new ListingDimensionInfo([ // All sibling nodes must have the same dimension type>, even if they don't contain a // bid. 'product_condition' = new ProductConditi>onInfo() ]) ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionOther]); // Get the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as part of the // >criterion ID. $adGroupCriterionResourceNameConditionOther = $adGroupCriterionConditionOther-getResourceName(); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other. // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 $adGroupCriterionBrandCoolBrand = self::createListingGroupUnitBiddable( $customerId, $adGroupId, $adGr>oupCriterionResourceNameConditio>nOther, new ListingDimensionInfo([ 'product_brand' = new ProductBrandInfo(['value'> = 'CoolBrand']) ]), 900000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrandCoolBrand]); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 $adGroupCriterionBrandCheapBrand = self::createListingGroupUnitBiddable( $customerId, > $adGroupId, $adGr>oupCriterionResourceNameConditionOther, new ListingDimensionInfo([ 'product_brand' = new P>roductBrandInfo(['value' = 'CheapBrand']) ]), 10000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrandCheapBrand]); // Biddable Unit node: (Brand other node) // * CPC bid: $0.05 $adGroupCriterionBrandOtherBrand = self::createListingGroupUnit>Biddable( $customerId, $adGroupId, $adGroupCriterionResourceNameConditionOther, new ListingDim>ensionInfo([ 'product_brand' = new ProductBrandInfo() ]), 50000 ); $operations[]> = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrand>OtherBrand]); // Issues a mutate request. $adGroupCriterionServiceClient = $googleAdsClient-getAdGroupCriterionServiceClient(); $response = $adGroupCriterionServiceClient-mutateAdGroupCriteria( MutateAdGroupCriteriaReque>st::build($cu>stomerId, $operations) ); printf( '>Added %d ad group criteria for listing group tree with the following resource ' . 'names:%s', $response-getResu>lts()-count(), PHP_EOL )as $addedAdGroupCriterion) { /** @var AdGroupCriterion $addedAdGroupCriterion */ print $addedAdGroupCriterion-getResourceName() . PHP_EOL; } }AddShoppingProductListingGroupTree.php
Python
def main( client: GoogleAdsClient, customer_id: str, ad_group_id: str, replace_existing_tree: bool, ) -> None: """Adds a shopping listing group tree to a shopping ad group. Args: client: An initialized Google Ads client. customer_id: The Google Ads customer ID. ad_group_id: The ad group ID to which the node will be added. replace_existing_tree: Boolean, whether to replace the existing listing group tree on the ad group. Defaults to false. """ # Get the AdGroupCriterionService client. ad_group_criterion_service: AdGroupCriterionServiceClient = ( client.get_service("AdGroupCriterionService") ) # Optional: Remove the existing listing group tree, if it already exists # on the ad group. The example will throw a LISTING_GROUP_ALREADY_EXISTS # error if a listing group tree already exists and this option is not # set to true. if replace_existing_tree: remove_listing_group_tree(client, customer_id, ad_group_id) # Create a list of ad group criteria operations. operations: List[AdGroupCriterionOperation] = [] # Construct the listing group tree "root" node. # Subdivision node: (Root node) ad_group_criterion_root_operation: AdGroupCriterionOperation = ( create_listing_group_subdivision(client, customer_id, ad_group_id) ) # Get the resource name that will be used for the root node. # This resource has not been created yet and will include the temporary # ID as part of the criterion ID. ad_group_criterion_root_resource_name: str = ( ad_group_criterion_root_operation.create.resource_name ) operations.append(ad_group_criterion_root_operation) # Construct the listing group unit nodes for NEW, USED, and other. product_condition_enum: ProductConditionEnum = ( client.enums.ProductConditionEnum ) condition_dimension_info: ListingDimensionInfo = client.get_type( "ListingDimensionInfo" ) # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 condition_dimension_info.product_condition.condition = ( product_condition_enum.NEW ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, 200_000, ) ) # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 condition_dimension_info.product_condition.condition = ( product_condition_enum.USED ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, 100_000, ) ) # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) # Note that all sibling nodes must have the same dimension type, even if # they don't contain a bid. client.copy_from( condition_dimension_info.product_condition, client.get_type("ProductConditionInfo"), ) ad_group_criterion_other_operation: AdGroupCriterionOperation = ( create_listing_group_subdivision( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, ) ) # Get the resource name that will be used for the condition other node. # This resource has not been created yet and will include the temporary # ID as part of the criterion ID. ad_group_criterion_other_resource_name: str = ( ad_group_criterion_other_operation.create.resource_name ) operations.append(ad_group_criterion_other_operation) # Build the listing group nodes for CoolBrand, CheapBrand, and other. brand_dimension_info: ListingDimensionInfo = client.get_type( "ListingDimensionInfo" ) # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 brand_dimension_info.product_brand.value = "CoolBrand" operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 900_000, ) ) # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 brand_dimension_info.product_brand.value = "CheapBrand" operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 10_000, ) ) # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 client.copy_from( brand_dimension_info.product_brand, client.get_type("ProductBrandInfo"), ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 50_000, ) ) # Add the ad group criteria. mutate_ad_group_criteria_response: MutateGoogleAdsResponse = ( ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=operations ) ) # Print the results of the successful mutates. print( "Added ad group criteria for the listing group tree with the " "following resource names:" ) for result in mutate_ad_group_crite;\t{result.resource_name}") print(f"{len(mutate_ad_group_criteria_response.results)} criteria added.")add_shopping_product_listing_group_tree.py
Ruby
def add_shopping_product_listing_group_tree( customer_id, ad_group_id, should_replace_existing_tree ) # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google::Ads::GoogleAds::GoogleAdsClient.new # 1) Optional: Remove the existing listing group tree, if it already exists # on the ad group. if should_replace_existing_tree remove_listing_group_tree(client, customer_id, ad_group_id) end # 2) Construct the listing group tree "root" node. # Subdivision node: (Root node) ad_group_criterion_root = create_listing_group_subdivision( client, customer_id, ad_group_id, ) # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. ad_group_criterion_root_resource_name = ad_group_criterion_root.resource_name operations = [client.operation.create_resource.ad_group_criterion(ad_group_criterion_root)] # 3) Construct the listing group unit nodes for NEW, USED, and other. # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info do |pci| pci.condition = :NEW end end ad_group_criterion_condition_new = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, 200_000, ) operation = client.operation.create_resource.ad_group_criterion( ad_group_criterion_condition_new<< ) operations operation # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info do |pci| pci.condition = :USED end end ad_group_criterion_condition_used = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, 100_000, ) operation = client.operation.create_resource.ad_group_criterion( ad_group_criterion_condition_used<< ) operations operation # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info end ad_group_criterion_condition_other = create_listing_group_subdivision( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, ) operation = client.operation.create_resource.ad_group_criterion( ad_group_criterion_condi<<tion_other ) operations operation ad_group_criterion_condition_other_resource_name = ad_group_criterion_condition_other.resource_name # 4) Construct the listing group unit nodes for CoolBrand, CheapBrand, and # other. # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info do |pbi| pbi.value = "CoolBrand" end end ad_group_criterion_brand_cool_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 900_000, ) operation = client.operation.create_resource.ad_group_criterion( ad_group_criter<<ion_brand_cool_brand ) operations operation # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info do |pbi| pbi.value = "CheapBrand" end end ad_group_criterion_brand_cheap_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 10_000, ) operation = client.operation.create_resource.ad_group_criterion( ad_gro<<up_criterion_brand_cheap_brand ) operations operation # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info end ad_group_criterion_brand_other_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 50_000, ) operation = client.operation.create_resource.ad_group_criterion( ad_gro<<up_criterion_brand_other_brand ) operations operation # Issue the mutate request. response = client.service.ad_group_criterion.mutate_ad_group_criteria( customer_id: customer_id, operations: operations, ) total_count = 0 response.results.each do |added_criterion| puts "Added ad group criterion with name: #{added_criterion.resource_name}" total_count += 1 added in total." endadd_shopping_product_listing_group_tree.rb
Perl
sub add_shopping_product_listing_group_tree { my ($api_client, $customer_id, $ad_group_id, $replace_existing_tree) = @_; # 1) Optional: Remove the existing listing group tree, if it already exists # on the ad group. if ($replace_existing_tree) { remove_listing_group_tree($api_client, $customer_id, $ad_group_id); } # Create a list of ad group criteria operations to add. my $operations = []; # 2) Construct the listing group tree "root" node. # Subdivision node: (Root node) my $ad_group_criterion_root = create_listing_group_subdivision($customer_id, $ad_group_id); # Get the resource name that will be used for the root node. # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. my $ad_group_criterion_root_resource_name = $ad_group_crite>rion_root-{resourceName}; push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroupCriterionOpera>tion -new({ > create = $ad_group_criterion_root }); # 3) Construct the listing group unit nodes for NEW, USED, and other. # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 my $ad_group_criterion_condition_new = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_root_resource_name, Google::Ads::GoogleAds::V25::Common::ListingDime>nsionInfo-new({ productC>ondition = Google::Ads::GoogleAds::V25::Common::ProductCond>itionInfo-new({ c>ondition = NEW })} ), 200000 ); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroupCriterionOpera>tion -new({ > create = $ad_group_criterion_condition_new }); # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 my $ad_group_criterion_condition_used = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_root_resource_name, Google::Ads::GoogleAds::V25::Common::ListingDime>nsionInfo-new({ productC>ondition = Google::Ads::GoogleAds::V25::Common::ProductCond>itionInfo-new({ c>ondition = USED })} ), 100000 ); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroupCriterionOpera>tion -new({ > create = $ad_group_criterion_condition_used }); # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) my $ad_group_criterion_condition_other = create_listing_group_subdivision( $customer_id, $ad_group_id, $ad_group_criterion_root_resource_name, Google::Ads::GoogleAds::V25::Common::L>istingDimensionInfo-new({ # All sibling nodes must have the same dimension type, even if they # don't contain a bid. > productCondition = Google::Ads::GoogleAds::V25::Commo>n::ProductConditionInfo-new()})); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroup>CriterionOperation > -new({ create = $ad_group_criterion_condition_other }); # Get the resource name that will be used for the condition other node. # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. my $ad_group_criterion_condition_other_resource_name = $ad_group_cr>iterion_condition_other-{resourceName}; # 4) Construct the listing group unit nodes for CoolBrand, CheapBrand, and # other. # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 my $ad_group_criterion_brand_cool_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_condition_other_resource_name, Google::Ads::GoogleAds::V25::Commo>n::ListingDimensionInfo-new(>{ productBrand = Google::Ads::GoogleAds::V25::C>ommon::ProductBrandInfo>-new( {value = "CoolBrand"})} ), 900000 ); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCriterionServic>e::AdGroupCriterionO>peration -new({ create = $ad_group_criterion_brand_cool_brand }); # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 my $ad_group_criterion_brand_cheap_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_condition_other_resource_name, Google::Ads::GoogleAds::>V25::Common::ListingDimensio>nInfo-new({ productBrand = Google::Ads::GoogleA>ds::V25::Common::Produc>tBrandInfo-new( {value = "CheapBrand"})} ), 10000 ); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCrite>rionService::AdGroup>CriterionOperation -new({ create = $ad_group_criterion_brand_cheap_brand }); # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 my $ad_group_criterion_brand_other_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_condition_other_resource_name, Google::Ads::G>oogleAds::V25::Common::Listi>ngDimensionInfo-new({ productBrand = Google::Ad>s::GoogleAds::V25::Common::ProductBrandInfo-new()} ), 50000 ); push @$operations, Google::Ads::GoogleAds::V25::Services::AdGroupCrite>rionService::AdGroup>CriterionOperation -new({ create = $ad_group_criterion_brand_other_brand }); # Add the ad group criterion. my $a>d_group_criteria_response >= $api_client-AdGroupCr>iterionService()-mutate({ c>ustomerId = $customer_id, operations = $operations }); printf "Added %d ad group criteria for listing group tree with the " . "following re>source names:\n", scalar @{$ad_group_criteria_response-{>results}}; foreach my $result> (@{$ad_group_criteria_response-{resultsuot;\n"; } return 1; }add_shopping_product_listing_group_tree.pl
curl
ListingDimensionInfo で使用可能なディメンション
リスティング項目が複数用意されており、リスティング グループ(広告グループ単位)やリスティング範囲(キャンペーン単位)の一部にできます。
次の ListingDimensionInfo タイプは、ショッピング キャンペーンでご利用いただけます。
ProductBrandInfoProductCategoryInfoProductCustomAttributeInfoProductChannelInfoProductChannelExclusivityInfoProductConditionInfoProductItemIdInfoProductTypeInfo
各リソースの
ProductCategoryConstant.ProductCategoryLocalizationフィールドには、サポートされているローカライゼーションのリストが含まれています。
このリソースから返されるデータについては、
商品カテゴリ定数を取得する例をご覧ください。
一時的な ID
広告グループ条件を作成する mutate リクエストがサーバー側で処理されるまで、条件に ID は割り当てられません。ただし、ListingGroupInfo
は完了するまで無効なので、下位区分を作成するたびに、同じリクエストで 1 つ以上の子と「Other 」ノードを作成する必要があります。
親と同じリクエストで作成された子ノードの parent_criterion_id の
ListingGroupInfo を設定するために、一時的な条件 ID を使用できます。
これはグローバルではなくローカルで固有の識別子であり、1 つの mutate
リクエストの範囲内でのみ適用されます。一時的な ID としては、任意の負の整数を使用できます。サンプルコードでは、Root の ID は
-1 に設定されます。ListingGroupInfo
リクエストの処理が完了すると、各 AdGroupCriterion には通常どおり正のグローバル ID が割り当てられます。
エラー処理
リスティング グループを作成する場合は、ツリー全体を 1 つのリクエストでアップロードする必要があります。ツリーは再帰的な性質を持つため、ツリー内の特定の箇所に問題がある場合でも、エラーが連鎖することがあります。エラー状態の根本原因が 1 つしかない場合でも、ツリー内のすべてのノードに対してエラー メッセージが返されることがあります。リスティング グループの作成時に多くのエラーが返された場合は、レスポンスで最も一般的なエラー理由のエラーを無視してみてください。返り値で 他のエラーを探して、根本的なエラーを特定します。たとえば、「x」というエラーが 50 件、「y」というエラーが 1 件返された場合は、「y」のエラーの修正に重点を置くと、エラー状態全体が解決する可能性があります。
サンプルコード
ショッピング リスティング グループを作成するための完全なコードは次のとおりです。
Java
// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.shoppingads; import com.beust.jcommander.Parameter; import com.google.ads.googleads.examples.utils.ArgumentNames; import com.google.ads.googleads.examples.utils.CodeSampleParams; import com.google.ads.googleads.lib.GoogleAdsClient; import com.google.ads.googleads.v25.common.ListingDimensionInfo; import com.google.ads.googleads.v25.common.ListingGroupInfo; import com.google.ads.googleads.v25.common.ProductBrandInfo; import com.google.ads.googleads.v25.common.ProductConditionInfo; import com.google.ads.googleads.v25.enums.AdGroupCriterionStatusEnum.AdGroupCriterionStatus; import com.google.ads.googleads.v25.enums.ListingGroupTypeEnum.ListingGroupType; import com.google.ads.googleads.v25.enums.ProductConditionEnum.ProductCondition; import com.google.ads.googleads.v25.errors.GoogleAdsError; import com.google.ads.googleads.v25.errors.GoogleAdsException; import com.google.ads.googleads.v25.resources.AdGroupCriterion; import com.google.ads.googleads.v25.services.AdGroupCriterionOperation; import com.google.ads.googleads.v25.services.AdGroupCriterionServiceClient; import com.google.ads.googleads.v25.services.GoogleAdsRow; import com.google.ads.googleads.v25.services.GoogleAdsServiceClient; import com.google.ads.googleads.v25.services.GoogleAdsServiceClient.SearchPagedResponse; import com.google.ads.googleads.v25.services.MutateAdGroupCriteriaResponse; import com.google.ads.googleads.v25.services.MutateAdGroupCriterionResult; import com.google.ads.googleads.v25.services.SearchGoogleAdsRequest; import com.google.ads.googleads.v25.utils.ResourceNames; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Adds a shopping listing group tree to a shopping ad group. The example will clear an existing * listing group tree and rebuild it include the following tr<ee >structure: * * pre * ProductCanonicalCondition NEW $0.20 * ProductCanonicalCondition USED $0.10 * ProductCanonicalCondition null (everything else) * ProductBrand CoolBrand $0.90 * ProductBrand CheapBrand $0.01 * ProductBrand null (everyt<hing> else) $0.50 * /pre */ public class AddShoppingProductListingGroupTree { private static class AddShoppingListingGroupParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true) private Long adGroupId; @Parameter(names = ArgumentNames.REPLACE_EXISTING_TREE, required = true, arity = 1) private Boolean replaceExistingTree; } public static void main(String[] args) { AddShoppingListingGroupParams params = new AddShoppingListingGroupParams(); if (!params.parseArguments(args)) { // Either pass the required parameters for this example on the command line, or insert them // into the code here. See the parameter class definition above for descriptions. params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE"); params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE"); // Optional: To replace the existing listing group tree on an ad group set this parameter to // true. // This option will remove the existing listing group tree before creating a replacement. params.replaceExistingTree = Boolean.parseBoolean("INSERT_REPLACE_EXISTING_TREE_HERE"); } GoogleAdsClient googleAdsClient = null; try { googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build(); } catch (FileNotFoundException fnfe) { System.err.printf( "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe); System.exit(1); } catch (IOException ioe) { System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe); System.exit(1); } try { new AddShoppingProductListingGroupTree() .runExample( googleAdsClient, params.customerId, params.adGroupId, params.replaceExistingTree); } catch (GoogleAdsException gae) { // GoogleAdsException is the base class for most exceptions thrown by an API request. // Instances of this exception have a message and a GoogleAdsFailure that contains a // collection of GoogleAdsErrors that indicate the underlying causes of the // GoogleAdsException. System.err.printf( "Request ID %s failed due to GoogleAdsException. Underlying errors:%n", gae.getRequestId()); int i = 0; for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) { System.err.printf(" Error %d: %s%n", i++, googleAdsError); } System.exit(1); } } /** * Runs the example. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupId the ID of the ad group. * @param replaceExistingTree replace the existing listing group tree on the ad group, if it * already exists. The example will throw a 'LISTING_GROUP_ALREADY_EXISTS' error if listing * group tree already exists and this option is not set to true. * @throws GoogleAdsException if an API request failed with one or more service errors. */ private void runExample( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, boolean replaceExistingTree) { // 1) Optional: Removes the existing listing group tree, if it already exists on the ad group. if (replaceExistingTree) { removeListingGroupTree(googleAdsC<lient, customerId, adGrou>pId); } // Creates <>a list of ad group criterion to add.q ListAdGroupCriterionOperation operations = new ArrayList(); // 2) Constructs the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = createListingGroupSubdivisionRoot(customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as part of the // criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.getResourceName(); operations.add(AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionRoot).build()); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() .setProductCondition( ProductConditionInfo.newBuilder().setCondition(ProductCondition.NEW).build()) .build(), 200_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionNew).build()); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() .setProductCondition( ProductConditionInfo.newBuilder().setCondition(ProductCondition.USED).build()) .build(), 100_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionUsed).build()); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = createListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, ListingDimensionInfo.newBuilder() // All sibling nodes must have the same dimension type, even if they don't contain a // bid. // parent .setProductCondition(ProductConditionInfo.newBuilder().build()) .build()); // Gets the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as part of the // criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.getResourceName(); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionConditionOther).build()); // 4) Constructs the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().setValue("CoolBrand").build()) .build(), 900_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandCoolBrand).build()); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().setValue("CheapBrand").build()) .build(), 10_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandCheapBrand).build()); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = createListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, ListingDimensionInfo.newBuilder() .setProductBrand(ProductBrandInfo.newBuilder().build()) .build(), 50_000L); operations.add( AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterionBrandOther).build()); // Issues a mutate request to add the ad group criterion to the ad group. try (AdGroupCriteri<onServiceClient adGroupCrite>rionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { ListMutateAdGroupCriterionResult mutateAdGroupCriteriaResults = adGroupCriterionServiceClient .mutateAdGroupCriteria(Long.toString(customerId), operations) .getResultsList(); for (MutateAdGroupCriterionResult mutateAdGroupCriterionResult : mutateAdGroupCriteriaResults) { System.out.printf( "Added ad group criterion for listing group with resource name: '%s'%n", mutateAdGroupCriterionResult.getResourceName()); } } } /** * Removes all the ad group criteria that define the existing listing group tree for an ad group. * Returns without an error if all listing group criterion are successfully removed. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupId the ID of the ad group that the new listing group tree will be removed from. * @throws GoogleAdsException if an API request failed with one or more service errors. */ private void removeListingGroupTree( GoogleAdsClient googleAdsClient, long customerId, long adGroupId) { try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { String searchQuery = "SELECT ad_group_criterion.resource_name " + "FROM ad_group_criterion " + "WHERE ad_group_criterion.type = LISTING_GROUP " + "AND ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL " + String.format("AND ad_group.id = %d", adGroupId); // Creates a request that will retrieve all listing groups where the parent ad group criterion // is NULL (and hence the root node in the tree) for a given ad group id. SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setQuery(searchQuery) .build(); // Issues the search request. SearchPagedResponse searchPagedResponse = googleAdsServiceClient.search(request); // Iterates over all rows in all pages to find the ad group criterion to remove. for (GoogleAdsRow googleAdsRow : searchPagedResponse.iterateAll()) { AdGroupCriterion adGroupCriterion = googleAdsRow.getAdGroupCriterion(); System.out.printf( "Found ad group criterion with the resource name: '%s'.%n", adGroupCriterion.getResourceName()); AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder() .setRemove(adGroupCriterion.getResourceName()) .build(); try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), Collections.singletonList(operation)); System.out.printf("Removed %d ad group criteria.%n", response.getResultsCount()); } } } } /** * Creates a new criterion containing a biddable unit listing group node. * * @param customerId the client customer ID. * @param adGroupId the ID of the ad group. * @param parentAdGroupCriterionResourceName the resource name of the parent of this criterion. * @param listingDimensionInfo the ListingDimensionInfo to be set for this listing group. * @param cpcBidMicros the CPC bid for items in this listing group. This value should be specified * in micros. * @return the ad group criterion object that contains the biddable unit listing group node. */ private AdGroupCriterion createListingGroupUnitBiddable( long customerId, long adGroupId, String parentAdGroupCriterionResourceName, ListingDimensionInfo listingDimensionInfo, long cpcBidMicros) { String adGroupResourceName = ResourceNames.adGroup(customerId, adGroupId); // Note: There are two approaches for creating new unit nodes: // (1) Set the ad group resource name on the criterion (no temporary ID required). // (2) Use a temporary ID to construct the criterion resource name and set it using // setResourceName. // In both cases you must set the parentAdGroupCriterionResourceName on the listing // group for non-root nodes. // This example demonstrates method (1). AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() // The ad group the listing group will be attached to. .setAdGroup(adGroupResourceName) .setStatus(AdGroupCriterionStatus.ENABLED) .setListingGroup( ListingGroupInfo.newBuilder() // Sets the type as a UNIT, which will allow the group to be biddable. .setType(ListingGroupType.UNIT) // Sets the ad group criterion resource name for the parent listing group. // This can include a temporary ID if the parent criterion is not yet created. // Use StringValue to convert from a String to a compatible argument type. .setParentAdGroupCriterion(parentAdGroupCriterionResourceName) // Case values contain the listing dimension used for the node. .setCaseValue(listingDimensionInfo) .build()) // Sets the bid for this listing group unit. // This will be used as the CPC bid for items that are included in this listing group .setCpcBidMicros(cpcBidMicros) .build(); return adGroupCriterion; } /** * Creates a new criterion containing a subdivision listing group node. * * @param customerId the client customer ID. * @param adGroupId the ID of the ad group. * @param adGroupCriterionId the ID of the criterion. This value will used to construct the * resource name. This can be a negative number if the criterion is yet to be created. * @param parentAdGroupCriterionResourceName the resource name of the parent of this criterion. * @param listingDimensionInfo the ListingDimensionInfo to be set for this listing group. * @return the ad group criterion object that contains the subdivision listing group node. */ private AdGroupCriterion createListingGroupSubdivision( long customerId, long adGroupId, long adGroupCriterionId, String parentAdGroupCriterionResourceName, ListingDimensionInfo listingDimensionInfo) { String adGroupCriterionResourceName = ResourceNames.adGroupCriterion(customerId, adGroupId, adGroupCriterionId); AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() // The resource name the criterion will be created with. This will define the ID for the // ad group criterion. .setResourceName(adGroupCriterionResourceName) .setStatus(AdGroupCriterionStatus.ENABLED) .setListingGroup( ListingGroupInfo.newBuilder() // Sets the type as a SUBDIVISION, which will allow the node to be the parent of // another sub-tree. .setType(ListingGroupType.SUBDIVISION) // Sets the ad group criterion resource name for the parent listing group. // This can include a temporary ID if the parent criterion is not yet created. // Uses StringValue to convert from a String to a compatible argument type. .setParentAdGroupCriterion(parentAdGroupCriterionResourceName) // Case values contain the listing dimension used for the node. .setCaseValue(listingDimensionInfo) .build()) .build(); return adGroupCriterion; } /** * Creates a new criterion containing a root subdivision listing group node. * * @param customerId the client customer ID. * @param adGroupId the ID of the ad group. * @param adGroupCriterionId the ID of the criterion. This value will used to construct the * resource name. This can be a negative number if the criterion is yet to be created. * @return the ad group criterion object that contains the listing group root node. */ private AdGroupCriterion createListingGroupSubdivisionRoot( long customerId, long adGroupId, long adGroupCriterionId) { String adGroupCriterionResourceName = ResourceNames.adGroupCriterion(customerId, adGroupId, adGroupCriterionId); AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() // The resource name the criterion will be created with. This will define the ID for the // ad group criterion. .setResourceName(adGroupCriterionResourceName) .setStatus(AdGroupCriterionStatus.ENABLED) .setListingGroup( ListingGroupInfo.newBuilder() // Sets the type as a SUBDIVISI parent of // another sub-tree. .setType(ListingGroupType.SUBDIVISION) .build()) .build(); return adGroupCriterion; } } AddShoppingProductListingGroupTree.java
C#
// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using CommandLine; using Google.Ads.Gax.Examples; using Google.Ads.GoogleAds.Lib; using Google.Ads.GoogleAds.V25.Common; using Google.Ads.GoogleAds.V25.Errors; using Google.Ads.GoogleAds.V25.Resources; using Google.Ads.GoogleAds.V25.Services; using System; using System.Collections.Generic; using System.Linq; using static Google.Ads.GoogleAds.V25.Enums.AdGroupCriterionStatusEnum.Types; using static Google.Ads.GoogleAds.V25.Enums.ListingGroupTypeEnum.Types; using static Google.Ads.GoogleAds.V25.Enums.ProductConditionEnum.Types; namespace Google.Ads.GoogleAds.Exa<mples.V>25 { /// summary /// This code example shows how to add a shopping listing group tree to a shopping ad group. /// The example will clear an existing listing group tree and rebuild it include the following /// tree structu<re:<>/span> /// /// code /// ProductCanonicalCondition NEW $0.20 /// ProductCanonicalCondition USED $0.10 /// ProductCanonicalCondition null (everything else) /// ProductBrand CoolBrand $0.90 /// ProductBrand CheapBrand $0.01 /// ProductBrand null (everything <else)> $0.50 < /// /c>ode /// /summary public class AddShoppingProductListingGroupTree : ExampleBas<e {> /// summary /// Command line opti<ons for running the see cref="AddShopping>ProductListingGroupTree"/ < ///> example. /// /summary public class Options : OptionsB<ase > { /// summary /// The Google Ads customer ID for which the <call is >made. /// /summary [Option("customerId", Required = true, HelpText = "The Google Ads customer ID for which the call is made.")] publ<ic long> CustomerId { get; set; } /// summary < //>/ The ID of the ad group. /// /summary [Option("adGroupId", Required = true, HelpText = "The ID of the ad group.&quo<t;)] > public long AdGroupId { get; set; } /// summary /// The boolean to indicate whether to replace the existing listing group tree on the /// ad group, if it already exists. The example will throw a /// LISTING_GROUP_ALREADY_EXISTS error if listing group tree already exist<s and th>is /// option is not set to true. /// /summary [Option("replaceExistingTree", Required = true, HelpText = "The boolean to indicate whether to replace the existing listing group tree on " + "the ad group, if it already exists. The example will throw a " + "LISTING_GROUP_ALREADY_EXISTS error if listing group tree already exists and " + "t<his opt>ion is not set to true.")] public bool ReplaceExistingTree { get; set; } < } > /// <summary />// Main method, to run this< code >example as a standalone application. /// /summary /// param name="args"The command line argumen<ts./par>am public static void Main(string[] args) { Options options = ExampleUtilities.ParseCommandLineOptions(args); AddShoppingProductListingGroupTree codeExample = new AddShoppingProductListingGroupTree(); Console.WriteLine(codeExample.Description); codeExample.Run(n<ew Goog>leAdsClient(), options.CustomerId, options.AdGroupId, o<ptions.R>eplaceExistingTree); } /// s>ummary /// Returns a description about the code example. /// /summary public override string Description = "This code example shows how to add a shopping listing group tree to a shopping ad " + "group. The example will clear an existing listing group tree and rebuild it include " + "the following tree structure:\n" + "ProductCanonicalCondition NEW $0.20\n" + "ProductCanonicalCondition USED $0.10\n" + "ProductCanonicalCondition null (everything< else)\>n" + " ProductBrand CoolB<rand $0.>90\n" + < " > ProductBrand CheapBra<nd $0.>01\n" + < " Pro>ductBrand null (everything else) $0.50\n"; < ///> summary < /// Runs the code >example. /// /s<ummary> /// <param name="client"The> Google Ads client./param /// param name="customerId"The Google Ads customer ID for which the call is made./param /// param name="ad<Grou>pId"The ID of the ad gr<oup./>param /// param name="replaceExistingTree"The boolean to indicate whether< to re>place the /// existing listing group tree on the ad group, if it already exists. The example will /// throw a codeLISTING_GROUP_ALREADY_EXISTS/code error if listing group tree already /// exists and this option is not set to true./param public void Run(GoogleAdsClient client, long customerId, long adGroupId, bool replaceExistingTree) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V25.AdGroupCriterionService); try { // 1) Optional: Remove the existing listing group tree, if it already exists on the < // ad group.> if (r<eplaceExistingTree) > { RemoveListingGroupTree(client, customerId, adGroupId); } // Create a list of ad group criterion to add ListAdGroupCriterionOperation operations = new ListAdGroupCriterionOperation(); // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = CreateListingGroupSubdivisionRoot( customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionRoot }); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.New } }, 200_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionNew }); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.Used } }, 100_000L ); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionUsed }); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = CreateListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { // All sibling nodes must have the same dimension type, even if they // don't contain a bid. ProductCondition = new ProductConditionInfo() } ); // Get the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionOther }); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CoolBrand" } }, 900_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCoolBrand }); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CheapBrand" } }, 10_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCheapBrand }); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() }, 50_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandOther }); // Issues a mutate request to add the ad group criterion to the ad group. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); // Display the results. foreach (MutateAdGroupCriterionResult mutateAdGroupCriterionResult in response.Results) { Console.WriteLine("Added ad group criterion for listing group with resource " + $"name: '{mutateAdGroupCriterionResult.ResourceName}."); } } catch (<GoogleA>dsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); < > Conso<le.WriteLine($">;Request ID: {e.RequestId}&<quot;)>; < throw; > } } /<// sum>mary </// Removes all the ad> group criteria that define the existing listing group tree for an /// ad group.< Retur>ns without an< error if all listing group criteri>on are successfully /// removed. /// /summary /// pa<ram name=&>quot;client"The Google Ads API client../param /// param name="customerId"The client customer ID./param /// param name="adGroupId"The ID of the ad group that the new listing group tree will /// be removed from./param /// exception cref="GoogleAdsException"Thrown if an API request failed with one or more /// service errors./exception private void RemoveListingGroupTree(GoogleAdsClient client, long customerId, long adGroupId) { // Get the GoogleAdsService. GoogleAdsServiceClient googleAdsService = client.GetService( Services.V25.GoogleAdsService); // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V25.AdGroupCriterionService); String searchQuery = "SELECT ad_group_criterion.resource_name FROM " + "ad_group_criterion WHERE ad_group_criterion.type = LISTING_GROUP AND " + "ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL " + $"AND ad_group.id = {adGroupId}"; // Creates a request that will retrieve all listing groups where the parent ad group // criterion is NULL (and hence the root node in the tree) for a given ad group ID. SearchGoogleAdsRequest request = new SearchGoogleAdsRequest() { CustomerId = customerId.ToString(), Query = searchQuery }; // Issues the search request. GoogleAdsRow googleAdsRow = googleAdsService.Search(request).FirstOrDefault(); if (googleAdsRow == null) { return; } AdGroupCriterion adGroupCriterion = googleAdsRow.AdGroupCriterion; Console.WriteLine("Found ad group criterion with the resource name: '{0}'.", adGroupCriterion.ResourceName); < > AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { < > Remove = adG<roupCriterion.ResourceN>ame }; < > MutateAdGr<oupCriteriaResponse re>sponse = < adGr>oupCriterionS<ervice.MutateAdGroupCriteria( > customerId.ToString(), new AdGroupCriterionOperation[] { op<eratio>n }); < Console.WriteLine($"Rem>oved {response.Results.Count}."); } /// summary < > /// Creates< a new criterion containi>ng a biddable unit listing group node. /// /summary /// param name="customerI<d">;The client c<ustomer> ID./param /// param name="adGroupId"The ID of the ad group./param </// para>m name="parentAdGroupCriterionResourceName"The resource name of the parent of /// this criterion./param /// param name="listingDimensionInfo"The ListingDimensionInfo to be set for this listing /// group./param /// param name="cpcBidMicros"The CPC bid for items in this listing group. This value /// should be specified in micros./param /// returnsThe ad group criterion object that contains the biddable unit listing group /// node./returns private AdGroupCriterion CreateListingGroupUnitBiddable(long customerId, long adGroupId, String parentAdGroupCriterionResourceName, ListingDimensionInfo listingDimensionInfo, long cpcBidMicros) { String adGroupResourceName = ResourceNames.AdGroup(customerId, adGroupId); AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { // The resource name the ad group the listing group node will be attached to unit. // Note: Listing group units do not require temporary IDs if ad group resource name // and parentAdGroupCriterionResourceName are specified. To use temporary IDs for // unit criteria, use ResourceName property. AdGroup = adGroupResourceName, Status = AdGroupCriterionStatus.Enabled, ListingGroup = new ListingGroupInfo() { // Set the type as a UNIT, which will allow the group to be biddable Type = ListingGroupType.Unit, // Set the ad group criterion resource name for the parent listing group. // This can include a criterion ID if the parent criterion is not yet created. // Use StringValue to convert from a String to a compatible argument type. < >ParentAdGroupCriterion = parentAdGroupCriterionResourceName, // Case valu<es conta>in the listin<g dimension used for th>e node. < C>aseValue = li<stingDimensionInfo > }, < > // Set th<e bid for this listing group un>it. // This will be used as the CPC bid for items that are included in this // listing group CpcBidMicros = cpcBidMicros < > }; < return adGroupCriterion; } > /// summary /// Creates a new criterion containing< a sub>division list<ing group node. /// /summ>ary /// param name="customerId"The client customer I<D./par>am //</ param> name="adGroupId"The ID of the ad group./param /// param name="adGro<upCriter>ionId"The ID of the criterion. This value will used to /// construct the resource name. This can be a negative number if the criterion is yet to /// be created./param /// param name="parentAdGroupCriterionResourceName"The resource name of the parent of /// this criterion./param /// param name="listingDimensionInfo"The ListingDimensionInfo to be set for this listing /// group./param /// returnsThe ad group criterion object that contains the subdivision listing group /// node./returns private AdGroupCriterion CreateListingGroupSubdivision(long customerId, long adGroupId, long adGroupCriterionId, String parentAdGroupCriterionResourceName, ListingDimensionInfo listingDimensionInfo) { String adGroupCriterionResourceName = ResourceNames.AdGroupCriterion( customerId, adGroupId, adGroupCriterionId); AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { // The resource name the criterion will be created with. This will define the // ID for the ad group criterion. ResourceName = adGroupCriterionResourceName, Status = AdGroupCriterionStatus.Enabled, ListingGroup = new ListingGroupInfo() { Type = ListingGroupType.Subdivision, // Se<t the a>d group criterion resource name for the parent listing group. // This can inclu<de a cri>terion ID if <the parent criterion is> not yet created. < > // U<se StringValue to conv>ert from a String to a <compat>ible argument< type. Pare>ntAdGroupCriterion = parentAdGroupCriterionResourceName, // Case values contain the listing dimension used for the node. CaseValu<e = li>stingDimensio<nInfo > } }; return adGroupCriterion; } < /// >summary /// Creates a new criterion containing a root subdivision listing group node. /// /summary /// param name="customerId"The client customer ID./param /// param name="adGroupId"The ID of the ad group./param /// param name="adGroupCriterionId"The ID of the criterion. This value will used to /// construct the resource name. This can be a negative number if the criterion is yet /// to be created./param /// returnsThe ad group criterion object that contains the listing group root node. /// /returns private AdGroupCriterion CreateListingGroupSubdivisionRoot(long customerId, long adGroupId, long adGroupCriterionId) { String adGroupCriterionResourceName = ResourceNames.AdGroupCriterion(customerId, adGroupId, adGroupCriterionId); AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { will be created with. This will define the ID // for the ad group criterion. ResourceName = adGroupCriterionResourceName, Status = AdGroupCriterionStatus.Enabled, ListingGroup = new ListingGroupInfo() { // Set the type as a SUBDIVISION, which will allow the node to be the parent of // another sub-tree. Type = ListingGroupType.Subdivision } }; return adGroupCriterion; } } } AddShoppingProductListingGroupTree.cs
PHP
<?php /** * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Ads\GoogleAds\Examples\ShoppingAds; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Lib\V25\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V25\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V25\GoogleAdsException; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Util\V25\ResourceNames; use Google\Ads\GoogleAds\V25\Common\ProductBrandInfo; use Google\Ads\GoogleAds\V25\Common\ListingDimensionInfo; use Google\Ads\GoogleAds\V25\Common\ListingGroupInfo; use Google\Ads\GoogleAds\V25\Common\ProductConditionInfo; use Google\Ads\GoogleAds\V25\Enums\AdGroupCriterionStatusEnum\AdGroupCriterionStatus; use Google\Ads\GoogleAds\V25\Enums\ListingGroupTypeEnum\ListingGroupType; use Google\Ads\GoogleAds\V25\Enums\ProductConditionEnum\ProductCondition; use Google\Ads\GoogleAds\V25\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V25\Resources\AdGroupCriterion; use Google\Ads\GoogleAds\V25\Services\AdGroupCriterionOperation; use Google\Ads\GoogleAds\V25\Services\GoogleAdsRow; use Google\Ads\GoogleAds\V25\Services\MutateAdGroupCriteriaRequest; use Google\Ads\GoogleAds\V25\Services\SearchGoogleAdsRequest; use Google\ApiCore\ApiException; /** * This example shows how to add a shopping listing group tree to a shopping ad group. The example * will optionally clear an existing listing group tree and rebuild it to include the followi<ng >tree * structure: * * pre * ProductCanonicalCondition NEW $0.20 * ProductCanonicalCondition USED $0.10 * ProductCanonicalCondition null (everything else) * ProductBrand CoolBrand $0.90 * ProductBrand CheapBrand $0.01 * ProductBrand null< (ev>erything else) $0.50 * /pre */ class AddShoppingProductListingGroupTree { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; private const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'; private const REPLACE_EXISTING_TREE = 'INSERT_BOOLEAN_TRUE_OR_FALSE_HERE'; public static function main() { // Either pass the required parameters for this example on the command line, or insert them // into the constan>ts above. $options = (new ArgumentParser())-parseCommand>Arguments([ ArgumentNames::CUSTOMER_ID = GetOpt::REQUIRE>D_ARGUMENT, ArgumentNames::AD_GROUP_ID = GetOpt::REQUIRED_ARGUMENT>, ArgumentNames::REPLACE_EXISTING_TREE = GetOpt::REQUIRED_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. > $oAuth>2Credential = (new OAuth2TokenBuilder())-fromFile()-build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. > $googleAdsClient = (ne>w GoogleAdsClientBuilder())-fromFile() -w>ithOAuth2Credential($oAuth2Credential) -build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID, $options[ArgumentNames::AD_GROUP_ID] ?: self::AD_GROUP_ID, $options[ArgumentNames::REPLACE_EXISTING_TREE] ?: self::REPLACE_EXISTING_TREE ); } catch (GoogleAdsException $googleAdsException) { printf( "Request with ID '%s' has failed.%sGoo>gle Ads failure details:%s", $googleAdsException-getRequestId(), PHP_EOL, > PHP_EOL > ); foreach ($googleAdsException-getGoogleAdsFailure()-getErrors() as $error) { /** @var GoogleAdsError $error */ > printf( > "\t%s: %s%s", > $error-getErrorCode()-getErrorCode(), $error-getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( > "ApiException was thrown with message '%s'.%s", $apiException-getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $adGroupId the ad group ID * @param bool $replaceExistingTree true if it should replace the existing listing group * tree on the ad group, if it already exists. The example will throw a * 'LISTING_GROUP_ALREADY_EXISTS' error if listing group tree already exists and this option * is not set to true */ public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId, bool $replaceExistingTree ) { // 1) Optional: Remove the existing listing group tree, if it already exists on the ad // group. if ($replaceExistingTree === 'true') { self::removeListingGroupTree($googleAdsClient, $customerId, $adGroupId); } // Create a list of ad group criteria to add. $operations = []; // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) $adGroupCriterionRoot = self::createListingGroupSubdivision($customerId, $adGroupId); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include> the temporary ID as part of the // criterion ID. $adGroupCriterionR>esourceNameRoot = $adGroupCriterionRoot-getResourceName(); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionRoot]); // 3) Construct the listing group unit nodes for NEW, USED and other. // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 $adGroupCriterionConditionNew = self::createListingGroupUnitBiddable( $customerId, $ad>GroupId, $adGroupCriterionResourceNameRoot, > new ListingDimensionInfo([ 'product_condition' = new ProductConditionInfo( ['condition' = Produc>tCondition::PBNEW] ) ]), 200000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionNew]); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 $adGroupCriterionConditionUsed = self::createListingGroupUnitBiddable( $cus>tomerId, $adGroupId, $adGroupCriterio>nResourceNameRoot, new ListingDimensionInfo([ 'product_condition' = new ProductConditionInfo( [>9;condition' = ProductCondition::USED] ) ]), 100000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionUsed]); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) $adGroupCriterionConditionOther = self::createListingGroupSubdivision( $customerId, $adGroupId, $adGroupCriterionResourceNameRoot, > new ListingDimensionInfo([ // All sibling nodes must have the same dimension type, even if they don't contain >a // bid. 'product_condition' = new ProductConditionInfo() ]) ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionConditionOther]); // Get the resource name that will be used for the condition other node. // T>his resource has not been created yet and will include the temporary ID as part of the // criterion ID. $adGroupCriterionResourceNameConditionOther = $adGroupCriterionConditionOther-getResourceName(); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other. // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 $adGroupCriterionBrandCoolBrand = self::>createListingGroupUnitBiddable( > $customerId, $adGroupId, $adGroupCriterionResourceNameConditionOther, new ListingDimension>Info([ 'product_brand' = new ProductBrandInfo(['value' = 'CoolBrand']) ]), 900000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrandCoolBrand]); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 $adGroupC>riterionBrandCheapBrand = self::>createListingGroupUnitBiddable( $customerId, $adGroupId, $adGroupCriterionResourceNameConditionOther, > new ListingDimensionInfo([ 'product_brand' = new ProductBrandInfo(['value' = 'CheapBrand']) ]), 10000 ); $operations[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrandCheapBrand]); // Biddable Unit node: (Brand other node) // * >CPC bid: $0.05 $adGroupCriterionBrandOtherBrand = self::createListingGroupUnitBiddable( $customerId, $adGroupId, > $adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo([ 'product_brand>9; = new ProductBrandInfo() ]), 50000 ); $opera>tions[] = new AdGroupCriterionOperation(['create' = $adGroupCriterionBrandOtherBrand]); // Issues a mutate request. $adGroupCriterionServiceClient = $googleAdsClient-getAdGroupCriterionServiceClient(); $response = $adGro>upCriterionSe>rviceClient-mutateAdGroupCriteria( MutateAdGroupCriteri>aRequest::build($customerId, $operations) ); printf( 'Added %d ad group criteria for listing group tree with the fo>llowing resource ' . 'names:%s', $response-getResults()-count(), PHP_EOL ); foreach ($response-getResults() as $addedAdGroupCriterion) { /** @var AdGroupCriterion $addedAdGroupCriterion */ print $addedAdGroupCriterion-getResourceName() . PHP_EOL; } } /** * Removes all the ad group criteria that define the existing listing group tree for an ad * group. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $a>dGroupId the ID of ad group that the existing listing group tree will be * removed from */ private static function removeListingGroupTree( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId ) { $googleAdsServiceClient = $googleAdsClient-getGoogleAdsServiceClient(); // Creates a query that retrieves a listing group tree. $query = 'SELECT ad_group_criterion.resource_name ' . 'F>ROM ad_group_criterion ' . 'WHERE ad_group_criterion.type = LISTING_GROUP ' . 'AND ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL ' . 'AND ad_group.id = ' . $adGroupI>d; // Issues a search request. $response = $googleAdsServiceClient-search(SearchGoogleAdsRequest::build($cust>omerId, $query)); $operations = []; // Iterates over all rows in all pages and prints the requested field values for // the listing> group tree in each row. foreach ($response-iterateAllElements() as $googleAdsRow) { /** @var GoogleAdsRow $googleAdsRow */ $adGroupCriterion = $googleAdsRow-getAdGroupCriterion(); pri>ntf( "F>ound an ad group criterion with the resource name: '%s'.%s", $adGroupCriterion-getResour>ceName(), PHP_EOL ); // Creates an ad group criterion operation. > $adGroupCriterionOperation = new AdGroupCriterionOperation(); $adGrou>pCriterionOperation-setRemove($adGroupCriterion-getResourceName()); $operations[] = $adGroupCriterionOperation; } if (count($operations) 0) { > // Issues >a mutate request. $adGroupCriterionServiceClient = $googleAdsClient-getAdGroupCriterionServiceClient(); $response = $adGroupCriterionServiceClient-mutateAdGroupCriteria( MutateAdGroupCriteriaRequest::build($customerId, $operations) ); printf("Removed %d ad group criteria.%s", $response-getResults()-count(), PHP_EOL); } } /** * Creates a new criterion containing a subdivision listing group node. If the parent ad group * criterion resource name is not specified, this method creates a root node. * * @param int $customerId the customer ID * @param int $adGroupId the ad group ID * @param string|null $parentAdGroupCriterionResourceName the resource name of the parent of * this criterion. If null, this method will create a root of the tree * @param ListingDimensionInfo|null $listingDimensionInfo the listing dimension info to be set * for this listing group. This is required for non-root subdivisions * @return AdGroupCriterion the ad group criterion that contains the listing group root node */ private static function createListingGroupSubdivision( int $customerId,> int $adGroupId, string $parentAdGroupCriterionResourceName = null, ListingDimensionInfo $listingDimensionInfo = null ) { static $tempId = 0; $listingGroupInfo = new ListingGroupInfo([ // Set the type as a SUBDI&&VISION, which will allow the node to be the parent of // another sub-tree. 'type' = ListingGroupType::SUBDIVISION ]); // If $parentAdGroupCriterionResourceName and $listingDimensionInfo are not n>ull, create // a non-root division by setting its parent and case value. if (!is_null($parentAdGroupCriterionResourceName) !is_null($listingDimensionInfo>)) { // Set the ad group criterion resource name for the parent listing group. // This can include a temporary ID if the parent criterion is not yet created. $listingGroupInfo-setParentAdGroupCriterion($parentAdGroupCriterionRes>ourceName); // Case values contain the listing dimension used for the node. $listingGroupInfo-setCaseValue($listingDimensionInfo); } $adGroupCriterion = new AdGroupCriterion([ // The resource name the criterion will be created with. This will define the ID for the // ad group >criterion. 'resource_name' = ResourceNames:>:forAdGroupCriterion( $customerId, $adGroupId, // Specify a decreasing negative number as a temporary ad group criterion ID. The // ad group criterion will get the real ID when created on the server. --$tempId ), 'status' = AdGroupCriterionStatus::ENABLED, 'listing_group' = $listingGroupInfo ]); return $adGroupCriterion; } /** * Creates a new criterion containing a biddable unit listing group node. * * @param int $customerId the customer ID * @param int $adGroupId the ad group ID * @param string $parentAdGroupCriterionResourceName the resource name of the parent of this * criterion * @param ListingDimensionInfo $listingDimensionInfo the listing dimension info to be set for * this listing group * @param int $cpcBidMicros the CPC bid for items in this listing group. This value should be * specified * @return AdGroupCriterion the ad group criterion that contains the biddable unit listing * group node */ private static function createListingGroupUnitBiddable( int $customerId, int $adGroupId, string $parentAdGroupCriterionResourceName, ListingDimensionInfo $listingDimensionInfo, int $cpcBidMicros ) { // Note: There are two approaches for creating new unit nodes: // (1) Set the ad group resource name on the criterion (no temporary ID required). // (2) Use a temporary ID >to construct the criterion resource name and set it using // setRes>ourceName. // In both cases you must set the parentAdGr>oupCriterionResourceName on the listing // group for non-root nodes. // This example demonstrates method (1). >$adGroupCriterion = new AdGroupCriterion([ // The ad group the listing group will be attached to. 'ad_group' = ResourceNames::forAdGroup($customerId, $adGroupId), 'status' = AdGroupCriterionStatus::ENABL>ED, 'listing_group' = new ListingGroupInfo([ // Set the type as a UNIT, which will allow the group to be biddabl>e. 'type' = ListingGroupType::UNIT, // Set the ad group criterion resource name for the parent listing group. // This can include a temporary ID if the parent criterion> is not yet created. 'parent_ad_group_criterion' = $parentAdGroupCriterionResourceName, e listing dimension used for the node. 'case_value' = $listingDimensionInfo ]), // Set the bid for this listing group unit. // This will be used as the CPC bid for items that are included in this listing group. 'cpc_bid_micros' = $cpcBidMicros ]); return $adGroupCriterion; } } AddShoppingProductListingGroupTree::main(); AddShoppingProductListingGroupTree.php
Python
#!/usr/bin/env python # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Adds a shopping listing group tree to a shopping ad group. The example will clear an existing listing group tree and rebuild it include the following tree structure: ProductCanonicalCondition NEW $0.20 ProductCanonicalCondition USED $0.10 ProductCanonicalCondition null (everything else) ProductBrand CoolBrand $0.90 ProductBrand CheapBrand $0.01 ProductBrand null (everything else) $0.50 """ import argparse import sys from typing import List, Optional from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v24.common.types.criteria import ( ListingDimensionInfo, ListingGroupInfo, ) from google.ads.googleads.v24.enums.types.product_condition import ( ProductConditionEnum, ) from google.ads.googleads.v24.resources.types.ad_group_criterion import ( AdGroupCriterion, ) from google.ads.googleads.v24.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) from google.ads.googleads.v24.services.services.ad_group_service import ( AdGroupServiceClient, ) from google.ads.googleads.v24.services.services.google_ads_service import ( GoogleAdsServiceClient, ) from google.ads.googleads.v24.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, ) from google.ads.googleads.v24.services.types.google_ads_service import ( MutateGoogleAdsResponse, SearchGoogleAdsRespons>e, ) last_criterion_id: int = 0 def next_id() - str: """Returns a decreasing negative number for temporary ad group criteria IDs. The ad group criteria will get real IDs when created on the server. Returns -1, -2, -3, etc. on subsequent calls. Returns: The string representation of a negative integer. """ global last_criterion_id last_criterion_id -= 1 return str(last_criterion_id) def main( client: GoogleAdsClient, > customer_id: str, ad_group_id: str, replace_existing_tree: bool, ) - None: """Adds a shopping listing group tree to a shopping ad group. Args: client: An initialized Google Ads client. customer_id: The Google Ads customer ID. ad_group_id: The ad group ID to which the node will be added. replace_existing_tree: Boolean, whether to replace the existing listing group tree on the ad group. Defaults to false. """ # Get the AdGroupCriterionService client. ad_group_criterion_service: AdGroupCriterionServiceClient = ( client.get_service("AdGroupCriterionService") ) # Optional: Remove the existing listing group tree, if it already exists # on the ad group. The example will throw a LISTING_GROUP_ALREADY_EXISTS # error if a listing group tree already exists and this option is not # set to true. if replace_existing_tree: remove_listing_group_tree(client, customer_id, ad_group_id) # Create a list of ad group criteria operations. operations: List[AdGroupCriterionOperation] = [] # Construct the listing group tree "root" node. # Subdivision node: (Root node) ad_group_criterion_root_operation: AdGroupCriterionOperation = ( create_listing_group_subdivision(client, customer_id, ad_group_id) ) # Get the resource name that will be used for the root node. # This resource has not been created yet and will include the temporary # ID as part of the criterion ID. ad_group_criterion_root_resource_name: str = ( ad_group_criterion_root_operation.create.resource_name ) operations.append(ad_group_criterion_root_operation) # Construct the listing group unit nodes for NEW, USED, and other. product_condition_enum: ProductConditionEnum = ( client.enums.ProductConditionEnum ) condition_dimension_info: ListingDimensionInfo = client.get_type( "ListingDimensionInfo" ) # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 condition_dimension_info.product_condition.condition = ( product_condition_enum.NEW ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, 200_000, ) ) # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 condition_dimension_info.product_condition.condition = ( product_condition_enum.USED ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, 100_000, ) ) # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) # Note that all sibling nodes must have the same dimension type, even if # they don't contain a bid. client.copy_from( condition_dimension_info.product_condition, client.get_type("ProductConditionInfo"), ) ad_group_criterion_other_operation: AdGroupCriterionOperation = ( create_listing_group_subdivision( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, condition_dimension_info, ) ) # Get the resource name that will be used for the condition other node. # This resource has not been created yet and will include the temporary # ID as part of the criterion ID. ad_group_criterion_other_resource_name: str = ( ad_group_criterion_other_operation.create.resource_name ) operations.append(ad_group_criterion_other_operation) # Build the listing group nodes for CoolBrand, CheapBrand, and other. brand_dimension_info: ListingDimensionInfo = client.get_type( "ListingDimensionInfo" ) # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 brand_dimension_info.product_brand.value = "CoolBrand" operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 900_000, ) ) # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 brand_dimension_info.product_brand.value = "CheapBrand" operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 10_000, ) ) # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 client.copy_from( brand_dimension_info.product_brand, client.get_type("ProductBrandInfo"), ) operations.append( create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_other_resource_name, brand_dimension_info, 50_000, ) ) # Add the ad group criteria. mutate_ad_group_criteria_response: MutateGoogleAdsResponse = ( ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=operations ) ) # Print the results of the successful mutates. print( "Added ad group criteria for the listing group tree with the " "following resource names:" ) for result in mutate_ad_group_criteria_response.results: >print(f"\t{result.resource_name}") print(f"{len(mutate_ad_group_criteria_response.results)} criteria added.") def remove_listing_group_tree( client: GoogleAdsClient, customer_id: str, ad_group_id: str, ) - None: """Removes ad group criteria for an ad group's existing listing group tree. Args: client: An initialized Google Ads client. customer_id: The Google Ads customer ID. ad_group_id: The ad group ID from which to remove the listing group tree. """ # Get the GoogleAdsService client. googleads_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService" ) print("Removing existing listing group tree...") # Create a search Google Ads request that will retrieve all listing groups # where the parent ad group criterion is NULL (and hence the root node in # the tree) for a given ad group id. # Note: ad_group_id is used as an int in the query. query: str = f""" SELECT ad_group_criterion.resource_name FROM ad_group_criterion WHERE ad_group_criterion.type = LISTING_GROUP AND ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL AND ad_group.id = {ad_group_id}""" results: SearchGoogleAdsResponse = googleads_service.search( customer_id=customer_id, query=query ) ad_group_criterion_operations: List[AdGroupCriterionOperation] = [] # Iterate over all rows to find the ad group criteria to remove. for row in results: criterion: AdGroupCriterion = row.ad_group_criterion print( "Found an ad group criterion with resource name: " f"'{criterion.resource_name}'." ) ad_group_criterion_operation: AdGroupCriterionOperation = ( client.get_type("AdGroupCriterionOperation") ) ad_group_criterion_operation.remove = criterion.resource_name ad_group_criterion_operations.append(ad_group_criterion_operation) if ad_group_criterion_operations: # Remove the ad group criteria that define the listing group tree. ad_group_criterion_service: AdGroupCriterionServiceClient = ( client.get_service("AdGroupCriterionService") ) response: MutateGoogleAdsResponse = ( ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operation>s=ad_group_criterion_operations, ) ) print(f"Removed {len(response.results)} ad group criteria.") def create_listing_group_subdivision( client: GoogleAdsClient, customer_id: str, ad_group_id: str, parent_ad_group_criterion_resource_name: Optional[str] = None, listing_dimension_info: Optional[ListingDimensionInfo] = None, ) - AdGroupCriterionOperation: """Creates a new criterion containing a subdivision listing group node. If the parent ad group criterion resource name or listing dimension info are not specified, this method creates a root node. Args: client: An initialized Google Ads client. customer_id: The Google Ads customer ID. ad_group_id: The ad group ID to which the node will be added. parent_ad_group_criterion_resource_name: The string resource name of the parent node to which this listing will be attached. listing_dimension_info: A ListingDimensionInfo object containing details for this listing. Returns: An AdGroupCriterionOperation containing a populated ad group criterion. """ # Create an ad group criterion operation and populate the criterion. operation: AdGroupCriterionOperation = client.get_type( "AdGroupCriterionOperation" ) ad_group_criterion: AdGroupCriterion = operation.create ad_group_criterion_service: AdGroupCriterionServiceClient = ( client.get_service("AdGroupCriterionService") ) # The resource name the criterion will be created with. This will define # the ID for the ad group criterion. ad_group_criterion.resource_name = ( ad_group_criterion_service.ad_group_criterion_path( customer_id, ad_group_id, next_id() ) ) ad_group_criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED listing_group_info: ListingGroupInfo = ad_group_criterion.listing_group # Set the type as a SUBDIVISION, which will allow the node to be the # parent of another sub-tree. listing_group_info.type_ = client.enums.ListingGroupTypeEnum.SUBDIVISION # If parent_ad_group_criterion_resource_name and listing_dimension_info # are not null, create a non-root division by setting its parent and case # value. if ( parent_ad_group_criterion_resource_name and listing_dimension_info is not None ): # Set the ad group criterion resource name for the parent listing group. # This can include a temporary ID if the parent criterion is not yet # created. listing_group_info.parent_ad_group_criterion = ( parent_ad_group_criterion_resource_name >) # Case values contain the listing dimension used for the node. client.copy_from(listing_group_info.case_value, listing_dimension_info) return operation def create_listing_group_unit_biddable( client: GoogleAdsClient, customer_id: str, ad_group_id: str, parent_ad_group_criterion_resource_name: str, listing_dimension_info: ListingDimensionInfo, cpc_bid_micros: Optional[int] = None, ) - AdGroupCriterionOperation: """Creates a new criterion containing a biddable unit listing group node. Args: client: An initialized Google Ads client. customer_id: The Google Ads customer ID. ad_group_id: The ad group ID to which the node will be added. parent_ad_group_criterion_resource_name: The string resource name of the parent node to which this listing will be attached. listing_dimension_info: A ListingDimensionInfo object containing details for this listing. cpc_bid_micros: The cost-per-click bid for this listing in micros. Returns: An AdGroupCriterionOperation with a populated create field. """ # Note: There are two approaches for creating new unit nodes: # (1) Set the ad group resource name on the criterion (no temporary ID # required). # (2) Use a temporary ID to construct the criterion resource name and set # it to the 'resourceName' attribute. # In both cases you must set the parent ad group criterion's resource name # on the listing group for non-root nodes. # This example demonstrates method (1). operation: AdGroupCriterionOperation = client.get_type( "AdGroupCriterionOperation" ) criterion: AdGroupCriterion = operation.create ad_group_service: AdGroupServiceClient = client.get_service( "AdGroupService" ) criterion.ad_group = ad_group_service.ad_group_path( customer_id, ad_group_id ) criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED # Set the bid for this listing group unit. # This will be used as the CPC bid for items that are included in this # listing group. if cpc_bid_micros: criterion.cpc_bid_micros = cpc_bid_micros listing_group: ListingGroupInfo = criterion.listing_group # Set the type as a UNIT, which will allow the group to be biddable. listing_group.type_ = client.enums.ListingGroupTypeEnum.UNIT # Set the ad group criterion resource name for the parent listing group. # This can have a temporary ID if the parent criterion is not yet created. listing_group.parent_ad_group_criterion = ( parent_ad_group_criterion_resource_name ) # Case values contain the listing dimension used for the node. if listing_dimension_info is not None: client.copy_from(listing_group.case_value, listing_dimension_info) return operation if __name__ == "__main__": parser = argparse.ArgumentParser( description="Add shopping product listing group tree to a shopping ad " "group." ) # The following argument(s) should be provided to run the example. parser.add_argument( "-c", "--customer_id", type=str, required=True, help="The Google Ads customer ID.", ) parser.add_argument( "-a", "--ad_group_id", type=str, required=True, help="The ID of the ad group that will receive the listing group tree.", ) parser.add_argument( "-r", "--replace_existing_tree", action="store_true", required=False, default=False, help="Optional, whether to replace the existing listing group tree on " "the ad group if one already exists. Defaults to false.", ) args: argparse.Namespace = parser.parse_args() # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( version="v24" ) try: main( customer_id, args.ad_group_id, args.replace_existing_tree, ) except GoogleAdsException as ex: print( f"Request with ID '{ex.request_id}' failed with status " f"'{ex.error.code().name}' and includes the following errors:" ) for error in ex.failure.errors: print(f"\tError with message '{error.message}'.") if error.location: for field_path_element in error.location.field_path_elements: print(f"\t\tOn field: {field_path_element.field_name}") sys.exit(1) add_shopping_product_listing_group_tree.py
Ruby
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example shows how to add a shopping listing group tree to a shopping ad # group. The example will optionally clear an existing listing group tree and # rebuild it to include the following tree structure: # # ProductCanonicalCondition NEW $0.20 # ProductCanonicalCondition USED $0.10 # ProductCanonicalCondition null (everything else) # ProductBrand CoolBrand $0.90 # ProductBrand CheapBrand $0.01 # ProductBrand null (everything else) $0.50 require 'optparse' require 'google/ads/google_ads' require 'date' def add_shopping_product_listing_group_tree( customer_id, ad_group_id, should_replace_existing_tree ) # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google::Ads::GoogleAds::GoogleAdsClient.new # 1) Optional: Remove the existing listing group tree, if it already exists # on the ad group. if should_replace_existing_tree remove_listing_group_tree(client, customer_id, ad_group_id) end # 2) Construct the listing group tree "root" node. # Subdivision node: (Root node) ad_group_criterion_root = create_listing_group_subdivision( client, customer_id, ad_group_id, ) # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. ad_group_criterion_root_resource_name = ad_group_criterion_root.resource_name operations = [client.operation.create_resource.ad_group_criterion(ad_group_criterion_root)] # 3) Construct the listing group unit nodes for NEW, USED, and other. # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info do |pci| pci.condition = :NEW end end ad_group_criterion_condition_new = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, 200_000, ) operation = client.operation.create_resource.ad_group_cri<<terion( ad_group_criterion_condition_new ) operations operation # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info do |pci| pci.condition = :USED end end ad_group_criterion_condition_used = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, 100_000, ) operation = client.operation.create_resource.ad_group_crit<<erion( ad_group_criterion_condition_used ) operations operation # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_condition = client.resource.product_condition_info end ad_group_criterion_condition_other = create_listing_group_subdivision( client, customer_id, ad_group_id, ad_group_criterion_root_resource_name, listing_dimension_info, ) operation = client.operation.create_resource.ad_g<<roup_criterion( ad_group_criterion_condition_other ) operations operation ad_group_criterion_condition_other_resource_name = ad_group_criterion_condition_other.resource_name # 4) Construct the listing group unit nodes for CoolBrand, CheapBrand, and # other. # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info do |pbi| pbi.value = "CoolBrand" end end ad_group_criterion_brand_cool_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 900_000, ) operation = client.operation.create_reso<<urce.ad_group_criterion( ad_group_criterion_brand_cool_brand ) operations operation # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info do |pbi| pbi.value = "CheapBrand" end end ad_group_criterion_brand_cheap_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 10_000, ) operation = client.operation.cr<<eate_resource.ad_group_criterion( ad_group_criterion_brand_cheap_brand ) operations operation # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 listing_dimension_info = client.resource.listing_dimension_info do |ldi| ldi.product_brand = client.resource.product_brand_info end ad_group_criterion_brand_other_brand = create_listing_group_unit_biddable( client, customer_id, ad_group_id, ad_group_criterion_condition_other_resource_name, listing_dimension_info, 50_000, ) operation = client.operation.cr<<eate_resource.ad_group_criterion( ad_group_criterion_brand_other_brand ) operations operation # Issue the mutate request. response = client.service.ad_group_criterion.mutate_ad_group_criteria( customer_id: customer_id, operations: operations, ) total_count = 0 response.results.each do |added_criterion| puts "Added ad group criterion with name: #{added_criterion.resource_name}" total_count += 1 end puts "#{total_count} criteria added in total." end def <<remove_listing_group_tree(client, customer_id, ad_group_id) ga_service = client.service.google_ads query = ~QUERY SELECT ad_group_criterion.resource_name FROM ad_group_criterion WHERE ad_group_criterion.type = LISTING_GROUP AND ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL AND ad_group.id = #{ad_group_id} QUERY response = ga_service.search(customer_id: customer_id, query: query) operations = response.map do |row| criterion = row.ad_group_criterion puts "Found an ad group criterion with resource name: #{criterion.resource_name}" client.operation.remove_resource.ad_group_criterion(criterion.resource_name) end if operations.any? response = client.service.ad_group_criterion.mutate_ad_group_criteria( customer_id: customer_id, operations: operations, ) puts "Removed #{response.results.count} ad group criteria." end end # Specify a decreasing negative number for temporary ad group criteria IDs. The # ad group criteria will get real IDs when created on the server. # Returns -1, -2, -3, etc. on subsequent calls. def next_id @id ||= 0 @id -= 1 end def create_listing_group_subdivision( client, customer_id, ad_group_id, parent_ad_group_criterion_name = nil, listing_dimension_info = nil ) client.resource.ad_group_criterion do |criterion| criterion.resource_name = client.path.ad_group_criterion( customer_id, ad_group_id, next_id, ) criterion.status = :ENABLED criterion.listing_group = client.resour&&ce.listing_group_info do |listing_group_info| listing_group_info.type = :SUBDIVISION if parent_ad_group_criterion_name listing_dimension_info listing_group_info.parent_ad_group_criterion = parent_ad_group_criterion_name listing_group_info.case_value = listing_dimension_info end end end end def create_listing_group_unit_biddable(client, customer_id, ad_group_id, parent_ad_group_criterion_name, listing_dimension_info, cpc_bid_micros) # Note: There are two approaches for creating new unit nodes: # (1) Set the ad group resource name on the criterion (no temporary ID # required). # (2) Use a temporary ID to construct the criterion resource name and set it # using the client.path utility. # In both cases you must set the parent ad group criterion's resource name on # the listing group for non-root nodes. # This example demonstrates method (1). client.resource.ad_group_criterion do |criterion| criterion.ad_group = client.path.ad_group(customer_id, ad_group_id) criterion.status = :ENABLED criterion.cpc_bid_micros = cpc_bid_micros criterion.listing_group = client.resource.listing_group_info do |listing_group| # The type UNIT allows the group to be biddable. listing_group.type = :UNIT listing_group.parent_ad_group_criterion = parent_ad_group_criterion_name listing_group.case_value = listing_dimension_info end end end if __FILE__ == $0 options = {} # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE' options[:ad_group_id] = 'INSERT_AD_GROUP_ID_HERE' # Specifying any value for this field on the command line will override this # to true. options[:should_replace_existing_tree] = false OptionParser.new do |opts| opts.banner = sprintf("Usage: #{File.basename(__FILE__)} [options]") opts.separator '' opts.separator 'Options:' opts.on('-C', '--customer-id CUSTOMER-ID', String, 'Customer ID') do |v| options[:customer_id] = v end opts.on('-A', '--ad-group-id AD-GROUP-ID', String, 'Ad Group ID') do |v| options[:ad_group_id] = v end opts.on('-r', '--replace-existing-tree REPLACE-EXISTING-TREE', TrueClass, 'Create Default Listing Group') do |v| options[:should_replace_existing_tree] = v end opts.separator '' opts.separator 'Help:' opts.on_tail('-h', '--help', 'Show this message') do put>s opts exit end end.parse! begin add_shopping_product_listing_group_tree( options.fetch(:customer_id).tr("-", ""), options.fetch(:ad_group_id), options.fetch(:should_replace_existing_tree), ) rescue Google::Ads::GoogleAds::Errors::GoogleAdsError = e e.failure.errors.each do |error| STDERR.printf("Error with message: %s\n", error.message) if error.location error.locati_element| STDERR.printf("\tOn field: %s\n", field_path_element.field_name) end end error.error_code.to_h.each do |k, v| next if v == :UNSPECIFIED STDERR.printf("\tType: %s\n\tCode: %s\n", k, v) end end raise end end add_shopping_product_listing_group_tree.rb
Perl
#!/usr/bin/perl -w # # Copyright 2019, Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example shows how to add a shopping listing group tree to a shopping ad # group. The example will optionally clear an existing listing group tree and # rebuild it to include the following tree structure: # # ProductCanonicalCondition NEW $0.20 # ProductCanonicalCondition USED $0.10 # ProductCanonicalCondition null (everything else) # ProductBrand CoolBrand $0.90 # ProductBrand CheapBrand $0.01 # ProductBrand null (everything else) $0.50 use strict; use warnings; use utf8; use FindBin qw($Bin); use lib "$Bin/../../lib"; use Google::Ads::GoogleAds::Client; use Google::Ads::GoogleAds::Utils::GoogleAdsHelper; use Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator; use Google::Ads::GoogleAds::V25::Resources::AdGroupCriterion; use Google::Ads::GoogleAds::V25::Common::ListingGroupInfo; use Google::Ads::GoogleAds::V25::Common::ListingDimensionInfo; use Google::Ads::GoogleAds::V25::Common::ProductConditionInfo; use Google::Ads::GoogleAds::V25::Common::ProductBrandInfo; use Google::Ads::GoogleAds::V25::Enums::ListingGroupTypeEnum qw(SUBDIVISION UNIT); use Google::Ads::GoogleAds::V25::Enums::AdGroupCriterionStatusEnum qw(ENABLED); use Google::Ads::GoogleAds::V25::Enums::ProductConditionEnum qw(NEW USED); use Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroupCriterionOperation; use Google::Ads::GoogleAds::V25::Services::GoogleAdsService::SearchGoogleAdsRequest; use Google::Ads::GoogleAds::V25::Utils::ResourceNames; use Getopt::Long qw(:config auto_help); use Pod::Usage; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. my $customer_id = "INSERT_CUSTOMER_ID_HERE"; my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; my $replace_existing_tree = undef; sub add_shopping_product_listing_group_tree { my ($api_client, $customer_id, $ad_group_id, $replace_existing_tree) = @_; # 1) Optional: Remove the existing listing group tree, if it already exists # on the ad group. if ($replace_existing_tree) { remove_listing_group_tree($api_client, $customer_id, $ad_group_id); } # Create a list of ad group criteria operations to add. my $operations = []; # 2) Construct the listing group tree "root" node. # Subdivision node: (Root node) my $ad_group_criterion_root = create_listing_group_subdivision($customer_id, $ad_group_id); # Get the resource name that will be used for the root node. # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. my $ad_group_>criterion_root_resource_name = $ad_group_criterion_root-{resourceName}; push @$operations, Google::Ads::GoogleAds::V25::Servic>es::AdGroupCriterion>Service::AdGroupCriterionOperation -new({ create = $ad_group_criterion_root }); # 3) Construct the listing group unit nodes for NEW, USED, and other. # Biddable Unit node: (Condition NEW node) # * Product Condition: NEW # * CPC bid: $0.20 my $ad_group_criterion_condition_new = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_root_resource_name, > Google::Ads::GoogleAds::V25::C>ommon::ListingDimensionInfo-new({ productCondition = > Google::Ads::GoogleAds::V25>::Common::ProductConditionInfo-new({ condition = NEW })} ), 200000 ); push @$operations, Google::Ads::GoogleAds::V25::Servic>es::AdGroupCriterion>Service::AdGroupCriterionOperation -new({ create = $ad_group_criterion_condition_new }); # Biddable Unit node: (Condition USED node) # * Product Condition: USED # * CPC bid: $0.10 my $ad_group_criterion_condition_used = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_root_resource_name, > Google::Ads::GoogleAds::V25::C>ommon::ListingDimensionInfo-new({ productCondition = > Google::Ads::GoogleAds::V25>::Common::ProductConditionInfo-new({ condition = USED })} ), 100000 ); push @$operations, Google::Ads::GoogleAds::V25::Servic>es::AdGroupCriterion>Service::AdGroupCriterionOperation -new({ create = $ad_group_criterion_condition_used }); # Sub-division node: (Condition "other" node) # * Product Condition: (not specified) my $ad_group_criterion_condition_other = create_listing_group_subdivision( $customer_id, $ad_group_id, $ad_group_criterion_root_resourc>e_name, Google::Ads::GoogleAds::V25::Common::ListingDimensionInfo-new({ # All sibling nodes must have the same dimension type, >even if they # don't contain a bid. productCondit>ion = Google::Ads::GoogleAds::V25::Common::ProductConditionInfo-new()})); push @$operations, Google::Ads::GoogleAd>s::V25::Services::Ad>GroupCriterionService::AdGroupCriterionOperation -new({ create = $ad_group_criterion_condition_other }); # Get the resource name that will be used for the condition other node. # This resource has not been created yet and will include the temporary ID as # part of the criterion ID. my $ad_group_criterio>n_condition_other_resource_name = $ad_group_criterion_condition_other-{resourceName}; # 4) Construct the listing group unit nodes for CoolBrand, CheapBrand, and # other. # Biddable Unit node: (Brand CoolBrand node) # * Brand: CoolBrand # * CPC bid: $0.90 my $ad_group_criterion_brand_cool_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_condition_other_res>ource_name, Google::Ads:>:GoogleAds::V25::Common::ListingDimensionInfo-new({ produ>ctBrand = Goo>gle::Ads::GoogleAds::V25::Common::ProductBrandInfo-new( {value = "CoolBrand"})} ), 900000 ); push @$operations, Google::Ads>::GoogleAds::V25::Se>rvices::AdGroupCriterionService::AdGroupCriterionOperation -new({ create = $ad_group_criterion_brand_cool_brand }); # Biddable Unit node: (Brand CheapBrand node) # * Brand: CheapBrand # * CPC bid: $0.01 my $ad_group_criterion_brand_cheap_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion_condition>_other_resource_name, Go>ogle::Ads::GoogleAds::V25::Common::ListingDimensionInfo-new({ > productBrand = > Google::Ads::GoogleAds::V25::Common::ProductBrandInfo-new( {value = "CheapBrand"})} ), 10000 ); push @$operations, G>oogle::Ads::GoogleAd>s::V25::Services::AdGroupCriterionService::AdGroupCriterionOperation -new({ create = $ad_group_criterion_brand_cheap_brand }); # Biddable Unit node: (Brand other node) # * CPC bid: $0.05 my $ad_group_criterion_brand_other_brand = create_listing_group_unit_biddable( $customer_id, $ad_group_id, $ad_group_criterion>_condition_other_resource_na>me, Google::Ads::GoogleAds::V25::Common::ListingDimensionInfo>-new({ productBrand = Google::Ads::GoogleAds::V25::Common::ProductBrandInfo-new()} ), 50000 ); push @$operations, G>oogle::Ads::GoogleAd>s::V25::Services::AdGroupCriterionService::AdGroupCriterionOperation -new({ create = $ad_group_criterion_brand_other_bran>d }); # Add the ad >group criterion. my $ad_g>roup_criteria_response = $api>_client-AdGroupCriterionService()-mutate({ customerId = $customer_id, operations = $operations }); printf "Added %d ad group criteria for listing g>roup tree with the " . "following resource names:\n>", scalar @{$ad_group_c>riteria_response-{results}}; foreach my $result (@{$ad_group_criteria_response-{results}}) { print $result-{resourceName}, "\n"; } return 1; } # Removes all the ad group criteria that define the existing listing group # tree for an ad group. sub remove_listing_group_tree { my ($api_client, $customer_id, $ad_group_id) = @_; my $search_query = "SELECT ad_group_criterion.resource_name " . "FROM ad_group_criterion WHERE ad_group_criterion.type = LISTING_GROUP " . "AND ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL " . "AND ad_group.id = $ad_group_id"; # Create a search Google Ads request that will retrieve all listing groups # where the parent ad group criterion is NULL (and hence the >root node in # the tre>e) for a given ad group id. my >$search_request = Google::Ads::GoogleAds::V25::Services::GoogleAdsService::SearchGoogleAd>sRequest -new({ customerId = $customer_id, query = $search_query });> # Get the Googl>eAdsService. my $google_ads_servi>ce = $api_client-GoogleAdsService(); my $iterator = Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator-new({ service = $google_ads_servi>ce, request = $search_request }); my $oper>ations = []; # Iterate over all rows in all pages> to find the ad group criterion to remove. while ($iterator-has_next) { my $google_ads_row = $iterator-next; > my $ad_group_criterion = $google_ads_row-{adGroupCriterion}; printf "Found an ad group criterion with the resource name: '%s'.\n", $ad_group_criterion-{resourceName}; # >Create an ad group cri>terion operation. > my $ad_group_criterion_operation = Google::Ads::GoogleAds::V25::Services::AdGroupCriterionService::AdGroupCriterionOperation -new({ remove = $ad_group_criterion-{resourceName}}); push @$operations, $ad_group_>criterion_operation; } > if (scalar @$operations) { > # Remove the ad group criterion> that define the listing group tree. my $ad_group_criteria_response = $api_client-AdGroupCriterionServi>ce()-mutate({ customerId = $customer_id, operations = $operations }); printf "Removed %d ad group criteria.\n", scalar @{$ad_group_criteria_response-{results}}; } } # Creates a new criterion containing a subdivision listing group node. If # the parent ad group criterion resource name is not specified, this method # creates a root node. sub create_listing_group_subdivision { my ($cu>stomer_id, $ad_group_id, $parent_ad_group_criterion_resource_name, $listing_dimension_info) = @_; my $listing_group_info> = Google::Ads::GoogleAds::V25::Common::ListingGroupInfo-new({ # Set the type as a SUBDIVISION, which will allow the node to be the # parent of another sub-tree. 'type' = SUBDIVISION }); # If $parent_ad_group_criterion_resource_name and $listing_dimension_info # are not null, create a non-root division by setting its parent and case value. if ($parent_ad_group_criterion_resource_name and $listing_d>imension_info) { # Set the ad group criterion resource name for the parent listing group. # This can include a temporary ID if the parent criterion is not yet >created. $listing_group_info-{parentAdGroupCriterion} = $parent_ad_group_criterion_resource_name; # Case values conta>in the listing dimension used for the node. $listing_group_info-{caseValue} = $listing_dimension_info; } my $ad_group_criterion = Googl>e::Ads::GoogleAds::V25::Resources::AdGroupCriterion-new({ # The resource name the criterion will be created with. This will define # the ID for t>he ad group criterion. r>esourceName = Google::Ads::GoogleAds::V25::Utils::ResourceNames::ad_group_criterion( $customer_id, $ad_group_id, next_id() ), status = ENABLED, listingGroup = $listing_group_info }); return $ad_group_criterion; } # Creates a new criterion containing a biddable unit listing group node. sub create_listing_group_unit_biddable { my ($customer_id, $ad_group_id, $parent_ad_group_criterion_resource_name, $listing_dimension_info, $cpc_bid_micros) = @_; # Note: There are two approaches for creating new unit nodes: # (1) Set the ad group resource name on the criterion (no temporary ID # required). # (2) Use a temporary ID to construct the criterion resource name and set it # to the 'resourceName' attribute. # In both cases you must set the parent ad> group criterion'>s resource name on # the listing group for non-root nodes. # This example demonstrates method (1). my $ad_group_criterio>n = Google::Ads::GoogleAds>::V25::Resources::AdGroupCriterion-new({ adGroup = Google>::Ads::GoogleAds::V25::Utils::ResourceNames::ad_group( $customer_id, $ad_group_id ), > status = ENABLED, listingGroup = Google::Ads::GoogleAds::V25::Common::ListingGroupInfo-new({ # Set the type as a UNIT, which will allow the group to be biddable. type => UNIT, # Set the ad group criterion resource name for the parent listing group. # This can include a temporary ID if >the parent criterion is not yet created. parentAdGroupCriterion = $parent_ad_group_criterion_resource_name, # Case values contain the listing dimension used for the node. caseValue = $l>isting_dimension_info } ), # Set the bid for this listing group unit. # This will be used as the CPC bid for items that are included in this # listing group. cpcBidMicros = $cpc_bid_micros }); return $ad_group_criterion; } # Specifies a decreasing negative number for temporary ad group criteria IDs. # The ad group criteria will get real IDs when created on the server. # Returns -1, -2, -3, etc. on subsequent calls. sub next_id { our $id ||= 0; $id -= 1; } # Don't run the example> if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; }> # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds::Client-new(); # By defa>ult examples are set to die on any server ret>urned fault. $api_client-set_die_on_faults(1)>; # Parameters passed on the command line will override any parameters set in code. GetOptions( "customer_id=s" = \$customer_id, "ad_group_id=i" = \$ad_group_id, "replace_existing_tree=s" = \$replace_existing_tree ); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage(2) if not check_params($customer_id, $ad_group_id); # Call the example. add_shopping_product_listing_group_tree($api_client, $customer_id =~ s/-//gr, $ad_group_id, $replace_existing_tree); =pod =head1 NAME add_shopping_product_listing_group_tree =head1 DESCRIPTION This example shows how to add a shopping listing group tree to a shopping ad group. The example will optionally clear an existing listing group tree and rebuild it to include the following tree structure: ProductCanonicalCondition NEW $0.20 ProductCanonicalCondition USED $0.10 ProductCanonicalCondition null (everything else) ProductBrand CoolBrand $0.90 ProductBrand CheapBrand $0.01 ProductBrand null (everything else) $0.50 =head1 SYNOPSIS add_shopping_product_listing_group_tree.pl [options] -help Show the help message. -customer_id The The ad group ID. -replace_existing_tree [optional] Replace the existing listing group tree on the ad group, if it already exists. =cut add_shopping_product_listing_group_tree.pl