|
| 1 | +#!/usr/bin/env python |
| 2 | +# Copyright 2023 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 | +"""Adds a page feed with URLs for a Dynamic Search Ads campaign.""" |
| 16 | + |
| 17 | +import argparse |
| 18 | +import resource |
| 19 | +import sys |
| 20 | + |
| 21 | +from examples.utils.example_helpers import get_printable_datetime |
| 22 | +from google.ads.googleads.client import GoogleAdsClient |
| 23 | +from google.ads.googleads.errors import GoogleAdsException |
| 24 | + |
| 25 | + |
| 26 | +# The label for the DSA page URLs. |
| 27 | +DSA_PAGE_URL_LABEL = "discounts" |
| 28 | + |
| 29 | + |
| 30 | +def main(client, customer_id, campaign_id, ad_group_id): |
| 31 | + """The main method that creates all necessary entities for the example. |
| 32 | +
|
| 33 | + Args: |
| 34 | + client: an initialized GoogleAdsClient instance. |
| 35 | + customer_id: a client customer ID. |
| 36 | + campaign_id: the ID for a Campaign. |
| 37 | + ad_group_id: the ID for an Ad Group. |
| 38 | + """ |
| 39 | + # Creates assets. |
| 40 | + asset_resource_names = create_assets( |
| 41 | + client, customer_id, DSA_PAGE_URL_LABEL |
| 42 | + ) |
| 43 | + |
| 44 | + # Creates an asset set - this is a collection of assets that can be |
| 45 | + # associated with a campaign. |
| 46 | + # Note: do not confuse this with an asset group. An asset group replaces ad |
| 47 | + # groups in some types of campaigns. |
| 48 | + asset_set_resource_name = create_asset_set(client, customer_id) |
| 49 | + |
| 50 | + # Adds the assets to the asset set |
| 51 | + add_assets_to_asset_set( |
| 52 | + client, customer_id, asset_resource_names, asset_set_resource_name |
| 53 | + ) |
| 54 | + |
| 55 | + # Links the asset set to the specified campaign. |
| 56 | + link_asset_set_to_campaign( |
| 57 | + client, customer_id, campaign_id, asset_set_resource_name |
| 58 | + ) |
| 59 | + |
| 60 | + # Optional: Targets web pages matching the feed's label in the ad group. |
| 61 | + if ad_group_id: |
| 62 | + add_dsa_target(client, customer_id, ad_group_id, DSA_PAGE_URL_LABEL) |
| 63 | + |
| 64 | + |
| 65 | +# [START add_asset] |
| 66 | +def create_assets(client, customer_id, dsa_page_url_label): |
| 67 | + """Creates assets to be used in a DSA page feed. |
| 68 | +
|
| 69 | + Args: |
| 70 | + client: an initialized GoogleAdsClient instance. |
| 71 | + customer_id: a client customer ID. |
| 72 | + dsa_page_url_label: the label for the DSA page URLs. |
| 73 | +
|
| 74 | + Returns: |
| 75 | + a list of the created assets' resource names. |
| 76 | + """ |
| 77 | + urls = [ |
| 78 | + "http://www.example.com/discounts/rental-cars", |
| 79 | + "http://www.example.com/discounts/hotel-deals", |
| 80 | + "http://www.example.com/discounts/flight-deals", |
| 81 | + ] |
| 82 | + operations = [] |
| 83 | + |
| 84 | + # Creates one asset per URL. |
| 85 | + for url in urls: |
| 86 | + # Creates an asset operation and adds it to the list of operations. |
| 87 | + operation = client.get_type("AssetOperation") |
| 88 | + asset = operation.create |
| 89 | + page_feed_asset = asset.page_feed_asset |
| 90 | + page_feed_asset.page_url = url |
| 91 | + # Recommended: adds labels to the asset. These labels can be used later |
| 92 | + # in ad group targeting to restrict the set of pages that can serve. |
| 93 | + page_feed_asset.labels.append(dsa_page_url_label) |
| 94 | + operations.append(operation) |
| 95 | + |
| 96 | + # Issues a mutate request to add the assets and prints its information. |
| 97 | + asset_service = client.get_service("AssetService") |
| 98 | + response = asset_service.mutate_assets( |
| 99 | + customer_id=customer_id, operations=operations |
| 100 | + ) |
| 101 | + |
| 102 | + print(f"Added {len(response.results)} assets:") |
| 103 | + |
| 104 | + resource_names = [] |
| 105 | + for result in response.results: |
| 106 | + resource_name = result.resource_name |
| 107 | + print(f"\tCreated an asset with resource name: '{resource_name}'") |
| 108 | + resource_names.append(resource_name) |
| 109 | + |
| 110 | + return resource_names |
| 111 | + # [END add_asset] |
| 112 | + |
| 113 | + |
| 114 | +# [START add_asset_set] |
| 115 | +def create_asset_set(client, customer_id): |
| 116 | + """Creates an asset set. |
| 117 | +
|
| 118 | + Args: |
| 119 | + client: an initialized GoogleAdsClient instance. |
| 120 | + customer_id: a client customer ID. |
| 121 | +
|
| 122 | + Returns: |
| 123 | + the created asset set's resource name. |
| 124 | + """ |
| 125 | + operation = client.get_type("AssetSetOperation") |
| 126 | + # Creates an asset set which will be used to link the dynamic page feed |
| 127 | + # assets to a campaign. |
| 128 | + asset_set = operation.create |
| 129 | + asset_set.name = f"My dynamic page feed {get_printable_datetime()}" |
| 130 | + asset_set.type_ = client.enums.AssetSetTypeEnum.PAGE_FEED |
| 131 | + |
| 132 | + # Issues a mutate request to add the asset set and prints its information. |
| 133 | + asset_set_service = client.get_service("AssetSetService") |
| 134 | + response = asset_set_service.mutate_asset_sets( |
| 135 | + customer_id=customer_id, operations=[operation] |
| 136 | + ) |
| 137 | + |
| 138 | + resource_name = response.results[0].resource_name |
| 139 | + print(f"Created an asset set with resource name: '{resource_name}'") |
| 140 | + return resource_name |
| 141 | + # [END add_asset_set] |
| 142 | + |
| 143 | + |
| 144 | +# [START add_asset_set_asset] |
| 145 | +def add_assets_to_asset_set( |
| 146 | + client, customer_id, asset_resource_names, asset_set_resource_name |
| 147 | +): |
| 148 | + """Adds assets to an asset set by creating an asset set asset link. |
| 149 | +
|
| 150 | + Args: |
| 151 | + client: an initialized GoogleAdsClient instance. |
| 152 | + customer_id: a client customer ID. |
| 153 | + asset_resource_names: a list of asset resource names. |
| 154 | + asset_set_resource_name: a resource name for an asset set. |
| 155 | + """ |
| 156 | + operations = [] |
| 157 | + for resource_name in asset_resource_names: |
| 158 | + # Creates an asset set asset operation and adds it to the list of |
| 159 | + # operations. |
| 160 | + operation = client.get_type("AssetSetAssetOperation") |
| 161 | + asset_set_asset = operation.create |
| 162 | + asset_set_asset.asset = resource_name |
| 163 | + asset_set_asset.asset_set = asset_set_resource_name |
| 164 | + operations.append(operation) |
| 165 | + |
| 166 | + # Issues a mutate request to add the asset set assets and prints its |
| 167 | + # information. |
| 168 | + asset_set_asset_service = client.get_service("AssetSetAssetService") |
| 169 | + response = asset_set_asset_service.mutate_asset_set_assets( |
| 170 | + customer_id=customer_id, operations=operations |
| 171 | + ) |
| 172 | + |
| 173 | + print(f"Added {len(response.results)} asset set assets:") |
| 174 | + |
| 175 | + for result in response.results: |
| 176 | + print( |
| 177 | + "\tCreated an asset set asset link with resourece name " |
| 178 | + f"'{result.resource_name}'" |
| 179 | + ) |
| 180 | + # [END add_asset_set_asset] |
| 181 | + |
| 182 | + |
| 183 | +# [START add_campaign_asset_set] |
| 184 | +def link_asset_set_to_campaign( |
| 185 | + client, customer_id, campaign_id, asset_set_resource_name |
| 186 | +): |
| 187 | + """Links the asset set to the campaign by creating a campaign asset set. |
| 188 | +
|
| 189 | + Args: |
| 190 | + client: an initialized GoogleAdsClient instance. |
| 191 | + customer_id: a client customer ID. |
| 192 | + campaign_id: the ID for a Campaign. |
| 193 | + asset_set_resource_name: a resource name for an asset set. |
| 194 | + """ |
| 195 | + googleads_service = client.get_service("GoogleAdsService") |
| 196 | + # Creates a campaign asset set representing the link between an asset set |
| 197 | + # and a campaign. |
| 198 | + operation = client.get_type("CampaignAssetSetOperation") |
| 199 | + campaign_asset_set = operation.create |
| 200 | + campaign_asset_set.asset_set = asset_set_resource_name |
| 201 | + campaign_asset_set.campaign = googleads_service.campaign_path( |
| 202 | + customer_id, campaign_id |
| 203 | + ) |
| 204 | + |
| 205 | + campaign_asset_set_service = client.get_service("CampaignAssetSetService") |
| 206 | + response = campaign_asset_set_service.mutate_campaign_asset_sets( |
| 207 | + customer_id=customer_id, operations=[operation] |
| 208 | + ) |
| 209 | + |
| 210 | + resource_name = response.results[0].resource_name |
| 211 | + print(f"Created a campaign asset set with resource name: '{resource_name}'") |
| 212 | + # [END add_campaign_asset_set] |
| 213 | + |
| 214 | + |
| 215 | +# [START add_dsa_target] |
| 216 | +def add_dsa_target(client, customer_id, ad_group_id, dsa_page_url_label): |
| 217 | + """Creates an ad group criterion targeting the DSA label. |
| 218 | +
|
| 219 | + Args: |
| 220 | + client: an initialized GoogleAdsClient instance. |
| 221 | + customer_id: a client customer ID. |
| 222 | + ad_group_id: the ID for an Ad Group. |
| 223 | + dsa_page_url_label: the label for the DSA page URLs. |
| 224 | + """ |
| 225 | + googleads_service = client.get_service("GoogleAdsService") |
| 226 | + # Creates the ad group criterion. |
| 227 | + operation = client.get_type("AdGroupCriterionOperation") |
| 228 | + criterion = operation.create |
| 229 | + criterion.ad_group = googleads_service.ad_group_path( |
| 230 | + customer_id, ad_group_id |
| 231 | + ) |
| 232 | + criterion.cpc_bid_micros = 1500000 |
| 233 | + # Creates the webpage info, or criterion for targeting webpages of an |
| 234 | + # advertiser's website. |
| 235 | + criterion.webpage.criterion_name = "Test Criterion" |
| 236 | + # Creates the webpage condition info that targets an advertiser's webpages |
| 237 | + # based on the custom label specified by the DSA page URL label |
| 238 | + # (e.g. "discounts"). |
| 239 | + webpage_condition = client.get_type("WebpageConditionInfo") |
| 240 | + webpage_condition.operand = ( |
| 241 | + client.enums.WebpageConditionOperandEnum.CUSTOM_LABEL |
| 242 | + ) |
| 243 | + webpage_condition.argument = dsa_page_url_label |
| 244 | + criterion.webpage.conditions.append(webpage_condition) |
| 245 | + |
| 246 | + # Issues a mutate request to add the ad group criterion and prints its |
| 247 | + # information. |
| 248 | + ad_group_criterion_service = client.get_service("AdGroupCriterionService") |
| 249 | + response = ad_group_criterion_service.mutate_ad_group_criteria( |
| 250 | + customer_id=customer_id, operations=[operation] |
| 251 | + ) |
| 252 | + |
| 253 | + print( |
| 254 | + "Created ad group criterion with resource name: " |
| 255 | + f"'{response.results[0].resource_name}'" |
| 256 | + ) |
| 257 | + # [END add_dsa_target] |
| 258 | + |
| 259 | + |
| 260 | +if __name__ == "__main__": |
| 261 | + # GoogleAdsClient will read the google-ads.yaml configuration file in the |
| 262 | + # home directory if none is specified. |
| 263 | + googleads_client = GoogleAdsClient.load_from_storage(version="v13") |
| 264 | + |
| 265 | + parser = argparse.ArgumentParser(description=( |
| 266 | + "Adds a page feed with URLs for a Dynamic Search Ads campaign" |
| 267 | + )) |
| 268 | + # The following argument(s) should be provided to run the example. |
| 269 | + parser.add_argument( |
| 270 | + "-c", |
| 271 | + "--customer_id", |
| 272 | + type=str, |
| 273 | + required=True, |
| 274 | + help="The Google Ads customer ID.", |
| 275 | + ) |
| 276 | + |
| 277 | + parser.add_argument( |
| 278 | + "-i", |
| 279 | + "--campaign_id", |
| 280 | + type=str, |
| 281 | + required=True, |
| 282 | + help="The Google Ads campaign ID.", |
| 283 | + ) |
| 284 | + |
| 285 | + parser.add_argument( |
| 286 | + "-a", "--ad_group_id", type=str, help="The Google Ads ad group ID." |
| 287 | + ) |
| 288 | + |
| 289 | + args = parser.parse_args() |
| 290 | + |
| 291 | + try: |
| 292 | + main( |
| 293 | + googleads_client, |
| 294 | + args.customer_id, |
| 295 | + args.campaign_id, |
| 296 | + args.ad_group_id, |
| 297 | + ) |
| 298 | + except GoogleAdsException as ex: |
| 299 | + print( |
| 300 | + f'Request with ID "{ex.request_id}" failed with status ' |
| 301 | + f'"{ex.error.code().name}" and includes the following errors:' |
| 302 | + ) |
| 303 | + for error in ex.failure.errors: |
| 304 | + print(f'Error with message "{error.message}".') |
| 305 | + if error.location: |
| 306 | + for field_path_element in error.location.field_path_elements: |
| 307 | + print(f"\t\tOn field: {field_path_element.field_name}") |
| 308 | + sys.exit(1) |
0 commit comments