Add Responsive Search Ad with Ad Customizer

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
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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

import com.beust.jcommander.Parameter;
import com.google.ads.googleads.examples.utils.ArgumentNames;
import com.google.ads.googleads.examples.utils.CodeSampleParams;
import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.ads.googleads.v16.enums.AdGroupAdStatusEnum.AdGroupAdStatus;
import com.google.ads.googleads.v16.services.AdGroupAdOperation;
import com.google.ads.googleads.v16.services.AdGroupAdServiceClient;
import com.google.ads.googleads.v16.services.MutateAdGroupAdsResponse;
import com.google.ads.googleads.v16.utils.ResourceNames;
import com.google.ads.googleads.v16.common.AdTextAsset;
import com.google.ads.googleads.v16.common.CustomizerValue;
import com.google.ads.googleads.v16.common.ResponsiveSearchAdInfo;
import com.google.ads.googleads.v16.enums.CustomizerAttributeTypeEnum.CustomizerAttributeType;
import com.google.ads.googleads.v16.errors.GoogleAdsError;
import com.google.ads.googleads.v16.errors.GoogleAdsException;
import com.google.ads.googleads.v16.resources.Ad;
import com.google.ads.googleads.v16.resources.AdGroupAd;
import com.google.ads.googleads.v16.resources.CustomerCustomizer;
import com.google.ads.googleads.v16.resources.CustomizerAttribute;
import com.google.ads.googleads.v16.services.CustomerCustomizerOperation;
import com.google.ads.googleads.v16.services.CustomerCustomizerServiceClient;
import com.google.ads.googleads.v16.services.CustomizerAttributeOperation;
import com.google.ads.googleads.v16.services.CustomizerAttributeServiceClient;
import com.google.ads.googleads.v16.services.MutateCustomerCustomizersResponse;
import com.google.ads.googleads.v16.services.MutateCustomizerAttributesResponse;
import com.google.common.collect.ImmutableList;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Adds a customizer attribute, links the customizer attribute to a customer, and then adds a
 * responsive search ad with a description using the ad customizer to the specified ad group.
 */
public class AddResponsiveSearchAdWithAdCustomizer {

  private static class AddResponsiveSearchAdWithAdCustomizerParams extends CodeSampleParams {

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

    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;

    // The name of the customizer attribute to be used in the ad customizer, which must be unique.
    // To run this example multiple times, change this value or specify its corresponding argument.
    // Note that there is a limit for the number of enabled customizer attributes in one account,
    // so you shouldn't run this example more than necessary.
    // Visit
    // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads?hl=en#rules_and_limitations
    // for details.
    //
    // Specify the customizer attribute name here or the default specified below will be used.
    @Parameter(names = ArgumentNames.CUSTOMIZER_ATTRIBUTE_NAME)
    private String customizerAttributeName = "Price";
  }

  public static void main(String[] args) {
    AddResponsiveSearchAdWithAdCustomizerParams params =
        new AddResponsiveSearchAdWithAdCustomizerParams();
    if (!params.parseArguments(args)) {

      // Either pass the required parameters for this example on the command line, or insert them
      // into the code here. See the parameter class definition above for descriptions.
      params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE");
      params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
      // Optional: To use a different customizer attribute name from the default ("Price"),
      // uncomment the line below and insert the desired customizer attribute name.
      // params.customizerAttributeName = "INSERT_CUSTOMIZER_ATTRIBUTE_NAME_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 AddResponsiveSearchAdWithAdCustomizer()
          .runExample(
              googleAdsClient, params.customerId, params.adGroupId, params.customizerAttributeName);
    } catch (GoogleAdsException gae) {
      // GoogleAdsException is the base class for most exceptions thrown by an API request.
      // Instances of this exception have a message and a GoogleAdsFailure that contains a
      // collection of GoogleAdsErrors that indicate the underlying causes of the
      // GoogleAdsException.
      System.err.printf(
          "Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
          gae.getRequestId());
      int i = 0;
      for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
        System.err.printf("  Error %d: %s%n", i++, googleAdsError);
      }
      System.exit(1);
    }
  }

  /**
   * Runs the example.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   * @param adGroupId the ad group ID.
   * @param customizerAttributeName the customizer attribute name.
   */
  private void runExample(
      GoogleAdsClient googleAdsClient,
      long customerId,
      long adGroupId,
      String customizerAttributeName) {
    String customizerAttributeResourceName =
        createCustomizerAttribute(googleAdsClient, customerId, customizerAttributeName);
    linkCustomizerAttributeToCustomer(googleAdsClient, customerId, customizerAttributeResourceName);
    createResponsiveSearchAdWithCustomization(
        googleAdsClient, customerId, adGroupId, customizerAttributeName);
  }

  /** Creates a customizer attribute with the specified customizer attribute name. */
  private static String createCustomizerAttribute(
      GoogleAdsClient googleAdsClient, long customerId, String customizerAttributeName) {
    // Creates a customizer attribute with the specified name.
    CustomizerAttribute customizerAttribute =
        CustomizerAttribute.newBuilder()
            .setName(customizerAttributeName)
            // Specifies the type to be 'PRICE' so that we can dynamically customize the part of the
            // ad's description that is a price of a product/service we advertise.
            .setType(CustomizerAttributeType.PRICE)
            .build();
    // Creates a customizer attribute operation for creating a customizer attribute.
    CustomizerAttributeOperation operation =
        CustomizerAttributeOperation.newBuilder().setCreate(customizerAttribute).build();

    try (CustomizerAttributeServiceClient customizerAttributeServiceClient =
        googleAdsClient.getLatestVersion().createCustomizerAttributeServiceClient()) {
      // Issues a mutate request to add the customizer attribute and prints its information.
      MutateCustomizerAttributesResponse response =
          customizerAttributeServiceClient.mutateCustomizerAttributes(
              Long.toString(customerId), ImmutableList.of(operation));
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Added a customizer with resource name '%s'.%n", resourceName);
      return resourceName;
    }
  }

  /**
   * Links the customizer attribute to the customer by providing a value to be used in a responsive
   * search ad that will be created in a later step.
   */
  private static void linkCustomizerAttributeToCustomer(
      GoogleAdsClient googleAdsClient, long customerId, String customizerAttributeResourceName) {
    // Creates a customer customizer with the value to be used in the responsive search ad.
    CustomerCustomizer customerCustomizer =
        CustomerCustomizer.newBuilder()
            .setCustomizerAttribute(customizerAttributeResourceName)
            // Specify '100USD' as a text value. The ad customizer will dynamically replace the
            // placeholder with this value when the ad serves.
            .setValue(
                CustomizerValue.newBuilder()
                    .setType(CustomizerAttributeType.PRICE)
                    .setStringValue("100USD")
                    .build())
            .build();

    // Creates a customer customizer operation.
    CustomerCustomizerOperation operation =
        CustomerCustomizerOperation.newBuilder().setCreate(customerCustomizer).build();

    try (CustomerCustomizerServiceClient customerCustomizerServiceClient =
        googleAdsClient.getLatestVersion().createCustomerCustomizerServiceClient()) {
      // Issues a mutate request to add the customer customizer and prints its information.
      MutateCustomerCustomizersResponse response =
          customerCustomizerServiceClient.mutateCustomerCustomizers(
              Long.toString(customerId), ImmutableList.of(operation));
      System.out.printf(
          "Added a customer customizer with resource name '%s'.%n",
          response.getResults(0).getResourceName());
    }
  }

  /** Creates a responsive search ad that uses the specified customizer attribute. */
  private static void createResponsiveSearchAdWithCustomization(
      GoogleAdsClient googleAdsClient,
      long customerId,
      long adGroupId,
      String customizerAttributeName) {
    List<String> headlines =
        ImmutableList.of("Cruise to Mars", "Best Space Cruise Line", "Experience the Stars");
    List<AdTextAsset> headlineAssets =
        headlines.stream()
            .map(headline -> AdTextAsset.newBuilder().setText(headline).build())
            .collect(Collectors.toList());
    List<String> descriptions =
        ImmutableList.of(
            "Buy your tickets now",
            // Creates this particular description using the ad customizer.
            // Visit
            // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads
            // for details about the placeholder format.
            // The ad customizer replaces the placeholder with the value we previously
            // created and linked to the customer using CustomerCustomizer.
            String.format("Just {CUSTOMIZER.%s:10USD}", customizerAttributeName));
    List<AdTextAsset> descriptionAssets =
        descriptions.stream()
            .map(description -> AdTextAsset.newBuilder().setText(description).build())
            .collect(Collectors.toList());

    // Creates an ad and sets responsive search ad info.
    Ad ad =
        Ad.newBuilder()
            .setResponsiveSearchAd(
                ResponsiveSearchAdInfo.newBuilder()
                    .addAllHeadlines(headlineAssets)
                    .addAllDescriptions(descriptionAssets)
                    .setPath1("all-inclusive")
                    .setPath2("deals")
                    .build())
            .addAllFinalUrls(ImmutableList.of("http://www.example.com"))
            .build();

    // Creates an ad group ad to hold the above ad.
    AdGroupAd adGroupAd =
        AdGroupAd.newBuilder()
            .setAdGroup(ResourceNames.adGroup(customerId, adGroupId))
            .setStatus(AdGroupAdStatus.PAUSED)
            .setAd(ad)
            .build();

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

    try (AdGroupAdServiceClient adGroupAdServiceClient =
        googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) {
      // Issues a mutate request to add the ad group ad and prints its information.
      MutateAdGroupAdsResponse response =
          adGroupAdServiceClient.mutateAdGroupAds(
              Long.toString(customerId), ImmutableList.of(operation));
      System.out.printf(
          "Created a responsive search ad with resource name '%s'.%n",
          response.getResults(0).getResourceName());
    }
  }
}

      

C#

This example is not yet available in C#; you can take a look at the other languages.
    

PHP

<?php

/**
 * 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
 *
 *     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\AdvancedOperations;

require __DIR__ . '/../../vendor/autoload.php';

use GetOpt\GetOpt;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsException;
use Google\Ads\GoogleAds\Util\V16\ResourceNames;
use Google\Ads\GoogleAds\V16\Common\AdTextAsset;
use Google\Ads\GoogleAds\V16\Common\CustomizerValue;
use Google\Ads\GoogleAds\V16\Common\ResponsiveSearchAdInfo;
use Google\Ads\GoogleAds\V16\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
use Google\Ads\GoogleAds\V16\Enums\CustomizerAttributeTypeEnum\CustomizerAttributeType;
use Google\Ads\GoogleAds\V16\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V16\Resources\Ad;
use Google\Ads\GoogleAds\V16\Resources\AdGroupAd;
use Google\Ads\GoogleAds\V16\Resources\CustomerCustomizer;
use Google\Ads\GoogleAds\V16\Resources\CustomizerAttribute;
use Google\Ads\GoogleAds\V16\Services\AdGroupAdOperation;
use Google\Ads\GoogleAds\V16\Services\CustomerCustomizerOperation;
use Google\Ads\GoogleAds\V16\Services\CustomizerAttributeOperation;
use Google\Ads\GoogleAds\V16\Services\MutateAdGroupAdsRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCustomerCustomizersRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCustomizerAttributesRequest;
use Google\ApiCore\ApiException;

/**
 * Adds a customizer attribute, links the customizer attribute to a customer, and then adds
 * a responsive search ad with a description using the ad customizer to the specified ad group.
 */
class AddResponsiveSearchAdWithAdCustomizer
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    private const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE';

    // The name of the customizer attribute to be used in the ad customizer, which must be unique.
    // To run this example multiple times, change this value or specify its corresponding argument.
    // Note that there is a limit for the number of enabled customizer attributes in one account,
    // so you shouldn't run this example more than necessary.
    // Visit https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations
    // for details.
    private const CUSTOMIZER_ATTRIBUTE_NAME = 'Price';

    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::AD_GROUP_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::CUSTOMIZER_ATTRIBUTE_NAME => GetOpt::OPTIONAL_ARGUMENT
        ]);

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

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

        try {
            self::runExample(
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
                $options[ArgumentNames::AD_GROUP_ID] ?: self::AD_GROUP_ID,
                $options[ArgumentNames::CUSTOMIZER_ATTRIBUTE_NAME]
                    ?: self::CUSTOMIZER_ATTRIBUTE_NAME
            );
        } catch (GoogleAdsException $googleAdsException) {
            printf(
                "Request with ID '%s' has failed.%sGoogle Ads failure details:%s",
                $googleAdsException->getRequestId(),
                PHP_EOL,
                PHP_EOL
            );
            foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {
                /** @var GoogleAdsError $error */
                printf(
                    "\t%s: %s%s",
                    $error->getErrorCode()->getErrorCode(),
                    $error->getMessage(),
                    PHP_EOL
                );
            }
            exit(1);
        } catch (ApiException $apiException) {
            printf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
            exit(1);
        }
    }

    /**
     * Runs the example.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param int $adGroupId the ad group ID
     * @param string $customizerAttributeName the customizer attribute name
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $adGroupId,
        string $customizerAttributeName
    ) {
        $customizerAttributeResourceName = self::createCustomizerAttribute(
            $googleAdsClient,
            $customerId,
            $customizerAttributeName
        );
        self::linkCustomizerAttributeToCustomer(
            $googleAdsClient,
            $customerId,
            $customizerAttributeResourceName
        );
        self::createResponsiveSearchAdWithCustomization(
            $googleAdsClient,
            $customerId,
            $adGroupId,
            $customizerAttributeName
        );
    }

    /**
     * Creates a customizer attribute with the specified customizer attribute name.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $customizerAttributeName the name of the customizer attribute
     * @return string the created customizer attribute resource name
     */
    private static function createCustomizerAttribute(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $customizerAttributeName
    ) {
        // Creates a customizer attribute with the specified name.
        $customizerAttribute = new CustomizerAttribute([
            'name' => $customizerAttributeName,
            // Specifies the type to be 'PRICE' so that we can dynamically customize the part of
            // the ad's description that is a price of a product/service we advertise.
            'type' => CustomizerAttributeType::PRICE
        ]);

        // Creates a customizer attribute operation for creating a customizer attribute.
        $operation = new CustomizerAttributeOperation();
        $operation->setCreate($customizerAttribute);

        // Issues a mutate request to add the customizer attribute and prints its information.
        $customizerAttributeServiceClient = $googleAdsClient->getCustomizerAttributeServiceClient();
        $response = $customizerAttributeServiceClient->mutateCustomizerAttributes(
            MutateCustomizerAttributesRequest::build($customerId, [$operation])
        );
        $customizerAttributeResourceName = $response->getResults()[0]->getResourceName();
        printf(
            "Added a customizer attribute with resource name '%s'.%s",
            $customizerAttributeResourceName,
            PHP_EOL
        );

        return $customizerAttributeResourceName;
    }

    /**
     * Links the customizer attribute to the customer by providing a value to be used in a
     * responsive search ad that will be created in a later step.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $customizerAttributeResourceName the customizer attribute resource name
     */
    private static function linkCustomizerAttributeToCustomer(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $customizerAttributeResourceName
    ) {
        // Creates a customer customizer with the value to be used in the responsive search ad.
        $customerCustomizer = new CustomerCustomizer([
            'customizer_attribute' => $customizerAttributeResourceName,
            // Specify '100USD' as a text value. The ad customizer will dynamically replace the
            // placeholder with this value when the ad serves.
            'value' => new CustomizerValue([
                'type' => CustomizerAttributeType::PRICE,
                'string_value' => '100USD'
            ])
        ]);

        // Creates a customer customizer operation.
        $operation = new CustomerCustomizerOperation();
        $operation->setCreate($customerCustomizer);

        // Issues a mutate request to add the customer customizer and prints its information.
        $customerCustomizerServiceClient = $googleAdsClient->getCustomerCustomizerServiceClient();
        $response = $customerCustomizerServiceClient->mutateCustomerCustomizers(
            MutateCustomerCustomizersRequest::build($customerId, [$operation])
        );
        printf(
            "Added a customer customizer with resource name '%s'.%s",
            $response->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }

    /**
     * Creates a responsive search ad that uses the specified customizer attribute.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the client customer ID
     * @param int $adGroupId the ad group ID in which to create the ad
     * @param string $customizerAttributeName the name of the customizer attribute
     */
    private static function createResponsiveSearchAdWithCustomization(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $adGroupId,
        string $customizerAttributeName
    ) {
        // Creates an ad and sets responsive search ad info.
        $ad = new Ad([
            'responsive_search_ad' => new ResponsiveSearchAdInfo([
                'headlines' => [
                    new AdTextAsset(['text' => 'Cruise to Mars']),
                    new AdTextAsset(['text' => 'Best Space Cruise Line']),
                    new AdTextAsset(['text' => 'Experience the Stars'])
                ],
                'descriptions' => [
                    new AdTextAsset(['text' => 'Buy your tickets now']),
                    // Creates this particular description using the ad customizer.
                    // Visit https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads
                    // for details about the placeholder format.
                    // The ad customizer replaces the placeholder with the value we previously
                    // created and linked to the customer using `CustomerCustomizer`.
                    new AdTextAsset(['text' => "Just {CUSTOMIZER.$customizerAttributeName:10USD}"])
                ],
                'path1' => 'all-inclusive',
                'path2' => 'deals'
            ]),
            'final_urls' => ['http://www.example.com']
        ]);

        // Creates an ad group ad to hold the above ad.
        $adGroupAd = new AdGroupAd([
            'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId),
            'status' => AdGroupAdStatus::PAUSED,
            'ad' => $ad
        ]);

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

        // Issues a mutate request to add the ad group ad and prints its information.
        $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient();
        $response = $adGroupAdServiceClient->mutateAdGroupAds(
            MutateAdGroupAdsRequest::build($customerId, [$adGroupAdOperation])
        );
        printf(
            "Created responsive search ad with resource name '%s'.%s",
            $response->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }
}

AddResponsiveSearchAdWithAdCustomizer::main();

      

Python

This example is not yet available in Python; you can take a look at the other languages.
    

Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# 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
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Adds a customizer attribute, links the customizer attribute to a customer,
# and then adds a responsive search ad with a description using the ad
# customizer to the specified ad group.

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

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

  customizer_attribute_resource_name = create_customizer_attribute(
    client,
    customer_id,
    customizer_attribute_name,
  )

  link_customizer_attribute_to_customer(
    client,
    customer_id,
    customizer_attribute_resource_name,
  )

  create_responsive_search_ad_with_customization(
    client,
    customer_id,
    ad_group_id,
    customizer_attribute_name,
  )
end

def create_customizer_attribute(client, customer_id, attribute_name)
  operation = client.operation.create_resource.customizer_attribute do |ca|
    ca.name = attribute_name
    ca.type = :PRICE
  end

  response = client.service.customizer_attribute.mutate_customizer_attributes(
    customer_id: customer_id,
    operations: [operation],
  )

  resource_name = response.results.first.resource_name
  puts "Created a customizer attribute with resource name #{resource_name}."

  resource_name
end

def link_customizer_attribute_to_customer(client, customer_id, resource_name)
  operation = client.operation.create_resource.customer_customizer do |cc|
    cc.customizer_attribute = resource_name
    cc.value = client.resource.customizer_value do |cv|
      cv.type = :PRICE
      cv.string_value = '100USD'
    end
  end

  response = client.service.customer_customizer.mutate_customer_customizers(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Created a customer customizer with resource name #{response.results.first.resource_name}."
end

def create_responsive_search_ad_with_customization(client, customer_id, ad_group_id, attribute_name)
  operation = client.operation.create_resource.ad_group_ad do |aga|
    aga.ad_group = client.path.ad_group(customer_id, ad_group_id)
    aga.status = :PAUSED
    aga.ad = client.resource.ad do |ad|
      ad.responsive_search_ad = client.resource.responsive_search_ad_info do |rsa|
        rsa.headlines << client.resource.ad_text_asset do |asset|
          asset.text = 'Cruise to Mars'
        end
        rsa.headlines << client.resource.ad_text_asset do |asset|
          asset.text = 'Best Space Cruise Line'
        end
        rsa.headlines << client.resource.ad_text_asset do |asset|
          asset.text = 'Experience the Stars'
        end

        rsa.descriptions << client.resource.ad_text_asset do |asset|
          asset.text = 'Buy your tickets now'
        end
        rsa.descriptions << client.resource.ad_text_asset do |asset|
          # Creates this particular description using the ad customizer.  Visit
          # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads
          # for details about the placeholder format.  The ad customizer
          # replaces the placeholder with the value we previously created and
          # linked to the customer using `CustomerCustomizer`.
          asset.text = "Just {CUSTOMIZER.#{attribute_name}:10USD}"
        end

        rsa.path1 = 'all-inclusive'
        rsa.path2 = 'deals'
      end

      ad.final_urls << 'http://www.example.com'
    end
  end

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

  puts "Created responsive search ad with resource name #{response.results.first.resource_name}."
end

if __FILE__ == $0
  options = {}
  DEFAULT_CUSTOMIZER_ATTRIBUTE_NAME = 'Price'

  # The following parameter(s) should be provided to run the example. You can
  # either specify these by changing the INSERT_XXX_ID_HERE values below, or on
  # the command line.
  #
  # Parameters passed on the command line will override any parameters set in
  # code.
  #
  # Running the example with -h will print the command line usage.
  options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE'
  options[:ad_group_id] = 'INSERT_AD_GROUP_ID_HERE'
  options[:customizer_attribute_name] = nil

  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, 'Customer ID') do |v|
      options[:customer_id] = v
    end

    opts.on('-A', '--ad-group-id AD-GROUP-ID', String, "AdGroup ID") do |v|
      options[:ad_group_id] = v
    end

    opts.on('-n', '--customizer-attribute-name CUSTOMIZER-ATTRIBUTE-NAME',
            String, "Customizer Attribute Name") do |v|
      options[:customizer_attribute_name] = v
    end

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

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end
  end.parse!
  if options[:customizer_attribute_name].nil?
    options[:customizer_attribute_name] = DEFAULT_CUSTOMIZER_ATTRIBUTE_NAME
  end

  begin
    add_responsive_search_ad_with_ad_customizer(
      options.fetch(:customer_id).tr("-", ""),
      options[:ad_group_id],
      options[:customizer_attribute_name],
    )
  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

This example is not yet available in Perl; you can take a look at the other languages.