Skip to content

Commit 5a62587

Browse files
authored
get_responsive_search_ads golden (also includes missing add_responsive_search_ad example) (googleads#223)
* added add_responsive_search_ad * added get_responsive_search_ad
1 parent 890d5af commit 5a62587

2 files changed

Lines changed: 217 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env python
2+
# Copyright 2020 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
"""This example adds a responsive search ad to a given ad group.
16+
17+
To get ad groups, run get_ad_groups.py.
18+
"""
19+
20+
21+
import argparse
22+
import sys
23+
from uuid import uuid4
24+
25+
from google.ads.google_ads.client import GoogleAdsClient
26+
from google.ads.google_ads.errors import GoogleAdsException
27+
28+
29+
def main(client, customer_id, ad_group_id):
30+
ad_group_ad_service = client.get_service('AdGroupAdService', version='v2')
31+
ad_group_service = client.get_service('AdGroupService', version='v2')
32+
33+
# Create the ad group ad.
34+
ad_group_ad_operation = client.get_type('AdGroupAdOperation', version='v2')
35+
ad_group_ad = ad_group_ad_operation.create
36+
ad_group_ad.status = client.get_type(
37+
'AdGroupAdStatusEnum', version='v2').PAUSED
38+
ad_group_ad.ad_group.value = ad_group_service.ad_group_path(
39+
customer_id, ad_group_id)
40+
41+
# Set responsive search ad info.
42+
final_url = ad_group_ad.ad.final_urls.add()
43+
final_url.value = 'http://www.example.com'
44+
45+
# Set a pinning to always choose this asset for HEADLINE_1. Pinning is
46+
# optional; if no pinning is set, then headlines and descriptions will be
47+
# rotated and the ones that perform best will be used more often.
48+
pinned_headline = _create_ad_text_asset(
49+
client,
50+
f'Cruise to Mars #{str(uuid4())[:8]}',
51+
client.get_type(
52+
'ServedAssetFieldTypeEnum', version='v2').HEADLINE_1)
53+
54+
ad_group_ad.ad.responsive_search_ad.headlines.extend([
55+
pinned_headline,
56+
_create_ad_text_asset(client, 'Best Space Cruise Line'),
57+
_create_ad_text_asset(client, 'Experience the Stars')])
58+
ad_group_ad.ad.responsive_search_ad.descriptions.extend([
59+
_create_ad_text_asset(client, 'Buy your tickets now'),
60+
_create_ad_text_asset(client, 'Visit the Red Planet')])
61+
ad_group_ad.ad.responsive_search_ad.path1.value = 'all-inclusive'
62+
ad_group_ad.ad.responsive_search_ad.path2.value = 'deals'
63+
64+
# Send a request to the server to add a responsive search ad.
65+
try:
66+
ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads(
67+
customer_id, [ad_group_ad_operation])
68+
except GoogleAdsException as ex:
69+
print(f'Request with ID "{ex.request_id}" failed with status '
70+
f'"{ex.error.code().name}" and includes the following errors:')
71+
for error in ex.failure.errors:
72+
print(f'\tError with message "{error.message}".')
73+
if error.location:
74+
for field_path_element in error.location.field_path_elements:
75+
print(f'\t\tOn field: {field_path_element.field_name}')
76+
sys.exit(1)
77+
78+
for result in ad_group_ad_response.results:
79+
print(f'Created responsive search ad with resource name '
80+
f'"{result.resource_name}".')
81+
82+
83+
def _create_ad_text_asset(client, text, pinned_field=None):
84+
"""Create an AdTextAsset."""
85+
ad_text_asset = client.get_type('AdTextAsset', version='v2')
86+
ad_text_asset.text.value = text
87+
if pinned_field:
88+
ad_text_asset.pinned_field = pinned_field
89+
return ad_text_asset
90+
91+
92+
if __name__ == '__main__':
93+
# GoogleAdsClient will read the google-ads.yaml configuration file in the
94+
# home directory if none is specified.
95+
google_ads_client = GoogleAdsClient.load_from_storage()
96+
97+
parser = argparse.ArgumentParser(
98+
description=('Adds an expanded text ad to the specified ad group ID, '
99+
'for the given customer ID.'))
100+
# The following argument(s) should be provided to run the example.
101+
parser.add_argument('-c', '--customer_id', type=str,
102+
required=True, help='The Google Ads customer ID.')
103+
parser.add_argument('-a', '--ad_group_id', type=str,
104+
required=True, help='The ad group ID.')
105+
args = parser.parse_args()
106+
107+
main(google_ads_client, args.customer_id, args.ad_group_id)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env python
2+
# Copyright 2020 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
"""This example gets non-removed responsive search ads in a specified ad group.
16+
17+
To add responsive search ads, run basic_operations/add_responsive_search_ad.py.
18+
To get ad groups, run basic_operations/get_ad_groups.py.
19+
"""
20+
21+
import argparse
22+
import sys
23+
24+
from google.ads.google_ads.client import GoogleAdsClient
25+
from google.ads.google_ads.errors import GoogleAdsException
26+
27+
28+
_DEFAULT_PAGE_SIZE = 1000
29+
30+
31+
def main(client, customer_id, page_size, ad_group_id=None):
32+
ga_service = client.get_service('GoogleAdsService', version='v2')
33+
34+
query = '''
35+
SELECT ad_group.id, ad_group_ad.ad.id,
36+
ad_group_ad.ad.responsive_search_ad.headlines,
37+
ad_group_ad.ad.responsive_search_ad.descriptions,
38+
ad_group_ad.status FROM ad_group_ad
39+
WHERE ad_group_ad.ad.type = RESPONSIVE_SEARCH_AD
40+
AND ad_group_ad.status != "REMOVED"'''
41+
42+
if ad_group_id:
43+
query = query + f' AND ad_group.id = {ad_group_id}'
44+
45+
results = ga_service.search(customer_id, query=query, page_size=page_size)
46+
aga_status_enum = client.get_type(
47+
'AdGroupAdStatusEnum', version='v2').AdGroupAdStatus
48+
49+
try:
50+
one_found = False
51+
52+
for row in results:
53+
one_found = True
54+
ad = row.ad_group_ad.ad
55+
print(f'Responsive search ad with resource name '
56+
f'"{ad.resource_name}", '
57+
f'status {aga_status_enum.Name(row.ad_group_ad.status)} '
58+
f'was found.')
59+
if ad.responsive_search_ad:
60+
responsive_search_ad_info = ad.responsive_search_ad
61+
print('Headlines:\n{}\n'
62+
'Descriptions:\n{}\n'.format(
63+
'\n'.join(_ad_text_assets_to_strs(
64+
client, responsive_search_ad_info.headlines)),
65+
'\n'.join(_ad_text_assets_to_strs(
66+
client, responsive_search_ad_info.descriptions))))
67+
else:
68+
print('\tResponsive search ad info was not found.')
69+
70+
if not one_found:
71+
print('No responsive search ads were found.')
72+
73+
except GoogleAdsException as ex:
74+
print(f'Request with ID "{ex.request_id}" failed with status '
75+
f'"{ex.error.code().name}" and includes the following errors:')
76+
for error in ex.failure.errors:
77+
print(f'\tError with message "{error.message}".')
78+
if error.location:
79+
for field_path_element in error.location.field_path_elements:
80+
print(f'\t\tOn field: {field_path_element.field_name}')
81+
sys.exit(1)
82+
83+
84+
def _ad_text_assets_to_strs(client, assets):
85+
"""Converts a list of AdTextAssets to a list of user-friendly strings."""
86+
sa_field_type_enum = client.get_type(
87+
'ServedAssetFieldTypeEnum', version='v2').ServedAssetFieldType
88+
s = []
89+
for asset in assets:
90+
s.append('\t"' + asset.text.value + '" pinned to ' +
91+
sa_field_type_enum.Name(asset.pinned_field))
92+
return s
93+
94+
if __name__ == '__main__':
95+
# GoogleAdsClient will read the google-ads.yaml configuration file in the
96+
# home directory if none is specified.
97+
google_ads_client = GoogleAdsClient.load_from_storage()
98+
99+
parser = argparse.ArgumentParser(
100+
description='List responsive display ads for specified customer. '
101+
'An ad_group is optional.')
102+
# The following argument(s) should be provided to run the example.
103+
parser.add_argument('-c', '--customer_id', type=str,
104+
required=True, help='The Google Ads customer ID.')
105+
parser.add_argument('-a', '--ad_group_id', type=str,
106+
required=False, help='The ad group ID. ')
107+
args = parser.parse_args()
108+
109+
main(google_ads_client, args.customer_id, _DEFAULT_PAGE_SIZE,
110+
ad_group_id=args.ad_group_id)

0 commit comments

Comments
 (0)