Skip to content

Commit a07a249

Browse files
authored
- Google Ads v6_1 release (#383)
- Deprecate v3_0 - Add log masking for CustomerUserAccessInvitation.email_address field. - Update examples to reflect changes to resource name helper methods.
1 parent d90d9e9 commit a07a249

File tree

3,114 files changed

+19768
-220744
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,114 files changed

+19768
-220744
lines changed

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
* 9.0.0
2+
- Google Ads v6_1 release
3+
- Deprecate v3_0
4+
- Add log masking for CustomerUserAccessInvitation.email_address field.
5+
- Update examples to reflect changes to resource name helper methods.
6+
17
* 8.2.0
28
- Added new client configuration environment variables.
39
- Added ability to configure YAML file location via environment variable.

examples/account_management/get_change_details.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,18 @@ def main(client, customer_id):
8787
elif resource_type == "AD_GROUP":
8888
old_resource = event.old_resource.ad_group
8989
new_resource = event.new_resource.ad_group
90+
elif resource_type == "AD_GROUP_AD":
91+
old_resource = event.old_resource.ad_group_ad
92+
new_resource = event.new_resource.ad_group_ad
9093
elif resource_type == "AD_GROUP_CRITERION":
9194
old_resource = event.old_resource.ad_group_criterion
9295
new_resource = event.new_resource.ad_group_criterion
9396
elif resource_type == "AD_GROUP_BID_MODIFIER":
9497
old_resource = event.old_resource.ad_group_bid_modifier
9598
new_resource = event.new_resource.ad_group_bid_modifier
99+
elif resource_type == "AD_GROUP_FEED":
100+
old_resource = event.old_resource.ad_group_feed
101+
new_resource = event.new_resource.ad_group_feed
96102
elif resource_type == "CAMPAIGN":
97103
old_resource = event.old_resource.campaign
98104
new_resource = event.new_resource.campaign
@@ -102,6 +108,15 @@ def main(client, customer_id):
102108
elif resource_type == "CAMPAIGN_CRITERION":
103109
old_resource = event.old_resource.campaign_criterion
104110
new_resource = event.new_resource.campaign_criterion
111+
elif resource_type == "CAMPAIGN_FEED":
112+
old_resource = event.old_resource.campaign_feed
113+
new_resource = event.new_resource.campaign_feed
114+
elif resource_type == "FEED":
115+
old_resource = event.old_resource.feed
116+
new_resource = event.new_resource.feed
117+
elif resource_type == "FEED_ITEM":
118+
old_resource = event.old_resource.feed_item
119+
new_resource = event.new_resource.feed_item
105120
else:
106121
print(
107122
"Unknown change_resource_type: '{event.change_resource_type}'"
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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 code example retrieves pending invitations for a customer account.
16+
17+
To create a pending invitation, see the invite_user_with_access_role.py
18+
example.
19+
"""
20+
21+
22+
import argparse
23+
import sys
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):
30+
"""The main method that creates all necessary entities for the example.
31+
32+
Args:
33+
client: An initialized GoogleAdsClient instance.
34+
customer_id: The client customer ID str.
35+
"""
36+
google_ads_service = client.get_service("GoogleAdsService", version="v6")
37+
# [START get_pending_invitations]
38+
query = """
39+
SELECT
40+
customer_user_access_invitation.invitation_id,
41+
customer_user_access_invitation.email_address,
42+
customer_user_access_invitation.access_role,
43+
customer_user_access_invitation.creation_date_time
44+
FROM customer_user_access_invitation
45+
WHERE customer_user_access_invitation.invitation_status = PENDING"""
46+
47+
try:
48+
response = google_ads_service.search_stream(customer_id, query=query)
49+
for batch in response:
50+
for row in batch.results:
51+
invite = row.customer_user_access_invitation
52+
print(
53+
"A pending invitation with "
54+
f"invitation ID: '{invite.invitation_id}', "
55+
f"email address: {invite.email_address}, "
56+
f"access role: {invite.access_role}, and "
57+
f"created on: {invite.creation_date_time} was found."
58+
)
59+
except GoogleAdsException as ex:
60+
print(
61+
f'Request with ID "{ex.request_id}" failed with status '
62+
f'"{ex.error.code().name}" and includes the following errors:'
63+
)
64+
for error in ex.failure.errors:
65+
print(f'\tError with message "{error.message}".')
66+
if error.location:
67+
for field_path_element in error.location.field_path_elements:
68+
print(f"\t\tOn field: {field_path_element.field_name}")
69+
sys.exit(1)
70+
# [END get_pending_invitations]
71+
72+
if __name__ == "__main__":
73+
# GoogleAdsClient will read the google-ads.yaml configuration file in the
74+
# home directory if none is specified.
75+
google_ads_client = GoogleAdsClient.load_from_storage()
76+
77+
parser = argparse.ArgumentParser(
78+
description=("Retrieves pending invitations for a customer account.")
79+
)
80+
# The following argument(s) should be provided to run the example.
81+
parser.add_argument(
82+
"-c",
83+
"--customer_id",
84+
type=str,
85+
required=True,
86+
help="The Google Ads customer ID.",
87+
)
88+
args = parser.parse_args()
89+
90+
main(google_ads_client, args.customer_id)
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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 code example sends an invitation email to a user.
16+
17+
The invitation is to manage a customer account with a desired access role.
18+
"""
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+
def main(client, customer_id, email_address, access_role):
29+
"""The main method that creates all necessary entities for the example.
30+
31+
Args:
32+
client: An initialized GoogleAdsClient instance.
33+
customer_id: The client customer ID str.
34+
email_address: The email address for the user receiving the invitation.
35+
access_role: The desired access role for the invitee.
36+
"""
37+
service = client.get_service(
38+
"CustomerUserAccessInvitationService", version="v6"
39+
)
40+
# [START invite_user_with_access_role]
41+
invitation_operation = client.get_type(
42+
"CustomerUserAccessInvitationOperation", version="v6"
43+
)
44+
invitation = invitation_operation.create
45+
invitation.email_address = email_address
46+
invitation.access_role = client.get_type(
47+
"AccessRoleEnum", version="v6"
48+
).AccessRole.Value(access_role)
49+
try:
50+
response = service.mutate_customer_user_access_invitation(
51+
customer_id, invitation_operation
52+
)
53+
print(
54+
"Customer user access invitation was sent for "
55+
f"customer ID: '{customer_id}', "
56+
f"email address {email_address}, and "
57+
f"access role {access_role}. The invitation resource name is: "
58+
f"{response.result.resource_name}"
59+
)
60+
except GoogleAdsException as ex:
61+
print(
62+
f'Request with ID "{ex.request_id}" failed with status '
63+
f'"{ex.error.code().name}" and includes the following errors:'
64+
)
65+
for error in ex.failure.errors:
66+
print(f'\tError with message "{error.message}".')
67+
if error.location:
68+
for field_path_element in error.location.field_path_elements:
69+
print(f"\t\tOn field: {field_path_element.field_name}")
70+
sys.exit(1)
71+
# [END invite_user_with_access_role]
72+
73+
if __name__ == "__main__":
74+
# GoogleAdsClient will read the google-ads.yaml configuration file in the
75+
# home directory if none is specified.
76+
google_ads_client = GoogleAdsClient.load_from_storage()
77+
78+
parser = argparse.ArgumentParser(
79+
description=(
80+
"Sends an invitation email to a user to manage a customer "
81+
"account with a desired access role."
82+
)
83+
)
84+
# The following argument(s) should be provided to run the example.
85+
parser.add_argument(
86+
"-c",
87+
"--customer_id",
88+
type=str,
89+
required=True,
90+
help="The Google Ads customer ID.",
91+
)
92+
parser.add_argument(
93+
"-e",
94+
"--email_address",
95+
type=str,
96+
required=True,
97+
help="The email address of the user to send the invitation to.",
98+
)
99+
parser.add_argument(
100+
"-a",
101+
"--access_role",
102+
type=str,
103+
required=True,
104+
choices=google_ads_client.get_type(
105+
"AccessRoleEnum", version="v6"
106+
).AccessRole.keys(),
107+
help="The updated user access role.",
108+
)
109+
args = parser.parse_args()
110+
111+
main(
112+
google_ads_client,
113+
args.customer_id,
114+
args.email_address,
115+
args.access_role,
116+
)

examples/basic_operations/pause_ad.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from google.api_core import protobuf_helpers
2222
from google.ads.google_ads.client import GoogleAdsClient
23-
from google.ads.google_ads.util import ResourceName
23+
from google.ads.google_ads.errors import GoogleAdsException
2424

2525

2626
def main(client, customer_id, ad_group_id, ad_id):
@@ -30,7 +30,7 @@ def main(client, customer_id, ad_group_id, ad_id):
3030

3131
ad_group_ad = ad_group_ad_operation.update
3232
ad_group_ad.resource_name = ad_group_ad_service.ad_group_ad_path(
33-
customer_id, ResourceName.format_composite(ad_group_id, ad_id)
33+
customer_id, ad_group_id, ad_id
3434
)
3535
ad_group_ad.status = client.get_type(
3636
"AdGroupStatusEnum", version="v6"
@@ -42,7 +42,7 @@ def main(client, customer_id, ad_group_id, ad_id):
4242
ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads(
4343
customer_id, [ad_group_ad_operation]
4444
)
45-
except google.ads.google_ads.errors.GoogleAdsException as ex:
45+
except GoogleAdsException as ex:
4646
print(
4747
'Request with ID "%s" failed with status "%s" and includes the '
4848
"following errors:" % (ex.request_id, ex.error.code().name)

examples/basic_operations/remove_ad.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,23 @@
1919
import sys
2020

2121
from google.ads.google_ads.client import GoogleAdsClient
22-
from google.ads.google_ads.util import ResourceName
22+
from google.ads.google_ads.errors import GoogleAdsException
2323

2424

2525
def main(client, customer_id, ad_group_id, ad_id):
2626
ad_group_ad_service = client.get_service("AdGroupAdService", version="v6")
2727
ad_group_ad_operation = client.get_type("AdGroupAdOperation", version="v6")
2828

2929
resource_name = ad_group_ad_service.ad_group_ad_path(
30-
customer_id, ResourceName.format_composite(ad_group_id, ad_id)
30+
customer_id, ad_group_id, ad_id
3131
)
3232
ad_group_ad_operation.remove = resource_name
3333

3434
try:
3535
ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads(
3636
customer_id, [ad_group_ad_operation]
3737
)
38-
except google.ads.google_ads.errors.GoogleAdsException as ex:
38+
except GoogleAdsException as ex:
3939
print(
4040
'Request with ID "%s" failed with status "%s" and includes the '
4141
"following errors:" % (ex.request_id, ex.error.code().name)

examples/basic_operations/remove_keyword.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@
2020

2121
from google.ads.google_ads.client import GoogleAdsClient
2222
from google.ads.google_ads.errors import GoogleAdsException
23-
from google.ads.google_ads.util import ResourceName
2423

2524

2625
def main(client, customer_id, ad_group_id, criterion_id):
2726
agc_service = client.get_service("AdGroupCriterionService", version="v6")
2827
agc_operation = client.get_type("AdGroupCriterionOperation", version="v6")
2928

30-
resource_name = agc_service.ad_group_criteria_path(
31-
customer_id, ResourceName.format_composite(ad_group_id, criterion_id)
29+
resource_name = agc_service.ad_group_criterion_path(
30+
customer_id, ad_group_id, criterion_id
3231
)
3332
agc_operation.remove = resource_name
3433

examples/basic_operations/update_keyword.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
from google.api_core import protobuf_helpers
2222
from google.ads.google_ads.client import GoogleAdsClient
23-
from google.ads.google_ads.util import ResourceName
2423

2524

2625
def main(client, customer_id, ad_group_id, criterion_id):
@@ -31,8 +30,8 @@ def main(client, customer_id, ad_group_id, criterion_id):
3130
)
3231

3332
ad_group_criterion = ad_group_criterion_operation.update
34-
ad_group_criterion.resource_name = agc_service.ad_group_criteria_path(
35-
customer_id, ResourceName.format_composite(ad_group_id, criterion_id)
33+
ad_group_criterion.resource_name = agc_service.ad_group_criterion_path(
34+
customer_id, ad_group_id, criterion_id
3635
)
3736
ad_group_criterion.status = client.get_type(
3837
"AdGroupCriterionStatusEnum", version="v6"

examples/campaign_management/add_campaign_bid_modifier.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,43 @@ def main(client, customer_id, campaign_id, bid_modifier_value):
4848
"InteractionTypeEnum", version="v6"
4949
).CALLS
5050

51-
# Add the campaign bid modifier.
51+
# [START mutable_resource]
52+
# Add the campaign bid modifier. Here we pass the optional parameter
53+
# response_content_type=MUTABLE_RESOURCE so that the response contains
54+
# the mutated object and not just its resource name.
5255
try:
5356
campaign_bm_response = campaign_bm_service.mutate_campaign_bid_modifiers(
54-
customer_id, [campaign_bid_modifier_operation]
57+
customer_id,
58+
[campaign_bid_modifier_operation],
59+
response_content_type=client.get_type(
60+
"ResponseContentTypeEnum", version="v6"
61+
).MUTABLE_RESOURCE,
5562
)
5663
except google.ads.google_ads.errors.GoogleAdsException as ex:
5764
print(
58-
'Request with ID "%s" failed with status "%s" and includes the '
59-
"following errors:" % (ex.request_id, ex.error.code().name)
65+
f'Request with ID "{ex.request_id}" failed with status '
66+
f'"{ex.error.code().name}" and includes the following errors:'
6067
)
6168
for error in ex.failure.errors:
62-
print('\tError with message "%s".' % error.message)
69+
print(f'\tError with message "{error.message}".')
6370
if error.location:
6471
for field_path_element in error.location.field_path_elements:
65-
print("\t\tOn field: %s" % field_path_element.field_name)
72+
print(f"\t\tOn field: {field_path_element.field_name}")
6673
sys.exit(1)
6774

75+
# The resource returned in the response can be accessed directly in the
76+
# results list. Its fields can be read directly, and it can also be mutated
77+
# further and used in subsequent requests, without needing to make
78+
# additional Get or Search requests.
79+
mutable_resource = campaign_bm_response.results[0].campaign_bid_modifier
6880
print(
69-
"Created campaign bid modifier: %s."
70-
% campaign_bm_response.results[0].resource_name
81+
"Created campaign bid modifier with resource_name "
82+
f"'{mutable_resource.resource_name}', criterion ID "
83+
f"'{mutable_resource.criterion_id}', and bid modifier value "
84+
f"'{mutable_resource.bid_modifier}', under the campaign with "
85+
f"resource_name '{mutable_resource.campaign}', "
7186
)
87+
# [END mutable_resource]
7288

7389

7490
if __name__ == "__main__":

0 commit comments

Comments
 (0)