Add Dynamic Remarketing Asset

Java

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

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

import com.beust.jcommander.Parameter;
import com.google.ads.googleads.examples.utils.ArgumentNames;
import com.google.ads.googleads.examples.utils.CodeSampleHelper;
import com.google.ads.googleads.examples.utils.CodeSampleParams;
import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.ads.googleads.v21.common.DynamicEducationAsset;
import com.google.ads.googleads.v21.enums.AssetSetTypeEnum.AssetSetType;
import com.google.ads.googleads.v21.errors.GoogleAdsError;
import com.google.ads.googleads.v21.errors.GoogleAdsException;
import com.google.ads.googleads.v21.resources.Asset;
import com.google.ads.googleads.v21.resources.AssetSet;
import com.google.ads.googleads.v21.resources.AssetSetAsset;
import com.google.ads.googleads.v21.resources.CampaignAssetSet;
import com.google.ads.googleads.v21.services.AssetOperation;
import com.google.ads.googleads.v21.services.AssetServiceClient;
import com.google.ads.googleads.v21.services.AssetSetAssetOperation;
import com.google.ads.googleads.v21.services.AssetSetAssetServiceClient;
import com.google.ads.googleads.v21.services.AssetSetOperation;
import com.google.ads.googleads.v21.services.AssetSetServiceClient;
import com.google.ads.googleads.v21.services.CampaignAssetSetOperation;
import com.google.ads.googleads.v21.services.CampaignAssetSetServiceClient;
import com.google.ads.googleads.v21.services.MutateAssetSetAssetsResponse;
import com.google.ads.googleads.v21.services.MutateAssetSetsResponse;
import com.google.ads.googleads.v21.services.MutateAssetsResponse;
import com.google.ads.googleads.v21.services.MutateCampaignAssetSetsResponse;
import com.google.ads.googleads.v21.utils.ResourceNames;
import com.google.common.collect.ImmutableList;
import java.io.FileNotFoundException;
import java.io.IOException;

/** Adds an asset for use in dynamic remarketing. */
public class AddDynamicRemarketingAsset {

  public static class AddDynamicRemarketingAssetParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
    public long customerId;

    // Specify a campaign type which supports dynamic remarketing, such as Display.
    @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
    public long campaignId;
  }

  public static void main(String[] args) throws IOException {
    AddDynamicRemarketingAssetParams params = new AddDynamicRemarketingAssetParams();
    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.campaignId = Long.parseLong("INSERT_CAMPAIGN_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 AddDynamicRemarketingAsset().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 exmaple. */
  private void runExample(
      GoogleAdsClient googleAdsClient, AddDynamicRemarketingAssetParams params) {
    // Creates an Asset.
    String assetResourceName = createAsset(googleAdsClient, params);
    // Creates an AssetSet - this is a collection of assets that can be associated with a campaign.
    // Note: do not confuse this with an AssetGroup. An AssetGroup replaces AdGroups in some types
    // of campaigns.
    String assetSetResourceName = createAssetSet(googleAdsClient, params);
    // Adds the Asset to the AssetSet.
    addAssetsToAssetSet(googleAdsClient, assetResourceName, assetSetResourceName, params);
    // Finally links the AssetSet to the Campaign.
    linkAssetSetToCampaign(googleAdsClient, assetSetResourceName, params);
  }

  /** Creates an Asset to use in dynamic remarketing. */
  private String createAsset(
      GoogleAdsClient googleAdsClient, AddDynamicRemarketingAssetParams params) {
    // Creates a DynamicEducationAsset.
    // See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation for a
    // detailed explanation of the field format.
    DynamicEducationAsset educationAsset =
        DynamicEducationAsset.newBuilder()
            // Defines meta-information about the school and program.
            .setSchoolName("The University of Unknown")
            .setAddress("Building 1, New York, 12345, USA")
            .setProgramName("BSc. Computer Science")
            .setSubject("Computer Science")
            .setProgramDescription("Slinging code for fun and profit!")
            // Sets up the program ID which is the ID that should be specified in the tracking
            // pixel.
            .setProgramId("bsc-cs-uofu")
            // Sets up the location ID which may additionally be specified in the tracking pixel.
            .setLocationId("nyc")
            .setImageUrl("https://gaagl.page.link/Eit5")
            .setAndroidAppLink("android-app://com.example.android/http/example.com/gizmos?1234")
            .setIosAppLink("exampleApp://content/page")
            .setIosAppStoreId(123L)
            .build();
    Asset asset =
        Asset.newBuilder()
            .setDynamicEducationAsset(educationAsset)
            .addFinalUrls("https://www.example.com")
            .build();
    // Creates an operation to add the asset.
    AssetOperation operation = AssetOperation.newBuilder().setCreate(asset).build();
    // Connects to the API.
    try (AssetServiceClient client =
        googleAdsClient.getLatestVersion().createAssetServiceClient()) {
      // Sends the mutate request.
      MutateAssetsResponse response =
          client.mutateAssets(String.valueOf(params.customerId), ImmutableList.of(operation));
      // Prints some information about the response.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created a dynamic education asset with resource name %s.%n", resourceName);
      return resourceName;
    }
  }

  /** Creates an AssetSet. */
  private String createAssetSet(
      GoogleAdsClient googleAdsClient, AddDynamicRemarketingAssetParams params) {
    // Creates an AssetSet which will be used to link the dynamic remarketing assets to a campaign.
    AssetSet assetSet =
        AssetSet.newBuilder()
            .setName("My dynamic remarketing assets " + CodeSampleHelper.getPrintableDateTime())
            .setType(AssetSetType.DYNAMIC_EDUCATION)
            .build();
    // Creates an operation to add the link.
    AssetSetOperation operation = AssetSetOperation.newBuilder().setCreate(assetSet).build();
    try (AssetSetServiceClient serviceClient =
        googleAdsClient.getLatestVersion().createAssetSetServiceClient()) {
      // Sends the mutate request.
      MutateAssetSetsResponse response =
          serviceClient.mutateAssetSets(
              String.valueOf(params.customerId), ImmutableList.of(operation));
      // Prints some information about the response.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created asset set with resource name %s.%n", resourceName);
      return resourceName;
    }
  }

  /** Adds an Asset to an AssetSet by creating an AssetSetAsset link. */
  private void addAssetsToAssetSet(
      GoogleAdsClient googleAdsClient,
      String assetResourceName,
      String assetSetResourceName,
      AddDynamicRemarketingAssetParams params) {
    AssetSetAsset assetSetAsset =
        AssetSetAsset.newBuilder()
            .setAsset(assetResourceName)
            .setAssetSet(assetSetResourceName)
            .build();
    // Creates an operation to add the link.
    AssetSetAssetOperation operation =
        AssetSetAssetOperation.newBuilder().setCreate(assetSetAsset).build();
    try (AssetSetAssetServiceClient client =
        googleAdsClient.getLatestVersion().createAssetSetAssetServiceClient()) {
      // Sends the mutate request.
      // Note this is the point that the API will enforce uniqueness of the
      // DynamicEducationAsset.product_id field. You can have any number of assets with the same
      // product_id, however, only one Asset is allowed per AssetSet with the same product ID.
      MutateAssetSetAssetsResponse response =
          client.mutateAssetSetAssets(
              String.valueOf(params.customerId), ImmutableList.of(operation));
      // Prints some information about the response.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created AssetSetAsset link with resource name %s.%n", resourceName);
    }
  }

  /** Links an AssetSet to Campaign by creating a CampaignAssetSet. */
  private void linkAssetSetToCampaign(
      GoogleAdsClient googleAdsClient,
      String assetSetResourceName,
      AddDynamicRemarketingAssetParams params) {
    // Creates a CampaignAssetSet representing the link between an AssetSet and a Campaign.
    CampaignAssetSet campaignAssetSet =
        CampaignAssetSet.newBuilder()
            .setCampaign(ResourceNames.campaign(params.customerId, params.campaignId))
            .setAssetSet(assetSetResourceName)
            .build();
    // Creates an operation to add the CampaignAssetSet.
    CampaignAssetSetOperation operation =
        CampaignAssetSetOperation.newBuilder().setCreate(campaignAssetSet).build();
    // Creates an API connection.
    try (CampaignAssetSetServiceClient client =
        googleAdsClient.getLatestVersion().createCampaignAssetSetServiceClient()) {
      // Issues the mutate request.
      MutateCampaignAssetSetsResponse response =
          client.mutateCampaignAssetSets(
              String.valueOf(params.customerId), ImmutableList.of(operation));
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created a CampaignAssetSet with resource name %s.%n", resourceName);
    }
  }
}

      

C#

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using CommandLine;
using Google.Ads.Gax.Examples;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.V21.Common;
using Google.Ads.GoogleAds.V21.Errors;
using Google.Ads.GoogleAds.V21.Resources;
using Google.Ads.GoogleAds.V21.Services;
using System;
using System.Collections.Generic;
using static Google.Ads.GoogleAds.V21.Enums.AssetSetTypeEnum.Types;

namespace Google.Ads.GoogleAds.Examples.V21
{
    /// <summary>
    /// This code example adds an asset for use in dynamic remarketing and links it to a campaign.
    /// </summary>
    public class AddDynamicRemarketingAsset : ExampleBase
    {
        /// <summary>
        /// Command line options for running the <see cref="AddDynamicRemarketingAsset"/> example.
        /// </summary>
        public class Options : OptionsBase
        {
            /// <summary>
            /// The Google Ads customer ID.
            /// </summary>
            [Option("customerId", Required = true, HelpText =
                "The Google Ads customer ID.")]
            public long CustomerId { get; set; }

            /// <summary>
            /// ID of the campaign to which the asset is linked.
            /// </summary>
            [Option("campaignId", Required = true, HelpText =
                "ID of the campaign to which the asset is linked. Specify a campaign type which " +
                "supports dynamic remarketing, such as Display.")]
            public long CampaignId { 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);

            AddDynamicRemarketingAsset codeExample = new AddDynamicRemarketingAsset();
            Console.WriteLine(codeExample.Description);
            codeExample.Run(new GoogleAdsClient(), options.CustomerId, options.CampaignId);
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This code example adds an asset for use in dynamic remarketing and links it to " +
            "a campaign.";

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <param name="campaignId">ID of the campaign to which the asset is linked. Specify a
        /// campaign type which supports dynamic remarketing, such as Display.</param>
        public void Run(GoogleAdsClient client, long customerId, long campaignId)
        {
            try
            {
                // Creates an Asset.
                string assetResourceName = CreateAsset(client, customerId);
                // Creates an AssetSet - this is a collection of assets that can be associated
                // with a campaign.
                // Note: do not confuse this with an AssetGroup. An AssetGroup replaces AdGroups
                // in some types of campaigns.
                string assetSetResourceName = CreateAssetSet(client, customerId);
                // Adds the Asset to the AssetSet.
                AddAssetsToAssetSet(client, customerId, assetResourceName, assetSetResourceName);
                // Finally links the AssetSet to the Campaign.
                LinkAssetSetToCampaign(client, customerId, campaignId, assetSetResourceName);
            }
            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 an Asset to use in dynamic remarketing.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <returns>The resource name of the newly created asset.</returns>
        private string CreateAsset(GoogleAdsClient client, long customerId)
        {
            AssetServiceClient assetService = client.GetService(Services.V21.AssetService);

            // Creates a DynamicEducationAsset.
            // See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation for a
            // detailed explanation of the field format.
            DynamicEducationAsset educationAsset = new DynamicEducationAsset()
            {
                // Defines meta-information about the school and program.
                SchoolName = "The University of Unknown",
                Address = "Building 1, New York, 12345, USA",
                ProgramName = "BSc. Computer Science",
                Subject = "Computer Science",
                ProgramDescription = "Slinging code for fun and profit!",
                // Sets up the program ID which is the ID that should be specified in
                // the tracking pixel.
                ProgramId = "bsc-cs-uofu",
                // Sets up the location ID which may additionally be specified in the
                // tracking pixel.
                LocationId = "nyc",
                ImageUrl = "https://gaagl.page.link/Eit5",
                AndroidAppLink = "android-app://com.example.android/http/example.com/gizmos?1234",
                IosAppLink = "exampleApp://content/page",
                IosAppStoreId = 123L
            };
            Asset asset = new Asset()
            {
                DynamicEducationAsset = educationAsset,
                // The final_urls list must not be empty
                FinalUrls = { "https://www.example.com" }
            };

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

            // Sends the mutate request.
            MutateAssetsResponse response =
                assetService.MutateAssets(customerId.ToString(), new[] { operation });
            // Prints some information about the response.
            string resourceName = response.Results[0].ResourceName;
            Console.Write($"Created a dynamic education asset with resource name {resourceName}.");
            return resourceName;
        }

        /// <summary>
        /// Creates the asset set.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <returns>The resource name of the asset set.</returns>
        private string CreateAssetSet(GoogleAdsClient client, long customerId)
        {
            AssetSetServiceClient assetSetService = client.GetService(
                Services.V21.AssetSetService);

            // Creates an AssetSet which will be used to link the dynamic remarketing assets
            // to a campaign.
            AssetSet assetSet = new AssetSet()
            {
                Name = "My dynamic remarketing assets " + ExampleUtilities.GetRandomString(),
                Type = AssetSetType.DynamicEducation
            };

            // Creates an operation to add the link.
            AssetSetOperation operation = new AssetSetOperation()
            {
                Create = assetSet
            };
            // Sends the mutate request.
            MutateAssetSetsResponse response = assetSetService.MutateAssetSets(
                customerId.ToString(), new[] { operation });
            // Prints some information about the response.
            string resourceName = response.Results[0].ResourceName;
            Console.WriteLine($"Created asset set with resource name {resourceName}.");
            return resourceName;
        }

        /// <summary>
        /// Adds an Asset to an AssetSet by creating an AssetSetAsset link.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <param name="assetResourceName">Name of the asset resource.</param>
        /// <param name="assetSetResourceName">Name of the asset set resource.</param>
        private void AddAssetsToAssetSet(GoogleAdsClient client, long customerId,
            string assetResourceName, string assetSetResourceName)
        {
            AssetSetAssetServiceClient assetSetAssetService = client.GetService(
                Services.V21.AssetSetAssetService);

            AssetSetAsset assetSetAsset = new AssetSetAsset()
            {
                Asset = assetResourceName,
                AssetSet = assetSetResourceName
            };

            // Creates an operation to add the link.
            AssetSetAssetOperation operation = new AssetSetAssetOperation()
            {
                Create = assetSetAsset
            };
            // Sends the mutate request.
            // Note this is the point that the API will enforce uniqueness of the
            // DynamicEducationAsset.program_id field. You can have any number of
            // assets with the same program_id, however, only one Asset is allowed
            // per AssetSet with the same program ID.
            MutateAssetSetAssetsResponse response =
                assetSetAssetService.MutateAssetSetAssets(
                    customerId.ToString(), new[] { operation });
            // Prints some information about the response.
            string resourceName = response.Results[0].ResourceName;
            Console.WriteLine($"Created AssetSetAsset link with resource name {resourceName}.");
        }

        /// <summary>
        /// Links an AssetSet to Campaign by creating a CampaignAssetSet.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <param name="campaignId">ID of the campaign to which the asset is linked. Specify a
        /// campaign type which supports dynamic remarketing, such as Display.</param>
        /// <param name="assetSetResourceName">Name of the asset set resource.</param>
        private void LinkAssetSetToCampaign(GoogleAdsClient client, long customerId,
            long campaignId, string assetSetResourceName)
        {
            CampaignAssetSetServiceClient campaignAssetSetService = client.GetService(
                Services.V21.CampaignAssetSetService);

            // Creates a CampaignAssetSet representing the link between an AssetSet and a Campaign.
            CampaignAssetSet campaignAssetSet = new CampaignAssetSet()
            {
                Campaign = ResourceNames.Campaign(customerId, campaignId),
                AssetSet = assetSetResourceName
            };

            // Creates an operation to add the CampaignAssetSet.
            CampaignAssetSetOperation operation = new CampaignAssetSetOperation()
            {
                Create = campaignAssetSet
            };

            // Issues the mutate request.
            MutateCampaignAssetSetsResponse response =
                campaignAssetSetService.MutateCampaignAssetSets(
                    customerId.ToString(), new[] { operation });
            string resourceName = response.Results[0].ResourceName;
            Console.WriteLine($"Created a CampaignAssetSet with resource name {resourceName}.");
        }
    }
}
      

PHP

<?php

/**
 * Copyright 2022 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\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V21\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V21\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V21\GoogleAdsException;
use Google\Ads\GoogleAds\Util\V21\ResourceNames;
use Google\Ads\GoogleAds\V21\Common\DynamicEducationAsset;
use Google\Ads\GoogleAds\V21\Enums\AssetSetTypeEnum\AssetSetType;
use Google\Ads\GoogleAds\V21\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V21\Resources\Asset;
use Google\Ads\GoogleAds\V21\Resources\AssetSet;
use Google\Ads\GoogleAds\V21\Resources\AssetSetAsset;
use Google\Ads\GoogleAds\V21\Resources\CampaignAssetSet;
use Google\Ads\GoogleAds\V21\Services\AssetOperation;
use Google\Ads\GoogleAds\V21\Services\AssetSetAssetOperation;
use Google\Ads\GoogleAds\V21\Services\AssetSetOperation;
use Google\Ads\GoogleAds\V21\Services\CampaignAssetSetOperation;
use Google\Ads\GoogleAds\V21\Services\MutateAssetSetAssetsRequest;
use Google\Ads\GoogleAds\V21\Services\MutateAssetSetsRequest;
use Google\Ads\GoogleAds\V21\Services\MutateAssetsRequest;
use Google\Ads\GoogleAds\V21\Services\MutateCampaignAssetSetsRequest;
use Google\ApiCore\ApiException;

/** Adds an asset for use in dynamic remarketing. */
class AddDynamicRemarketingAsset
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    // Specify a campaign type which supports dynamic remarketing, such as Display.
    private const CAMPAIGN_ID = 'INSERT_CAMPAIGN_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::CAMPAIGN_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)
            ->build();

        try {
            self::runExample(
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
                $options[ArgumentNames::CAMPAIGN_ID] ?: self::CAMPAIGN_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 client customer ID
     * @param int $campaignId the campaign ID
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $campaignId
    ) {
        // Creates an asset.
        $assetResourceName = self::createAsset($googleAdsClient, $customerId);
        // Creates an asset set - this is a collection of assets that can be associated with a
        // campaign.
        // Note: do not confuse this with an asset group. An asset group replaces ad groups in some
        // types of campaigns.
        $assetSetResourceName = self::createAssetSet($googleAdsClient, $customerId);
        // Adds the asset to the asset set.
        self::addAssetsToAssetSet(
            $googleAdsClient,
            $customerId,
            $assetResourceName,
            $assetSetResourceName
        );
        // Finally links the asset set to the specified campaign.
        self::linkAssetSetToCampaign(
            $googleAdsClient,
            $assetSetResourceName,
            $customerId,
            $campaignId
        );
    }

    /**
     * Creates an asset to use in dynamic remarketing.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the client customer ID
     * @return string the created asset's resource name
     */
    private static function createAsset(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        // Creates a dynamic education asset.
        // See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation for a
        // detailed explanation of the field format.
        $dynamicEducationAsset = new DynamicEducationAsset([
            // Defines meta-information about the school and program.
            'school_name' => 'The University of Unknown',
            'address' => 'Building 1, New York, 12345, USA',
            'program_name' => 'BSc. Computer Science',
            'subject' => 'Computer Science',
            'program_description' => 'Slinging code for fun and profit!',
            // Sets up the program ID which is the ID that should be specified in the tracking
            // pixel.
            'program_id' => 'bsc-cs-uofu',
            // Sets up the location ID which may additionally be specified in the tracking pixel.
            'location_id' => 'nyc',
            'image_url' => 'https://gaagl.page.link/Eit5',
            'android_app_link' => 'android-app://com.example.android/http/example.com/gizmos?1234',
            'ios_app_link' => 'exampleApp://content/page',
            'ios_app_store_id' => 123
        ]);

        // Wraps the dynamic education asset in an asset.
        $asset = new Asset([
            'dynamic_education_asset' => $dynamicEducationAsset,
            'final_urls' => ['https://www.example.com']
        ]);

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

        // Issues a mutate request to add the asset and prints its information.
        $assetServiceClient = $googleAdsClient->getAssetServiceClient();
        $response = $assetServiceClient->mutateAssets(
            MutateAssetsRequest::build($customerId, [$assetOperation])
        );
        $assetResourceName = $response->getResults()[0]->getResourceName();
        printf(
            "Created a dynamic education asset with resource name: '%s'.%s",
            $assetResourceName,
            PHP_EOL
        );

        return $assetResourceName;
    }

    /**
     * Creates an asset set.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the client customer ID
     * @return string the created asset set's resource name
     */
    private static function createAssetSet(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        // Creates an asset set which will be used to link the dynamic remarketing assets to a
        // campaign.
        $assetSet = new AssetSet([
            'name' => 'My dynamic remarketing assets ' . Helper::getPrintableDatetime(),
            'type' => AssetSetType::DYNAMIC_EDUCATION
        ]);

        // Creates an asset set operation.
        $assetSetOperation = new AssetSetOperation();
        $assetSetOperation->setCreate($assetSet);

        // Issues a mutate request to add the asset set and prints its information.
        $assetSetServiceClient = $googleAdsClient->getAssetSetServiceClient();
        $response = $assetSetServiceClient->mutateAssetSets(
            MutateAssetSetsRequest::build($customerId, [$assetSetOperation])
        );
        $assetSetResourceName = $response->getResults()[0]->getResourceName();
        printf(
            "Created an asset set with resource name: '%s'.%s",
            $assetSetResourceName,
            PHP_EOL
        );

        return $assetSetResourceName;
    }

    /**
     * Adds an asset to an asset set by creating an asset set asset link.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the client customer ID
     * @param string $assetResourceName the asset resource name
     * @param string $assetSetResourceName the asset set resource name
     */
    private static function addAssetsToAssetSet(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $assetResourceName,
        string $assetSetResourceName
    ) {
        // Creates an asset set asset.
        $assetSetAsset = new AssetSetAsset([
            'asset' => $assetResourceName,
            'asset_set' => $assetSetResourceName
        ]);

        // Creates an asset set asset operation.
        $assetSetAssetOperation = new AssetSetAssetOperation();
        $assetSetAssetOperation->setCreate($assetSetAsset);

        // Issues a mutate request to add the asset set asset and prints its information.
        // Note this is the point that the API will enforce uniqueness of the
        // DynamicEducationAsset::program_id field. You can have any number of assets with the same
        // program_id, however, only one asset is allowed per asset set with the same product ID.
        $assetSetAssetServiceClient = $googleAdsClient->getAssetSetAssetServiceClient();
        $response = $assetSetAssetServiceClient->mutateAssetSetAssets(
            MutateAssetSetAssetsRequest::build($customerId, [$assetSetAssetOperation])
        );
        printf(
            "Created asset set asset link with resource name: '%s'.%s",
            $response->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }

    /**
     * Links the specified asset set to the specified campaign by creating a campaign asset set.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param string $assetSetResourceName the  asset set's resource name to link
     * @param int $customerId the customer ID
     * @param int $campaignId the campaign ID to link the asset set to
     */
    private static function linkAssetSetToCampaign(
        GoogleAdsClient $googleAdsClient,
        string $assetSetResourceName,
        int $customerId,
        int $campaignId
    ) {
        // Creates a campaign asset set representing the link between an asset set and a campaign.
        $campaignAssetSet = new CampaignAssetSet([
            'asset_set' => $assetSetResourceName,
            'campaign' => ResourceNames::forCampaign($customerId, $campaignId)
        ]);

        // Creates a campaign asset set operation.
        $campaignAssetSetOperation = new CampaignAssetSetOperation();
        $campaignAssetSetOperation->setCreate($campaignAssetSet);

        // Issues a mutate request to add the campaign asset set and prints its information.
        $campaignAssetSetServiceClient = $googleAdsClient->getCampaignAssetSetServiceClient();
        $response = $campaignAssetSetServiceClient->mutateCampaignAssetSets(
            MutateCampaignAssetSetsRequest::build($customerId, [$campaignAssetSetOperation])
        );
        printf(
            "Created a campaign asset set with resource name: '%s'.%s",
            $response->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }
}

AddDynamicRemarketingAsset::main();

      

Python

#!/usr/bin/env python
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Adds an asset for use in dynamic remarketing."""


import argparse
from datetime import datetime
import sys

from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
from google.ads.googleads.v21.common.types.asset_types import (
    DynamicEducationAsset,
)
from google.ads.googleads.v21.resources.types.asset import Asset
from google.ads.googleads.v21.resources.types.asset_set import AssetSet
from google.ads.googleads.v21.resources.types.asset_set_asset import (
    AssetSetAsset,
)
from google.ads.googleads.v21.resources.types.campaign_asset_set import (
    CampaignAssetSet,
)
from google.ads.googleads.v21.services.services.asset_service import (
    AssetServiceClient,
)
from google.ads.googleads.v21.services.types.asset_service import (
    AssetOperation,
    MutateAssetsResponse,
)
from google.ads.googleads.v21.services.services.asset_set_service import (
    AssetSetServiceClient,
)
from google.ads.googleads.v21.services.types.asset_set_service import (
    AssetSetOperation,
    MutateAssetSetsResponse,
)
from google.ads.googleads.v21.services.services.asset_set_asset_service import (
    AssetSetAssetServiceClient,
)
from google.ads.googleads.v21.services.types.asset_set_asset_service import (
    AssetSetAssetOperation,
    MutateAssetSetAssetsResponse,
)
from google.ads.googleads.v21.services.services.campaign_asset_set_service import (
    CampaignAssetSetServiceClient,
)
from google.ads.googleads.v21.services.types.campaign_asset_set_service import (
    CampaignAssetSetOperation,
    MutateCampaignAssetSetsResponse,
)
from google.ads.googleads.v21.services.services.google_ads_service import (
    GoogleAdsServiceClient,
)


def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None:
    """The main method that creates all necessary entities for the example.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        campaign_id: the ID for a campaign of a type that supports dynamic
            remarketing, such as Display.
    """
    asset_resource_name: str = create_asset(client, customer_id)
    asset_set_resource_name: str = create_asset_set(client, customer_id)
    add_assets_to_asset_set(
        client, asset_resource_name, asset_set_resource_name, customer_id
    )
    link_asset_set_to_campaign(
        client, asset_set_resource_name, customer_id, campaign_id
    )


def create_asset(client: GoogleAdsClient, customer_id: str) -> str:
    """Creates a DynamicEducationAsset.

    See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation
    for a detailed explanation of the field format.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.

    Returns:
        The resource name for an asset.
    """
    # Creates an operation to add the asset.
    operation: AssetOperation = client.get_type("AssetOperation")
    asset: Asset = operation.create
    # The final_urls list must not be empty
    asset.final_urls.append("https://www.example.com")
    education_asset: DynamicEducationAsset = asset.dynamic_education_asset
    # Defines meta-information about the school and program.
    education_asset.school_name = "The University of Unknown"
    education_asset.address = "Building 1, New York, 12345, USA"
    education_asset.program_name = "BSc. Computer Science"
    education_asset.subject = "Computer Science"
    education_asset.program_description = "Slinging code for fun and profit!"
    # Sets up the program ID which is the ID that should be specified in the
    # tracking pixel.
    education_asset.program_id = "bsc-cs-uofu"
    # Sets up the location ID which may additionally be specified in the
    # tracking pixel.
    education_asset.location_id = "nyc"
    education_asset.image_url = "https://gaagl.page.link/Eit5"
    education_asset.android_app_link = (
        "android-app://com.example.android/http/example.com/gizmos?1234"
    )
    education_asset.ios_app_link = "exampleApp://content/page"
    education_asset.ios_app_store_id = 123

    asset_service: AssetServiceClient = client.get_service("AssetService")
    response: MutateAssetsResponse = asset_service.mutate_assets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name: str = response.results[0].resource_name
    print(
        f"Created a dynamic education asset with resource name '{resource_name}'"
    )

    return resource_name


def create_asset_set(client: GoogleAdsClient, customer_id: str) -> str:
    """Creates an AssetSet.

    The AssetSet will be used to link the dynamic remarketing assets to a
    campaign.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.

    Returns:
        The resource name for an asset set.
    """
    # Creates an operation to create the asset set.
    operation: AssetSetOperation = client.get_type("AssetSetOperation")
    asset_set: AssetSet = operation.create
    asset_set.name = f"My dynamic remarketing assets {datetime.now()}"
    asset_set.type_ = client.enums.AssetSetTypeEnum.DYNAMIC_EDUCATION

    asset_set_service: AssetSetServiceClient = client.get_service(
        "AssetSetService"
    )
    response: MutateAssetSetsResponse = asset_set_service.mutate_asset_sets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name: str = response.results[0].resource_name
    print(f"Created asset set with resource name '{resource_name}'")

    return resource_name


def add_assets_to_asset_set(
    client: GoogleAdsClient,
    asset_resource_name: str,
    asset_set_resource_name: str,
    customer_id: str,
) -> None:
    """Adds an Asset to an AssetSet by creating an AssetSetAsset link.

    Args:
        client: an initialized GoogleAdsClient instance.
        asset_set_resource_name; the resource name for an asset set.
        asset_resource_name; the resource name for an asset.
        customer_id: a client customer ID.
    """
    # Creates an operation to add the asset set asset.
    operation: AssetSetAssetOperation = client.get_type(
        "AssetSetAssetOperation"
    )
    asset_set_asset: AssetSetAsset = operation.create
    asset_set_asset.asset = asset_resource_name
    asset_set_asset.asset_set = asset_set_resource_name

    asset_set_asset_service: AssetSetAssetServiceClient = client.get_service(
        "AssetSetAssetService"
    )
    # Note this is the point that the API will enforce uniqueness of the
    # DynamicEducationAsset.program_id field. You can have any number of assets
    # with the same program ID, however, only one asset is allowed per asset set
    # with the same program ID.
    response: MutateAssetSetAssetsResponse = (
        asset_set_asset_service.mutate_asset_set_assets(
            customer_id=customer_id, operations=[operation]
        )
    )
    resource_name: str = response.results[0].resource_name
    print(f"Created asset set asset link with resource name '{resource_name}'")


def link_asset_set_to_campaign(
    client: GoogleAdsClient,
    asset_set_resource_name: str,
    customer_id: str,
    campaign_id: str,
) -> None:
    """Creates a CampaignAssetSet.

    The CampaignAssetSet represents the link between an AssetSet and a Campaign.

    Args:
        client: an initialized GoogleAdsClient instance.
        asset_set_resource_name; the resource name for an asset set.
        customer_id: a client customer ID.
        campaign_id: the ID for a campaign of a type that supports dynamic
            remarketing, such as Display.
    """
    googleads_service: GoogleAdsServiceClient = client.get_service(
        "GoogleAdsService"
    )
    # Creates an operation to add the campaign asset set.
    operation: CampaignAssetSetOperation = client.get_type(
        "CampaignAssetSetOperation"
    )
    campaign_asset_set: CampaignAssetSet = operation.create
    campaign_asset_set.campaign = googleads_service.campaign_path(
        customer_id, campaign_id
    )
    campaign_asset_set.asset_set = asset_set_resource_name

    campaign_asset_set_service: CampaignAssetSetServiceClient = (
        client.get_service("CampaignAssetSetService")
    )
    response: MutateCampaignAssetSetsResponse = (
        campaign_asset_set_service.mutate_campaign_asset_sets(
            customer_id=customer_id, operations=[operation]
        )
    )
    resource_name: str = response.results[0].resource_name
    print(f"Created a campaign asset set with resource name '{resource_name}'")


if __name__ == "__main__":
    parser: argparse.ArgumentParser = argparse.ArgumentParser(
        description="Adds an asset for use in dynamic remarketing."
    )
    # 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.",
    )
    # The following argument(s) are optional.
    parser.add_argument(
        "-i",
        "--campaign_id",
        type=str,
        required=True,
        help="The campaign ID. Specify a campaign type which supports dynamic "
        "remarketing, such as Display.",
    )
    args: argparse.Namespace = parser.parse_args()

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

    try:
        main(googleads_client, args.customer_id, args.campaign_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'Error 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 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Adds an asset for use in dynamic remarketing.

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

def add_dynamic_remarketing_asset(customer_id, campaign_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 an Asset.
  asset_resource_name = create_asset(client, customer_id)
  # Creates an AssetSet - this is a collection of assets that can be associated with a campaign.
  # Note: do not confuse this with an AssetGroup. An AssetGroup replaces AdGroups in some types
  # of campaigns.
  asset_set_resource_name = create_asset_set(client, customer_id)
  # Adds the Asset to the AssetSet.
  add_assets_to_asset_set(client, asset_resource_name, asset_set_resource_name, customer_id)
  # Finally links the AssetSet to the Campaign.
  link_asset_set_to_campaign(client, asset_set_resource_name, customer_id, campaign_id)
end

def create_asset(client, customer_id)
  # Creates a DynamicEducationAsset.
  # See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation for a
  # detailed explanation of the field format.

  # Creates an operation to add the asset.
  operation = client.operation.create_resource.asset do |asset|
    asset.final_urls << 'https://www.example.com'
    asset.dynamic_education_asset = client.resource.dynamic_education_asset do |dea|
      # Defines meta-information about the school and program.
      dea.school_name = 'The University of Unknown'
      dea.address = 'Building 1, New York, 12345, USA'
      dea.program_name = 'BSc. Computer Science'
      dea.subject = 'Computer Science'
      dea.program_description = 'Slinging code for fun and profit!'
      # Sets up the program ID which is the ID that should be specified in the
      # tracking pixel.
      dea.program_id = 'bsc-cs-uofu'
      # Sets up the location ID which may additionally be specified in the
      # tracking pixel.
      dea.location_id = 'nyc'
      dea.image_url = 'https://gaagl.page.link/Eit5'
      dea.android_app_link = 'android-app://com.example.android/http/example.com/gizmos?1234'
      dea.ios_app_link = 'exampleApp://content/page'
      dea.ios_app_store_id = 123
    end
  end

  # Sends the mutate request.
  response = client.service.asset.mutate_assets(
    customer_id: customer_id,
    operations: [operation],
  )
  resource_name = response.results.first.resource_name
  puts "Created a dynamic education asset with resource name '#{resource_name}'"

  resource_name
end

def create_asset_set(client, customer_id)
  # Creates an AssetSet which will be used to link the dynamic remarketing assets to a campaign.

  # Creates an operation to add the asset set.
  operation = client.operation.create_resource.asset_set do |asset_set|
    asset_set.name = "My dynamic remarketing assets #{Time.now}"
    asset_set.type = :DYNAMIC_EDUCATION
  end

  # Sends the mutate request.
  response = client.service.asset_set.mutate_asset_sets(
    customer_id: customer_id,
    operations: [operation],
  )
  resource_name = response.results.first.resource_name
  puts "Created asset set with resource name '#{resource_name}'"

  resource_name
end

def add_assets_to_asset_set(client, asset_resource_name, asset_set_resource_name, customer_id)
  # Creates an operation to add the asset set asset.
  operation = client.operation.create_resource.asset_set_asset do |asa|
    asa.asset = asset_resource_name
    asa.asset_set = asset_set_resource_name
  end

  # Sends the mutate request.
  #
  # Note this is the point that the API will enforce uniqueness of the
  # DynamicEducationAsset.program_id field. You can have any number of assets
  # with the same program ID, however, only one asset is allowed per asset set
  # with the same program ID.
  response = client.service.asset_set_asset.mutate_asset_set_assets(
    customer_id: customer_id,
    operations: [operation],
  )
  resource_name = response.results.first.resource_name
  puts "Created asset set asset link with resource name '#{resource_name}'"
end

def link_asset_set_to_campaign(client, asset_set_resource_name, customer_id, campaign_id)
  # Creates a CampaignAssetSet representing the link between an AssetSet and a Campaign.

  # Creates an operation to add the campaign asset set.
  operation = client.operation.create_resource.campaign_asset_set do |cas|
    cas.campaign = client.path.campaign(customer_id, campaign_id)
    cas.asset_set = asset_set_resource_name
  end

  # Issues the mutate request.
  response = client.service.campaign_asset_set.mutate_campaign_asset_sets(
    customer_id: customer_id,
    operations: [operation],
  )
  resource_name = response.results.first.resource_name
  puts "Created a campaign asset set with resource name '#{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[:campaign_id] = 'INSERT_CAMPAIGN_ID_HERE'

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

    opts.separator ''
    opts.separator 'Options:'

    opts.on('-C', '--customer-id CUSTOMER-ID', String, 'The Google Ads customer ID.') do |v|
      options[:customer_id] = v
    end

    opts.on('-I', '--campaign-id CAMPAIGN-ID', String,
      'The campaign ID. Specify a campaign type which supports dynamic ' \
      'remarketing, such as Display.') do |v|
      options[:campaign_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_dynamic_remarketing_asset(options.fetch(:customer_id).tr("-", ""), options[:campaign_id])
  rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
    e.failure.errors.each do |error|
      STDERR.printf("Error with message: %s\n", error.message)
      if error.location
        error.location.field_path_elements.each do |field_path_element|
          STDERR.printf("\tOn field: %s\n", field_path_element.field_name)
        end
      end
      error.error_code.to_h.each do |k, v|
        next if v == :UNSPECIFIED
        STDERR.printf("\tType: %s\n\tCode: %s\n", k, v)
      end
    end
    raise
  end
end


      

Perl

#!/usr/bin/perl -w
#
# Copyright 2022, 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.
#
# Adds an asset for use in dynamic remarketing.

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::V21::Resources::Asset;
use Google::Ads::GoogleAds::V21::Resources::AssetSet;
use Google::Ads::GoogleAds::V21::Resources::AssetSetAsset;
use Google::Ads::GoogleAds::V21::Resources::CampaignAssetSet;
use Google::Ads::GoogleAds::V21::Common::DynamicEducationAsset;
use Google::Ads::GoogleAds::V21::Enums::AssetSetTypeEnum qw(DYNAMIC_EDUCATION);
use Google::Ads::GoogleAds::V21::Services::AssetService::AssetOperation;
use Google::Ads::GoogleAds::V21::Services::AssetSetService::AssetSetOperation;
use
  Google::Ads::GoogleAds::V21::Services::AssetSetAssetService::AssetSetAssetOperation;
use
  Google::Ads::GoogleAds::V21::Services::CampaignAssetSetService::CampaignAssetSetOperation;
use Google::Ads::GoogleAds::V21::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";
# Specify a campaign type which supports dynamic remarketing, such as Display.
my $campaign_id = "INSERT_CAMPAIGN_ID_HERE";

sub add_dynamic_remarketing_asset {
  my ($api_client, $customer_id, $campaign_id) = @_;

  # Create an Asset.
  my $asset_resource_name = create_asset($api_client, $customer_id);

  # Create an AssetSet - this is a collection of assets that can be associated
  # with a campaign.
  # Note: do not confuse this with an AssetGroup. An AssetGroup replaces AdGroups
  # in some types of campaigns.
  my $asset_set_resource_name = create_asset_set($api_client, $customer_id);

  # Add the Asset to the AssetSet.
  add_assets_to_asset_set($api_client, $customer_id, $asset_resource_name,
    $asset_set_resource_name);

  # Finally link the AssetSet to the Campaign.
  link_asset_set_to_campaign($api_client, $customer_id, $campaign_id,
    $asset_set_resource_name);

  return 1;
}

# Creates an Asset to use in dynamic remarketing.
sub create_asset {
  my ($api_client, $customer_id) = @_;

  # Create a DynamicEducationAsset.
  # See https://support.google.com/google-ads/answer/6053288?#zippy=%2Ceducation
  # for a detailed explanation of the field format.
  my $education_asset =
    Google::Ads::GoogleAds::V21::Common::DynamicEducationAsset->new({
      # Define meta-information about the school and program.
      schoolName         => "The University of Unknown",
      address            => "Building 1, New York, 12345, USA",
      programName        => "BSc. Computer Science",
      subject            => "Computer Science",
      programDescription => "Slinging code for fun and profit!",
      # Set up the program ID which is the ID that should be specified in the
      # tracking pixel.
      programId => "bsc-cs-uofu",
      # Set up the location ID which may additionally be specified in the tracking pixel.
      locationId     => "nyc",
      imageUrl       => "https://gaagl.page.link/Eit5",
      androidAppLink =>
        "android-app://com.example.android/http/example.com/gizmos?1234",
      iosAppLink    => "exampleApp://content/page",
      iosAppStoreId => 123
    });
  my $asset = Google::Ads::GoogleAds::V21::Resources::Asset->new({
      dynamicEducationAsset => $education_asset,
      finalUrls             => ["https://www.example.com"]});

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

  # Send the mutate request.
  my $response = $api_client->AssetService()->mutate({
      customerId => $customer_id,
      operations => [$operation]});

  # Print some information about the response.
  my $resource_name = $response->{results}[0]{resourceName};
  printf "Created a dynamic education asset with resource name '%s'.\n",
    $resource_name;
  return $resource_name;
}

# Creates an AssetSet.
sub create_asset_set {
  my ($api_client, $customer_id) = @_;

  # Create an AssetSet which will be used to link the dynamic remarketing assets
  # to a campaign.
  my $asset_set = Google::Ads::GoogleAds::V21::Resources::AssetSet->new({
    name => "My dynamic remarketing assets #" . uniqid(),
    type => DYNAMIC_EDUCATION
  });

  # Create an operation to add the AssetSet.
  my $operation =
    Google::Ads::GoogleAds::V21::Services::AssetSetService::AssetSetOperation->
    new({
      create => $asset_set
    });

  # Send the mutate request.
  my $response = $api_client->AssetSetService()->mutate({
      customerId => $customer_id,
      operations => [$operation]});

  # Print some information about the response.
  my $resource_name = $response->{results}[0]{resourceName};
  printf "Created asset set with resource name '%s'.\n", $resource_name;
  return $resource_name;
}

# Adds an Asset to an AssetSet by creating an AssetSetAsset link.
sub add_assets_to_asset_set {
  my ($api_client, $customer_id, $asset_resource_name, $asset_set_resource_name)
    = @_;

  my $asset_set_asset =
    Google::Ads::GoogleAds::V21::Resources::AssetSetAsset->new({
      asset    => $asset_resource_name,
      assetSet => $asset_set_resource_name
    });

  # Create an operation to add the link.
  my $operation =
    Google::Ads::GoogleAds::V21::Services::AssetSetAssetService::AssetSetAssetOperation
    ->new({
      create => $asset_set_asset
    });

  # Send the mutate request.
  # Note this is the point that the API will enforce uniqueness of the
  # DynamicEducationAsset.programId field. You can have any number of assets
  # with the same programId, however, only one Asset is allowed per AssetSet
  # with the same program ID.
  my $response = $api_client->AssetSetAssetService()->mutate({
      customerId => $customer_id,
      operations => [$operation]});

  # Print some information about the response.
  my $resource_name = $response->{results}[0]{resourceName};
  printf "Created AssetSetAsset link with resource name '%s'.\n",
    $resource_name;
}

# Links an AssetSet to Campaign by creating a CampaignAssetSet.
sub link_asset_set_to_campaign {
  my ($api_client, $customer_id, $campaign_id, $asset_set_resource_name) = @_;

  # Create a CampaignAssetSet representing the link between an AssetSet and a Campaign.
  my $campaign_asset_set =
    Google::Ads::GoogleAds::V21::Resources::CampaignAssetSet->new({
      campaign => Google::Ads::GoogleAds::V21::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
      assetSet => $asset_set_resource_name
    });

  # Create an operation to add the CampaignAssetSet.
  my $operation =
    Google::Ads::GoogleAds::V21::Services::CampaignAssetSetService::CampaignAssetSetOperation
    ->new({
      create => $campaign_asset_set
    });

  # Issue the mutate request.
  my $response = $api_client->CampaignAssetSetService()->mutate({
      customerId => $customer_id,
      operations => [$operation]});

  # Print some information about the response.
  my $resource_name = $response->{results}[0]{resourceName};
  printf "Created a CampaignAssetSet with resource name '%s'.\n",
    $resource_name;
}

# Don't run the example if the file is being included.
if (abs_path($0) ne abs_path(__FILE__)) {
  return 1;
}

# Get Google Ads Client, credentials will be read from ~/googleads.properties.
my $api_client = Google::Ads::GoogleAds::Client->new();

# By default examples are set to die on any server returned fault.
$api_client->set_die_on_faults(1);

# Parameters passed on the command line will override any parameters set in code.
GetOptions("customer_id=s" => \$customer_id, "campaign_id=i" => \$campaign_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, $campaign_id);

# Call the example.
add_dynamic_remarketing_asset($api_client, $customer_id =~ s/-//gr,
  $campaign_id);

=pod

=head1 NAME

add_dynamic_remarketing_asset

=head1 DESCRIPTION

Adds an asset for use in dynamic remarketing.

=head1 SYNOPSIS

add_dynamic_remarketing_asset.pl [options]

    -help                       Show the help message.
    -customer_id                The Google Ads customer ID.
    -campaign_id                Specify a campaign type which supports dynamic
                                remarketing, such as Display.

=cut