Dodaj zasób remarketingu dynamicznego

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.v11.common.DynamicEducationAsset;
import com.google.ads.googleads.v11.enums.AssetSetTypeEnum.AssetSetType;
import com.google.ads.googleads.v11.errors.GoogleAdsError;
import com.google.ads.googleads.v11.errors.GoogleAdsException;
import com.google.ads.googleads.v11.resources.Asset;
import com.google.ads.googleads.v11.resources.AssetSet;
import com.google.ads.googleads.v11.resources.AssetSetAsset;
import com.google.ads.googleads.v11.resources.CampaignAssetSet;
import com.google.ads.googleads.v11.services.AssetOperation;
import com.google.ads.googleads.v11.services.AssetServiceClient;
import com.google.ads.googleads.v11.services.AssetSetAssetOperation;
import com.google.ads.googleads.v11.services.AssetSetAssetServiceClient;
import com.google.ads.googleads.v11.services.AssetSetOperation;
import com.google.ads.googleads.v11.services.AssetSetServiceClient;
import com.google.ads.googleads.v11.services.CampaignAssetSetOperation;
import com.google.ads.googleads.v11.services.CampaignAssetSetServiceClient;
import com.google.ads.googleads.v11.services.MutateAssetSetAssetsResponse;
import com.google.ads.googleads.v11.services.MutateAssetSetsResponse;
import com.google.ads.googleads.v11.services.MutateAssetsResponse;
import com.google.ads.googleads.v11.services.MutateCampaignAssetSetsResponse;
import com.google.ads.googleads.v11.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.V11.Common;
using Google.Ads.GoogleAds.V11.Errors;
using Google.Ads.GoogleAds.V11.Resources;
using Google.Ads.GoogleAds.V11.Services;
using System;
using System.Collections.Generic;
using static Google.Ads.GoogleAds.V11.Enums.AssetSetTypeEnum.Types;

namespace Google.Ads.GoogleAds.Examples.V11
{
    /// <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.V11.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.V11.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.V11.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.V11.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\V11\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V11\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V11\GoogleAdsException;
use Google\Ads\GoogleAds\Util\V11\ResourceNames;
use Google\Ads\GoogleAds\V11\Common\DynamicEducationAsset;
use Google\Ads\GoogleAds\V11\Enums\AssetSetTypeEnum\AssetSetType;
use Google\Ads\GoogleAds\V11\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V11\Resources\Asset;
use Google\Ads\GoogleAds\V11\Resources\AssetSet;
use Google\Ads\GoogleAds\V11\Resources\AssetSetAsset;
use Google\Ads\GoogleAds\V11\Resources\CampaignAssetSet;
use Google\Ads\GoogleAds\V11\Services\AssetOperation;
use Google\Ads\GoogleAds\V11\Services\AssetSetAssetOperation;
use Google\Ads\GoogleAds\V11\Services\AssetSetOperation;
use Google\Ads\GoogleAds\V11\Services\CampaignAssetSetOperation;
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(
            $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(
            $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(
            $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(
            $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 uuid import uuid4

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


def main(client, customer_id, campaign_id):
    """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 = _create_asset(client, customer_id)
    asset_set_resource_name = _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, customer_id):
    """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 = client.get_type("AssetOperation")
    asset = operation.create
    # The final_urls list must not be empty
    asset.final_urls.append("https://www.example.com")
    education_asset = 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 = client.get_service("AssetService")
    response = asset_service.mutate_assets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name = 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, customer_id):
    """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 = client.get_type("AssetSetOperation")
    asset_set = operation.create
    asset_set.name = f"My dynamic remarketing assets {datetime.now()}"
    asset_set.type_ = client.enums.AssetSetTypeEnum.DYNAMIC_EDUCATION

    asset_set_service = client.get_service("AssetSetService")
    response = asset_set_service.mutate_asset_sets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name = 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, asset_resource_name, asset_set_resource_name, customer_id
):
    """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 = client.get_type("AssetSetAssetOperation")
    asset_set_asset = operation.create
    asset_set_asset.asset = asset_resource_name
    asset_set_asset.asset_set = asset_set_resource_name

    asset_set_asset_service = 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 = asset_set_asset_service.mutate_asset_set_assets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created asset set asset link with resource name '{resource_name}'")


def _link_asset_set_to_campaign(
    client, asset_set_resource_name, customer_id, campaign_id
):
    """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 = client.get_service("GoogleAdsService")
    # Creates an operation to add the campaign asset set.
    operation = client.get_type("CampaignAssetSetOperation")
    campaign_asset_set = 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 = client.get_service("CampaignAssetSetService")
    response = campaign_asset_set_service.mutate_campaign_asset_sets(
        customer_id=customer_id, operations=[operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created a campaign asset set with resource name '{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="v11")

    parser = 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 = parser.parse_args()

    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::V11::Resources::Asset;
use Google::Ads::GoogleAds::V11::Resources::AssetSet;
use Google::Ads::GoogleAds::V11::Resources::AssetSetAsset;
use Google::Ads::GoogleAds::V11::Resources::CampaignAssetSet;
use Google::Ads::GoogleAds::V11::Common::DynamicEducationAsset;
use Google::Ads::GoogleAds::V11::Enums::AssetSetTypeEnum qw(DYNAMIC_EDUCATION);
use Google::Ads::GoogleAds::V11::Services::AssetService::AssetOperation;
use Google::Ads::GoogleAds::V11::Services::AssetSetService::AssetSetOperation;
use
  Google::Ads::GoogleAds::V11::Services::AssetSetAssetService::AssetSetAssetOperation;
use
  Google::Ads::GoogleAds::V11::Services::CampaignAssetSetService::CampaignAssetSetOperation;
use Google::Ads::GoogleAds::V11::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::V11::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::V11::Resources::Asset->new({
      dynamicEducationAsset => $education_asset,
      finalUrls             => ["https://www.example.com"]});

  # Create an operation to add the asset.
  my $operation =
    Google::Ads::GoogleAds::V11::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::V11::Resources::AssetSet->new({
    name => "My dynamic remarketing assets #" . uniqid(),
    type => DYNAMIC_EDUCATION
  });

  # Create an operation to add the AssetSet.
  my $operation =
    Google::Ads::GoogleAds::V11::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::V11::Resources::AssetSetAsset->new({
      asset    => $asset_resource_name,
      assetSet => $asset_set_resource_name
    });

  # Create an operation to add the link.
  my $operation =
    Google::Ads::GoogleAds::V11::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::V11::Resources::CampaignAssetSet->new({
      campaign => Google::Ads::GoogleAds::V11::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
      assetSet => $asset_set_resource_name
    });

  # Create an operation to add the CampaignAssetSet.
  my $operation =
    Google::Ads::GoogleAds::V11::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