Add Shopping Product Ad

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 static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime;

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.v16.common.ListingGroupInfo;
import com.google.ads.googleads.v16.common.ManualCpc;
import com.google.ads.googleads.v16.common.ShoppingProductAdInfo;
import com.google.ads.googleads.v16.enums.AdGroupAdStatusEnum.AdGroupAdStatus;
import com.google.ads.googleads.v16.enums.AdGroupCriterionStatusEnum.AdGroupCriterionStatus;
import com.google.ads.googleads.v16.enums.AdGroupStatusEnum.AdGroupStatus;
import com.google.ads.googleads.v16.enums.AdGroupTypeEnum.AdGroupType;
import com.google.ads.googleads.v16.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType;
import com.google.ads.googleads.v16.enums.BudgetDeliveryMethodEnum.BudgetDeliveryMethod;
import com.google.ads.googleads.v16.enums.CampaignStatusEnum.CampaignStatus;
import com.google.ads.googleads.v16.enums.ListingGroupTypeEnum.ListingGroupType;
import com.google.ads.googleads.v16.errors.GoogleAdsError;
import com.google.ads.googleads.v16.errors.GoogleAdsException;
import com.google.ads.googleads.v16.resources.Ad;
import com.google.ads.googleads.v16.resources.AdGroup;
import com.google.ads.googleads.v16.resources.AdGroupAd;
import com.google.ads.googleads.v16.resources.AdGroupCriterion;
import com.google.ads.googleads.v16.resources.Campaign;
import com.google.ads.googleads.v16.resources.Campaign.ShoppingSetting;
import com.google.ads.googleads.v16.resources.CampaignBudget;
import com.google.ads.googleads.v16.services.AdGroupAdOperation;
import com.google.ads.googleads.v16.services.AdGroupAdServiceClient;
import com.google.ads.googleads.v16.services.AdGroupCriterionOperation;
import com.google.ads.googleads.v16.services.AdGroupCriterionServiceClient;
import com.google.ads.googleads.v16.services.AdGroupOperation;
import com.google.ads.googleads.v16.services.AdGroupServiceClient;
import com.google.ads.googleads.v16.services.CampaignBudgetOperation;
import com.google.ads.googleads.v16.services.CampaignBudgetServiceClient;
import com.google.ads.googleads.v16.services.CampaignOperation;
import com.google.ads.googleads.v16.services.CampaignServiceClient;
import com.google.ads.googleads.v16.services.MutateAdGroupAdResult;
import com.google.ads.googleads.v16.services.MutateAdGroupCriterionResult;
import com.google.ads.googleads.v16.services.MutateAdGroupResult;
import com.google.ads.googleads.v16.services.MutateCampaignBudgetsResponse;
import com.google.ads.googleads.v16.services.MutateCampaignResult;
import com.google.ads.googleads.v16.services.MutateCampaignsResponse;
import com.google.common.collect.ImmutableList;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;

/**
 * Creates a standard shopping campaign, a shopping product ad group and a shopping product ad.
 *
 * <p>Prerequisite: You need to have access to a Merchant Center account. You can find instructions
 * to create a Merchant Center account here: https://support.google.com/merchants/answer/188924.
 * This account must be linked to your Google Ads account.
 */
public class AddShoppingProductAd {

  private static class AddShoppingProductAdParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
    private Long customerId;

    @Parameter(names = ArgumentNames.MERCHANT_CENTER_ACCOUNT_ID, required = true)
    private Long merchantCenterAccountId;

    @Parameter(names = ArgumentNames.CREATE_DEFAULT_LISTING_GROUP, required = true, arity = 1)
    private Boolean createDefaultListingGroup;
  }

  public static void main(String[] args) {
    AddShoppingProductAdParams params = new AddShoppingProductAdParams();
    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.merchantCenterAccountId = Long.parseLong("INSERT_MERCHANT_CENTER_ACCOUNT_ID_HERE");
      params.createDefaultListingGroup =
          Boolean.parseBoolean("INSERT_CREATE_DEFAULT_LISTING_GROUP_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 AddShoppingProductAd()
          .runExample(
              googleAdsClient,
              params.customerId,
              params.merchantCenterAccountId,
              params.createDefaultListingGroup);
    } 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 merchantCenterAccountId the Merchant Center account ID.
   * @param createDefaultListingGroup the boolean to indicate if a default listing group should be
   *     created for the ad group. Set to false if the listing group will be constructed elsewhere.
   *     See AddShoppingProductListingGroupTree for a more comprehensive example.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void runExample(
      GoogleAdsClient googleAdsClient,
      long customerId,
      long merchantCenterAccountId,
      boolean createDefaultListingGroup) {

    // Creates a budget to be used by the campaign that will be created below.
    String budgetResourceName = addCampaignBudget(googleAdsClient, customerId);

    // Creates a standard shopping campaign.
    String campaignResourceName =
        addStandardShoppingCampaign(
            googleAdsClient, customerId, budgetResourceName, merchantCenterAccountId);

    // Creates a shopping product ad group.
    String adGroupResourceName =
        addShoppingProductAdGroup(googleAdsClient, customerId, campaignResourceName);

    // Creates a shopping product ad group ad.
    addShoppingProductAdGroupAd(googleAdsClient, customerId, adGroupResourceName);

    if (createDefaultListingGroup) {
      // Creates an ad group criterion containing a listing group.
      // This will be the listing group tree for 'All products' and will contain a single biddable
      // unit node.
      addDefaultShoppingListingGroup(googleAdsClient, customerId, adGroupResourceName);
    }
  }

  /**
   * Creates a new campaign budget in the specified client account.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @return resource name of the newly created budget.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String addCampaignBudget(GoogleAdsClient googleAdsClient, long customerId) {
    CampaignBudget budget =
        CampaignBudget.newBuilder()
            .setName("Interplanetary Cruise Budget #" + getPrintableDateTime())
            .setDeliveryMethod(BudgetDeliveryMethod.STANDARD)
            .setAmountMicros(5_000_000L)
            .build();

    CampaignBudgetOperation op = CampaignBudgetOperation.newBuilder().setCreate(budget).build();

    try (CampaignBudgetServiceClient campaignBudgetServiceClient =
        googleAdsClient.getLatestVersion().createCampaignBudgetServiceClient()) {
      MutateCampaignBudgetsResponse response =
          campaignBudgetServiceClient.mutateCampaignBudgets(
              Long.toString(customerId), ImmutableList.of(op));
      String budgetResourceName = response.getResults(0).getResourceName();
      System.out.printf("Added a budget with resource name: '%s'%n", budgetResourceName);
      return budgetResourceName;
    }
  }

  /**
   * Creates a new standard shopping campaign in the specified client account.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param budgetResourceName the resource name of the budget for the campaign.
   * @param merchantCenterAccountId the Merchant Center account ID.
   * @return resource name of the newly created campaign.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String addStandardShoppingCampaign(
      GoogleAdsClient googleAdsClient,
      long customerId,
      String budgetResourceName,
      long merchantCenterAccountId) {

    // Configures the shopping settings.
    ShoppingSetting shoppingSetting =
        ShoppingSetting.newBuilder()
            // Sets the priority of the campaign. Higher numbers take priority over lower numbers.
            // For Shopping product ad campaigns, allowed values are between 0 and 2, inclusive.
            .setCampaignPriority(0)
            .setMerchantId(merchantCenterAccountId)
            // Enables local inventory ads for this campaign.
            .setEnableLocal(true)
            .build();

    // Create the standard shopping campaign.
    Campaign campaign =
        Campaign.newBuilder()
            .setName("Interplanetary Cruise #" + getPrintableDateTime())
            // Configures settings related to shopping campaigns including advertising channel type
            // and shopping setting.
            .setAdvertisingChannelType(AdvertisingChannelType.SHOPPING)
            .setShoppingSetting(shoppingSetting)
            // Recommendation: Sets the campaign to PAUSED when creating it to prevent
            // the ads from immediately serving. Set to ENABLED once you've added
            // targeting and the ads are ready to serve.
            .setStatus(CampaignStatus.PAUSED)
            // Sets the bidding strategy to Manual CPC (with eCPC disabled). eCPC for standard
            // Shopping campaigns is deprecated. If eCPC is set to true, Google Ads ignores the
            // setting and behaves as if the setting was false. See this blog post for more
            // information:
            // https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
            // Recommendation: Use one of the automated bidding strategies for Shopping campaigns
            // to help you optimize your advertising spend. More information can be found here:
            // https://support.google.com/google-ads/answer/6309029.
            .setManualCpc(ManualCpc.newBuilder().setEnhancedCpcEnabled(false).build())
            // Sets the budget.
            .setCampaignBudget(budgetResourceName)
            .build();

    // Creates a campaign operation.
    CampaignOperation operation = CampaignOperation.newBuilder().setCreate(campaign).build();

    // Issues a mutate request to add the campaign.
    try (CampaignServiceClient campaignServiceClient =
        googleAdsClient.getLatestVersion().createCampaignServiceClient()) {
      MutateCampaignsResponse response =
          campaignServiceClient.mutateCampaigns(
              Long.toString(customerId), Collections.singletonList(operation));
      MutateCampaignResult result = response.getResults(0);
      System.out.printf(
          "Added a standard shopping campaign with resource name: '%s'%n",
          result.getResourceName());
      return result.getResourceName();
    }
  }


  /**
   * Creates a new shopping product ad group in the specified campaign.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param campaignResourceName the resource name of the shopping campaign that the new ad group
   *     will belong to.
   * @return resource name of the newly created ad group.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String addShoppingProductAdGroup(
      GoogleAdsClient googleAdsClient, long customerId, String campaignResourceName) {
    // Creates an ad group.
    AdGroup adGroup =
        AdGroup.newBuilder()
            .setName("Earth to Mars Cruises #" + getPrintableDateTime())
            .setCampaign(campaignResourceName)
            // Sets the ad group type to SHOPPING_PRODUCT_ADS. This is the only value possible for
            // ad groups that contain shopping product ads.
            .setType(AdGroupType.SHOPPING_PRODUCT_ADS)
            .setCpcBidMicros(1_000_000L)
            .setStatus(AdGroupStatus.ENABLED)
            .build();

    // Creates an ad group operation.
    AdGroupOperation operation = AdGroupOperation.newBuilder().setCreate(adGroup).build();

    // Issues a mutate request to add an ad group.
    try (AdGroupServiceClient adGroupServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupServiceClient()) {
      MutateAdGroupResult mutateAdGroupResult =
          adGroupServiceClient
              .mutateAdGroups(Long.toString(customerId), Collections.singletonList(operation))
              .getResults(0);
      System.out.printf(
          "Added a product shopping ad group with resource name: '%s'%n",
          mutateAdGroupResult.getResourceName());
      return mutateAdGroupResult.getResourceName();
    }
  }


  /**
   * Creates a new shopping product ad group ad in the specified ad group.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param adGroupResourceName the resource name of the ad group that the new ad group ad will
   *     belong to.
   * @return resource name of the newly created ad group ad.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String addShoppingProductAdGroupAd(
      GoogleAdsClient googleAdsClient, long customerId, String adGroupResourceName) {
    // Creates a new shopping product ad.
    Ad ad =
        Ad.newBuilder().setShoppingProductAd(ShoppingProductAdInfo.newBuilder().build()).build();
    // Creates a new ad group ad and sets the shopping product ad to it.
    AdGroupAd adGroupAd =
        AdGroupAd.newBuilder()
            // Sets the ad to the ad created above.
            .setAd(ad)
            .setStatus(AdGroupAdStatus.PAUSED)
            // Sets the ad group.
            .setAdGroup(adGroupResourceName)
            .build();

    // Creates an ad group ad operation.
    AdGroupAdOperation operation = AdGroupAdOperation.newBuilder().setCreate(adGroupAd).build();

    // Issues a mutate request to add an ad group ad.
    try (AdGroupAdServiceClient adGroupAdServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) {
      MutateAdGroupAdResult mutateAdGroupAdResult =
          adGroupAdServiceClient
              .mutateAdGroupAds(Long.toString(customerId), Collections.singletonList(operation))
              .getResults(0);
      System.out.printf(
          "Added a product shopping ad group ad with resource name: '%s'%n",
          mutateAdGroupAdResult.getResourceName());
      return mutateAdGroupAdResult.getResourceName();
    }
  }


  /**
   * Creates a new default shopping listing group for the specified ad group. A listing group is the
   * Google Ads API representation of a "product group" described in the Google Ads user interface.
   * The listing group will be added to the ad group using an "ad group criterion". The criterion
   * will contain the bid for a given listing group.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param adGroupResourceName the resource name of the ad group that the new listing group will
   *     belong to.
   * @return resource name of the newly created ad group criterion containing the listing group.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String addDefaultShoppingListingGroup(
      GoogleAdsClient googleAdsClient, long customerId, String adGroupResourceName) {
    // Creates a new ad group criterion. This will contain the "default" listing group (All
    // products).
    AdGroupCriterion adGroupCriterion =
        AdGroupCriterion.newBuilder()
            .setAdGroup(adGroupResourceName)
            .setStatus(AdGroupCriterionStatus.ENABLED)
            // Creates a new listing group. This will be the top-level "root" node.
            // Sets the type of the listing group to be a biddable unit.
            .setListingGroup(ListingGroupInfo.newBuilder().setType(ListingGroupType.UNIT).build())
            // Sets the bid for products in this listing group unit.
            .setCpcBidMicros(500_000L)
            .build();

    AdGroupCriterionOperation operation =
        AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build();

    try (AdGroupCriterionServiceClient adGroupCriterionServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) {
      MutateAdGroupCriterionResult mutateAdGroupCriteriaResult =
          adGroupCriterionServiceClient
              .mutateAdGroupCriteria(
                  Long.toString(customerId), Collections.singletonList(operation))
              .getResults(0);
      System.out.printf(
          "Added an ad group criterion containing a listing group with resource name: '%s'%n",
          mutateAdGroupCriteriaResult.getResourceName());
      return mutateAdGroupCriteriaResult.getResourceName();
    }
  }
}

      

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.V16.Common;
using Google.Ads.GoogleAds.V16.Errors;
using Google.Ads.GoogleAds.V16.Resources;
using Google.Ads.GoogleAds.V16.Services;
using System;
using System.Collections.Generic;
using static Google.Ads.GoogleAds.V16.Enums.AdGroupAdStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AdGroupCriterionStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AdGroupStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AdGroupTypeEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AdvertisingChannelTypeEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.BudgetDeliveryMethodEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.CampaignStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.ListingGroupTypeEnum.Types;
using static Google.Ads.GoogleAds.V16.Resources.Campaign.Types;

namespace Google.Ads.GoogleAds.Examples.V16
{
    /// <summary>
    /// This code example creates a standard shopping campaign, a shopping product ad group and a
    /// shopping product ad.
    ///
    /// Prerequisite: You need to have access to a Merchant Center account. You can find
    /// instructions to create a Merchant Center account here:
    /// https://support.google.com/merchants/answer/188924.
    /// This account must be linked to your AdWords account.The integration instructions can be
    /// found at: https://developers.google.com/adwords/shopping/full-automation/articles/t15.
    /// </summary>
    public class AddShoppingProductAd : ExampleBase
    {
        /// <summary>
        /// Command line options for running the <see cref="AddShoppingProductAd"/> example.
        /// </summary>
        public class Options : OptionsBase
        {
            /// <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.")]
            public long CustomerId { get; set; }

            /// <summary>
            /// The Merchant Center account ID.
            /// </summary>
            [Option("merchantCenterAccountId", Required = true, HelpText =
                "The Merchant Center account ID.")]
            public long MerchantCenterAccountId { get; set; }

            /// <summary>
            /// The boolean to indicate if a default listing group should be created for the ad
            /// group. Set to false if the listing group will be constructed elsewhere.
            /// See AddShoppingListingGroupTree for a more comprehensive example.
            /// </summary>
            [Option("createDefaultListingGroup", Required = true, HelpText =
                "The boolean to indicate if a default listing group should be created for the " +
                "ad group. Set to false if the listing group will be constructed elsewhere. " +
                "See AddShoppingListingGroupTree for a more comprehensive example.")]
            public bool CreateDefaultListingGroup { get; set; }
        }

        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            Options options = ExampleUtilities.ParseCommandLine<Options>(args);

            AddShoppingProductAd codeExample = new AddShoppingProductAd();
            Console.WriteLine(codeExample.Description);
            codeExample.Run(new GoogleAdsClient(), options.CustomerId,
                options.MerchantCenterAccountId, options.CreateDefaultListingGroup);
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This code example creates a standard shopping campaign, a shopping product ad group " +
            "and a shopping product ad." +
            "\nPrerequisite: You need to have access to a Merchant Center account. You can find " +
            "instructions to create a Merchant Center account here: " +
            "https://support.google.com/merchants/answer/188924." +
            "\nThis account must be linked to your AdWords account.The integration instructions " +
            "can be found at: " +
            "https://developers.google.com/adwords/shopping/full-automation/articles/t15.";

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <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="merchantCenterAccountId">The Merchant Center account ID.</param>
        /// <param name="createDefaultListingGroup">The boolean to indicate if a default listing
        /// group should be created for the ad group. Set to false if the listing group will be
        /// constructed elsewhere.
        ///
        /// See AddShoppingListingGroupTree for a more comprehensive example.</param>
        public void Run(GoogleAdsClient client, long customerId, long merchantCenterAccountId,
            bool createDefaultListingGroup)
        {
            try
            {
                // Creates a budget to be used by the campaign that will be created below.
                string budgetResourceName = AddCampaignBudget(client, customerId);

                // Creates a standard shopping campaign.
                string campaignResourceName = AddStandardShoppingCampaign(
                    client, customerId, budgetResourceName, merchantCenterAccountId);

                // Creates a product shopping ad group.
                string adGroupResourceName = AddProductShoppingAdGroup(
                    client, customerId, campaignResourceName);

                // Creates a product shopping ad group ad.
                AddProductShoppingAdGroupAd(client, customerId, adGroupResourceName);

                if (createDefaultListingGroup)
                {
                    // Creates an ad group criterion containing a listing group.
                    // This will be the listing group tree for 'All products' and will contain
                    // a single biddable unit node.
                    AddDefaultShoppingListingGroup(client, customerId, adGroupResourceName);
                }
            }
            catch (GoogleAdsException e)
            {
                Console.WriteLine("Failure:");
                Console.WriteLine($"Message: {e.Message}");
                Console.WriteLine($"Failure: {e.Failure}");
                Console.WriteLine($"Request ID: {e.RequestId}");
                throw;
            }
        }

        /// <summary>
        /// Creates a new campaign budget in the specified client account.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <returns>Resource name of the newly created budget.</returns>
        /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more
        /// service errors.</exception>
        private string AddCampaignBudget(GoogleAdsClient client, long customerId)
        {
            // Get the CampaignBudgetService.
            CampaignBudgetServiceClient campaignBudgetService =
                client.GetService(Services.V16.CampaignBudgetService);

            CampaignBudget budget = new CampaignBudget()
            {
                Name = "Interplanetary Cruise Budget #" + ExampleUtilities.GetRandomString(),
                DeliveryMethod = BudgetDeliveryMethod.Standard,
                AmountMicros = 5_000_000L
            };

            CampaignBudgetOperation operation = new CampaignBudgetOperation()
            {
                Create = budget
            };

            MutateCampaignBudgetsResponse response =
                campaignBudgetService.MutateCampaignBudgets(customerId.ToString(),
                    new CampaignBudgetOperation[] { operation });
            string budgetResourceName = response.Results[0].ResourceName;
            Console.WriteLine("Added a budget with resource name: '{0}'.", budgetResourceName);
            return budgetResourceName;
        }

        /// <summary>
        ///  Creates a new standard shopping campaign in the specified client account.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="budgetResourceName">The resource name of the budget for the campaign.
        /// </param>
        /// <param name="merchantCenterAccountId">The Merchant Center account ID.</param>
        /// <returns>Resource name of the newly created campaign.</returns>
        /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more
        /// service errors.</exception>
        private string AddStandardShoppingCampaign(GoogleAdsClient client, long customerId,
            string budgetResourceName, long merchantCenterAccountId)
        {
            // Get the CampaignService.
            CampaignServiceClient campaignService =
                client.GetService(Services.V16.CampaignService);

            // Configures the shopping settings.
            ShoppingSetting shoppingSetting = new ShoppingSetting()
            {
                // Sets the priority of the campaign. Higher numbers take priority over lower
                // numbers. For Shopping Product Ad campaigns, allowed values are between 0 and 2,
                // inclusive.
                CampaignPriority = 0,

                MerchantId = merchantCenterAccountId,

                // Enables local inventory ads for this campaign.
                EnableLocal = true
            };

            // Create the standard shopping campaign.
            Campaign campaign = new Campaign()
            {
                Name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString(),

                // Configures settings related to shopping campaigns including advertising channel
                // type and shopping setting.
                AdvertisingChannelType = AdvertisingChannelType.Shopping,

                ShoppingSetting = shoppingSetting,

                // Recommendation: Set the campaign to PAUSED when creating it to prevent
                // the ads from immediately serving. Set to ENABLED once you've added
                // targeting and the ads are ready to serve
                Status = CampaignStatus.Paused,

                // Sets the bidding strategy to Manual CPC (with eCPC disabled). eCPC for standard
                // Shopping campaigns is deprecated. If eCPC is set to true, Google Ads ignores the
                // setting and behaves as if the setting was false. See this blog post for more
                // information:
                // https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
                // Recommendation: Use one of the automated bidding strategies for Shopping
                // campaigns to help you optimize your advertising spend. More information can be
                // found here: https://support.google.com/google-ads/answer/6309029
                ManualCpc = new ManualCpc()
                {
                    EnhancedCpcEnabled = false
                },

                // Sets the budget.
                CampaignBudget = budgetResourceName
            };

            // Creates a campaign operation.
            CampaignOperation operation = new CampaignOperation()
            {
                Create = campaign
            };

            // Issues a mutate request to add the campaign.
            MutateCampaignsResponse response =
                campaignService.MutateCampaigns(customerId.ToString(),
                    new CampaignOperation[] { operation });
            MutateCampaignResult result = response.Results[0];
            Console.WriteLine("Added a standard shopping campaign with resource name: '{0}'.",
                result.ResourceName);
            return result.ResourceName;
        }

        /// <summary>
        /// Creates a new product shopping ad group in the specified campaign.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="campaignResourceName">Resource name of the shopping campaign that the
        /// new ad group will belong to.</param>
        /// <returns>Resource name of the newly created ad group.</returns>
        /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more
        /// service errors.</exception>
        private string AddProductShoppingAdGroup(GoogleAdsClient client, long customerId,
                    string campaignResourceName)
        {
            // Get the AdGroupService.
            AdGroupServiceClient adGroupService = client.GetService(Services.V16.AdGroupService);

            // Creates an ad group.
            AdGroup adGroup = new AdGroup()
            {
                Name = "Earth to Mars Cruises #" + ExampleUtilities.GetRandomString(),
                Campaign = campaignResourceName,
                // Sets the ad group type to SHOPPING_PRODUCT_ADS. This is the only value possible
                // for ad groups that contain shopping product ads.
                Type = AdGroupType.ShoppingProductAds,
                CpcBidMicros = 1_000_000L,
                Status = AdGroupStatus.Enabled
            };

            // Creates an ad group operation.
            AdGroupOperation operation = new AdGroupOperation()
            {
                Create = adGroup
            };

            // Issues a mutate request to add an ad group.
            MutateAdGroupResult mutateAdGroupResult =
                adGroupService
                    .MutateAdGroups(customerId.ToString(), new AdGroupOperation[] { operation })
                    .Results[0];
            Console.WriteLine("Added a product shopping ad group with resource name: '{0}'.",
                mutateAdGroupResult.ResourceName);
            return mutateAdGroupResult.ResourceName;
        }

        /// <summary>
        /// Creates a new Shopping product ad group ad in the specified ad group.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="adGroupResourceName">The resource name of the ad group that the new ad
        /// group ad will belong to.</param>
        /// <returns>Resource name of the newly created ad group ad.</returns>
        /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more
        /// service errors.</exception>
        private string AddProductShoppingAdGroupAd(GoogleAdsClient client, long customerId,
            string adGroupResourceName)
        {
            // Get the AdGroupAdService.
            AdGroupAdServiceClient adGroupAdService = client.GetService(
                Services.V16.AdGroupAdService);

            // Creates a new shopping product ad.
            Ad ad = new Ad()
            {
                ShoppingProductAd = new ShoppingProductAdInfo()
                {
                }
            };

            // Creates a new ad group ad and sets the shopping product ad to it.
            AdGroupAd adGroupAd = new AdGroupAd()
            {
                // Sets the ad to the ad created above.
                Ad = ad,

                Status = AdGroupAdStatus.Paused,

                // Sets the ad group.
                AdGroup = adGroupResourceName
            };

            // Creates an ad group ad operation.
            AdGroupAdOperation operation = new AdGroupAdOperation()
            {
                Create = adGroupAd
            };

            // Issues a mutate request to add an ad group ad.
            MutateAdGroupAdResult mutateAdGroupAdResult = adGroupAdService.MutateAdGroupAds(
                customerId.ToString(), new AdGroupAdOperation[] { operation }).Results[0];
            Console.WriteLine("Added a product shopping ad group ad with resource name: '{0}'.",
                mutateAdGroupAdResult.ResourceName);
            return mutateAdGroupAdResult.ResourceName;
        }

        /// <summary>
        /// Creates a new default shopping listing group for the specified ad group. A listing
        /// group is the Google Ads API representation of a "product group" described in the
        /// Google Ads user interface. The listing group will be added to the ad group using an
        /// "ad group criterion".
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="adGroupResourceName">The resource name of the ad group that the new
        /// listing group will belong to.</param>
        /// <returns>Resource name of the newly created ad group criterion containing the
        /// listing group.</returns>
        /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more
        /// service errors.</exception>
        private string AddDefaultShoppingListingGroup(GoogleAdsClient client, long customerId,
            string adGroupResourceName)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(
                Services.V16.AdGroupCriterionService);

            // Creates a new ad group criterion. This will contain the "default" listing group (All
            // products).
            AdGroupCriterion adGroupCriterion = new AdGroupCriterion()
            {
                AdGroup = adGroupResourceName,
                Status = AdGroupCriterionStatus.Enabled,

                // Creates a new listing group. This will be the top-level "root" node.
                // Set the type of the listing group to be a biddable unit.
                ListingGroup = new ListingGroupInfo()
                {
                    Type = ListingGroupType.Unit
                },
                // Set the bid for products in this listing group unit.
                CpcBidMicros = 500_000L
            };

            AdGroupCriterionOperation operation = new AdGroupCriterionOperation()
            {
                Create = adGroupCriterion
            };

            MutateAdGroupCriterionResult mutateAdGroupCriteriaResult =
                adGroupCriterionService.MutateAdGroupCriteria(customerId.ToString(),
                    new AdGroupCriterionOperation[] { operation }).Results[0];
            Console.WriteLine("Added an ad group criterion containing a listing group with " +
                "resource name: '{0}'.", mutateAdGroupCriteriaResult.ResourceName);
            return mutateAdGroupCriteriaResult.ResourceName;
        }
    }
}

      

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\Examples\Utils\Helper;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\V16\Common\ListingGroupInfo;
use Google\Ads\GoogleAds\V16\Common\ManualCpc;
use Google\Ads\GoogleAds\V16\Common\ShoppingProductAdInfo;
use Google\Ads\GoogleAds\V16\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
use Google\Ads\GoogleAds\V16\Enums\AdGroupStatusEnum\AdGroupStatus;
use Google\Ads\GoogleAds\V16\Enums\AdGroupTypeEnum\AdGroupType;
use Google\Ads\GoogleAds\V16\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
use Google\Ads\GoogleAds\V16\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod;
use Google\Ads\GoogleAds\V16\Enums\CampaignStatusEnum\CampaignStatus;
use Google\Ads\GoogleAds\V16\Enums\ListingGroupTypeEnum\ListingGroupType;
use Google\Ads\GoogleAds\V16\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V16\Resources\Ad;
use Google\Ads\GoogleAds\V16\Resources\AdGroup;
use Google\Ads\GoogleAds\V16\Resources\AdGroupAd;
use Google\Ads\GoogleAds\V16\Resources\AdGroupCriterion;
use Google\Ads\GoogleAds\V16\Resources\Campaign;
use Google\Ads\GoogleAds\V16\Resources\Campaign\ShoppingSetting;
use Google\Ads\GoogleAds\V16\Resources\CampaignBudget;
use Google\Ads\GoogleAds\V16\Services\AdGroupAdOperation;
use Google\Ads\GoogleAds\V16\Services\AdGroupCriterionOperation;
use Google\Ads\GoogleAds\V16\Services\AdGroupOperation;
use Google\Ads\GoogleAds\V16\Services\CampaignBudgetOperation;
use Google\Ads\GoogleAds\V16\Services\CampaignOperation;
use Google\Ads\GoogleAds\V16\Services\MutateAdGroupAdsRequest;
use Google\Ads\GoogleAds\V16\Services\MutateAdGroupCriteriaRequest;
use Google\Ads\GoogleAds\V16\Services\MutateAdGroupsRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCampaignBudgetsRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCampaignsRequest;
use Google\ApiCore\ApiException;

/**
 * This example creates a standard shopping campaign, a shopping product ad group and a shopping
 * product ad.
 *
 * <p>Prerequisite: You need to have access to a Merchant Center account. You can find instructions
 * to create a Merchant Center account here: https://support.google.com/merchants/answer/188924.
 * This account must be linked to your Google Ads account.
 */
class AddShoppingProductAd
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    private const MERCHANT_CENTER_ACCOUNT_ID = 'INSERT_MERCHANT_CENTER_ACCOUNT_ID_HERE';
    private const CREATE_DEFAULT_LISTING_GROUP = '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 constants above.
        $options = (new ArgumentParser())->parseCommandArguments([
            ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::MERCHANT_CENTER_ACCOUNT_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::CREATE_DEFAULT_LISTING_GROUP => GetOpt::REQUIRED_ARGUMENT
        ]);

        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct a Google Ads client configured from a properties file and the
        // OAuth2 credentials above.
        $googleAdsClient = (new GoogleAdsClientBuilder())->fromFile()
            ->withOAuth2Credential($oAuth2Credential)
            // We set this value to true to show how to use GAPIC v2 source code. You can remove the
            // below line if you wish to use the old-style source code. Note that in that case, you
            // probably need to modify some parts of the code below to make it work.
            // For more information, see
            // https://developers.devsite.corp.google.com/google-ads/api/docs/client-libs/php/gapic.
            ->usingGapicV2Source(true)
            ->build();

        try {
            self::runExample(
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
                $options[ArgumentNames::MERCHANT_CENTER_ACCOUNT_ID]
                    ?: self::MERCHANT_CENTER_ACCOUNT_ID,
                $options[ArgumentNames::CREATE_DEFAULT_LISTING_GROUP]
                    ?: self::CREATE_DEFAULT_LISTING_GROUP
            );
        } catch (GoogleAdsException $googleAdsException) {
            printf(
                "Request with ID '%s' has failed.%sGoogle 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 $merchantCenterAccountId the Merchant Center account ID
     * @param bool $createDefaultListingGroup true if a default listing group should be
     *     created for the ad group. Set to false if the listing group will be constructed
     *     elsewhere. See AddShoppingProductListingGroupTree for a more comprehensive example
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $merchantCenterAccountId,
        bool $createDefaultListingGroup
    ) {
        // Creates a budget to be used by the campaign that will be created below.
        $budgetResourceName = self::addCampaignBudget($googleAdsClient, $customerId);
        // Creates a standard shopping campaign.
        $campaignResourceName = self::addStandardShoppingCampaign(
            $googleAdsClient,
            $customerId,
            $budgetResourceName,
            $merchantCenterAccountId
        );
        // Creates a shopping product ad group.
        $adGroupResourceName =
            self::addShoppingProductAdGroup($googleAdsClient, $customerId, $campaignResourceName);
        // Creates a shopping product ad group ad.
        self::addShoppingProductAdGroupAd($googleAdsClient, $customerId, $adGroupResourceName);

        if ($createDefaultListingGroup === 'true') {
            // Creates an ad group criterion containing a listing group.
            // This will be the listing group tree for 'All products' and will contain a single
            // biddable unit node.
            self::addDefaultShoppingListingGroup(
                $googleAdsClient,
                $customerId,
                $adGroupResourceName
            );
        }
    }

    /**
     * Creates a new campaign budget in the specified client account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @return string the resource name of the newly created budget
     */
    private static function addCampaignBudget(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        // Creates a campaign budget.
        $budget = new CampaignBudget([
            'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(),
            'delivery_method' => BudgetDeliveryMethod::STANDARD,
            // Sets the amount of budget.
            'amount_micros' => 50000000
        ]);

        // Creates a campaign budget operation.
        $campaignBudgetOperation = new CampaignBudgetOperation();
        $campaignBudgetOperation->setCreate($budget);

        // Issues a mutate request.
        $campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();
        $response = $campaignBudgetServiceClient->mutateCampaignBudgets(
            MutateCampaignBudgetsRequest::build($customerId, [$campaignBudgetOperation])
        );

        /** @var CampaignBudget $addedBudget */
        $addedBudget = $response->getResults()[0];
        printf(
            "Added a budget with resource name '%s'.%s",
            $addedBudget->getResourceName(),
            PHP_EOL
        );

        return $addedBudget->getResourceName();
    }

    /**
     * Creates a new shopping product campaign in the specified client account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $budgetResourceName the resource name of budget for a new campaign
     * @param int $merchantCenterAccountId the Merchant Center account ID
     * @return string the resource name of the newly created campaign
     */
    private static function addStandardShoppingCampaign(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $budgetResourceName,
        int $merchantCenterAccountId
    ) {
        // Creates a standard shopping campaign.
        $campaign = new Campaign([
            'name' => 'Interplanetary Cruise Campaign #' . Helper::getPrintableDatetime(),
            // Configures settings related to shopping campaigns including advertising channel type
            // and shopping setting.
            'advertising_channel_type' => AdvertisingChannelType::SHOPPING,
            // Configures the shopping settings.
            'shopping_setting' => new ShoppingSetting([
                // Sets the priority of the campaign. Higher numbers take priority over lower
                // numbers. For Shopping product ad campaigns, allowed values are between 0 and 2,
                // inclusive.
                'campaign_priority' => 0,
                'merchant_id' => $merchantCenterAccountId,
                // Enables local inventory ads for this campaign
                'enable_local' => true
            ]),
            // Recommendation: Set the campaign to PAUSED when creating it to prevent
            // the ads from immediately serving. Set to ENABLED once you've added
            // targeting and the ads are ready to serve.
            'status' => CampaignStatus::PAUSED,
            // Sets the bidding strategy to Manual CPC (with eCPC disabled). eCPC for standard
            // Shopping campaigns is deprecated. If eCPC is set to true, Google Ads ignores the
            // setting and behaves as if the setting was false. See this blog post for more
            // information:
            // https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
            // Recommendation: Use one of the automated bidding strategies for Shopping campaigns
            // to help you optimize your advertising spend. More information can be found here:
            // https://support.google.com/google-ads/answer/6309029.
            'manual_cpc' => new ManualCpc(['enhanced_cpc_enabled' => false]),
            // Sets the budget.
            'campaign_budget' => $budgetResourceName
        ]);

        // Creates a campaign operation.
        $campaignOperation = new CampaignOperation();
        $campaignOperation->setCreate($campaign);

        // Issues a mutate request to add campaigns.
        $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
        $response = $campaignServiceClient->mutateCampaigns(
            MutateCampaignsRequest::build($customerId, [$campaignOperation])
        );

        /** @var Campaign $addedCampaign */
        $addedCampaign = $response->getResults()[0];
        printf(
            "Added a standard shopping campaign with resource name '%s'.%s",
            $addedCampaign->getResourceName(),
            PHP_EOL
        );

        return $addedCampaign->getResourceName();
    }

    /**
     * Creates a new shopping product ad group in the specified campaign.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $campaignResourceName the resource name of campaign that a new ad group will
     *     belong to
     * @return string the resource name of the newly created ad group
     */
    private static function addShoppingProductAdGroup(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $campaignResourceName
    ) {
        // Creates an ad group.
        $adGroup = new AdGroup([
            'name' => 'Earth to Mars Cruise #' . Helper::getPrintableDatetime(),
            // Sets the campaign.
            'campaign' => $campaignResourceName,
            // Sets the ad group type to SHOPPING_PRODUCT_ADS. This is the only value possible for
            // ad groups that contain shopping product ads.
            'type' => AdGroupType::SHOPPING_PRODUCT_ADS,
            'cpc_bid_micros' => 10000000,
            'status' => AdGroupStatus::ENABLED
        ]);

        // Creates an ad group operation.
        $adGroupOperation = new AdGroupOperation();
        $adGroupOperation->setCreate($adGroup);

        // Issues a mutate request to add an ad group.
        $adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
        $response = $adGroupServiceClient->mutateAdGroups(
            MutateAdGroupsRequest::build($customerId, [$adGroupOperation])
        );

        /** @var AdGroup $addedAdGroup */
        $addedAdGroup = $response->getResults()[0];
        printf(
            "Added a shopping product ad group with resource name '%s'.%s",
            $addedAdGroup->getResourceName(),
            PHP_EOL
        );

        return $addedAdGroup->getResourceName();
    }

    /**
     * Creates a new shopping product ad group ad in the specified ad group.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the resource name of ad group that a new ad group ad will
     *     belong to
     */
    private static function addShoppingProductAdGroupAd(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName
    ) {
        // Creates a new shopping product ad.
        $ad = new Ad(['shopping_product_ad' => new ShoppingProductAdInfo()]);

        // Creates a new ad group ad and sets the shopping product ad to it.
        $adGroupAd = new AdGroupAd([
            'ad' => $ad,
            'status' => AdGroupAdStatus::PAUSED,
            // Sets the ad group.
            'ad_group' => $adGroupResourceName
        ]);

        // Creates an ad group ad operation.
        $adGroupAdOperation = new AdGroupAdOperation();
        $adGroupAdOperation->setCreate($adGroupAd);

        // Issues a mutate request to add an ad group ad.
        $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient();
        $response = $adGroupAdServiceClient->mutateAdGroupAds(
            MutateAdGroupAdsRequest::build($customerId, [$adGroupAdOperation])
        );

        /** @var AdGroupAd $addedAdGroupAd */
        $addedAdGroupAd = $response->getResults()[0];
        printf(
            "Added a shopping product ad group ad with resource name '%s'.%s",
            $addedAdGroupAd->getResourceName(),
            PHP_EOL
        );
    }

    /**
     * Creates a new default shopping listing group for the specified ad group. A listing group is
     * the Google Ads API representation of a "product group" described in the Google Ads user
     * interface. The listing group will be added to the ad group using an "ad group criterion".
     * The criterion will contain the bid for a given listing group.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the resource name of ad group that the new listing group
     *     will belong to
     */
    private static function addDefaultShoppingListingGroup(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName
    ) {
        // Creates a new ad group criterion. This will contain the "default" listing group (All
        // products).
        $adGroupCriterion = new AdGroupCriterion([
            'ad_group' => $adGroupResourceName,
            'status' => AdGroupAdStatus::ENABLED,
            // Creates a new listing group. This will be the top-level "root" node.
            // Set the type of the listing group to be a biddable unit.
            'listing_group' => new ListingGroupInfo(['type' => ListingGroupType::UNIT]),
            // Set the bid for products in this listing group unit.
            'cpc_bid_micros' => 500000
        ]);

        // Creates an ad group criterion operation.
        $adGroupCriterionOperation = new AdGroupCriterionOperation();
        $adGroupCriterionOperation->setCreate($adGroupCriterion);

        // Issues a mutate request to add an ad group criterion.
        $adGroupCriterionServiceClient = $googleAdsClient->getAdGroupCriterionServiceClient();
        $response = $adGroupCriterionServiceClient->mutateAdGroupCriteria(
            MutateAdGroupCriteriaRequest::build($customerId, [$adGroupCriterionOperation])
        );

        /** @var AdGroupCriterion $addedAdGroupCriterion */
        $addedAdGroupCriterion = $response->getResults()[0];
        printf(
            "Added an ad group criterion containing a listing group with resource name: '%s'.%s",
            $addedAdGroupCriterion->getResourceName(),
            PHP_EOL
        );
    }
}

AddShoppingProductAd::main();

      

Python

#!/usr/bin/env python
# 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.
"""This example creates a standard shopping product ad.

In the process of creating a standard shopping campaign and a shopping product
ad group are also created.

Prerequisite: You need to have access to a Merchant Center account. You can find
instructions to create a Merchant Center account here:
https://support.google.com/merchants/answer/188924.

This account must be linked to your Google Ads account.
"""


import argparse
import sys
import uuid

from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException


def main(
    client,
    customer_id,
    merchant_center_account_id,
    create_default_listing_group,
):
    # Creates a budget to be used by the campaign that will be created below.
    budget_resource_name = add_campaign_budget(client, customer_id)

    # Create a standard shopping campaign.
    campaign_resource_name = add_standard_shopping_campaign(
        client, customer_id, budget_resource_name, merchant_center_account_id
    )

    # Create a shopping product ad group.
    ad_group_resource_name = add_shopping_product_ad_group(
        client, customer_id, campaign_resource_name
    )

    # Create a shopping product ad group ad.
    add_shopping_product_ad_group_ad(
        client, customer_id, ad_group_resource_name
    )

    if create_default_listing_group:
        # Creates an ad group criterion containing a listing group.
        # This will be the listing group tree for 'All products' and will
        # contain a single biddable unit node.
        add_default_shopping_listing_group(
            client, customer_id, ad_group_resource_name
        )


def add_campaign_budget(client, customer_id):
    """Creates a new campaign budget in the specified client account."""
    campaign_budget_service = client.get_service("CampaignBudgetService")

    # Create a budget, which can be shared by multiple campaigns.
    campaign_budget_operation = client.get_type("CampaignBudgetOperation")
    campaign_budget = campaign_budget_operation.create
    campaign_budget.name = f"Interplanetary Budget {uuid.uuid4()}"
    campaign_budget.delivery_method = (
        client.enums.BudgetDeliveryMethodEnum.STANDARD
    )
    campaign_budget.amount_micros = 500000

    # Add budget.
    campaign_budget_response = campaign_budget_service.mutate_campaign_budgets(
        customer_id=customer_id, operations=[campaign_budget_operation]
    )

    budget_resource_name = campaign_budget_response.results[0].resource_name

    print(f"Added a budget with resource name: '{budget_resource_name}'")

    return budget_resource_name


def add_shopping_product_ad_group_ad(
    client, customer_id, ad_group_resource_name
):
    """Creates a new shopping product ad group ad in the specified ad group."""
    ad_group_ad_service = client.get_service("AdGroupAdService")

    # Creates a new ad group ad and sets the product ad to it.
    ad_group_ad_operation = client.get_type("AdGroupAdOperation")
    ad_group_ad = ad_group_ad_operation.create
    ad_group_ad.ad_group = ad_group_resource_name
    ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED
    client.copy_from(
        ad_group_ad.ad.shopping_product_ad,
        client.get_type("ShoppingProductAdInfo"),
    )

    # Add the ad group ad.
    ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads(
        customer_id=customer_id, operations=[ad_group_ad_operation]
    )

    ad_group_ad_resource_name = ad_group_ad_response.results[0].resource_name

    print(
        f"Created shopping product ad group ad '{ad_group_ad_resource_name}'."
    )

    return ad_group_resource_name


def add_shopping_product_ad_group(client, customer_id, campaign_resource_name):
    """Creates a new shopping product ad group in the specified campaign."""
    ad_group_service = client.get_service("AdGroupService")

    # Create ad group.
    ad_group_operation = client.get_type("AdGroupOperation")
    ad_group = ad_group_operation.create
    ad_group.name = f"Earth to Mars cruise {uuid.uuid4()}"
    ad_group.status = client.enums.AdGroupStatusEnum.ENABLED
    ad_group.campaign = campaign_resource_name
    # Sets the ad group type to SHOPPING_PRODUCT_ADS. This is the only value
    # possible for ad groups that contain shopping product ads.
    ad_group.type_ = client.enums.AdGroupTypeEnum.SHOPPING_PRODUCT_ADS
    ad_group.cpc_bid_micros = 10000000

    # Add the ad group.
    ad_group_response = ad_group_service.mutate_ad_groups(
        customer_id=customer_id, operations=[ad_group_operation]
    )

    ad_group_resource_name = ad_group_response.results[0].resource_name

    print(
        "Added a product shopping ad group with resource name "
        f"'{ad_group_resource_name}'."
    )

    return ad_group_resource_name


def add_standard_shopping_campaign(
    client, customer_id, budget_resource_name, merchant_center_account_id
):
    """Creates a new standard shopping campaign in the specified client account."""
    campaign_service = client.get_service("CampaignService")

    # Create standard shopping campaign.
    campaign_operation = client.get_type("CampaignOperation")
    campaign = campaign_operation.create
    campaign.name = f"Interplanetary Cruise Campaign {uuid.uuid4()}"

    # Configures settings related to shopping campaigns including advertising
    # channel type and shopping setting.
    campaign.advertising_channel_type = (
        client.enums.AdvertisingChannelTypeEnum.SHOPPING
    )
    campaign.shopping_setting.merchant_id = merchant_center_account_id

    # Sets the priority of the campaign. Higher numbers take priority over lower
    # numbers. For standard shopping campaigns, allowed values are between 0 and
    # 2, inclusive.
    campaign.shopping_setting.campaign_priority = 0

    # Enables local inventory ads for this campaign.
    campaign.shopping_setting.enable_local = True

    # Recommendation: Set the campaign to PAUSED when creating it to prevent the
    # ads from immediately serving. Set to ENABLED once you've added targeting
    # and the ads are ready to serve.
    campaign.status = client.enums.CampaignStatusEnum.PAUSED

    # Sets the bidding strategy to Manual CPC (with eCPC disabled). eCPC for
    # standard Shopping campaigns is deprecated. If eCPC is set to true, Google
    # Ads ignores the setting and behaves as if the setting was false. See this
    # blog post for more information:
    # https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
    # Recommendation: Use one of the automated bidding strategies for Shopping
    # campaigns to help you optimize your advertising spend. More information
    # can be found here: https://support.google.com/google-ads/answer/6309029
    campaign.manual_cpc.enhanced_cpc_enabled = False

    # Sets the budget.
    campaign.campaign_budget = budget_resource_name

    # Add the campaign.
    campaign_response = campaign_service.mutate_campaigns(
        customer_id=customer_id, operations=[campaign_operation]
    )

    campaign_resource_name = campaign_response.results[0].resource_name

    print(
        "Added a standard shopping campaign with resource name "
        f"'{campaign_resource_name}'."
    )

    return campaign_resource_name


def add_default_shopping_listing_group(
    client, customer_id, ad_group_resource_name
):
    """Creates a new default shopping listing group for the specified ad group.

    A listing group is the Google Ads API representation of a "product group"
    described in the Google Ads user interface. The listing group will be added
    to the ad group using an "ad group criterion". The criterion will contain
    the bid for a given listing group.
    """
    ad_group_criterion_service = client.get_service("AdGroupCriterionService")

    # Creates a new ad group criterion. This will contain the "default" listing
    # group (All products).
    ad_group_criterion_operation = client.get_type("AdGroupCriterionOperation")
    ad_group_criterion = ad_group_criterion_operation.create
    ad_group_criterion.ad_group = ad_group_resource_name
    ad_group_criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED
    ad_group_criterion.listing_group.type_ = (
        client.enums.ListingGroupTypeEnum.UNIT
    )
    #  Set the bid for products in this listing group unit.
    ad_group_criterion.cpc_bid_micros = 500000

    ad_group_criterion_response = (
        ad_group_criterion_service.mutate_ad_group_criteria(
            customer_id=customer_id, operations=[ad_group_criterion_operation]
        )
    )

    print(
        "Added an ad group criterion containing a listing group with "
        f"'{ad_group_criterion_response.results[0].resource_name}'."
    )


if __name__ == "__main__":
    # GoogleAdsClient will read the google-ads.yaml configuration file in the
    # home directory if none is specified.
    googleads_client = GoogleAdsClient.load_from_storage(version="v16")

    parser = argparse.ArgumentParser(
        description=(
            "Adds a standard shopping campaign, a shopping product ad "
            "group and a shopping product ad to the specified "
            "merchant account."
        )
    )
    # 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(
        "-m",
        "--merchant_center_account_id",
        type=int,
        required=True,
        help="The merchant center account ID.",
    )
    parser.add_argument(
        "-d",
        "--create_default_listing_group",
        action="store_true",
        default=False,
        help="Create a default listing group.",
    )
    args = parser.parse_args()

    try:
        main(
            googleads_client,
            args.customer_id,
            args.merchant_center_account_id,
            args.create_default_listing_group,
        )
    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)

      

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 creates a standard shopping product campaign, ad group, and ad.
#
# Prerequisite: You need to have access to a Merchant Center account. You can
# find instructions to create a Merchant Center account here:
# https://support.google.com/merchants/answer/188924
#
# This account must be linked to your Google Ads account.

require 'optparse'
require 'google/ads/google_ads'
require 'date'

def add_shopping_product_ad(
    customer_id, merchant_center_id, create_default_listing_group)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  budget_name = add_campaign_budget(client, customer_id)

  campaign_name = add_standard_shopping_campaign(
    client,
    customer_id,
    budget_name,
    merchant_center_id,
  )

  ad_group_name = add_shopping_product_ad_group(
    client,
    customer_id,
    campaign_name,
  )

  add_shopping_product_ad_group_ad(client, customer_id, ad_group_name)

  if create_default_listing_group
    # The default listing group will be for 'All products' and will contain
    # a single biddable unit node.
    add_default_shopping_listing_group(client, customer_id, ad_group_name)
  end
end

def add_campaign_budget(client, customer_id)

  operation = client.operation.create_resource.campaign_budget do |budget|
    budget.name = "Interplanetary Budget ##{(Time.new.to_f * 1000).to_i}"
    budget.delivery_method = :STANDARD
    budget.amount_micros = 500_000
  end

  service = client.service.campaign_budget
  response = service.mutate_campaign_budgets(
    customer_id: customer_id,
    operations: [operation],
  )

  budget_name = response.results.first.resource_name

  puts "Added a budget with resource name: #{budget_name}"

  budget_name
end

def add_standard_shopping_campaign(
    client, customer_id, budget_name, merchant_center_id)

  operation = client.operation.create_resource.campaign do |campaign|
    campaign.name = "Interplanetary Cruise Campaign ##{(Time.new.to_f * 1000).to_i}"

    # Shopping campaign specific settings
    campaign.advertising_channel_type = :SHOPPING

    campaign.shopping_setting = client.resource.shopping_setting do |shopping_setting|
      shopping_setting.merchant_id = merchant_center_id
      shopping_setting.campaign_priority = 0
      shopping_setting.enable_local = true
    end

    campaign.status = :PAUSED

    # Sets the bidding strategy to Manual CPC (with eCPC disabled). eCPC for standard
    # Shopping campaigns is deprecated. If eCPC is set to true, Google Ads ignores the
    # setting and behaves as if the setting was false. See this blog post for more
    # information:
    # https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
    campaign.manual_cpc = client.resource.manual_cpc do |manual_cpc|
      manual_cpc.enhanced_cpc_enabled = false
    end

    campaign.campaign_budget = budget_name
  end

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

  campaign_name = response.results.first.resource_name

  puts "Added a standard shopping campaign with resource name #{campaign_name}."

  campaign_name
end

def add_shopping_product_ad_group(client, customer_id, campaign_name)
  operation = client.operation.create_resource.ad_group do |ad_group|
    ad_group.name = "Earth to Mars cruise ##{(Time.new.to_f * 1000).to_i}"
    ad_group.status = :ENABLED
    ad_group.campaign = campaign_name
    ad_group.type = :SHOPPING_PRODUCT_ADS
    ad_group.cpc_bid_micros = 10_000_000
  end

  service = client.service.ad_group
  response = service.mutate_ad_groups(
    customer_id: customer_id,
    operations: [operation],
  )

  ad_group_name = response.results.first.resource_name

  puts "Added a product shopping ad group with resource name #{ad_group_name}."

  ad_group_name
end

def add_shopping_product_ad_group_ad(client, customer_id, ad_group_name)

  operation = client.operation.create_resource.ad_group_ad do |ad_group_ad|
    ad_group_ad.ad_group = ad_group_name
    ad_group_ad.status = :PAUSED
    ad_group_ad.ad = client.resource.ad do |ad|
      ad.shopping_product_ad = client.resource.shopping_product_ad_info
    end
  end

  service = client.service.ad_group_ad
  response = service.mutate_ad_group_ads(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Created shopping product ad group ad " \
       "#{response.results.first.resource_name}"
end

def add_default_shopping_listing_group(client, customer_id, ad_group_name)

  operation = client.operation.create_resource.ad_group_criterion do |criterion|
    criterion.ad_group = ad_group_name
    criterion.status = :ENABLED
    criterion.listing_group = client.resource.listing_group_info do |lgi|
      lgi.type = :UNIT
    end

    criterion.cpc_bid_micros = 500_000
  end

  service = client.service.ad_group_criterion
  response = service.mutate_ad_group_criteria(
    customer_id: customer_id,
    operations: [operation]
  )

  puts "Added an ad group criterion containing a listing group with resource " \
       "name #{response.results.first.resource_name}."
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[:merchant_center_id] = 'INSERT_MERCHANT_CENTER_ID_HERE'
  # Specifying any value for this field on the command line will override this
  # to true.
  options[:create_default_listing_group] = 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('-M', '--merchant-center-account-id MERCHANT-CENTER-ACCOUNT-ID', Integer,
        'Merchant Center ID') do |v|
      options[:merchant_center_id] = v
    end

    opts.on('-d', '--create-default-listing-group CREATE-DEFAULT-LISTING-GROUP',
        TrueClass, 'Create Default Listing Group') do |v|
      options[:create_default_listing_group] = v
    end

    opts.separator ''
    opts.separator 'Help:'

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end
  end.parse!

  begin
    add_shopping_product_ad(
      options.fetch(:customer_id).tr("-", ""),
      options.fetch(:merchant_center_id),
      options.fetch(:create_default_listing_group),
    )
  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.location.field_path_elements.each do |field_path_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

      

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 creates a standard shopping campaign, a shopping product ad group
# and a shopping product ad.
#
# Prerequisite: You need to have access to a Merchant Center account. You can
# find instructions to create a Merchant Center account here:
# https://support.google.com/merchants/answer/188924
# This account must be linked to your Google Ads account.

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::V16::Resources::CampaignBudget;
use Google::Ads::GoogleAds::V16::Resources::Campaign;
use Google::Ads::GoogleAds::V16::Resources::ShoppingSetting;
use Google::Ads::GoogleAds::V16::Resources::AdGroup;
use Google::Ads::GoogleAds::V16::Resources::AdGroupAd;
use Google::Ads::GoogleAds::V16::Resources::Ad;
use Google::Ads::GoogleAds::V16::Resources::AdGroupCriterion;
use Google::Ads::GoogleAds::V16::Common::ManualCpc;
use Google::Ads::GoogleAds::V16::Common::ShoppingProductAdInfo;
use Google::Ads::GoogleAds::V16::Common::ListingGroupInfo;
use Google::Ads::GoogleAds::V16::Enums::BudgetDeliveryMethodEnum   qw(STANDARD);
use Google::Ads::GoogleAds::V16::Enums::AdvertisingChannelTypeEnum qw(SHOPPING);
use Google::Ads::GoogleAds::V16::Enums::AdGroupTypeEnum
  qw(SHOPPING_PRODUCT_ADS);
use Google::Ads::GoogleAds::V16::Enums::CampaignStatusEnum;
use Google::Ads::GoogleAds::V16::Enums::AdGroupStatusEnum;
use Google::Ads::GoogleAds::V16::Enums::AdGroupAdStatusEnum;
use Google::Ads::GoogleAds::V16::Enums::ListingGroupTypeEnum qw(UNIT);
use Google::Ads::GoogleAds::V16::Enums::AdGroupCriterionStatusEnum;
use
  Google::Ads::GoogleAds::V16::Services::CampaignBudgetService::CampaignBudgetOperation;
use Google::Ads::GoogleAds::V16::Services::CampaignService::CampaignOperation;
use Google::Ads::GoogleAds::V16::Services::AdGroupService::AdGroupOperation;
use Google::Ads::GoogleAds::V16::Services::AdGroupAdService::AdGroupAdOperation;
use
  Google::Ads::GoogleAds::V16::Services::AdGroupCriterionService::AdGroupCriterionOperation;

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 $merchant_center_account_id   = "INSERT_MERCHANT_CENTER_ACCOUNT_ID_HERE";
my $create_default_listing_group = undef;

sub add_shopping_product_ad {
  my ($api_client, $customer_id, $merchant_center_account_id,
    $create_default_listing_group)
    = @_;

  # Create a budget to be used by the campaign that will be created below.
  my $budget_resource_name = add_campaign_budget($api_client, $customer_id);

  # Create a standard shopping campaign.
  my $campaign_resource_name =
    add_standard_shopping_campaign($api_client, $customer_id,
    $budget_resource_name, $merchant_center_account_id);

  # Create a shopping product ad group.
  my $ad_group_resource_name =
    add_shopping_product_ad_group($api_client, $customer_id,
    $campaign_resource_name);

  # Create a shopping product ad group ad.
  add_shopping_product_ad_group_ad($api_client, $customer_id,
    $ad_group_resource_name);

  if ($create_default_listing_group) {
    # Create an ad group criterion containing a listing group.
    # This will be the listing group tree for 'All products' and will
    # contain a single biddable unit node.
    add_default_shopping_listing_group($api_client, $customer_id,
      $ad_group_resource_name);
  }

  return 1;
}

# Creates a new campaign budget in the specified client account.
sub add_campaign_budget {
  my ($api_client, $customer_id) = @_;

  # Create a campaign budget.
  my $campaign_budget =
    Google::Ads::GoogleAds::V16::Resources::CampaignBudget->new({
      name           => "Interplanetary Cruise Budget #" . uniqid(),
      deliveryMethod => STANDARD,
      # Set the amount of budget.
      amountMicros => 5000000
    });

  # Create a campaign budget operation.
  my $campaign_budget_operation =
    Google::Ads::GoogleAds::V16::Services::CampaignBudgetService::CampaignBudgetOperation
    ->new({create => $campaign_budget});

  # Add the campaign budget.
  my $campaign_budget_resource_name =
    $api_client->CampaignBudgetService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_budget_operation]})->{results}[0]{resourceName};

  printf "Added a budget with resource name: '%s'.\n",
    $campaign_budget_resource_name;

  return $campaign_budget_resource_name;
}

# Creates a new standard shopping campaign in the specified client account.
sub add_standard_shopping_campaign {
  my ($api_client, $customer_id, $budget_resource_name,
    $merchant_center_account_id)
    = @_;

  # Create a standard shopping campaign.
  my $campaign = Google::Ads::GoogleAds::V16::Resources::Campaign->new({
      name => "Interplanetary Cruise Campaign #" . uniqid(),
      # Configure settings related to shopping campaigns including advertising
      # channel type and shopping setting.
      advertisingChannelType => SHOPPING,
      shoppingSetting        =>
        Google::Ads::GoogleAds::V16::Resources::ShoppingSetting->new({
          merchantId => $merchant_center_account_id,
          # Set the priority of the campaign. Higher numbers take priority over
          # lower numbers. For standard shopping campaigns, allowed values are
          # between 0 and 2, inclusive.
          campaignPriority => 0,
          # Enable local inventory ads for this campaign.
          enableLocal => "true"
        }
        ),
      # Recommendation: Set the campaign to PAUSED when creating it to prevent
      # the ads from immediately serving. Set to ENABLED once you've added
      # targeting and the ads are ready to serve.
      status => Google::Ads::GoogleAds::V16::Enums::CampaignStatusEnum::PAUSED,
      # Set the bidding strategy to Manual CPC (with eCPC disabled). eCPC for
      # standard Shopping campaigns is deprecated. If eCPC is set to true,
      # Google Ads ignores the setting and behaves as if the setting was false.
      # See this blog post for more information:
      # https://ads-developers.googleblog.com/2023/09/google-ads-shopping-campaign-enhanced.html
      # Recommendation: Use one of the automated bidding strategies for shopping
      # campaigns to help you optimize your advertising spend. More information
      # can be found here: https://support.google.com/google-ads/answer/6309029.
      manualCpc => Google::Ads::GoogleAds::V16::Common::ManualCpc->new(
        {enhancedCpcEnabled => "false"}
      ),
      # Set the budget.
      campaignBudget => $budget_resource_name
    });

  # Create a campaign operation.
  my $campaign_operation =
    Google::Ads::GoogleAds::V16::Services::CampaignService::CampaignOperation->
    new({create => $campaign});

  # Add the campaign.
  my $campaign_resource_name = $api_client->CampaignService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_operation]})->{results}[0]{resourceName};

  printf "Added a standard shopping campaign with resource name: '%s'.\n",
    $campaign_resource_name;

  return $campaign_resource_name;
}

# Creates a new shopping product ad group in the specified campaign.
sub add_shopping_product_ad_group {
  my ($api_client, $customer_id, $campaign_resource_name) = @_;

  # Create an ad group.
  my $ad_group = Google::Ads::GoogleAds::V16::Resources::AdGroup->new({
    name     => "Earth to Mars Cruises #" . uniqid(),
    campaign => $campaign_resource_name,
    # Set the ad group type to SHOPPING_PRODUCT_ADS. This is the only value
    # possible for ad groups that contain shopping product ads.
    type         => SHOPPING_PRODUCT_ADS,
    cpcBidMicros => 1000000,
    status => Google::Ads::GoogleAds::V16::Enums::AdGroupStatusEnum::ENABLED
  });

  # Create an ad group operation.
  my $ad_group_operation =
    Google::Ads::GoogleAds::V16::Services::AdGroupService::AdGroupOperation->
    new({create => $ad_group});

  # Add the ad group.
  my $ad_group_resource_name = $api_client->AdGroupService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_operation]})->{results}[0]{resourceName};

  printf "Added a product shopping ad group with resource name: '%s'.\n",
    $ad_group_resource_name;

  return $ad_group_resource_name;
}

# Creates a new shopping product ad group ad in the specified ad group.
sub add_shopping_product_ad_group_ad {
  my ($api_client, $customer_id, $ad_group_resource_name) = @_;

  # Create an ad group ad and set a shopping product ad to it.
  my $ad_group_ad = Google::Ads::GoogleAds::V16::Resources::AdGroupAd->new({
      # Set the ad group.
      adGroup => $ad_group_resource_name,
      # Set the ad to a new shopping product ad.
      ad => Google::Ads::GoogleAds::V16::Resources::Ad->new({
          shoppingProductAd =>
            Google::Ads::GoogleAds::V16::Common::ShoppingProductAdInfo->new()}
      ),
      status => Google::Ads::GoogleAds::V16::Enums::AdGroupAdStatusEnum::PAUSED
    });

  # Create an ad group ad operation.
  my $ad_group_ad_operation =
    Google::Ads::GoogleAds::V16::Services::AdGroupAdService::AdGroupAdOperation
    ->new({create => $ad_group_ad});

  # Add the ad group ad.
  my $ad_group_ad_resource_name = $api_client->AdGroupAdService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_ad_operation]})->{results}[0]{resourceName};

  printf "Added a product shopping ad group ad with resource name: '%s'.\n",
    $ad_group_ad_resource_name;

  return $ad_group_ad_resource_name;
}

# Creates a new default shopping listing group for the specified ad group. A listing
# group is the Google Ads API representation of a "product group" described in the
# Google Ads user interface. The listing group will be added to the ad group using an
# "ad group criterion". The criterion will contain the bid for a given listing group.
sub add_default_shopping_listing_group {
  my ($api_client, $customer_id, $ad_group_resource_name) = @_;

  # Create a new ad group criterion. This will contain the "default" listing group
  # (All products).
  my $ad_group_criterion =
    Google::Ads::GoogleAds::V16::Resources::AdGroupCriterion->new({
      # Set the ad group.
      adGroup => $ad_group_resource_name,
      # Create a new listing group. This will be the top-level "root" node.
      # Set the type of the listing group to be a biddable unit.
      listingGroup =>
        Google::Ads::GoogleAds::V16::Common::ListingGroupInfo->new({
          type => UNIT
        }
        ),
      # Set the bid for products in this listing group unit.
      cpcBidMicros => 500000,
      status       =>
        Google::Ads::GoogleAds::V16::Enums::AdGroupCriterionStatusEnum::ENABLED
    });

  # Create an ad group criterion operation.
  my $ad_group_criterion_operation =
    Google::Ads::GoogleAds::V16::Services::AdGroupCriterionService::AdGroupCriterionOperation
    ->new({create => $ad_group_criterion});

  # Add the listing group criterion.
  my $ad_group_criterion_resource_name =
    $api_client->AdGroupCriterionService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_criterion_operation]}
  )->{results}[0]{resourceName};

  printf "Added an ad group criterion containing a listing group " .
    "with resource name: '%s'.\n", $ad_group_criterion_resource_name;

  return $ad_group_criterion_resource_name;
}

# 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 default examples are set to die on any server returned 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,
  "merchant_center_account_id=i"   => \$merchant_center_account_id,
  "create_default_listing_group=s" => \$create_default_listing_group
);

# 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, $merchant_center_account_id);

# Call the example.
add_shopping_product_ad($api_client, $customer_id =~ s/-//gr,
  $merchant_center_account_id, $create_default_listing_group);

=pod

=head1 NAME

add_shopping_product_ad

=head1 DESCRIPTION

This example creates a standard shopping campaign, a shopping product ad group
and a shopping product ad.

Prerequisite: You need to have access to a Merchant Center account. You can find
instructions to create a Merchant Center account here:
https://support.google.com/merchants/answer/188924
This account must be linked to your Google Ads account.

=head1 SYNOPSIS

add_shopping_product_ad.pl [options]

    -help                           Show the help message.
    -customer_id                    The Google Ads customer ID.
    -merchant_center_account_id     The Merchant Center account ID.
    -create_default_listing_group   [optional] Create default listing group.

=cut