Add Merchant Center Dynamic Remarketing Campaign

Java

// 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.

package com.google.ads.googleads.examples.remarketing;

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.AdImageAsset;
import com.google.ads.googleads.v16.common.AdTextAsset;
import com.google.ads.googleads.v16.common.ImageAsset;
import com.google.ads.googleads.v16.common.ManualCpc;
import com.google.ads.googleads.v16.common.ResponsiveDisplayAdInfo;
import com.google.ads.googleads.v16.common.UserListInfo;
import com.google.ads.googleads.v16.enums.AdGroupStatusEnum.AdGroupStatus;
import com.google.ads.googleads.v16.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType;
import com.google.ads.googleads.v16.enums.AssetTypeEnum.AssetType;
import com.google.ads.googleads.v16.enums.CampaignStatusEnum.CampaignStatus;
import com.google.ads.googleads.v16.enums.DisplayAdFormatSettingEnum.DisplayAdFormatSetting;
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.Asset;
import com.google.ads.googleads.v16.resources.Campaign;
import com.google.ads.googleads.v16.resources.Campaign.ShoppingSetting;
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.AssetOperation;
import com.google.ads.googleads.v16.services.AssetServiceClient;
import com.google.ads.googleads.v16.services.CampaignOperation;
import com.google.ads.googleads.v16.services.CampaignServiceClient;
import com.google.ads.googleads.v16.services.MutateAdGroupAdsResponse;
import com.google.ads.googleads.v16.services.MutateAdGroupCriteriaResponse;
import com.google.ads.googleads.v16.services.MutateAdGroupsResponse;
import com.google.ads.googleads.v16.services.MutateAssetsResponse;
import com.google.ads.googleads.v16.services.MutateCampaignsResponse;
import com.google.ads.googleads.v16.utils.ResourceNames;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.protobuf.ByteString;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

/**
 * Creates a shopping campaign associated with an existing merchant center account, along with a
 * related ad group and dynamic display ad, and targets a user list for remarketing purposes.
 */
public class AddMerchantCenterDynamicRemarketingCampaign {
  private static class AddMerchantCenterDynamicRemarketingCampaignParams 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.CAMPAIGN_BUDGET_ID, required = true)
    private long campaignBudgetId;

    @Parameter(names = ArgumentNames.USER_LIST_ID, required = true)
    private long userListId;
  }

  public static void main(String[] args) throws IOException {
    AddMerchantCenterDynamicRemarketingCampaignParams params =
        new AddMerchantCenterDynamicRemarketingCampaignParams();
    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.campaignBudgetId = Long.parseLong("INSERT_CAMPAIGN_BUDGET_ID_HERE");
      params.userListId = Long.parseLong("INSERT_USER_LIST_ID_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 AddMerchantCenterDynamicRemarketingCampaign().runExample(googleAdsClient, params);
    } 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 params the AddMerchantCenterDynamicRemarketingCampaignParams for the example.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void runExample(
      GoogleAdsClient googleAdsClient, AddMerchantCenterDynamicRemarketingCampaignParams params)
      throws IOException {
    // Creates a shopping campaign associated with a given merchant center account.
    String campaignResourceName =
        createCampaign(
            googleAdsClient,
            params.customerId,
            params.merchantCenterAccountId,
            params.campaignBudgetId);
    // Creates an ad group for the campaign.
    String adGroupResourceName =
        createAdGroup(googleAdsClient, params.customerId, campaignResourceName);
    // Creates a dynamic display ad in the ad group.
    createAd(googleAdsClient, params.customerId, adGroupResourceName);
    // Targets a specific user list for remarketing.
    attachUserList(googleAdsClient, params.customerId, adGroupResourceName, params.userListId);
  }

  /**
   * Creates a campaign linked to a Merchant Center product feed.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param merchantCenterAccountId the Merchant Center account ID.
   * @param campaignBudgetId the campaign budget ID.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String createCampaign(
      GoogleAdsClient googleAdsClient,
      long customerId,
      long merchantCenterAccountId,
      long campaignBudgetId) {
    String budgetResourceName = ResourceNames.campaignBudget(customerId, campaignBudgetId);

    // Creates the campaign.
    Campaign campaign =
        Campaign.newBuilder()
            .setName("Shopping campaign #" + getPrintableDateTime())
            // Dynamic remarketing campaigns are only available on the Google Display Network.
            .setAdvertisingChannelType(AdvertisingChannelType.DISPLAY)
            .setStatus(CampaignStatus.PAUSED)
            .setCampaignBudget(budgetResourceName)
            .setManualCpc(ManualCpc.newBuilder().build())
            // The settings for the shopping campaign.
            // This connects the campaign to the merchant center account.
            .setShoppingSetting(
                ShoppingSetting.newBuilder()
                    .setCampaignPriority(0)
                    .setMerchantId(merchantCenterAccountId)
                    .setEnableLocal(true)
                    .build())
            .build();

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

    // Creates the campaign service client.
    try (CampaignServiceClient campaignServiceClient =
        googleAdsClient.getLatestVersion().createCampaignServiceClient()) {
      // Adds the campaign.
      MutateCampaignsResponse response =
          campaignServiceClient.mutateCampaigns(
              Long.toString(customerId), ImmutableList.of(operation));
      String campaignResourceName = response.getResults(0).getResourceName();
      System.out.printf("Created campaign with resource name '%s'.%n", campaignResourceName);
      return campaignResourceName;
    }
  }


  /**
   * Creates an ad group for the remarketing campaign.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param campaignResourceName the campaign resource name.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String createAdGroup(
      GoogleAdsClient googleAdsClient, long customerId, String campaignResourceName) {
    // Creates the ad group.
    AdGroup adGroup =
        AdGroup.newBuilder()
            .setName("Dynamic remarketing ad group")
            .setCampaign(campaignResourceName)
            .setStatus(AdGroupStatus.ENABLED)
            .build();

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

    // Creates the ad group service client.
    try (AdGroupServiceClient adGroupServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupServiceClient()) {
      // Adds the ad group.
      MutateAdGroupsResponse response =
          adGroupServiceClient.mutateAdGroups(
              Long.toString(customerId), ImmutableList.of(operation));
      String adGroupResourceName = response.getResults(0).getResourceName();
      System.out.printf("Created ad group with resource name '%s'.%n", adGroupResourceName);
      return adGroupResourceName;
    }
  }


  /**
   * Creates the responsive display ad.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param adGroupResourceName the campaign resource name.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void createAd(
      GoogleAdsClient googleAdsClient, long customerId, String adGroupResourceName)
      throws IOException {
    String marketingImageUrl = "https://gaagl.page.link/Eit5";
    String marketingImageName = "Marketing Image";
    String marketingImageResourceName =
        uploadAsset(googleAdsClient, customerId, marketingImageUrl, marketingImageName);
    String squareMarketingImageName = "Square Marketing Image";
    String squareMarketingImageUrl = "https://gaagl.page.link/bjYi";
    String squareMarketingImageResourceName =
        uploadAsset(googleAdsClient, customerId, squareMarketingImageUrl, squareMarketingImageName);

    // Creates the responsive display ad info object.
    ResponsiveDisplayAdInfo responsiveDisplayAdInfo =
        ResponsiveDisplayAdInfo.newBuilder()
            .addMarketingImages(
                AdImageAsset.newBuilder().setAsset(marketingImageResourceName).build())
            .addSquareMarketingImages(
                AdImageAsset.newBuilder().setAsset(squareMarketingImageResourceName).build())
            .addHeadlines(AdTextAsset.newBuilder().setText("Travel").build())
            .setLongHeadline(AdTextAsset.newBuilder().setText("Travel the World").build())
            .addDescriptions(AdTextAsset.newBuilder().setText("Take to the air!").build())
            .setBusinessName("Interplanetary Cruises")
            // Optional: Call to action text.
            // Valid texts: https://support.google.com/adwords/answer/7005917
            .setCallToActionText("Apply Now")
            // Optional: Sets the ad colors.
            .setMainColor("#0000ff")
            .setAccentColor("#ffff00")
            // Optional: Sets to false to strictly render the ad using the colors.
            .setAllowFlexibleColor(false)
            // Optional: Sets the format setting that the ad will be served in.
            .setFormatSetting(DisplayAdFormatSetting.NON_NATIVE)
            // Optional: Creates a logo image and sets it to the ad.
            /*
            .addLogoImages(
                AdImageAsset.newBuilder()
                    .setAsset(StringValue.of("INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE"))
                    .build())
            */
            // Optional: Creates a square logo image and sets it to the ad.
            /*
            .addSquareLogoImages(
                AdImageAsset.newBuilder()
                    .setAsset(StringValue.of("INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE"))
                    .build())
            */
            .build();

    // Creates the ad.
    Ad ad =
        Ad.newBuilder()
            .setResponsiveDisplayAd(responsiveDisplayAdInfo)
            .addFinalUrls("http://www.example.com/")
            .build();

    // Creates the ad group ad.
    AdGroupAd adGroupAd = AdGroupAd.newBuilder().setAdGroup(adGroupResourceName).setAd(ad).build();

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

    // Creates the ad group ad service client.
    try (AdGroupAdServiceClient adGroupAdServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) {
      // Adds the ad group ad.
      MutateAdGroupAdsResponse response =
          adGroupAdServiceClient.mutateAdGroupAds(
              Long.toString(customerId), ImmutableList.of(operation));
      System.out.printf(
          "Created ad group ad with resource name '%s'.%n",
          response.getResults(0).getResourceName());
    }
  }


  /**
   * Adds an image to the Google Ads account.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param imageUrl the url of the image.
   * @param assetName the name of the asset.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String uploadAsset(
      GoogleAdsClient googleAdsClient, long customerId, String imageUrl, String assetName)
      throws IOException {
    byte[] imageData = ByteStreams.toByteArray(new URL(imageUrl).openStream());

    // Creates the image asset.
    Asset asset =
        Asset.newBuilder()
            .setName(assetName)
            .setType(AssetType.IMAGE)
            .setImageAsset(ImageAsset.newBuilder().setData(ByteString.copyFrom(imageData)).build())
            .build();

    // Creates the asset operation.
    AssetOperation operation = AssetOperation.newBuilder().setCreate(asset).build();

    // Creates the asset service client.
    try (AssetServiceClient assetServiceClient =
        googleAdsClient.getLatestVersion().createAssetServiceClient()) {
      // Adds the image asset.
      MutateAssetsResponse response =
          assetServiceClient.mutateAssets(Long.toString(customerId), ImmutableList.of(operation));
      String imageResourceName = response.getResults(0).getResourceName();
      System.out.printf("Created image asset with resource name '%s'.%n", imageResourceName);
      return imageResourceName;
    }
  }

  /**
   * Targets a user list.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param adGroupResourceName the campaign resource name.
   * @param userListId ID of the user list.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void attachUserList(
      GoogleAdsClient googleAdsClient,
      long customerId,
      String adGroupResourceName,
      long userListId) {
    String userListResourceName = ResourceNames.userList(customerId, userListId);
    // Creates the ad group criterion that targets the user list.
    AdGroupCriterion adGroupCriterion =
        AdGroupCriterion.newBuilder()
            .setAdGroup(adGroupResourceName)
            .setUserList(UserListInfo.newBuilder().setUserList(userListResourceName).build())
            .build();

    // Creates the ad group criterion operation.
    AdGroupCriterionOperation operation =
        AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build();

    // Creates the ad group criterion service client.
    try (AdGroupCriterionServiceClient adGroupCriterionServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) {
      // Adds the ad group criterion.
      MutateAdGroupCriteriaResponse response =
          adGroupCriterionServiceClient.mutateAdGroupCriteria(
              Long.toString(customerId), ImmutableList.of(operation));
      System.out.printf(
          "Created ad group criterion with resource name '%s'.%n",
          response.getResults(0).getResourceName());
    }
  }
}

      

C#

// 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
//
//     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.Gax.Util;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.Util;
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 Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using static Google.Ads.GoogleAds.V16.Enums.AdGroupStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AdvertisingChannelTypeEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.AssetTypeEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.CampaignStatusEnum.Types;
using static Google.Ads.GoogleAds.V16.Enums.DisplayAdFormatSettingEnum.Types;

namespace Google.Ads.GoogleAds.Examples.V16
{
    /// <summary>
    /// This code example creates a shopping campaign associated with an existing Merchant Center
    /// account, along with a related ad group and responsive display ad, and targets a user list
    /// for remarketing purposes.
    /// </summary>
    public class AddMerchantCenterDynamicRemarketingCampaign : ExampleBase
    {
        /// <summary>
        /// Command line options for running the
        /// <see cref="AddMerchantCenterDynamicRemarketingCampaign"/> 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>
            /// ID of the Merchant Center account to be associated with the new campaign.
            /// </summary>
            [Option("merchantCenterAccountId", Required = true, HelpText =
                "ID of the Merchant Center account to be associated with the new campaign.")]
            public long MerchantCenterAccountId { get; set; }

            /// <summary>
            /// ID of the campaign budget to be associated with the new campaign.
            /// </summary>
            [Option("campaignBudgetId", Required = true, HelpText =
                "ID of the campaign budget to be associated with the new campaign.")]
            public long CampaignBudgetId { get; set; }

            /// <summary>
            /// ID of the user list to be used for remarketing.
            /// </summary>
            [Option("userListId", Required = true, HelpText =
                "ID of the user list to be used for remarketing.")]
            public long UserListId { 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);

            AddMerchantCenterDynamicRemarketingCampaign codeExample =
                new AddMerchantCenterDynamicRemarketingCampaign();
            Console.WriteLine(codeExample.Description);
            codeExample.Run(new GoogleAdsClient(), options.CustomerId,
                options.MerchantCenterAccountId, options.CampaignBudgetId, options.UserListId);
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This code example creates a shopping campaign associated with an existing Merchant " +
            "Center account, along with a related ad group and responsive display ad, and " +
            "targets a user list for remarketing purposes.";

        /// <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">ID of the Merchant Center account to be
        /// associated with the new campaign.</param>
        /// <param name="campaignBudgetId">ID of the campaign budget to be associated with the new
        /// campaign.</param>
        /// <param name="userListId">ID of the user list to be used for remarketing.</param>
        public void Run(GoogleAdsClient client, long customerId, long merchantCenterAccountId,
            long campaignBudgetId, long userListId)
        {
            try
            {
                // Creates a shopping campaign associated with a given Merchant Center account.
                string campaignResourceName = CreateCampaign(client, customerId,
                    merchantCenterAccountId, campaignBudgetId);

                // Creates an ad group for the campaign.
                string adGroupResourceName = CreateAdGroup(client, customerId,
                    campaignResourceName);

                // Creates a responsive display ad in the ad group.
                CreateAd(client, customerId, adGroupResourceName);

                // Targets a specific user list for remarketing.
                AttachUserList(client, customerId, adGroupResourceName, userListId);
            }
            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 campaign linked to a Merchant Center product feed.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="merchantCenterAccountId">The Merchant Center account ID.</param>
        /// <param name="campaignBudgetId">The campaign budget ID.</param>
        /// <returns>The string resource name for the newly created campaign.</returns>
        private string CreateCampaign(GoogleAdsClient client, long customerId,
            long merchantCenterAccountId, long campaignBudgetId)
        {
            // Creates the Campaign Service client.
            CampaignServiceClient campaignServiceClient =
                client.GetService(Services.V16.CampaignService);

            string budgetResourceName = ResourceNames.CampaignBudget(customerId, campaignBudgetId);

            // Creates the campaign.
            Campaign campaign = new Campaign()
            {
                Name = "Shopping campaign #" + ExampleUtilities.GetRandomString(),
                // Dynamic remarketing campaigns are only available on the Google Display Network.
                AdvertisingChannelType = AdvertisingChannelType.Display,
                Status = CampaignStatus.Paused,
                CampaignBudget = budgetResourceName,
                ManualCpc = new ManualCpc(),
                // The settings for the shopping campaign.
                // This connects the campaign to the Merchant Center account.
                ShoppingSetting = new Campaign.Types.ShoppingSetting()
                {
                    CampaignPriority = 0,
                    MerchantId = merchantCenterAccountId,
                    EnableLocal = true
                }
            };

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

            // Adds the campaign.
            MutateCampaignsResponse response = campaignServiceClient.MutateCampaigns(customerId
                .ToString(), new[] { operation });
            string campaignResourceName = response.Results.First().ResourceName;
            Console.WriteLine($"Created campaign with resource name '{campaignResourceName}'.");
            return campaignResourceName;
        }

        /// <summary>
        /// Creates an ad group for the remarketing campaign.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="campaignResourceName">The campaign resource name.</param>
        /// <returns>The string resource name for the newly created ad group.</returns>
        private string CreateAdGroup(GoogleAdsClient client, long customerId,
            string campaignResourceName)
        {
            // Creates the ad group service client.
            AdGroupServiceClient adGroupServiceClient =
                client.GetService(Services.V16.AdGroupService);

            // Creates the ad group.
            AdGroup adGroup = new AdGroup()
            {
                Name = "Dynamic remarketing ad group",
                Campaign = campaignResourceName,
                Status = AdGroupStatus.Enabled
            };

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

            // Adds the ad group.
            MutateAdGroupsResponse response = adGroupServiceClient.MutateAdGroups(
                customerId.ToString(), new[] { operation });

            string adGroupResourceName = response.Results.First().ResourceName;
            Console.WriteLine($"Created ad group with resource name '{adGroupResourceName}'.");
            return adGroupResourceName;
        }

        /// <summary>
        /// Creates the responsive display ad.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="adGroupResourceName">The ad group resource name to receive the ad.</param>
        private void CreateAd(GoogleAdsClient client, long customerId, string adGroupResourceName)
        {
            // Creates the ad group ad service client.
            AdGroupAdServiceClient adGroupAdServiceClient =
                client.GetService(Services.V16.AdGroupAdService);

            string marketingImageUrl = "https://gaagl.page.link/Eit5";
            string marketingImageName = "Marketing Image";
            string marketingImageResourceName =
                UploadAsset(client, customerId, marketingImageUrl, marketingImageName);
            string squareMarketingImageName = "Square Marketing Image";
            string squareMarketingImageUrl = "https://gaagl.page.link/bjYi";
            string squareMarketingImageResourceName =
                UploadAsset(client, customerId, squareMarketingImageUrl, squareMarketingImageName);

            // Creates the responsive display ad info object.
            ResponsiveDisplayAdInfo responsiveDisplayAdInfo = new ResponsiveDisplayAdInfo()
            {
                MarketingImages =
                {
                    new AdImageAsset()
                    {
                        Asset = marketingImageResourceName
                    }
                },
                SquareMarketingImages =
                {
                    new AdImageAsset()
                    {
                        Asset = squareMarketingImageResourceName
                    }
                },
                Headlines =
                {
                    new AdTextAsset()
                    {
                        Text = "Travel"
                    }
                },
                LongHeadline = new AdTextAsset()
                {
                    Text = "Travel the World"
                },
                Descriptions =
                {
                    new AdTextAsset()
                    {
                        Text = "Take to the air!"
                    }
                },
                BusinessName = "Interplanetary Cruises",
                // Optional: Call to action text.
                // Valid texts: https://support.google.com/adwords/answer/7005917
                CallToActionText = "Apply Now",
                // Optional: Sets the ad colors.
                MainColor = "#0000ff",
                AccentColor = "#ffff00",
                // Optional: Sets to false to strictly render the ad using the colors.
                AllowFlexibleColor = false,
                // Optional: Sets the format setting that the ad will be served in.
                FormatSetting = DisplayAdFormatSetting.NonNative,
                // Optional: Creates a logo image and sets it to the ad.
                /*
                    LogoImages = { new AdImageAsset()
                    {
                        Asset = "INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE"
                    }}
                */
                // Optional: Creates a square logo image and sets it to the ad.
                /*
                    SquareLogoImages = { new AdImageAsset()
                    {
                        Asset = "INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE"
                    }}
                */
            };

            // Creates the ad.
            Ad ad = new Ad()
            {
                ResponsiveDisplayAd = responsiveDisplayAdInfo,
                FinalUrls = { "http://www.example.com/" }
            };

            // Creates the ad group ad.
            AdGroupAd adGroupAd = new AdGroupAd()
            {
                AdGroup = adGroupResourceName,
                Ad = ad
            };

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

            // Adds the ad group ad.
            MutateAdGroupAdsResponse response = adGroupAdServiceClient.MutateAdGroupAds
                (customerId.ToString(), new[] { operation });
            Console.WriteLine("Created ad group ad with resource name " +
                              $"'{response.Results.First().ResourceName}'.");
        }

        /// <summary>
        /// Adds an image to the Google Ads account.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="imageUrl">The URL of the image.</param>
        /// <param name="assetName">The name of the asset.</param>
        /// <returns>The string resource name of the newly uploaded asset.</returns>
        private string UploadAsset(GoogleAdsClient client, long customerId,
            string imageUrl, string assetName)
        {
            // Creates the asset service client.
            AssetServiceClient assetServiceClient = client.GetService(Services.V16.AssetService);

            byte[] imageData = MediaUtilities.GetAssetDataFromUrl(imageUrl, client.Config);

            // Creates the image asset.
            Asset asset = new Asset()
            {
                Name = assetName,
                Type = AssetType.Image,
                ImageAsset = new ImageAsset()
                {
                    Data = ByteString.CopyFrom(imageData)
                }
            };

            // Creates the asset operation.
            AssetOperation operation = new AssetOperation()
            {
                Create = asset
            };

            // Adds the image asset.
            MutateAssetsResponse response = assetServiceClient.MutateAssets(customerId.ToString()
                , new[] { operation });
            string imageResourceName = response.Results.First().ResourceName;
            Console.WriteLine($"Created image asset with resource name '{imageResourceName}'.");
            return imageResourceName;
        }

        /// <summary>
        /// Targets the specified user list to 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 campaign resource name.</param>
        /// <param name="userListId">The user list ID.</param>
        private void AttachUserList(GoogleAdsClient client, long customerId,
            string adGroupResourceName, long userListId)
        {
            // Creates the ad group criterion service client.
            AdGroupCriterionServiceClient adGroupCriterionServiceClient = client.GetService
                (Services.V16.AdGroupCriterionService);

            string userListResourceName = ResourceNames.UserList(customerId, userListId);

            // Creates the ad group criterion that targets the user list.
            AdGroupCriterion adGroupCriterion = new AdGroupCriterion()
            {
                AdGroup = adGroupResourceName,
                UserList = new UserListInfo()
                {
                    UserList = userListResourceName
                }
            };

            // Creates the ad group criterion operation.
            AdGroupCriterionOperation operation = new AdGroupCriterionOperation()
            {
                Create = adGroupCriterion
            };

            // Adds the ad group criterion.
            MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient
                .MutateAdGroupCriteria(customerId.ToString(), new[] { operation });
            Console.WriteLine("Created ad group criterion with resource name " +
                              $"'{response.Results.First().ResourceName}'.");
        }
    }
}

      

PHP

<?php

/**
 * 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.
 */

namespace Google\Ads\GoogleAds\Examples\Remarketing;

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\Util\V16\ResourceNames;
use Google\Ads\GoogleAds\V16\Common\AdImageAsset;
use Google\Ads\GoogleAds\V16\Common\AdTextAsset;
use Google\Ads\GoogleAds\V16\Common\ImageAsset;
use Google\Ads\GoogleAds\V16\Common\ManualCpc;
use Google\Ads\GoogleAds\V16\Common\ResponsiveDisplayAdInfo;
use Google\Ads\GoogleAds\V16\Common\UserListInfo;
use Google\Ads\GoogleAds\V16\Enums\AdGroupStatusEnum\AdGroupStatus;
use Google\Ads\GoogleAds\V16\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
use Google\Ads\GoogleAds\V16\Enums\AssetTypeEnum\AssetType;
use Google\Ads\GoogleAds\V16\Enums\CampaignStatusEnum\CampaignStatus;
use Google\Ads\GoogleAds\V16\Enums\DisplayAdFormatSettingEnum\DisplayAdFormatSetting;
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\Asset;
use Google\Ads\GoogleAds\V16\Resources\Campaign;
use Google\Ads\GoogleAds\V16\Resources\Campaign\ShoppingSetting;
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\AssetOperation;
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\MutateAssetResult;
use Google\Ads\GoogleAds\V16\Services\MutateAssetsRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCampaignsRequest;
use Google\ApiCore\ApiException;

/**
 * This example creates a shopping campaign associated with an existing merchant center account,
 * along with a related ad group and dynamic display ad, and targets a user list for remarketing
 * purposes.
 */
class AddMerchantCenterDynamicRemarketingCampaign
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    private const MERCHANT_CENTER_ACCOUNT_ID = 'INSERT_MERCHANT_CENTER_ACCOUNT_ID_HERE';
    private const CAMPAIGN_BUDGET_ID = 'INSERT_CAMPAIGN_BUDGET_ID_HERE';
    private const USER_LIST_ID = 'INSERT_USER_LIST_ID_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::CAMPAIGN_BUDGET_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::USER_LIST_ID => 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::CAMPAIGN_BUDGET_ID] ?: self::CAMPAIGN_BUDGET_ID,
                $options[ArgumentNames::USER_LIST_ID] ?: self::USER_LIST_ID
            );
        } 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 int $campaignBudgetId the campaign budget ID
     * @param int $userListId the user list ID
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $merchantCenterAccountId,
        int $campaignBudgetId,
        int $userListId
    ) {
        // Creates a shopping campaign associated with a given merchant center account.
        $campaignResourceName = self::createCampaign(
            $googleAdsClient,
            $customerId,
            $merchantCenterAccountId,
            $campaignBudgetId
        );

        // Creates an ad group for the campaign.
        $adGroupResourceName =
            self::createAdGroup($googleAdsClient, $customerId, $campaignResourceName);

        // Creates a dynamic display ad in the ad group.
        self::createAd($googleAdsClient, $customerId, $adGroupResourceName);

        // Targets a specific user list for remarketing.
        self::attachUserList($googleAdsClient, $customerId, $adGroupResourceName, $userListId);
    }

    /**
     * Creates a campaign linked to a Merchant Center product feed.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param int $merchantCenterAccountId the Merchant Center account ID
     * @param int $campaignBudgetId the campaign budget ID
     * @return string the resource name of the newly created campaign
     */
    private static function createCampaign(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $merchantCenterAccountId,
        int $campaignBudgetId
    ): string {
        // Configures the settings for the shopping campaign.
        $shoppingSettings = new ShoppingSetting([
            'campaign_priority' => 0,
            'merchant_id' => $merchantCenterAccountId,
            'enable_local' => true
        ]);

        // Creates the campaign.
        $campaign = new Campaign([
            'name' => 'Shopping campaign #' . Helper::getPrintableDatetime(),
            // Dynamic remarketing campaigns are only available on the Google Display Network.
            'advertising_channel_type' => AdvertisingChannelType::DISPLAY,
            'status' => CampaignStatus::PAUSED,
            'campaign_budget' => ResourceNames::forCampaignBudget($customerId, $campaignBudgetId),
            'manual_cpc' => new ManualCpc(),
            // This connects the campaign to the merchant center account.
            'shopping_setting' => $shoppingSettings
        ]);

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

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

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

        return $addedCampaignResourceName;
    }

    /**
     * Creates an ad group for the remarketing campaign.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $campaignResourceName the resource name of the campaign that
     *     the new ad group will belong to
     * @return string the resource name of the newly created ad group
     */
    private static function createAdGroup(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $campaignResourceName
    ): string {
        // Creates the ad group.
        $adGroup = new AdGroup([
            'name' => 'Dynamic remarketing ad group',
            'campaign' => $campaignResourceName,
            'status' => AdGroupStatus::ENABLED
        ]);

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

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

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

        return $addedAdGroupResourceName;
    }

    /**
     * Creates the responsive display ad.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the resource name of the ad group that
     *     the new ad group ad will belong to
     */
    private static function createAd(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName
    ) {
        $marketingImageResourceName = self::uploadAsset(
            $googleAdsClient,
            $customerId,
            'https://gaagl.page.link/Eit5',
            'Marketing Image'
        );
        $squareMarketingImageResourceName = self::uploadAsset(
            $googleAdsClient,
            $customerId,
            'https://gaagl.page.link/bjYi',
            'Square Marketing Image'
        );

        // Creates the responsive display ad info object.
        $responsiveDisplayAdInfo = new ResponsiveDisplayAdInfo([
            'marketing_images' => [new AdImageAsset(['asset' => $marketingImageResourceName])],
            'square_marketing_images' => [new AdImageAsset([
                'asset' => $squareMarketingImageResourceName
            ])],
            'headlines' => [new AdTextAsset(['text' => 'Travel'])],
            'long_headline' => new AdTextAsset(['text' => 'Travel the World']),
            'descriptions' => [new AdTextAsset(['text' => 'Take to the air!'])],
            'business_name' => 'Interplanetary Cruises',
            // Optional: Call to action text.
            // Valid texts: https://support.google.com/google-ads/answer/7005917
            'call_to_action_text' => 'Apply Now',
            // Optional: Sets the ad colors.
            'main_color' => '#0000ff',
            'accent_color' => '#ffff00',
            // Optional: Sets to false to strictly render the ad using the colors.
            'allow_flexible_color' => false,
            // Optional: Sets the format setting that the ad will be served in.
            'format_setting' => DisplayAdFormatSetting::NON_NATIVE
            // Optional: Creates a logo image and sets it to the ad.
            // 'logo_images' => [new AdImageAsset([
            //     'asset' => 'INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE'
            // ])],
            // Optional: Creates a square logo image and sets it to the ad.
            // 'square_logo_images' => [new AdImageAsset([
            //     'asset' => 'INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE'
            // ])]
        ]);

        // Creates a new ad group ad.
        $adGroupAd = new AdGroupAd([
            'ad' => new Ad([
                'responsive_display_ad' => $responsiveDisplayAdInfo,
                'final_urls' => ['http://www.example.com/']
            ]),
            'ad_group' => $adGroupResourceName
        ]);

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

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

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

    /**
     * Adds an image asset to the Google Ads account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $imageUrl the image URL
     * @param string $assetName the asset name
     * @return string the resource name of the newly added asset
     */
    private static function uploadAsset(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $imageUrl,
        string $assetName
    ): string {
        // Creates an asset.
        $asset = new Asset([
            'name' => $assetName,
            'type' => AssetType::IMAGE,
            'image_asset' => new ImageAsset(['data' => file_get_contents($imageUrl)])
        ]);

        // Creates an asset operation.
        $assetOperation = new AssetOperation();
        $assetOperation->setCreate($asset);

        // Issues a mutate request to add the asset.
        $assetServiceClient = $googleAdsClient->getAssetServiceClient();
        $response = $assetServiceClient->mutateAssets(
            MutateAssetsRequest::build($customerId, [$assetOperation])
        );

        // Prints the resource name of the added image asset.
        /** @var MutateAssetResult $addedImageAsset */
        $addedImageAsset = $response->getResults()[0];
        $addedImageAssetResourceName = $addedImageAsset->getResourceName();
        printf(
            "Created image asset with resource name '%s'.%s",
            $addedImageAssetResourceName,
            PHP_EOL
        );

        return $addedImageAssetResourceName;
    }

    /**
     * Targets a user list.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the resource name of the ad group that
     *     the user list will be attached to
     * @param int $userListId the user list ID
     */
    private static function attachUserList(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName,
        int $userListId
    ) {
        // Creates the ad group criterion that targets the user list.
        $adGroupCriterion = new AdGroupCriterion([
            'ad_group' => $adGroupResourceName,
            'user_list' => new UserListInfo([
                'user_list' => ResourceNames::forUserList($customerId, $userListId)
            ])
        ]);

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

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

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

AddMerchantCenterDynamicRemarketingCampaign::main();

      

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.
"""Creates a campaign associated with an existing Merchant Center account.

Creates a shopping campaign, related ad group and dynamic display ad, and
targets a user list for remarketing purposes.
"""


import argparse
import requests
import sys
from uuid import uuid4

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


def main(
    client,
    customer_id,
    merchant_center_account_id,
    campaign_budget_id,
    user_list_id,
):
    """Creates a campaign associated with an existing Merchant Center account.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        merchant_center_account_id: The target Merchant Center account ID.
        campaign_budget_id: The ID of the campaign budget to utilize.
        user_list_id: The ID of the user list to target for remarketing.
    """
    # Create a shopping campaign associated with a given Merchant Center
    # account.
    campaign_resource_name = create_campaign(
        client, customer_id, merchant_center_account_id, campaign_budget_id
    )

    # Create an ad group for the campaign.
    ad_group_resource_name = create_ad_group(
        client, customer_id, campaign_resource_name
    )

    # Create a dynamic display ad in the ad group.
    create_ad(client, customer_id, ad_group_resource_name)

    # Target a specific user list for remarketing.
    attach_user_list(client, customer_id, ad_group_resource_name, user_list_id)


def create_campaign(
    client, customer_id, merchant_center_account_id, campaign_budget_id
):
    """Creates a campaign linked to a Merchant Center product feed.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        merchant_center_account_id: The target Merchant Center account ID.
        campaign_budget_id: The ID of the campaign budget to utilize.
    Returns:
        The string resource name of the newly created campaign.
    """
    # Gets the CampaignService client.
    campaign_service = client.get_service("CampaignService")

    # Creates a campaign operation and configures the new campaign.
    campaign_operation = client.get_type("CampaignOperation")
    campaign = campaign_operation.create
    campaign.name = f"Shopping campaign #{uuid4()}"
    # Configures the settings for the shopping campaign.
    campaign.shopping_setting.campaign_priority = 0
    # This connects the campaign to the Merchant Center account.
    campaign.shopping_setting.merchant_id = merchant_center_account_id
    campaign.shopping_setting.enable_local = True
    # Dynamic remarketing campaigns are only available on the Google Display
    # Network.
    campaign.advertising_channel_type = (
        client.enums.AdvertisingChannelTypeEnum.DISPLAY
    )
    campaign.status = client.enums.CampaignStatusEnum.PAUSED
    campaign.campaign_budget = client.get_service(
        "CampaignBudgetService"
    ).campaign_budget_path(customer_id, campaign_budget_id)
    client.copy_from(campaign.manual_cpc, client.get_type("ManualCpc"))

    # Issues a mutate request to 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(f"Created campaign with resource name '{campaign_resource_name}'.")

    return campaign_resource_name


def create_ad_group(client, customer_id, campaign_resource_name):
    """Creates an ad group for the remarketing campaign.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        campaign_resource_name: The resource name of the target campaign.
    Returns:
        The string resource name of the newly created ad group.
    """
    # Gets the AdGroupService.
    ad_group_service = client.get_service("AdGroupService")

    # Creates an ad group operation and configures the new ad group.
    ad_group_operation = client.get_type("AdGroupOperation")
    ad_group = ad_group_operation.create
    ad_group.name = "Dynamic remarketing ad group"
    ad_group.campaign = campaign_resource_name
    ad_group.status = client.enums.AdGroupStatusEnum.ENABLED

    # Issues a mutate request to 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

    return ad_group_resource_name


def create_ad(client, customer_id, ad_group_resource_name):
    """Creates the responsive display ad.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        ad_group_resource_name: The resource name of the target ad group.
    """
    # Get the AdGroupAdService client.
    ad_group_ad_service = client.get_service("AdGroupAdService")

    # Upload image assets for the ad.
    marketing_image_resource_name = upload_image_asset(
        client, customer_id, "https://gaagl.page.link/Eit5", "Marketing Image"
    )
    square_marketing_image_resource_name = upload_image_asset(
        client,
        customer_id,
        "https://gaagl.page.link/bjYi",
        "Square Marketing Image",
    )

    # Create the relevant asset objects for the ad.
    marketing_image = client.get_type("AdImageAsset")
    marketing_image.asset = marketing_image_resource_name
    square_marketing_image = client.get_type("AdImageAsset")
    square_marketing_image.asset = square_marketing_image_resource_name
    headline = client.get_type("AdTextAsset")
    headline.text = "Travel"
    description = client.get_type("AdTextAsset")
    description.text = "Take to the air!"

    # Create an ad group ad operation and set the ad group ad values.
    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.ad.final_urls.append("http://www.example.com/")

    # Configure the responsive display ad info object.
    responsive_display_ad_info = ad_group_ad.ad.responsive_display_ad
    responsive_display_ad_info.marketing_images.append(marketing_image)
    responsive_display_ad_info.square_marketing_images.append(
        square_marketing_image
    )
    responsive_display_ad_info.headlines.append(headline)
    responsive_display_ad_info.long_headline.text = "Travel the World"
    responsive_display_ad_info.descriptions.append(description)
    responsive_display_ad_info.business_name = "Interplanetary Cruises"
    # Optional: Call to action text.
    # Valid texts: https://support.google.com/google-ads/answer/7005917
    responsive_display_ad_info.call_to_action_text = "Apply Now"
    # Optional: Set the ad colors.
    responsive_display_ad_info.main_color = "#0000ff"
    responsive_display_ad_info.accent_color = "#ffff00"
    # Optional: Set to false to strictly render the ad using the colors.
    responsive_display_ad_info.allow_flexible_color = False
    # Optional: Set the format setting that the ad will be served in.
    responsive_display_ad_info.format_setting = (
        client.enums.DisplayAdFormatSettingEnum.NON_NATIVE
    )
    # Optional: Create a logo image and set it to the ad.
    # logo_image = client.get_type("AdImageAsset")
    # logo_image.asset = "INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE"
    # responsive_display_ad_info.logo_images.append(logo_image)
    # Optional: Create a square logo image and set it to the ad.
    # square_logo_image = client.get_type("AdImageAsset")
    # square_logo_image.asset = "INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE"
    # responsive_display_ad_info.square_logo_images.append(square_logo_image)

    # Issue a mutate request to 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]
    )
    print(
        "Created ad group ad with resource name "
        f"'{ad_group_ad_response.results[0].resource_name}'."
    )


def upload_image_asset(client, customer_id, image_url, asset_name):
    """Adds an image asset to the Google Ads account.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        image_url: The URL of the image source.
        asset_name: The string label for this image asset.
    Returns:
        The string resource name of the newly uploaded image asset.
    """
    # Get the AssetService client.
    asset_service = client.get_service("AssetService")

    # Fetch the image data.
    image_data = requests.get(image_url).content

    # Create an asset operation and set the image asset values.
    asset_operation = client.get_type("AssetOperation")
    asset = asset_operation.create
    asset.type_ = client.enums.AssetTypeEnum.IMAGE
    asset.image_asset.data = image_data
    asset.name = asset_name

    mutate_asset_response = asset_service.mutate_assets(
        customer_id=customer_id, operations=[asset_operation]
    )
    image_asset_resource_name = mutate_asset_response.results[0].resource_name
    print(
        "Created image asset with resource name "
        f"'{image_asset_resource_name}'."
    )

    return image_asset_resource_name


def attach_user_list(client, customer_id, ad_group_resource_name, user_list_id):
    """Targets a user list with an ad group.

    Args:
        client: An initialized GoogleAds client.
        customer_id: The Google Ads customer ID.
        ad_group_resource_name: The resource name of the target ad group.
        user_list_id: The ID of the user list to target for remarketing.
    """
    # Get the AdGroupCriterionService client.
    ad_group_criterion_service = client.get_service("AdGroupCriterionService")

    # Create an ad group criterion operation and set the ad group criterion
    # values.
    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.user_list.user_list = client.get_service(
        "UserListService"
    ).user_list_path(customer_id, user_list_id)

    # Issue a mutate request to add the ad group criterion.
    ad_group_criterion_response = (
        ad_group_criterion_service.mutate_ad_group_criteria(
            customer_id=customer_id, operations=[ad_group_criterion_operation]
        )
    )
    print(
        "Created ad group criterion with resource name "
        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=(
            "Creates a shopping campaign associated with an existing "
            "Merchant Center 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 target Merchant Center account ID.",
    )
    parser.add_argument(
        "-b",
        "--campaign_budget_id",
        type=int,
        required=True,
        help="The campaign budget ID to apply to the campaign.",
    )
    parser.add_argument(
        "-u",
        "--user_list_id",
        type=int,
        required=True,
        help="The user list ID to target.",
    )
    args = parser.parse_args()

    try:
        main(
            googleads_client,
            args.customer_id,
            args.merchant_center_account_id,
            args.campaign_budget_id,
            args.user_list_id,
        )
    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 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.
#
# This example creates a shopping campaign associated with an existing merchant
# center account, along with a related ad group and dynamic display ad, and
# targets a user list for remarketing purposes.

require "optparse"
require "date"
require "open-uri"
require "google/ads/google_ads"

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

  # Creates a shopping campaign associated with a given merchant center account.
  campaign_resource_name = create_campaign(
    client,
    customer_id,
    merchant_center_id,
    campaign_budget_id
  )

  # Creates an ad group for the campaign.
  ad_group_resource_name = create_ad_group(client, customer_id,
                                           campaign_resource_name)

  # Creates a dynamic display ad in the ad group.
  create_ad(client, customer_id, ad_group_resource_name)

  # Targets a specific user list for remarketing.
  attach_user_list(client, customer_id, ad_group_resource_name, user_list_id)
end

# Creates a campaign linked to a Merchant Center product feed.
def create_campaign(client, customer_id, merchant_center_id, campaign_budget_id)
  operation = client.operation.create_resource.campaign do |c|
    c.name = "Shopping campaign ##{(Time.new.to_f * 1000).to_i}"

    # Dynamic remarketing campaigns are only available on the Google Display
    # Network.
    c.advertising_channel_type = :DISPLAY
    c.status = :PAUSED
    c.campaign_budget = client.path.campaign_budget(customer_id,
                                                    campaign_budget_id)
    c.manual_cpc = client.resource.manual_cpc

    # The settings for the shopping campaign.
    # This connects the campaign to the merchant center account.
    c.shopping_setting = client.resource.shopping_setting do |ss|
      ss.campaign_priority = 0
      ss.merchant_id = merchant_center_id.to_i
      ss.enable_local = true
    end
  end

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

  puts "Created campaign: #{response.results.first.resource_name}"
  response.results.first.resource_name
end

# Creates an ad group for the remarketing campaign.
def create_ad_group(client, customer_id, campaign_resource_name)
  # Creates the ad group.
  ad_group = client.resource.ad_group do |ag|
    ag.name = "Dynamic remarketing ad group #{(Time.now.to_f * 1000).to_i}"
    ag.campaign = campaign_resource_name
    ag.status = :ENABLED
  end

  # Creates the ad group operation.
  operation = client.operation.create_resource.ad_group(ad_group)
  response = client.service.ad_group.mutate_ad_groups(
    customer_id: customer_id,
    operations: [operation]
  )

  puts "Created ad group: #{response.results.first.resource_name}"
  response.results.first.resource_name
end

# Creates the responsive display ad.
def create_ad(client, customer_id, ad_group_resource_name)
  marketing_image_url = "https://gaagl.page.link/Eit5"
  square_marketing_image_url = "https://gaagl.page.link/bjYi"
  marketing_image_asset_resource_name = upload_asset(
    client, customer_id, marketing_image_url, "Marketing Image"
  )
  square_marketing_image_asset_resource_name = upload_asset(
    client, customer_id, square_marketing_image_url, "Square Marketing Image"
  )

  # Creates an ad group ad operation.
  operation = client.operation.create_resource.ad_group_ad do |aga|
    aga.ad_group = ad_group_resource_name
    aga.status = :PAUSED
    aga.ad = client.resource.ad do |a|
      a.final_urls << "https://www.example.com"

      # Creates the responsive display ad info object.
      a.responsive_display_ad = client.resource.responsive_display_ad_info do |rda|
        rda.headlines << client.resource.ad_text_asset do |ata|
          ata.text = "Travel"
        end
        rda.long_headline = client.resource.ad_text_asset do |ata|
          ata.text = "Travel the World"
        end
        rda.descriptions << client.resource.ad_text_asset do |ata|
          ata.text = "Take to the air!"
        end
        rda.business_name = "Interplanetary Cruises"
        rda.marketing_images << client.resource.ad_image_asset do |aia|
          aia.asset = marketing_image_asset_resource_name
        end
        rda.square_marketing_images << client.resource.ad_image_asset do |aia|
          aia.asset = square_marketing_image_asset_resource_name
        end
        # Optional: Call to action text.
        # Valid texts: https://support.google.com/google-ads/answer/7005917
        rda.call_to_action_text = "Apply Now"
        # Optional: Sets the ad colors.
        rda.main_color = "#0000ff"
        rda.accent_color = "#ffff00"
        # Optional: Sets to false to strictly render the ad using the colors.
        rda.allow_flexible_color = false
        # Optional: Sets the format setting that the ad will be served in.
        rda.format_setting = :NON_NATIVE
        # Optional: Creates a logo image and sets it to the ad.
        # rda.logo_images << client.resource.ad_image_asset do |aia|
        #   aia.asset = "INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE"
        # end
        # Optional: Creates a square logo image and sets it to the ad.
        # rda.square_logo_images << client.resource.ad_image_asset do |aia|
        #   aia.asset = "INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE"
        # end
      end
    end
  end

  # Issues a mutate request to add the ad group ad.
  response = client.service.ad_group_ad.mutate_ad_group_ads(
    customer_id: customer_id,
    operations: [operation]
  )

  # Prints out some information about the newly created ad.
  resource_name = response.results.first.resource_name
  puts "Created ad group ad: #{resource_name}"

  resource_name
end

# Adds an image to the Google Ads account.
def upload_asset(client, customer_id, image_url, image_name)
  # Creates an asset operation.
  operation = client.operation.create_resource.asset do |a|
    a.name = image_name
    a.type = :IMAGE
    a.image_asset = client.resource.image_asset do |image|
      image.data = open(image_url) { |f| f.read }
    end
  end

  # Issues a mutate request to add the asset.
  response = client.service.asset.mutate_assets(
    customer_id: customer_id,
    operations: [operation]
  )

  # Prints out information about the newly added asset.
  resource_name = response.results.first.resource_name
  puts "Created image asset: #{resource_name}"

  resource_name
end

# Targets a user list.
def attach_user_list(client, customer_id, ad_group_resource_name, user_list_id)
  user_list_resource_name = client.path.user_list(customer_id, user_list_id)

  # Creates the ad group criterion that targets the user list.
  ad_group_criterion = client.resource.ad_group_criterion do |agc|
    agc.ad_group = ad_group_resource_name
    agc.user_list = client.resource.user_list_info do |ul|
      ul.user_list = user_list_resource_name
    end
  end

  # Creates the ad group criterion operation.
  op = client.operation.create_resource.ad_group_criterion(ad_group_criterion)

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

  puts "Created ad group criterion: #{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_ACCOUNT_ID_HERE"
  options[:campaign_budget_id] = "INSERT_CAMPAIGN_BUDGET_ID_HERE"
  options[:user_list_id] = "INSERT_USER_LIST_ID_HERE"

  OptionParser.new do |opts|
    opts.banner = format("Usage: %s [options]", File.basename(__FILE__))

    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",
            String, "Merchant Center Account ID") do |v|
      options[:merchant_center_id] = v
    end

    opts.on("-b", "--campaign-budget-id CAMPAIGN-BUDGET-ID", String,
            "Campaign Budget ID") do |v|
      options[:campaign_budget_id] = v
    end

    opts.on("-u", "--user-list-id USER-LIST-ID", String, "User List ID") do |v|
      options[:user_list_id] = v
    end

    opts.separator ""
    opts.separator "Help:"

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

  begin
    add_merchant_center_dynamic_remarketing_campaign(
      options.fetch(:customer_id).tr("-", ""),
      options.fetch(:merchant_center_id),
      options.fetch(:campaign_budget_id),
      options.fetch(:user_list_id)
    )
  rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
    e.failure.errors.each do |error|
      STDERR.printf("Error with message: %s\n", error.message)
      error.location&.field_path_elements&.each do |field_path_element|
        STDERR.printf("\tOn field: %s\n", field_path_element.field_name)
      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 shopping campaign associated with an existing Merchant
# Center account, along with a related ad group and dynamic display ad, and
# targets a user list for remarketing purposes.

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::MediaUtils;
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::Asset;
use Google::Ads::GoogleAds::V16::Resources::AdGroupCriterion;
use Google::Ads::GoogleAds::V16::Common::ManualCpc;
use Google::Ads::GoogleAds::V16::Common::ResponsiveDisplayAdInfo;
use Google::Ads::GoogleAds::V16::Common::AdImageAsset;
use Google::Ads::GoogleAds::V16::Common::AdTextAsset;
use Google::Ads::GoogleAds::V16::Common::ImageAsset;
use Google::Ads::GoogleAds::V16::Common::UserListInfo;
use Google::Ads::GoogleAds::V16::Enums::AdvertisingChannelTypeEnum qw(DISPLAY);
use Google::Ads::GoogleAds::V16::Enums::CampaignStatusEnum;
use Google::Ads::GoogleAds::V16::Enums::AdGroupStatusEnum;
use Google::Ads::GoogleAds::V16::Enums::DisplayAdFormatSettingEnum
  qw(NON_NATIVE);
use Google::Ads::GoogleAds::V16::Enums::AssetTypeEnum qw(IMAGE);
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::AssetService::AssetOperation;
use
  Google::Ads::GoogleAds::V16::Services::AdGroupCriterionService::AdGroupCriterionOperation;
use Google::Ads::GoogleAds::V16::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 $merchant_center_account_id = "INSERT_MERCHANT_CENTER_ACCOUNT_ID_HERE";
my $campaign_budget_id         = "INSERT_CAMPAIGN_BUDGET_ID_HERE";
my $user_list_id               = "INSERT_USER_LIST_ID_HERE";

sub add_merchant_center_dynamic_remarketing_campaign {
  my ($api_client, $customer_id, $merchant_center_account_id,
    $campaign_budget_id, $user_list_id)
    = @_;

  # Create a shopping campaign associated with a given Merchant Center account.
  my $campaign_resource_name =
    create_campaign($api_client, $customer_id, $merchant_center_account_id,
    $campaign_budget_id);

  # Create an ad group for the campaign.
  my $ad_group_resource_name =
    create_ad_group($api_client, $customer_id, $campaign_resource_name);

  # Create a dynamic display ad in the ad group.
  create_ad($api_client, $customer_id, $ad_group_resource_name);

  # Target a specific user list for remarketing.
  attach_user_list($api_client, $customer_id, $ad_group_resource_name,
    $user_list_id);

  return 1;
}

# Creates a campaign linked to a Merchant Center product feed.
sub create_campaign {
  my ($api_client, $customer_id, $merchant_center_account_id,
    $campaign_budget_id)
    = @_;

  # Configure the settings for the shopping campaign.
  my $shopping_settings =
    Google::Ads::GoogleAds::V16::Resources::ShoppingSetting->new({
      campaignPriority => 0,
      merchantId       => $merchant_center_account_id,
      enableLocal      => "true"
    });

  # Create the campaign.
  my $campaign = Google::Ads::GoogleAds::V16::Resources::Campaign->new({
      name => "Shopping campaign #" . uniqid(),
      # Dynamic remarketing campaigns are only available on the Google Display Network.
      advertisingChannelType => DISPLAY,
      status => Google::Ads::GoogleAds::V16::Enums::CampaignStatusEnum::PAUSED,
      campaignBudget =>
        Google::Ads::GoogleAds::V16::Utils::ResourceNames::campaign_budget(
        $customer_id, $campaign_budget_id
        ),
      manualCpc => Google::Ads::GoogleAds::V16::Common::ManualCpc->new(),
      # This connects the campaign to the Merchant Center account.
      shoppingSetting => $shopping_settings
    });

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

  # Issue a mutate request to add the campaign.
  my $campaigns_response = $api_client->CampaignService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_operation]});

  my $campaign_resource_name = $campaigns_response->{results}[0]{resourceName};
  printf "Created campaign with resource name '%s'.\n", $campaign_resource_name;

  return $campaign_resource_name;
}

# Creates an ad group for the remarketing campaign.
sub create_ad_group {
  my ($api_client, $customer_id, $campaign_resource_name) = @_;

  # Create the ad group.
  my $ad_group = Google::Ads::GoogleAds::V16::Resources::AdGroup->new({
    name     => "Dynamic remarketing ad group",
    campaign => $campaign_resource_name,
    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});

  # Issue a mutate request to add the ad group.
  my $ad_groups_response = $api_client->AdGroupService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_operation]});

  my $ad_group_resource_name = $ad_groups_response->{results}[0]{resourceName};
  printf "Created ad group with resource name '%s'.\n", $ad_group_resource_name;

  return $ad_group_resource_name;
}

# Creates the responsive display ad.
sub create_ad {
  my ($api_client, $customer_id, $ad_group_resource_name) = @_;

  my $marketing_image_resource_name = upload_asset(
    $api_client, $customer_id,
    "https://gaagl.page.link/Eit5",
    "Marketing Image"
  );

  my $square_marketing_image_resource_name = upload_asset(
    $api_client, $customer_id,
    "https://gaagl.page.link/bjYi",
    "Square Marketing Image"
  );

  # Create the responsive display ad info object.
  my $responsive_display_ad_info =
    Google::Ads::GoogleAds::V16::Common::ResponsiveDisplayAdInfo->new({
      marketingImages => [
        Google::Ads::GoogleAds::V16::Common::AdImageAsset->new({
            asset => $marketing_image_resource_name
          })
      ],
      squareMarketingImages => [
        Google::Ads::GoogleAds::V16::Common::AdImageAsset->new({
            asset => $square_marketing_image_resource_name
          })
      ],
      headlines => [
        Google::Ads::GoogleAds::V16::Common::AdTextAsset->new({
            text => "Travel"
          })
      ],
      longHeadline => Google::Ads::GoogleAds::V16::Common::AdTextAsset->new({
          text => "Travel the World"
        }
      ),
      descriptions => [
        Google::Ads::GoogleAds::V16::Common::AdTextAsset->new({
            text => "Take to the air!"
          })
      ],
      businessName => "Interplanetary Cruises",
      # Optional: Call to action text.
      # Valid texts: https://support.google.com/google-ads/answer/7005917
      callToActionText => "Apply Now",
      # Optional: Set the ad colors.
      mainColor   => "#0000ff",
      accentColor => "#ffff00",
      # Optional: Set to false to strictly render the ad using the colors.
      allowFlexibleColor => "false",
      # Optional: Set the format setting that the ad will be served in.
      formatSetting => NON_NATIVE,
      # Optional: Create a logo image and set it to the ad.
      # logoImages => [
      #   Google::Ads::GoogleAds::V16::Common::AdImageAsset->new({
      #       asset => "INSERT_LOGO_IMAGE_RESOURCE_NAME_HERE"
      #     })
      # ],
      # Optional: Create a square logo image and set it to the ad.
      # squareLogoImages => [
      #   Google::Ads::GoogleAds::V16::Common::AdImageAsset->new({
      #       asset => "INSERT_SQUARE_LOGO_IMAGE_RESOURCE_NAME_HERE"
      #     })
      # ]
    });

  # Create an ad group ad.
  my $ad_group_ad = Google::Ads::GoogleAds::V16::Resources::AdGroupAd->new({
      adGroup => $ad_group_resource_name,
      ad      => Google::Ads::GoogleAds::V16::Resources::Ad->new({
          responsiveDisplayAd => $responsive_display_ad_info,
          finalUrls           => ["http://www.example.com/"]})});

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

  # Issue a mutate request to add the ad group ad.
  my $ad_group_ads_response = $api_client->AdGroupAdService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_ad_operation]});

  printf "Created ad group ad with resource name '%s'.\n",
    $ad_group_ads_response->{results}[0]{resourceName};
}

# Adds an image asset to the Google Ads account.
sub upload_asset {
  my ($api_client, $customer_id, $image_url, $asset_name) = @_;

  my $image_data = get_base64_data_from_url($image_url);

  # Create an asset.
  my $asset = Google::Ads::GoogleAds::V16::Resources::Asset->new({
      name       => $asset_name,
      type       => IMAGE,
      imageAsset => Google::Ads::GoogleAds::V16::Common::ImageAsset->new({
          data => $image_data
        })});

  # Create an asset operation.
  my $asset_operation =
    Google::Ads::GoogleAds::V16::Services::AssetService::AssetOperation->new({
      create => $asset
    });

  # Issue a mutate request to add the asset.
  my $assets_response = $api_client->AssetService()->mutate({
      customerId => $customer_id,
      operations => [$asset_operation]});

  my $image_asset_resource_name = $assets_response->{results}[0]{resourceName};
  printf "Created image asset with resource name '%s'.\n",
    $image_asset_resource_name;

  return $image_asset_resource_name;
}

# Targets a user list.
sub attach_user_list {
  my ($api_client, $customer_id, $ad_group_resource_name, $user_list_id) = @_;

  # Create the ad group criterion that targets the user list.
  my $ad_group_criterion =
    Google::Ads::GoogleAds::V16::Resources::AdGroupCriterion->new({
      adGroup  => $ad_group_resource_name,
      userList => Google::Ads::GoogleAds::V16::Common::UserListInfo->new({
          userList =>
            Google::Ads::GoogleAds::V16::Utils::ResourceNames::user_list(
            $customer_id, $user_list_id
            )})});

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

  # Issue a mutate request to add the ad group criterion.
  my $ad_group_criteria_response =
    $api_client->AdGroupCriterionService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_criterion_operation]});

  printf "Created ad group criterion with resource name '%s'.\n",
    $ad_group_criteria_response->{results}[0]{resourceName};
}

# 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,
  "campaign_budget_id=i"         => \$campaign_budget_id,
  "user_list_id=i"               => \$user_list_id
);

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

# Call the example.
add_merchant_center_dynamic_remarketing_campaign($api_client,
  $customer_id =~ s/-//gr,
  $merchant_center_account_id, $campaign_budget_id, $user_list_id);

=pod

=head1 NAME

add_merchant_center_dynamic_remarketing_campaign

=head1 DESCRIPTION

This example creates a shopping campaign associated with an existing Merchant
Center account, along with a related ad group and dynamic display ad, and
targets a user list for remarketing purposes.

=head1 SYNOPSIS

add_merchant_center_dynamic_remarketing_campaign.pl [options]

    -help                           Show the help message.
    -customer_id                    The Google Ads customer ID.
    -merchant_center_account_id     The Merchant Center account ID.
    -campaign_budget_id             The campaign budget ID.
    -user_list_id                   The user list ID.

=cut