Add Responsive Search Ad with Ad Customizer
Stay organized with collections
Save and categorize content based on your preferences.
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.v20.enums.AdGroupAdStatusEnum.AdGroupAdStatus
;
import
com.google.ads.googleads.v20.services.AdGroupAdOperation
;
import
com.google.ads.googleads.v20.services.AdGroupAdServiceClient
;
import
com.google.ads.googleads.v20.services.MutateAdGroupAdsResponse
;
import
com.google.ads.googleads.v20.utils.ResourceNames
;
import
com.google.ads.googleads.v20.common.AdTextAsset
;
import
com.google.ads.googleads.v20.common.CustomizerValue
;
import
com.google.ads.googleads.v20.common.ResponsiveSearchAdInfo
;
import
com.google.ads.googleads.v20.enums.CustomizerAttributeTypeEnum.CustomizerAttributeType
;
import
com.google.ads.googleads.v20.errors.GoogleAdsError
;
import
com.google.ads.googleads.v20.errors.GoogleAdsException
;
import
com.google.ads.googleads.v20.resources.Ad
;
import
com.google.ads.googleads.v20.resources.AdGroupAd
;
import
com.google.ads.googleads.v20.resources.CustomerCustomizer
;
import
com.google.ads.googleads.v20.resources.CustomizerAttribute
;
import
com.google.ads.googleads.v20.services.CustomerCustomizerOperation
;
import
com.google.ads.googleads.v20.services.CustomerCustomizerServiceClient
;
import
com.google.ads.googleads.v20.services.CustomizerAttributeOperation
;
import
com.google.ads.googleads.v20.services.CustomizerAttributeServiceClient
;
import
com.google.ads.googleads.v20.services.MutateCustomerCustomizersResponse
;
import
com.google.ads.googleads.v20.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\V20\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V20\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V20\GoogleAdsException;
use Google\Ads\GoogleAds\Util\V20\ResourceNames;
use Google\Ads\GoogleAds\V20\Common\AdTextAsset;
use Google\Ads\GoogleAds\V20\Common\CustomizerValue;
use Google\Ads\GoogleAds\V20\Common\ResponsiveSearchAdInfo;
use Google\Ads\GoogleAds\V20\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
use Google\Ads\GoogleAds\V20\Enums\CustomizerAttributeTypeEnum\CustomizerAttributeType;
use Google\Ads\GoogleAds\V20\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V20\Resources\Ad;
use Google\Ads\GoogleAds\V20\Resources\AdGroupAd;
use Google\Ads\GoogleAds\V20\Resources\CustomerCustomizer;
use Google\Ads\GoogleAds\V20\Resources\CustomizerAttribute;
use Google\Ads\GoogleAds\V20\Services\AdGroupAdOperation;
use Google\Ads\GoogleAds\V20\Services\CustomerCustomizerOperation;
use Google\Ads\GoogleAds\V20\Services\CustomizerAttributeOperation;
use Google\Ads\GoogleAds\V20\Services\MutateAdGroupAdsRequest;
use Google\Ads\GoogleAds\V20\Services\MutateCustomerCustomizersRequest;
use Google\Ads\GoogleAds\V20\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)
->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
(
"
\t
On 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
(
"
\t
Type: %s
\n\t
Code: %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.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License
, and code samples are licensed under the Apache 2.0 License
. For details, see the Google Developers Site Policies
. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-06-30 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-06-30 UTC."],[[["\u003cp\u003eThis code uses the Google Ads API to create responsive search ads with dynamic content using ad customizers.\u003c/p\u003e\n"],["\u003cp\u003eAd customizers allow for updating elements like price in ad copy without creating separate ads.\u003c/p\u003e\n"],["\u003cp\u003eThe code provides implementations in PHP and Ruby, while Python, Perl, and C# are not currently supported.\u003c/p\u003e\n"],["\u003cp\u003eCustomizer attributes are linked to customer accounts and assigned default values for fallback.\u003c/p\u003e\n"],["\u003cp\u003eUsing ad customizers provides benefits like dynamic content updates, improved relevance, and time savings.\u003c/p\u003e\n"]]],[],null,[]]