The code samples below provide examples for managing Shopping campaigns using the AdWords API. Client Library.
Build a product partition tree for an ad group
#!/usr/bin/env python # # Copyright 2016 Google Inc. All Rights Reserved. # # 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 # # http://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. """This example creates a ProductPartition tree. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ # Import appropriate modules from the client library. from googleads import adwords ADGROUP_ID = 'INSERT_AD_GROUP_ID_HERE' class ProductPartitionHelper(object): """A helper for creating ProductPartition trees.""" def __init__(self, adgroup_id): """Initializer. Args: adgroup_id: The ID of the AdGroup that we wish to attach the partition tree to. """ # The next temporary criterion ID to be used. # When creating our tree we need to specify the parent-child relationships # between nodes. However, until a criterion has been created on the server # we do not have a criterion ID with which to refer to it. # Instead we can specify temporary IDs that are specific to a single mutate # request. Once the criteria have been created they are assigned an ID as # normal and the temporary ID will no longer refer to it. # A valid temporary ID is any negative integer. self.next_id = -1 # The set of mutate operations needed to create the current tree. self.operations = [] self.adgroup_id = adgroup_id def CreateSubdivision(self, parent=None, value=None): """Creates a subdivision node. Args: parent: The node that should be this node's parent. value: The value being partitioned on. Returns: A new subdivision node. """ division = { 'xsi_type': 'ProductPartition', 'partitionType': 'SUBDIVISION', 'id': str(self.next_id) } # The root has neither a parent nor a value. if parent is not None: division['parentCriterionId'] = parent['id'] division['caseValue'] = value adgroup_criterion = { 'xsi_type': 'BiddableAdGroupCriterion', 'adGroupId': self.adgroup_id, 'criterion': division } self.CreateAddOperation(adgroup_criterion) self.next_id -= 1 return division def CreateUnit(self, parent=None, value=None, bid_amount=None): """Creates a unit node. Args: parent: The node that should be this node's parent. value: The value being partitioned on. bid_amount: The amount to bid for matching products, in micros. Returns: A new unit node. """ unit = { 'xsi_type': 'ProductPartition', 'partitionType': 'UNIT' } # The root node has neither a parent nor a value. if parent is not None: unit['parentCriterionId'] = parent['id'] unit['caseValue'] = value if bid_amount is not None and bid_amount > 0: bidding_strategy_configuration = { 'bids': [{ 'xsi_type': 'CpcBid', 'bid': { 'xsi_type': 'Money', 'microAmount': str(bid_amount) } }] } adgroup_criterion = { 'xsi_type': 'BiddableAdGroupCriterion', 'biddingStrategyConfiguration': bidding_strategy_configuration } else: adgroup_criterion = { 'xsi_type': 'NegativeAdGroupCriterion' } adgroup_criterion['adGroupId'] = self.adgroup_id adgroup_criterion['criterion'] = unit self.CreateAddOperation(adgroup_criterion) return unit def GetOperations(self): """Returns the set of mutate operations needed to create the current tree. Returns: The set of operations """ return self.operations def CreateAddOperation(self, criterion): """Creates an AdGroupCriterionOperation for the given criterion. Args: criterion: The criterion we want to add. """ operation = { 'operator': 'ADD', 'operand': criterion } self.operations.append(operation) def main(client, adgroup_id): """Runs the example.""" adgroup_criterion_service = client.GetService( 'AdGroupCriterionService', version='v201809') helper = ProductPartitionHelper(adgroup_id) # The most trivial partition tree has only a unit node as the root, e.g.: # helper.CreateUnit(bid_amount=100000) root = helper.CreateSubdivision() new_product_canonical_condition = { 'xsi_type': 'ProductCanonicalCondition', 'condition': 'NEW' } used_product_canonical_condition = { 'xsi_type': 'ProductCanonicalCondition', 'condition': 'USED' } other_product_canonical_condition = { 'xsi_type': 'ProductCanonicalCondition', } helper.CreateUnit(root, new_product_canonical_condition, 200000) helper.CreateUnit(root, used_product_canonical_condition, 100000) other_condition = helper.CreateSubdivision( root, other_product_canonical_condition) cool_product_brand = { 'xsi_type': 'ProductBrand', 'value': 'CoolBrand' } cheap_product_brand = { 'xsi_type': 'ProductBrand', 'value': 'CheapBrand' } other_product_brand = { 'xsi_type': 'ProductBrand', } helper.CreateUnit(other_condition, cool_product_brand, 900000) helper.CreateUnit(other_condition, cheap_product_brand, 10000) other_brand = helper.CreateSubdivision(other_condition, other_product_brand) # The value for the bidding category is a fixed ID for the 'Luggage & Bags' # category. You can retrieve IDs for categories from the ConstantDataService. # See the 'GetProductTaxonomy' example for more details. luggage_category = { 'xsi_type': 'ProductBiddingCategory', 'type': 'BIDDING_CATEGORY_L1', 'value': '-5914235892932915235' } generic_category = { 'xsi_type': 'ProductBiddingCategory', 'type': 'BIDDING_CATEGORY_L1', } helper.CreateUnit(other_brand, luggage_category, 750000) helper.CreateUnit(other_brand, generic_category, 110000) # Make the mutate request result = adgroup_criterion_service.mutate(helper.GetOperations()) children = {} root_node = None # For each criterion, make an array containing each of its children. # We always create the parent before the child, so we can rely on that here. for adgroup_criterion in result['value']: children[adgroup_criterion['criterion']['id']] = [] if 'parentCriterionId' in adgroup_criterion['criterion']: children[adgroup_criterion['criterion']['parentCriterionId']].append( adgroup_criterion['criterion']) else: root_node = adgroup_criterion['criterion'] # Show the tree DisplayTree(root_node, children) def DisplayTree(node, children, level=0): """Recursively display a node and each of its children. Args: node: The node we're displaying the children of. children: Children of the parent node. level: How deep in the tree we are. """ value = '' node_type = '' if 'caseValue' in node: case_value = node['caseValue'] node_type = case_value['ProductDimension.Type'] if node_type == 'ProductCanonicalCondition': value = (case_value['condition'] if 'condition' in case_value else 'OTHER') elif node_type == 'ProductBiddingCategory': value = '%s(%s)' % (case_value['type'], case_value['value'] if 'value' in case_value else 'OTHER') else: value = (case_value['value'] if 'value' in case_value else 'OTHER') print('%sid: %s, node_type: %s, value: %s\n' % (' ' * level, node['id'], node_type, value)) for child_node in children[node['id']]: DisplayTree(child_node, children, level + 1) if __name__ == '__main__': # Initialize client object. adwords_client = adwords.AdWordsClient.LoadFromStorage() main(adwords_client, ADGROUP_ID)
Set a product scope for a campaign
#!/usr/bin/env python # # Copyright 2016 Google Inc. All Rights Reserved. # # 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 # # http://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. """Restricts products that will be included in a campaign with a ProductScope. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ # Import appropriate modules from the client library. from googleads import adwords CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE' def main(client, campaign_id): campaign_criterion_service = client.GetService( 'CampaignCriterionService', version='v201809') product_scope = { 'xsi_type': 'ProductScope', # This set of dimensions is for demonstration purposes only. It would be # extremely unlikely that you want to include so many dimensions in your # product scope. 'dimensions': [ { 'xsi_type': 'ProductBrand', 'value': 'Nexus' }, { 'xsi_type': 'ProductCanonicalCondition', 'condition': 'NEW' }, { 'xsi_type': 'ProductCustomAttribute', 'type': 'CUSTOM_ATTRIBUTE_0', 'value': 'my attribute value' }, { 'xsi_type': 'ProductOfferId', 'value': 'book1' }, { 'xsi_type': 'ProductType', 'type': 'PRODUCT_TYPE_L1', 'value': 'Media' }, { 'xsi_type': 'ProductType', 'type': 'PRODUCT_TYPE_L2', 'value': 'Books' }, # The value for the bidding category is a fixed ID for the "Luggage # & Bags" category. You can retrieve IDs for categories from the # ConstantDataService. See the "GetProductCategoryTaxonomy" example # for more details. { 'xsi_type': 'ProductBiddingCategory', 'type': 'BIDDING_CATEGORY_L1', 'value': '-5914235892932915235' } ] } campaign_criterion = { 'campaignId': campaign_id, 'criterion': product_scope } operations = [{ 'operator': 'ADD', 'operand': campaign_criterion }] # Make the request result = campaign_criterion_service.mutate(operations) for criterion in result['value']: print('Created a ProductScope criterion with Id: %s' % criterion['criterion']['id']) if __name__ == '__main__': # Initialize client object. adwords_client = adwords.AdWordsClient.LoadFromStorage() main(adwords_client, CAMPAIGN_ID)
Add a Shopping campaign
#!/usr/bin/env python # # Copyright 2016 Google Inc. All Rights Reserved. # # 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 # # http://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. """This example adds a Shopping campaign. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ import uuid # Import appropriate modules from the client library. from googleads import adwords BUDGET_ID = 'INSERT_BUDGET_ID_HERE' # If set to true, a default partition will be created. If running the # add_product_partition_tree.py example right after this example, make # sure this stays set to false. CREATE_DEFAULT_PARTITION = False MERCHANT_ID = 'INSERT_MERCHANT_ID_HERE' def main(client, budget_id, merchant_id, create_default_partition): campaign_service = client.GetService('CampaignService', version='v201809') ad_group_service = client.GetService('AdGroupService', version='v201809') ad_group_ad_service = client.GetService('AdGroupAdService', version='v201809') # Create campaign campaign = { 'name': 'Shopping campaign #%s' % uuid.uuid4(), # The advertisingChannelType is what makes this a shopping campaign 'advertisingChannelType': 'SHOPPING', # Recommendation: Set the campaign to PAUSED when creating it to stop the # ads from immediately serving. Set to ENABLED once you've added targeting # and the ads are ready to serve. 'status': 'PAUSED', # Set portfolio budget (required) 'budget': { 'budgetId': budget_id }, 'biddingStrategyConfiguration': { 'biddingStrategyType': 'MANUAL_CPC' }, 'settings': [ # All shopping campaigns need a ShoppingSetting { 'xsi_type': 'ShoppingSetting', 'salesCountry': 'US', 'campaignPriority': '0', 'merchantId': merchant_id, # Set to "True" to enable Local Inventory Ads in your campaign. 'enableLocal': True } ] } campaign_operations = [{ 'operator': 'ADD', 'operand': campaign }] result = campaign_service.mutate(campaign_operations) for campaign in result['value']: print('Campaign with name "%s" and ID "%s" was added.' % (campaign['name'], campaign['id'])) # Create the AdGroup ad_group = { 'campaignId': campaign['id'], 'name': 'AdGroup #%s' % uuid.uuid4() } adgroup_operations = { 'operator': 'ADD', 'operand': ad_group } # Make the mutate request to add the AdGroup to the Shopping Campaign ad_group = ad_group_service.mutate(adgroup_operations)['value'][0] ad_group_id = ad_group['id'] print('AdGroup with name "%s" and ID "%s" was added.' % (ad_group['name'], ad_group_id)) # Create an AdGroup Ad adgroup_ad = { 'adGroupId': ad_group_id, # Create ProductAd 'ad': { 'xsi_type': 'ProductAd', 'Ad.Type': 'ProductAd' } } ad_operation = { 'operator': 'ADD', 'operand': adgroup_ad } # Make the mutate request to add the ProductAd to the AdGroup ad_result = ad_group_ad_service.mutate([ad_operation]) for adgroup_ad in ad_result['value']: print('ProductAd with ID "%s" was added.' % adgroup_ad['ad']['id']) if create_default_partition: CreateDefaultPartition(client, ad_group_id) def CreateDefaultPartition(client, ad_group_id): """Creates a default partition. Args: client: an AdWordsClient instance. ad_group_id: an integer ID for an ad group. """ ad_group_criterion_service = client.GetService('AdGroupCriterionService', version='v201809') operations = [{ 'operator': 'ADD', 'operand': { 'xsi_type': 'BiddableAdGroupCriterion', 'adGroupId': ad_group_id, # Make sure that caseValue and parentCriterionId are left unspecified. # This makes this partition as generic as possible to use as a # fallback when others don't match. 'criterion': { 'xsi_type': 'ProductPartition', 'partitionType': 'UNIT' }, 'biddingStrategyConfiguration': { 'bids': [{ 'xsi_type': 'CpcBid', 'bid': { 'microAmount': 500000 } }] } } }] ad_group_criterion = ad_group_criterion_service.mutate(operations)['value'][0] print('Ad group criterion with ID "%d" in ad group with ID "%d" was added.' % (ad_group_criterion['criterion']['id'], ad_group_criterion['adGroupId'])) if __name__ == '__main__': # Initialize client object. adwords_client = adwords.AdWordsClient.LoadFromStorage() main(adwords_client, BUDGET_ID, MERCHANT_ID, CREATE_DEFAULT_PARTITION)
Add a Smart Shopping campaign
#!/usr/bin/env python # # Copyright 2018 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 # # http://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. """This example adds a Smart Shopping campaign with an ad group and ad group ad. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ import uuid # Import appropriate modules from the client library. from googleads import adwords # If set to true, a default partition will be created. # Set it to false if you plan to run the add_product_partition_tree.py # example right after this example. CREATE_DEFAULT_PARTITION = False MERCHANT_ID = 'INSERT_MERCHANT_ID_HERE' def main(client, merchant_id, create_default_partition): budget_id = CreateBudget(client) campaign_id = CreateSmartCampaign(client, budget_id, merchant_id) ad_group_id = CreateSmartShoppingAdGroup(client, campaign_id) CreateSmartShoppingAd(client, ad_group_id) if create_default_partition: CreateDefaultPartition(client, ad_group_id) def CreateBudget(client): """Adds a new budget. Args: client: an AdWordsClient instance. Returns: A budget ID. """ budget_service = client.GetService('BudgetService', version='v201809') budget = { 'name': 'Interplanetary budget #%s' % uuid.uuid4(), 'amount': { 'microAmount': '50000000' }, 'deliveryMethod': 'STANDARD', # Non-shared budgets are required for Smart Shopping campaigns. 'isExplicitlyShared': False } budget_operations = [{ 'operator': 'ADD', 'operand': budget }] # Add the budget. budget_id = budget_service.mutate(budget_operations)['value'][0][ 'budgetId'] return budget_id def CreateSmartCampaign(client, budget_id, merchant_id): """Adds a new Smart Shopping campaign. Args: client: an AdWordsClient instance. budget_id: the str ID of the budget to be associated with the Shopping campaign. merchant_id: the str ID of the merchant account to be associated with the Shopping campaign. Returns: A campaign ID. """ campaign_service = client.GetService('CampaignService', version='v201809') # Create campaign with required and optional settings. campaign = { 'name': 'Shopping campaign #%s' % uuid.uuid4(), # The advertisingChannelType is what makes this a Shopping campaign. 'advertisingChannelType': 'SHOPPING', # Sets the advertisingChannelSubType to SHOPPING_GOAL_OPTIMIZED_ADS to # make this a Smart Shopping campaign. 'advertisingChannelSubType': 'SHOPPING_GOAL_OPTIMIZED_ADS', # Recommendation: Set the campaign to PAUSED when creating it to stop the # ads from immediately serving. Set to ENABLED once you've added targeting # and the ads are ready to serve. 'status': 'PAUSED', # Set portfolio budget (required). 'budget': {'budgetId': budget_id}, # Set a bidding strategy. Only MAXIMIZE_CONVERSION_VALUE is supported. 'biddingStrategyConfiguration': { 'biddingStrategyType': 'MAXIMIZE_CONVERSION_VALUE' }, 'settings': [{ # All Shopping campaigns need a ShoppingSetting. 'xsi_type': 'ShoppingSetting', 'salesCountry': 'US', 'merchantId': merchant_id }] } campaign_operations = [{ 'operator': 'ADD', 'operand': campaign }] result = campaign_service.mutate(campaign_operations)['value'][0] print('Smart Shopping campaign with name "%s" and ID "%s" was added.' % (result['name'], result['id'])) return result['id'] def CreateSmartShoppingAdGroup(client, campaign_id): """Adds a new Smart Shopping ad group. Args: client: an AdWordsClient instance. campaign_id: the str ID of a Smart Shopping campaign. Returns: An ad group ID. """ ad_group_service = client.GetService('AdGroupService', version='v201809') # Create the ad group. ad_group = { 'campaignId': campaign_id, 'name': 'Smart Shopping ad group #%s' % uuid.uuid4(), # Set the ad group type to SHOPPING_GOAL_OPTIMIZED_ADS. 'adGroupType': 'SHOPPING_GOAL_OPTIMIZED_ADS' } adgroup_operations = { 'operator': 'ADD', 'operand': ad_group } # Make the mutate request to add the AdGroup to the Smart Shopping campaign. ad_group = ad_group_service.mutate(adgroup_operations)['value'][0] ad_group_id = ad_group['id'] print('AdGroup with name "%s" and ID "%s" was added.' % (ad_group['name'], ad_group_id)) return ad_group_id def CreateSmartShoppingAd(client, ad_group_id): """Adds a new Smart Shopping ad. Args: client: an AdWordsClient instance. ad_group_id: an integer ID for an ad group. """ ad_group_ad_service = client.GetService('AdGroupAdService', version='v201809') # Create an AdGroup Ad. adgroup_ad = { 'adGroupId': ad_group_id, # Create a Smart Shopping ad (Goal-optimized Shopping ad). 'ad': { 'xsi_type': 'GoalOptimizedShoppingAd' } } ad_operation = { 'operator': 'ADD', 'operand': adgroup_ad } # Make the mutate request to add the Smart Shopping ad to the AdGroup. ad_result = ad_group_ad_service.mutate([ad_operation]) for adgroup_ad in ad_result['value']: print('Smart Shopping ad with ID "%s" was added.' % adgroup_ad['ad']['id']) def CreateDefaultPartition(client, ad_group_id): """Creates a default partition. Args: client: an AdWordsClient instance. ad_group_id: an integer ID for an ad group. """ ad_group_criterion_service = client.GetService('AdGroupCriterionService', version='v201809') operations = [{ 'operator': 'ADD', 'operand': { 'xsi_type': 'BiddableAdGroupCriterion', 'adGroupId': ad_group_id, # Make sure that caseValue and parentCriterionId are left unspecified. # This makes this partition as generic as possible to use as a # fallback when others don't match. 'criterion': { 'xsi_type': 'ProductPartition', 'partitionType': 'UNIT' } } }] ad_group_criterion = ad_group_criterion_service.mutate(operations)['value'][0] print('Ad group criterion with ID "%d" in ad group with ID "%d" was added.' % (ad_group_criterion['criterion']['id'], ad_group_criterion['adGroupId'])) if __name__ == '__main__': # Initialize client object. adwords_client = adwords.AdWordsClient.LoadFromStorage() main(adwords_client, MERCHANT_ID, CREATE_DEFAULT_PARTITION)
Get the set of product bidding categories
#!/usr/bin/env python # # Copyright 2016 Google Inc. All Rights Reserved. # # 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 # # http://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. """This example fetches the set of valid ProductBiddingCategories. The LoadFromStorage method is pulling credentials and properties from a "googleads.yaml" file. By default, it looks for this file in your home directory. For more information, see the "Caching authentication information" section of our README. """ # Import appropriate modules from the client library. from googleads import adwords def main(client): service = client.GetService('ConstantDataService', version='v201809') selector = { 'predicates': [ { 'field': 'Country', 'operator': 'IN', 'values': ['US'] } ] } result = service.getProductBiddingCategoryData(selector) bidding_categories = {} root_categories = [] for product_bidding_category in result: category_id = product_bidding_category['dimensionValue']['value'] parent_id = None name = product_bidding_category['displayValue'][0]['value'] # Note: There may be cases where there isn't a value. if ('parentDimensionValue' in product_bidding_category and 'value' in product_bidding_category['parentDimensionValue']): parent_id = product_bidding_category['parentDimensionValue']['value'] if category_id not in bidding_categories: bidding_categories[category_id] = {} category = bidding_categories[category_id] if parent_id is not None: if parent_id not in bidding_categories: bidding_categories[parent_id] = {} parent = bidding_categories[parent_id] if 'children' not in parent: parent['children'] = [] parent['children'].append(category) else: root_categories.append(category) category['id'] = category_id category['name'] = name DisplayCategories(root_categories) def DisplayCategories(categories, prefix=''): for category in categories: print('%s%s [%s]' % (prefix, category['name'], category['id'])) if 'children' in category: DisplayCategories(category['children'], '%s%s > ' % (prefix, category['name'])) if __name__ == '__main__': # Initialize client object. adwords_client = adwords.AdWordsClient.LoadFromStorage() main(adwords_client)