Skip to content

Commit

Permalink
Combine Ad Responsive Search Ad With Customizer into Full example
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfrg committed Dec 12, 2023
1 parent 142debd commit 5a46886
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 296 deletions.
215 changes: 184 additions & 31 deletions examples/advanced_operations/add_responsive_search_ad_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
import argparse
import sys
import uuid

import requests

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


# Keywords from user.
_KEYWORD_TEXT_EXACT_1 = "example of exact match"
_KEYWORD_TEXT_PHRASE_1 = "example of phrase match"
Expand All @@ -51,24 +51,9 @@
_COUNTRY_CODE = "AR"


def create_ad_text_asset(client, text, pinned_field=None):
"""Create an AdTextAsset.
Args:
client: an initialized GoogleAdsClient instance.
text: text for headlines and descriptions.
pinned_field: to pin a text asset so it always shows in the ad.
Returns:
An ad text asset.
"""
ad_text_asset = client.get_type("AdTextAsset")
ad_text_asset.text = text
if pinned_field:
ad_text_asset.pinned_field = pinned_field
return ad_text_asset


def main(client, customer_id, omit_image_extensions):
def main(
client, customer_id, omit_image_extensions, customizer_attribute_name=None
):
"""
The main method that creates all necessary entities for the example.
Expand All @@ -79,6 +64,16 @@ def main(client, customer_id, omit_image_extensions):
Returns:
A responsive search ad with all settings required to run campaign.
"""

if customizer_attribute_name:
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 a budget, which can be shared by multiple campaigns.
campaign_budget = create_campaign_budget(client, customer_id)

Expand All @@ -90,7 +85,9 @@ def main(client, customer_id, omit_image_extensions):
client, customer_id, campaign_resource_name
)

create_ad_group_ad(client, customer_id, ad_group_resource_name)
create_ad_group_ad(
client, customer_id, ad_group_resource_name, customizer_attribute_name
)

add_keywords(client, customer_id, ad_group_resource_name)

Expand All @@ -104,6 +101,133 @@ def main(client, customer_id, omit_image_extensions):
add_images(client, customer_id, campaign_resource_name)


# [START add_responsive_search_ad_full_customizer_1]
def create_customizer_attribute(client, customer_id, customizer_attribute_name):
"""Creates a customizer attribute with the given customizer attribute name.
Args:
client: an initialized GoogleAdsClient instance.
customer_id: a client customer ID.
customizer_attribute_name: the name for the customizer attribute.
Returns:
A resource name for a customizer attribute.
"""
# Creates a customizer attribute operation for creating a customizer
# attribute.
operation = client.get_type("CustomizerAttributeOperation")
# Creates a customizer attribute with the specified name.
customizer_attribute = operation.create
customizer_attribute.name = customizer_attribute_name
# 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.
customizer_attribute.type_ = client.enums.CustomizerAttributeTypeEnum.PRICE

# Issues a mutate request to add the customizer attribute and prints its
# information.
customizer_attribute_service = client.get_service(
"CustomizerAttributeService"
)
response = customizer_attribute_service.mutate_customizer_attributes(
customer_id=customer_id, operations=[operation]
)
resource_name = response.results[0].resource_name

print(f"Added a customizer attribute with resource name: '{resource_name}'")

return resource_name


# [END add_responsive_search_ad_full_customizer_1]


# [START add_responsive_search_full_customizer_2]
def link_customizer_attribute_to_customer(
client, customer_id, customizer_attribute_resource_name
):
"""Links the customizer attribute to the customer.
This is done by providing a value to be used in a responsive search ad
that will be created in a later step.
Args:
client: an initialized GoogleAdsClient instance.
customer_id: a client customer ID.
customizer_attribute_resource_name: a resource name for customizer
attribute.
"""
# Creates a customer customizer operation.
operation = client.get_type("CustomerCustomizerOperation")
# Creates a customer customizer with the value to be used in the responsive
# search ad.
customer_customizer = operation.create
customer_customizer.customizer_attribute = (
customizer_attribute_resource_name
)
customer_customizer.value.type_ = (
client.enums.CustomizerAttributeTypeEnum.PRICE
)
# Specify '100USD' as a text value. The ad customizer will dynamically
# replace the placeholder with this value when the ad serves.
customer_customizer.value.string_value = "100USD"

customer_customizer_service = client.get_service(
"CustomerCustomizerService"
)
# Issues a mutate request to add the customer customizer and prints its
# information.
response = customer_customizer_service.mutate_customer_customizers(
customer_id=customer_id, operations=[operation]
)
resource_name = response.results[0].resource_name

print(f"Added a customer customizer with resource name: '{resource_name}'")


# [END add_responsive_search_full_customizer_2]


def create_ad_text_asset(client, text, pinned_field=None):
"""Create an AdTextAsset.
Args:
client: an initialized GoogleAdsClient instance.
text: text for headlines and descriptions.
pinned_field: to pin a text asset so it always shows in the ad.
Returns:
An ad text asset.
"""
ad_text_asset = client.get_type("AdTextAsset")
ad_text_asset.text = text
if pinned_field:
ad_text_asset.pinned_field = pinned_field
return ad_text_asset


def create_ad_text_asset_with_customizer(client, customizer_attribute_name):
"""Create an AdTextAsset.
Args:
client: an initialized GoogleAdsClient instance.
customizer_attribute_name: The resource Name of the customizer attribute.
Returns:
An ad text asset.
"""
ad_text_asset = client.get_type("AdTextAsset")

# 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.
ad_text_asset.text = (
f"Just {{CUSTOMIZER.{customizer_attribute_name}:10USD}}"
)

return ad_text_asset


def create_campaign_budget(client, customer_id):
"""Creates campaign budget resource.
Expand Down Expand Up @@ -221,13 +345,17 @@ def create_ad_group(client, customer_id, campaign_resource_name):
return ad_group_resource_name


def create_ad_group_ad(client, customer_id, ad_group_resource_name):
def create_ad_group_ad(
client, customer_id, ad_group_resource_name, customizer_attribute_name
):
"""Creates ad group ad.
Args:
client: an initialized GoogleAdsClient instance.
customer_id: a client customer ID.
ad_group_resource_name: an ad group resource name.
customizer_attribute_name: (optional) the resource name of the customizer attribute
to use in one of the descriptions
Returns:
Ad group ad resource name.
Expand Down Expand Up @@ -265,11 +393,17 @@ def create_ad_group_ad(client, customer_id, ad_group_resource_name):
)

# Description 1 and 2
description_1 = create_ad_text_asset(client, "Desc 1 testing")
description_2 = None
if customizer_attribute_name:
description_2 = create_ad_text_asset_with_customizer(
client, customizer_attribute_name
)
else:
description_2 = create_ad_text_asset(client, "Desc 2 testing")

ad_group_ad.ad.responsive_search_ad.descriptions.extend(
[
create_ad_text_asset(client, "Desc 1 testing"),
create_ad_text_asset(client, "Desc 2 testing"),
]
[description_1, description_2]
)

# Paths
Expand Down Expand Up @@ -413,11 +547,7 @@ def add_geo_targeting(client, customer_id, campaign_resource_name):
for suggestion in results.geo_target_constant_suggestions:
geo_target_constant = suggestion.geo_target_constant
print(
f"{geo_target_constant.resource_name} "
f"({geo_target_constant.name}, "
f"{geo_target_constant.country_code}, "
f"{geo_target_constant.target_type}, "
f"{geo_target_constant.status.name}) "
f"geo_target_constant: {geo_target_constant} "
f"is found in _LOCALE ({suggestion.locale}) "
f"with reach ({suggestion.reach}) "
f"from search term ({suggestion.search_term})."
Expand Down Expand Up @@ -551,10 +681,33 @@ def add_images(client, customer_id, campaign_resource_name):
help="Whether or not the campaign will use image extensions.",
)

# The name of the customizer attribute to be used in the ad customizer, which
# must be unique for a given customer account. To run this example multiple
# times, specify a unique value as a command line 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. For more details visit:
# https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations
parser.add_argument(
"-n",
"--customizer_attribute_name",
type=str,
default=None,
help=(
"The name of the customizer attribute to be created. The name must "
"be unique across a single client account, so be sure not to use "
"the same value more than once."
),
)

args = parser.parse_args()

try:
main(googleads_client, args.customer_id)
main(
googleads_client,
args.customer_id,
args.omit_image_extensions,
args.customizer_attribute_name,
)
except GoogleAdsException as ex:
print(
f'Request with ID "{ex.request_id}" failed with status '
Expand Down
Loading

0 comments on commit 5a46886

Please sign in to comment.