Get started with Search campaigns

Search campaigns allow you to show text ads on Google Search results pages and Google partner sites. With the Google Ads API, you can create, manage, and optimize these campaigns programmatically.

Search campaigns are ideal when you want to reach users actively searching for specific keywords related to your business.

This guide walks you through all the steps necessary to build your first Search campaign.

Prerequisites

Before creating a Search campaign, verify you have the following:

  • A valid production Google Ads account

  • An approved billing setup

  • Access to the Google Ads API

Required Resources

When creating a Search campaign, a bulk mutate request provides a way to create multiple required resources simultaneously. This means you can establish a valid, serving campaign with just one request. Although you don't have to create every resource in a single bulk request, the following resources are mandatory for your Search campaign to be valid and active:

Resource Hierarchy

The Object hierarchy chart demonstrates the organizational structure of a Search campaign.

Create a Search campaign

To create a Search campaign using the Google Ads API, follow these steps:

  1. Create a Campaign Budget

    • Create or use an existing CampaignBudget. This resource can be shared across campaigns.
  2. Create the Search Campaign

  3. Create Ad Groups

    • Create an AdGroup . An AdGroup is a container for ads and keywords.
  4. Add keywords (Ad Group Criteria)

  5. Create ResponsiveSearchAds

Code example to create a Search campaign

The following code example demonstrates how to create a complete Search campaign. It covers:

  • Create a Campaign and a CampaignBudget .
  • Set the bidding strategy
  • Populate the campaign with AdGroup s, AdGroupAd s (including ResponsiveSearchAd s), and AdGroupCriterion s.
  • How to optionally geotarget your audiences with a CampaignCriterion object.

Java

This example is not yet available in Java; you can take a look at the other languages.

C#

 // Copyright 2021 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. 
 using 
  
 CommandLine 
 ; 
 using 
  
 Google.Ads.Gax.Examples 
 ; 
 using 
  
 Google.Ads.Gax.Util 
 ; 
 using 
  
 Google.Ads.GoogleAds.Lib 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Common 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Resources 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Services 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 System.Linq 
 ; 
 using 
  
 System 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupAdStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdvertisingChannelTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 CampaignStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 KeywordMatchTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Services 
 . 
 SuggestGeoTargetConstantsRequest 
 . 
 Types 
 ; 
 using 
  
 Google.Ads.GoogleAds.Config 
 ; 
 using 
  
 Google.Ads.GoogleAds.Extensions.Config 
 ; 
 namespace 
  
 Google.Ads.GoogleAds.Examples.V21 
 { 
  
 /// <summary> 
  
 /// Adds a customizer attribute, links the customizer attribute to a customer, and then adds 
  
 /// a responsive search ad with a description using the ad customizer to the specified ad group. 
  
 /// </summary> 
  
 public 
  
 class 
  
 AddResponsiveSearchAdFull 
  
 : 
  
 ExampleBase 
  
 { 
  
 /// <summary> 
  
 /// </summary> 
  
 public 
  
 class 
  
 Options 
  
 : 
  
 OptionsBase 
  
 { 
  
 /// <summary> 
  
 /// The Google Ads customer ID. 
  
 /// </summary> 
  
 [Option("customerId", Required = true, HelpText = 
 "The Google Ads customer ID.")] 
  
 public 
  
 long 
  
 CustomerId 
  
 { 
  
 get 
 ; 
  
 set 
 ; 
  
 } 
  
 /// <summary> 
  
 /// The Google Ads customizer attribute name ID. 
  
 /// </summary> 
  
 [Option("customizerAttributeName", Required = false, HelpText = 
 "The Google Ads customizer attribute name.", Default = CUSTOMIZER_ATTRIBUTE_NAME)] 
  
 public 
  
 string 
  
 CustomizerAttributeName 
  
 { 
  
 get 
 ; 
  
 set 
 ; 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Main method, to run this code example as a standalone application. 
  
 /// </summary> 
  
 /// <param name="args">The command line arguments.</param> 
  
 public 
  
 static 
  
 void 
  
 Main 
 ( 
 string 
 [] 
  
 args 
 ) 
  
 { 
  
 Options 
  
 options 
  
 = 
  
 ExampleUtilities 
 . 
 ParseCommandLine<Options> 
 ( 
 args 
 ); 
  
 AddResponsiveSearchAdFull 
  
 codeExample 
  
 = 
  
 new 
  
 AddResponsiveSearchAdFull 
 (); 
  
 Console 
 . 
 WriteLine 
 ( 
 codeExample 
 . 
 Description 
 ); 
  
 codeExample 
 . 
 Run 
 ( 
  
 new 
  
 GoogleAdsClient 
 (), 
  
 options 
 . 
 CustomerId 
 , 
  
 options 
 . 
 CustomizerAttributeName 
  
 ); 
  
 } 
  
 // The name of the customizer attribute to be used in the ad customizer must be unique for a 
  
 // given client account. To run this example multiple times, change this value or specify 
  
 // its corresponding 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. 
  
 // 
  
 // Visit the following link for more details: 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations 
  
 private 
  
 const 
  
 string 
  
 CUSTOMIZER_ATTRIBUTE_NAME 
  
 = 
  
 "Price" 
 ; 
  
 /// <summary> 
  
 /// Returns a description about the code example. 
  
 /// </summary> 
  
 public 
  
 override 
  
 string 
  
 Description 
  
 = 
>  
 "Adds a customizer attribute, links the customizer attribute to a customer, and then " 
  
 + 
  
 "adds a responsive search ad with a description using the ad customizer to the " 
  
 + 
  
 "specified ad group." 
 ; 
  
 /// <summary> 
  
 /// Runs the example. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID.</param> 
  
 /// <param name="customizerAttributeName">The customizer attribute name.</param> 
  
 public 
  
 void 
  
 Run 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 string 
  
 customizerAttributeResourceName 
  
 = 
  
 CreateCustomizerAttribute 
 ( 
  
 client 
 , 
  
 customerId 
 , 
  
 customizerAttributeName 
  
 ); 
  
 LinkCustomizerAttributeToCustomer 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 customizerAttributeResourceName 
 ); 
  
 string 
  
 campaignBudgetResourceName 
  
 = 
  
 AddCampaignBudget 
 ( 
 client 
 , 
  
 customerId 
 ); 
  
 string 
  
 campaignResourceName 
  
 = 
  
 AddCampaign 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignBudgetResourceName 
 ); 
  
 string 
  
 adGroupResourceName 
  
 = 
  
 AddAdGroup 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 CreateResponsiveSearchAdWithCustomization 
 ( 
  
 client 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 , 
  
 customizerAttributeName 
  
 ); 
  
 AddKeywords 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 ); 
  
 AddGeoTargeting 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Creates a customizer attribute with the specified customizer attribute name. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="customizerAttributeName">The name of the customizer attribute.</param> 
  
 /// <returns>The created customizer attribute resource name.</returns> 
  
 private 
  
 string 
  
 CreateCustomizerAttribute 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates a customizer attribute operation for creating a customizer attribute. 
  
 CustomizerAttributeOperation 
  
 operation 
  
 = 
  
 new 
  
 CustomizerAttributeOperation 
 () 
  
 { 
  
 // Creates a customizer attribute with the specified name. 
  
 Create 
  
 = 
  
 new 
  
 CustomizerAttribute 
 () 
  
 { 
  
 Name 
  
 = 
  
 customizerAttributeName 
 , 
  
 // 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. 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
  
 } 
  
 }; 
  
 CustomizerAttributeServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CustomizerAttributeService 
 ); 
  
 // Issues a mutate request to add the customizer attribute and prints its information. 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateCustomizerAttributes 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added a customizer attribute with resource name '{resourceName}'." 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Links the customizer attribute to the customer by providing a value to be used in a 
  
 /// responsive search ad that will be created in a later step. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="customizerAttributeResourceName">The resource name of the customizer 
  
 /// attribute.</param> 
  
 private 
  
 void 
  
 LinkCustomizerAttributeToCustomer 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeResourceName 
 ) 
  
 { 
  
 // Creates a customer customizer operation. 
  
 CustomerCustomizerOperation 
  
 operation 
  
 = 
  
 new 
  
 CustomerCustomizerOperation 
 () 
  
 { 
  
 // Creates a customer customizer with the value to be used in the responsive search 
  
 // ad. 
  
 Create 
  
 = 
  
 new 
  
 CustomerCustomizer 
 () 
  
 { 
  
 CustomizerAttribute 
  
 = 
  
 customizerAttributeResourceName 
 , 
  
 Value 
  
 = 
  
 new 
  
 CustomizerValue 
 () 
  
 { 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
 , 
  
 // Specify '100USD' as a text value. The ad customizer will dynamically 
  
 // replace the placeholder with this value when the ad serves. 
  
 StringValue 
  
 = 
  
 "100USD" 
  
 } 
  
 } 
  
 }; 
  
 CustomerCustomizerServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CustomerCustomizerService 
 ); 
  
 // Issues a mutate request to add the customer customizer and prints its information. 
  
 MutateCustomerCustomizersResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateCustomerCustomizers 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added a customer customizer with resource name '{resourceName}'." 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Adds a campaign budget. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <returns>The campaign budget resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddCampaignBudget 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 // Get the CampaignBudgetService. 
  
 CampaignBudgetServiceClient 
  
 campaignBudgetService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CampaignBudgetService 
 ); 
  
 // Create the budget. 
  
 CampaignBudget 
  
 campaignBudget 
  
 = 
  
 new 
  
 CampaignBudget 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Interplanetary Cruise Budget #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 AmountMicros 
  
 = 
  
 3 
 _000_000 
 , 
  
 DeliveryMethod 
  
 = 
  
 BudgetDeliveryMethod 
 . 
 Standard 
  
 }; 
  
 // Create the operation. 
  
 CampaignBudgetOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignBudgetOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaignBudget 
  
 }; 
  
 // Add the campaign budget. 
  
 MutateCampaignBudgetsResponse 
  
 response 
  
 = 
  
 campaignBudgetService 
 . 
 MutateCampaignBudgets 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 CampaignBudgetOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Display the result. 
  
 string 
  
 budgetResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added budget with resource name '{budgetResourceName}'." 
 ); 
  
 return 
  
 budgetResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Adds a campaign. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="budgetResourceName">The campaign budget resource name.</param> 
  
 /// <returns>The campaign resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddCampaign 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 budgetResourceName 
 ) 
  
 { 
  
 // Get the CampaignService. 
  
 CampaignServiceClient 
  
 campaignService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CampaignService 
 ); 
  
 // Create the campaign. 
  
 Campaign 
  
 campaign 
  
 = 
  
 new 
  
 Campaign 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Testing RSA via API #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 AdvertisingChannelType 
  
 = 
  
 AdvertisingChannelType 
 . 
 Search 
 , 
  
 Status 
  
 = 
  
 CampaignStatus 
 . 
 Paused 
 , 
  
 ManualCpc 
  
 = 
  
 new 
  
 ManualCpc 
 (), 
  
 NetworkSettings 
  
 = 
  
 new 
  
 Campaign 
 . 
 Types 
 . 
 NetworkSettings 
 () 
  
 { 
  
 TargetGoogleSearch 
  
 = 
  
 true 
 , 
  
 TargetSearchNetwork 
  
 = 
  
 true 
 , 
  
 TargetPartnerSearchNetwork 
  
 = 
  
 false 
 , 
  
 // Enable Display Expansion on Search campaigns. For more details see: 
  
 // https://support.google.com/google-ads/answer/7193800 
  
 TargetContentNetwork 
  
 = 
  
 true 
  
 }, 
  
 CampaignBudget 
  
 = 
  
 budgetResourceName 
 , 
  
 StartDate 
  
 = 
  
 DateTime 
 . 
 Now 
 . 
 AddDays 
 ( 
 1 
 ). 
 ToString 
 ( 
 "yyyyMMdd" 
 ), 
  
 EndDate 
  
 = 
  
 DateTime 
 . 
 Now 
 . 
 AddDays 
 ( 
 30 
 ). 
 ToString 
 ( 
 "yyyyMMdd" 
 ) 
  
 }; 
  
 // Create the operation. 
  
 CampaignOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaign 
  
 }; 
  
 // Add the campaign. 
  
 MutateCampaignsResponse 
  
 response 
  
 = 
  
 campaignService 
 . 
 MutateCampaigns 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 CampaignOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Displays the result. 
  
 string 
  
 campaignResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added campaign with resource name '{campaignResourceName}'." 
 ); 
  
 return 
  
 campaignResourceName 
 ; 
  
 } 
  
 /// <summary>Adds an ad group.</summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="campaignResourceName">The campaign resource name.</param> 
  
 /// <returns>The ad group resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddAdGroup 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 campaignResourceName 
 ) 
  
 { 
  
 // Get the AdGroupService. 
  
 AdGroupServiceClient 
  
 adGroupService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupService 
 ); 
  
 // Create the ad group. 
  
 AdGroup 
  
 adGroup 
  
 = 
  
 new 
  
 AdGroup 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Testing RSA via API #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 Campaign 
  
 = 
  
 campaignResourceName 
 , 
  
 Type 
  
 = 
  
 AdGroupType 
 . 
 SearchStandard 
 , 
  
 Status 
  
 = 
  
 AdGroupStatus 
 . 
 Enabled 
 , 
  
 // If you want to set up a max CPC bid, uncomment the line below. 
  
 // CpcBidMicros = 50_000 
  
 }; 
  
 // Create the operation. 
  
 AdGroupOperation 
  
 operation 
  
 = 
  
 new 
  
 AdGroupOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 adGroup 
  
 }; 
  
 // Add the ad group. 
  
 MutateAdGroupsResponse 
  
 response 
  
 = 
  
 adGroupService 
 . 
 MutateAdGroups 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 AdGroupOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Display the results. 
  
 string 
  
 adGroupResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added ad group with resource name '{adGroupResourceName}'." 
 ); 
  
 return 
  
 adGroupResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Creates a responsive search ad that uses the specified customizer attribute. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="adGroupResourceName">The resource name of the ad group.</param> 
  
 /// <param name="customizerAttributeName">The name of the customizer attribute.</param> 
  
 private 
  
 void 
  
 CreateResponsiveSearchAdWithCustomization 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 adGroupResourceName 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates an ad group ad operation. 
  
 AdGroupAdOperation 
  
 operation 
  
 = 
  
 new 
  
 AdGroupAdOperation 
 () 
  
 { 
  
 // Creates an ad group ad to hold the ad. 
  
 Create 
  
 = 
  
 new 
  
 AdGroupAd 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupAdStatus 
 . 
 Enabled 
 , 
  
 // Creates an ad and sets responsive search ad info. 
  
 Ad 
  
 = 
  
 new 
  
 Ad 
 () 
  
 { 
  
 ResponsiveSearchAd 
  
 = 
  
 new 
  
 ResponsiveSearchAdInfo 
 () 
  
 { 
  
 Headlines 
  
 = 
  
 { 
  
 // Sets a pinning to always choose this asset for HEADLINE_1. 
  
 // Pinning is optional; if no pinning is set, then headlines and 
  
 // descriptions will be rotated and the ones that perform best will 
  
 //be used more often. 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Cruise to Mars" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Best Space Cruise Line" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Experience the Stars" 
  
 } 
  
 }, 
  
 Descriptions 
  
 = 
  
 { 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Buy your tickets now" 
  
 }, 
  
 // Creates this particular description using the ad customizer. For 
  
 // details about the placeholder format, visit the following: 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads 
  
 // 
  
 // The ad customizer replaces the placeholder with the value we 
  
 // previously created and linked to the customer using 
  
 // `CustomerCustomizer`. 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Just {{CUSTOMIZER.{customizerAttributeName}:10USD}}" 
  
 } 
  
 }, 
  
 Path1 
  
 = 
  
 "all-inclusive" 
 , 
  
 Path2 
  
 = 
  
 "deals" 
  
 }, 
  
 FinalUrls 
  
 = 
  
 { 
  
 "http://www.example.com" 
  
 } 
  
 } 
  
 } 
  
 }; 
  
 // Issues a mutate request to add the ad group ad and prints its information. 
  
 AdGroupAdServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupAdService 
 ); 
  
 MutateAdGroupAdsResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateAdGroupAds 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Created responsive search ad with resource name '{resourceName}'." 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Creates 3 keyword match types: EXACT, PHRASE, and BROAD. 
  
 /// EXACT: ads may show on searches that ARE the same meaning as your keyword. 
  
 /// PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
  
 /// BROAD: ads may show on searches that RELATE to your keyword. 
  
 /// For smart bidding, BROAD is the recommended one. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="adGroupResourceName">The resource name of the ad group.</param> 
  
 private 
  
 void 
  
 AddKeywords 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 adGroupResourceName 
 ) 
  
 { 
  
 // Get the AdGroupCriterionService. 
  
 AdGroupCriterionServiceClient 
  
 adGroupCriterionService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupCriterionService 
 ); 
  
 List<AdGroupCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<AdGroupCriterionOperation> 
 (); 
  
 AdGroupCriterionOperation 
  
 exactMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of exact match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Exact 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // exactMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 exactMatchOperation 
 ); 
  
 AdGroupCriterionOperation 
  
 phraseMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of phrase match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Phrase 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // phraseMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 phraseMatchOperation 
 ); 
  
 AdGroupCriterionOperation 
  
 broadMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of broad match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Broad 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // broadMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 broadMatchOperation 
 ); 
  
 MutateAdGroupCriteriaResponse 
  
 response 
  
 = 
  
 adGroupCriterionService 
 . 
 MutateAdGroupCriteria 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 operations 
 ); 
  
 // Display the results. 
  
 foreach 
  
 ( 
 MutateAdGroupCriterionResult 
  
 newAdGroupCriterion 
  
 in 
  
 response 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "Keyword with resource name '{0}' was created." 
 , 
  
 newAdGroupCriterion 
 . 
 ResourceName 
 ); 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Creates geo targets. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="campaignResourceName">The resource name of the campaign.</param> 
  
 private 
  
 void 
  
 AddGeoTargeting 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 campaignResourceName 
 ) 
  
 { 
  
 GeoTargetConstantServiceClient 
  
 geoTargetConstantService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 GeoTargetConstantService 
 ); 
  
 SuggestGeoTargetConstantsRequest 
  
 suggestGeoTargetConstantsRequest 
  
 = 
  
 new 
  
 SuggestGeoTargetConstantsRequest 
 () 
  
 { 
  
 // Locale uses the ISO 639-1 format. 
  
 Locale 
  
 = 
  
 "es" 
 , 
  
 // A list of available country codes can be referenced here: 
  
 // https://developers.google.com/google-ads/api/reference/data/geotargets 
  
 CountryCode 
  
 = 
  
 "AR" 
 , 
  
 LocationNames 
  
 = 
  
 new 
  
 LocationNames 
 () 
  
 { 
  
 Names 
  
 = 
  
 { 
 "Buenos aires" 
 , 
  
 "San Isidro" 
 , 
  
 "Mar del Plata" 
 } 
  
 } 
  
 }; 
  
 SuggestGeoTargetConstantsResponse 
  
 suggestGeoTargetConstantsResponse 
  
 = 
  
 geoTargetConstantService 
 . 
 SuggestGeoTargetConstants 
 ( 
  
 suggestGeoTargetConstantsRequest 
 ); 
  
 List<CampaignCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<CampaignCriterionOperation> 
 (); 
  
 foreach 
  
 ( 
 GeoTargetConstantSuggestion 
  
 suggestion 
  
 in 
  
 suggestGeoTargetConstantsResponse 
 . 
 GeoTargetConstantSuggestions 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Geo target constant: {suggestion.GeoTargetConstant.Name} was " 
  
 + 
  
 $"found in locale ({suggestion.Locale}) with reach ({suggestion.Reach}) from " 
  
 + 
  
 $"search term ({suggestion.SearchTerm})" 
 ); 
  
 CampaignCriterionOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 CampaignCriterion 
 () 
  
 { 
  
 Campaign 
  
 = 
  
 campaignResourceName 
 , 
  
 Location 
  
 = 
  
 new 
  
 LocationInfo 
 () 
  
 { 
  
 GeoTargetConstant 
  
 = 
  
 suggestion 
 . 
 GeoTargetConstant 
 . 
 ResourceName 
  
 } 
  
 } 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 operation 
 ); 
  
 } 
  
 CampaignCriterionServiceClient 
  
 campaignCriterionService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CampaignCriterionService 
 ); 
  
 MutateCampaignCriteriaResponse 
  
 mutateCampaignCriteriaResponse 
  
 = 
  
 campaignCriterionService 
 . 
 MutateCampaignCriteria 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 operations 
 ); 
  
 foreach 
  
 ( 
 MutateCampaignCriterionResult 
  
 result 
  
 in 
  
 mutateCampaignCriteriaResponse 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added campaign criterion {result.ResourceName}" 
 ); 
  
 } 
  
 } 
  
 } 
 } 
  
  

PHP

This example is not yet available in PHP; you can take a look at the other languages.

Python

 #!/usr/bin/env python 
 # Copyright 2023 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 
 # 
 #     https://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 shows how to create a complete Responsive Search ad. 
 Includes creation of: budget, campaign, ad group, ad group ad, 
 keywords, and geo targeting. 
 More details on Responsive Search ads can be found here: 
 https://support.google.com/google-ads/answer/7684791 
 """ 
 import 
  
 argparse 
 import 
  
 sys 
 import 
  
 uuid 
 from 
  
 typing 
  
 import 
 List 
 , 
 Optional 
 from 
  
 google.ads.googleads.client 
  
 import 
 GoogleAdsClient 
 from 
  
 google.ads.googleads.errors 
  
 import 
 GoogleAdsException 
 from 
  
 google.ads.googleads.v21.common.types.ad_asset 
  
 import 
 AdTextAsset 
 from 
  
 google.ads.googleads.v21.enums.types.served_asset_field_type 
  
 import 
 ( 
 ServedAssetFieldTypeEnum 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.ad_group 
  
 import 
 AdGroup 
 from 
  
 google.ads.googleads.v21.resources.types.ad_group_ad 
  
 import 
 AdGroupAd 
 from 
  
 google.ads.googleads.v21.resources.types.ad_group_criterion 
  
 import 
 ( 
 AdGroupCriterion 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.campaign 
  
 import 
 Campaign 
 from 
  
 google.ads.googleads.v21.resources.types.campaign_budget 
  
 import 
 ( 
 CampaignBudget 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.campaign_criterion 
  
 import 
 ( 
 CampaignCriterion 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.customer_customizer 
  
 import 
 ( 
 CustomerCustomizer 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.customizer_attribute 
  
 import 
 ( 
 CustomizerAttribute 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.ad_group_criterion_service 
  
 import 
 ( 
 AdGroupCriterionServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.ad_group_service 
  
 import 
 ( 
 AdGroupServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.campaign_budget_service 
  
 import 
 ( 
 CampaignBudgetServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.campaign_criterion_service 
  
 import 
 ( 
 CampaignCriterionServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.campaign_service 
  
 import 
 ( 
 CampaignServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.customer_customizer_service 
  
 import 
 ( 
 CustomerCustomizerServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.customizer_attribute_service 
  
 import 
 ( 
 CustomizerAttributeServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.geo_target_constant_service 
  
 import 
 ( 
 GeoTargetConstantServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.geo_target_constant_service 
  
 import 
 ( 
 SuggestGeoTargetConstantsRequest 
 , 
 SuggestGeoTargetConstantsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdOperation 
 , 
 MutateAdGroupAdsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_criterion_service 
  
 import 
 ( 
 AdGroupCriterionOperation 
 , 
 MutateAdGroupCriteriaResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_service 
  
 import 
 ( 
 AdGroupOperation 
 , 
 MutateAdGroupsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.campaign_budget_service 
  
 import 
 ( 
 CampaignBudgetOperation 
 , 
 MutateCampaignBudgetsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.campaign_criterion_service 
  
 import 
 ( 
 CampaignCriterionOperation 
 , 
 MutateCampaignCriteriaResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.campaign_service 
  
 import 
 ( 
 CampaignOperation 
 , 
 MutateCampaignsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.customer_customizer_service 
  
 import 
 ( 
 CustomerCustomizerOperation 
 , 
 MutateCustomerCustomizersResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.customizer_attribute_service 
  
 import 
 ( 
 CustomizerAttributeOperation 
 , 
 MutateCustomizerAttributesResponse 
 , 
 ) 
 # Keywords from user. 
 KEYWORD_TEXT_EXACT 
 = 
 "example of exact match" 
 KEYWORD_TEXT_PHRASE 
 = 
 "example of phrase match" 
 KEYWORD_TEXT_BROAD 
 = 
 "example of broad match" 
 # Geo targeting from user. 
 GEO_LOCATION_1 
 = 
 "Buenos aires" 
 GEO_LOCATION_2 
 = 
 "San Isidro" 
 GEO_LOCATION_3 
 = 
 "Mar del Plata" 
 # LOCALE and COUNTRY_CODE are used for geo targeting. 
 # LOCALE is using ISO 639-1 format. If an invalid LOCALE is given, 
 # 'es' is used by default. 
 LOCALE 
 = 
 "es" 
 # A list of country codes can be referenced here: 
 # https://developers.google.com/google-ads/api/reference/data/geotargets 
 COUNTRY_CODE 
 = 
 "AR" 
 def 
  
 main 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 Optional 
 [ 
 str 
 ] 
 = 
 None 
 , 
 ) 
 - 
> None 
 : 
  
 """ 
 The main method that creates all necessary entities for the example. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_attribute_name: The name of the customizer attribute to be 
 created 
 """ 
 if 
 customizer_attribute_name 
 : 
 customizer_attribute_resource_name 
 : 
 str 
 = 
 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 
 : 
 str 
 = 
 create_campaign_budget 
 ( 
 client 
 , 
 customer_id 
 ) 
 campaign_resource_name 
 : 
 str 
 = 
 create_campaign 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_budget 
 ) 
 ad_group_resource_name 
 : 
 str 
 = 
 create_ad_group 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_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 
 ) 
 add_geo_targeting 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_resource_name 
 ) 
 def 
  
 create_customizer_attribute 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """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. 
 """ 
 # Create a customizer attribute operation for creating a customizer 
 # attribute. 
 operation 
 : 
 CustomizerAttributeOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomizerAttributeOperation" 
 ) 
 # Create a customizer attribute with the specified name. 
 customizer_attribute 
 : 
 CustomizerAttribute 
 = 
 operation 
 . 
 create 
 customizer_attribute 
 . 
 name 
 = 
 customizer_attribute_name 
 # Specify 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 
 # Issue a mutate request to add the customizer attribute and prints its 
 # information. 
 customizer_attribute_service 
 : 
 CustomizerAttributeServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomizerAttributeService" 
 ) 
 ) 
 response 
 : 
 MutateCustomizerAttributesResponse 
 = 
 ( 
 customizer_attribute_service 
 . 
 mutate_customizer_attributes 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added a customizer attribute with resource name: ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 return 
 resource_name 
 def 
  
 link_customizer_attribute_to_customer 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_resource_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Links the customizer attribute to the customer. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_attribute_resource_name: a resource name for  customizer 
 attribute. 
 """ 
 # Create a customer customizer operation. 
 operation 
 : 
 CustomerCustomizerOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomerCustomizerOperation" 
 ) 
 # Create a customer customizer with the value to be used in the responsive 
 # search ad. 
 customer_customizer 
 : 
 CustomerCustomizer 
 = 
 operation 
 . 
 create 
 customer_customizer 
 . 
 customizer_attribute 
 = 
 ( 
 customizer_attribute_resource_name 
 ) 
 customer_customizer 
 . 
 value 
 . 
 type_ 
 = 
 ( 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 PRICE 
 ) 
 # The ad customizer will dynamically replace the placeholder with this value 
 # when the ad serves. 
 customer_customizer 
 . 
 value 
 . 
 string_value 
 = 
 "100USD" 
 customer_customizer_service 
 : 
 CustomerCustomizerServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomerCustomizerService" 
 ) 
 ) 
 # Issue a mutate request to create the customer customizer and prints its 
 # information. 
 response 
 : 
 MutateCustomerCustomizersResponse 
 = 
 ( 
 customer_customizer_service 
 . 
 mutate_customer_customizers 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added a customer customizer to the customer with resource name: ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 def 
  
 create_ad_text_asset 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 text 
 : 
 str 
 , 
 pinned_field 
 : 
 Optional 
 [ 
 ServedAssetFieldTypeEnum 
 . 
 ServedAssetFieldType 
 ] 
 = 
 None 
 , 
 ) 
 - 
> AdTextAsset 
 : 
  
 """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 AdTextAsset. 
 """ 
 ad_text_asset 
 : 
 AdTextAsset 
 = 
 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 
 : 
 GoogleAdsClient 
 , 
 customizer_attribute_resource_name 
 : 
 str 
 ) 
 - 
> AdTextAsset 
 : 
  
 """Create an AdTextAsset. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customizer_attribute_resource_name: The resource name of the customizer attribute. 
 Returns: 
 An AdTextAsset. 
 """ 
 ad_text_asset 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 # Create 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_resource_name}:10USD} } 
 " 
 ) 
 return 
 ad_text_asset 
 def 
  
 create_campaign_budget 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates campaign budget resource. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 Returns: 
 Campaign budget resource name. 
 """ 
 # Create a budget, which can be shared by multiple campaigns. 
 campaign_budget_service 
 : 
 CampaignBudgetServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignBudgetService" 
 ) 
 campaign_budget_operation 
 : 
 CampaignBudgetOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignBudgetOperation" 
 ) 
 campaign_budget 
 : 
 CampaignBudget 
 = 
 campaign_budget_operation 
 . 
 create 
 campaign_budget 
 . 
 name 
 = 
 f 
 "Campaign budget 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 campaign_budget 
 . 
 delivery_method 
 = 
 ( 
 client 
 . 
 enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 STANDARD 
 ) 
 campaign_budget 
 . 
 amount_micros 
 = 
 500000 
 # Add budget. 
 campaign_budget_response 
 : 
 MutateCampaignBudgetsResponse 
 = 
 ( 
 campaign_budget_service 
 . 
 mutate_campaign_budgets 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 campaign_budget_operation 
 ] 
 ) 
 ) 
 return 
 campaign_budget_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 def 
  
 create_campaign 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_budget 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates campaign resource. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_budget: a budget resource name. 
 Returns: 
 Campaign resource name. 
 """ 
 campaign_service 
 : 
 CampaignServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignService" 
 ) 
 campaign_operation 
 : 
 CampaignOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignOperation" 
 ) 
 campaign 
 : 
 Campaign 
 = 
 campaign_operation 
 . 
 create 
 campaign 
 . 
 name 
 = 
 f 
 "Testing RSA via API 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 campaign 
 . 
 advertising_channel_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 AdvertisingChannelTypeEnum 
 . 
 SEARCH 
 ) 
 # Recommendation: Set the campaign to PAUSED when creating it to prevent 
 # the ads from immediately serving. Set to ENABLED once you've added 
 # targeting and the ads are ready to serve. 
 campaign 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 CampaignStatusEnum 
 . 
 PAUSED 
 # Set the bidding strategy and budget. 
 # The bidding strategy for Maximize Clicks is TargetSpend. 
 # The target_spend_micros is deprecated so don't put any value. 
 # See other bidding strategies you can select in the link below. 
 # https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
 campaign 
 . 
 target_spend 
 . 
 target_spend_micros 
 = 
 0 
 campaign 
 . 
 campaign_budget 
 = 
 campaign_budget 
 # Set the campaign network options. 
 campaign 
 . 
 network_settings 
 . 
 target_google_search 
 = 
 True 
 campaign 
 . 
 network_settings 
 . 
 target_search_network 
 = 
 True 
 campaign 
 . 
 network_settings 
 . 
 target_partner_search_network 
 = 
 False 
 # Enable Display Expansion on Search campaigns. For more details see: 
 # https://support.google.com/google-ads/answer/7193800 
 campaign 
 . 
 network_settings 
 . 
 target_content_network 
 = 
 True 
 # # Optional: Set the start date. 
 # start_time = datetime.date.today() + datetime.timedelta(days=1) 
 # campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT) 
 # # Optional: Set the end date. 
 # end_time = start_time + datetime.timedelta(weeks=4) 
 # campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT) 
 # Add the campaign. 
 campaign_response 
 : 
 MutateCampaignsResponse 
 = 
 ( 
 campaign_service 
 . 
 mutate_campaigns 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 campaign_operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 campaign_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Created campaign 
 { 
 resource_name 
 } 
 ." 
 ) 
 return 
 resource_name 
 def 
  
 create_ad_group 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_resource_name 
 : 
 str 
 , 
 ) 
 - 
> str 
 : 
  
 """Creates ad group. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_resource_name: a campaign resource name. 
 Returns: 
 Ad group ID. 
 """ 
 ad_group_service 
 : 
 AdGroupServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupService" 
 ) 
 ad_group_operation 
 : 
 AdGroupOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupOperation" 
 ) 
 ad_group 
 : 
 AdGroup 
 = 
 ad_group_operation 
 . 
 create 
 ad_group 
 . 
 name 
 = 
 f 
 "Testing RSA via API 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 ad_group 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupStatusEnum 
 . 
 ENABLED 
 ad_group 
 . 
 campaign 
 = 
 campaign_resource_name 
 ad_group 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 AdGroupTypeEnum 
 . 
 SEARCH_STANDARD 
 # If you want to set up a max CPC bid uncomment line below. 
 # ad_group.cpc_bid_micros = 10000000 
 # Add the ad group. 
 ad_group_response 
 : 
 MutateAdGroupsResponse 
 = 
 ( 
 ad_group_service 
 . 
 mutate_ad_groups 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 ad_group_operation 
 ] 
 ) 
 ) 
 ad_group_resource_name 
 : 
 str 
 = 
 ad_group_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Created ad group 
 { 
 ad_group_resource_name 
 } 
 ." 
 ) 
 return 
 ad_group_resource_name 
 def 
  
 create_ad_group_ad 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_resource_name 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 Optional 
 [ 
 str 
 ], 
 ) 
 - 
> None 
 : 
  
 """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) If present, indicates the resource 
 name of the customizer attribute to use in one of the descriptions 
 Returns: 
 None. 
 """ 
 ad_group_ad_service 
 : 
 AdGroupAdServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupAdService" 
 ) 
 ad_group_ad_operation 
 : 
 AdGroupAdOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupAdOperation" 
 ) 
 ad_group_ad 
 : 
 AdGroupAd 
 = 
 ad_group_ad_operation 
 . 
 create 
 ad_group_ad 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupAdStatusEnum 
 . 
 ENABLED 
 ad_group_ad 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 # Set responsive search ad info. 
 # https://developers.google.com/google-ads/api/reference/rpc/latest/ResponsiveSearchAdInfo 
 # The list of possible final URLs after all cross-domain redirects for the ad. 
 ad_group_ad 
 . 
 ad 
 . 
 final_urls 
 . 
 append 
 ( 
 "https://www.example.com/" 
 ) 
 # Set a pinning to always choose this asset for HEADLINE_1. Pinning is 
 # optional; if no pinning is set, then headlines and descriptions will be 
 # rotated and the ones that perform best will be used more often. 
 # Headline 1 
 served_asset_enum 
 : 
 ServedAssetFieldTypeEnum 
 = 
 ( 
 client 
 . 
 enums 
 . 
 ServedAssetFieldTypeEnum 
 ) 
 pinned_headline 
 : 
 AdTextAsset 
 = 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 1 testing" 
 , 
 served_asset_enum 
 ) 
 # Headline 2 and 3 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 headlines 
 . 
 extend 
 ( 
 [ 
 pinned_headline 
 , 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 2 testing" 
 ), 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 3 testing" 
 ), 
 ] 
 ) 
 # Description 1 and 2 
 description_1 
 : 
 AdTextAsset 
 = 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Desc 1 testing" 
 ) 
 description_2 
 : 
 Optional 
 [ 
 AdTextAsset 
 ] 
 = 
 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 
 ( 
 [ 
 description_1 
 , 
 description_2 
 ] 
 ) 
 # Paths 
 # First and second part of text that can be appended to the URL in the ad. 
 # If you use the examples below, the ad will show 
 # https://www.example.com/all-inclusive/deals 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 path1 
 = 
 "all-inclusive" 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 path2 
 = 
 "deals" 
 # Send a request to the server to add a responsive search ad. 
 ad_group_ad_response 
 : 
 MutateAdGroupAdsResponse 
 = 
 ( 
 ad_group_ad_service 
 . 
 mutate_ad_group_ads 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 ad_group_ad_operation 
 ] 
 ) 
 ) 
 for 
 result 
 in 
 ad_group_ad_response 
 . 
 results 
 : 
 print 
 ( 
 f 
 "Created responsive search ad with resource name " 
 f 
 '" 
 { 
 result 
 . 
 resource_name 
 } 
 ".' 
 ) 
 def 
  
 add_keywords 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_resource_name 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Creates keywords. 
 Creates 3 keyword match types: EXACT, PHRASE, and BROAD. 
 EXACT: ads may show on searches that ARE the same meaning as your keyword. 
 PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
 BROAD: ads may show on searches that RELATE to your keyword. 
 For smart bidding, BROAD is the recommended one. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_resource_name: an ad group resource name. 
 """ 
 ad_group_criterion_service 
 : 
 AdGroupCriterionServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "AdGroupCriterionService" 
 ) 
 ) 
 operations 
 : 
 List 
 [ 
 AdGroupCriterionOperation 
 ] 
 = 
 [] 
 # Create keyword 1. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_EXACT 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 EXACT 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Create keyword 2. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_PHRASE 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 PHRASE 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Create keyword 3. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_BROAD 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 BROAD 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Add keywords 
 ad_group_criterion_response 
 : 
 MutateAdGroupCriteriaResponse 
 = 
 ( 
 ad_group_criterion_service 
 . 
 mutate_ad_group_criteria 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 operations 
 , 
 ) 
 ) 
 for 
 result 
 in 
 ad_group_criterion_response 
 . 
 results 
 : 
 print 
 ( 
 "Created keyword " 
 f 
 " 
 { 
 result 
 . 
 resource_name 
 } 
 ." 
 ) 
 def 
  
 add_geo_targeting 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_resource_name 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Creates geo targets. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_resource_name: an campaign resource name. 
 Returns: 
 None. 
 """ 
 geo_target_constant_service 
 : 
 GeoTargetConstantServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "GeoTargetConstantService" 
 ) 
 ) 
 # Search by location names from 
 # GeoTargetConstantService.suggest_geo_target_constants() and directly 
 # apply GeoTargetConstant.resource_name. 
 gtc_request 
 : 
 SuggestGeoTargetConstantsRequest 
 = 
 client 
 . 
 get_type 
 ( 
 "SuggestGeoTargetConstantsRequest" 
 ) 
 gtc_request 
 . 
 locale 
 = 
 LOCALE 
 gtc_request 
 . 
 country_code 
 = 
 COUNTRY_CODE 
 # The location names to get suggested geo target constants. 
 gtc_request 
 . 
 location_names 
 . 
 names 
 . 
 extend 
 ( 
 [ 
 GEO_LOCATION_1 
 , 
 GEO_LOCATION_2 
 , 
 GEO_LOCATION_3 
 ] 
 ) 
 results 
 : 
 SuggestGeoTargetConstantsResponse 
 = 
 ( 
 geo_target_constant_service 
 . 
 suggest_geo_target_constants 
 ( 
 gtc_request 
 ) 
 ) 
 operations 
 : 
 List 
 [ 
 CampaignCriterionOperation 
 ] 
 = 
 [] 
 for 
 suggestion 
 in 
 results 
 . 
 geo_target_constant_suggestions 
 : 
 print 
 ( 
 "geo_target_constant: " 
 f 
 " 
 { 
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
 } 
 " 
 f 
 "is found in LOCALE ( 
 { 
 suggestion 
 . 
 locale 
 } 
 ) " 
 f 
 "with reach ( 
 { 
 suggestion 
 . 
 reach 
 } 
 ) " 
 f 
 "from search term ( 
 { 
 suggestion 
 . 
 search_term 
 } 
 )." 
 ) 
 # Create the campaign criterion for location targeting. 
 campaign_criterion_operation 
 : 
 CampaignCriterionOperation 
 = 
 ( 
 client 
 . 
 get_type 
 ( 
 "CampaignCriterionOperation" 
 ) 
 ) 
 campaign_criterion 
 : 
 CampaignCriterion 
 = 
 ( 
 campaign_criterion_operation 
 . 
 create 
 ) 
 campaign_criterion 
 . 
 campaign 
 = 
 campaign_resource_name 
 campaign_criterion 
 . 
 location 
 . 
 geo_target_constant 
 = 
 ( 
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
 ) 
 operations 
 . 
 append 
 ( 
 campaign_criterion_operation 
 ) 
 campaign_criterion_service 
 : 
 CampaignCriterionServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CampaignCriterionService" 
 ) 
 ) 
 campaign_criterion_response 
 : 
 MutateCampaignCriteriaResponse 
 = 
 ( 
 campaign_criterion_service 
 . 
 mutate_campaign_criteria 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 * 
 operations 
 ] 
 ) 
 ) 
 for 
 result 
 in 
 campaign_criterion_response 
 . 
 results 
 : 
 print 
 ( 
 f 
 'Added campaign criterion " 
 { 
 result 
 . 
 resource_name 
 } 
 ".' 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 parser 
 : 
 argparse 
 . 
 ArgumentParser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "Creates a Responsive Search Ad for specified customer." 
 ) 
 ) 
 # The following argument(s) should be provided to run the example. 
 parser 
 . 
 add_argument 
 ( 
 "-c" 
 , 
 "--customer_id" 
 , 
 type 
 = 
 str 
 , 
 required 
 = 
 True 
 , 
 help 
 = 
 "The Google Ads customer ID." 
 , 
 ) 
 # The name of the customizer attribute 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 
 # 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 client account, so be sure not to use " 
 "the same value more than once." 
 ), 
 ) 
 args 
 : 
 argparse 
 . 
 Namespace 
 = 
 parser 
 . 
 parse_args 
 () 
 # GoogleAdsClient will read the google-ads.yaml configuration file in the 
 # home directory if none is specified. 
 googleads_client 
 : 
 GoogleAdsClient 
 = 
 GoogleAdsClient 
 . 
 load_from_storage 
 ( 
 version 
 = 
 "v21" 
 ) 
 try 
 : 
 main 
 ( 
 googleads_client 
 , 
 args 
 . 
 customer_id 
 , 
 args 
 . 
 customizer_attribute_name 
 , 
 ) 
 except 
 GoogleAdsException 
 as 
 ex 
 : 
 print 
 ( 
 f 
 'Request with ID " 
 { 
 ex 
 . 
 request_id 
 } 
 " failed with status ' 
 f 
 '" 
 { 
 ex 
 . 
 error 
 . 
 code 
 () 
 . 
 name 
 } 
 " and includes the following errors:' 
 ) 
 for 
 error 
 in 
 ex 
 . 
 failure 
 . 
 errors 
 : 
 print 
 ( 
 f 
 'Error with message " 
 { 
 error 
 . 
 message 
 } 
 ".' 
 ) 
 if 
 error 
 . 
 location 
 : 
 for 
 field_path_element 
 in 
 error 
 . 
 location 
 . 
 field_path_elements 
 : 
 print 
 ( 
 f 
 " 
 \t\t 
 On field: 
 { 
 field_path_element 
 . 
 field_name 
 } 
 " 
 ) 
 sys 
 . 
 exit 
 ( 
 1 
 ) 
  

Ruby

This example is not yet available in Ruby; you can take a look at the other languages.

Perl

 #!/usr/bin/perl -w 
 # 
 # Copyright 2024, 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 shows how to create a complete Responsive Search ad. 
 # Includes creation of: budget, campaign, ad group, ad group ad, keywords, 
 # and geo targeting. More details on Responsive Search ads can be found here: 
 # https://support.google.com/google-ads/answer/7684791 
 use 
  
 strict 
 ; 
 use 
  
 warnings 
 ; 
 use 
  
 utf8 
 ; 
 use 
  
 FindBin 
  
 qw($Bin) 
 ; 
 use 
  
 lib 
  
 "$Bin/../../lib" 
 ; 
 use 
  
 Google::Ads::GoogleAds::Client 
 ; 
 use 
  
 Google::Ads::GoogleAds::Utils::GoogleAdsHelper 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::Campaign 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CampaignBudget 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CampaignCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CustomizerAttribute 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CustomerCustomizer 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::Ad 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroup 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupAd 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::NetworkSettings 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::AdTextAsset 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::CustomizerValue 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::ImageDimension 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::KeywordInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::LocationInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::ResponsiveSearchAdInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::TargetSpend 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdvertisingChannelTypeEnum 
  
 qw(SEARCH) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::BudgetDeliveryMethodEnum 
  
 qw(STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::CustomizerAttributeTypeEnum 
  
 qw(PRICE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupAdStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupCriterionStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupTypeEnum 
  
 qw(SEARCH_STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AssetTypeEnum 
  
 qw(IMAGE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::CampaignStatusEnum 
  
 qw(PAUSED) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::KeywordMatchTypeEnum 
  
 qw(BROAD EXACT PHRASE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::MimeTypeEnum 
  
 qw(IMAGE_PNG) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::ServedAssetFieldTypeEnum 
  
 qw(HEADLINE_1) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupService::AdGroupOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService::AdGroupAdOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCriterionService::AdGroupCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AssetService::AssetOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignBudgetService::CampaignBudgetOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignCriterionService::CampaignCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignService::CampaignOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CustomizerAttributeService::CustomizerAttributeOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CustomerCustomizerService::CustomerCustomizerOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::GeoTargetConstantService::LocationNames 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames 
 ; 
 use 
  
 Getopt::Long 
  
 qw(:config auto_help) 
 ; 
 use 
  
 Pod::Usage 
 ; 
 use 
  
 Cwd 
  
 qw(abs_path) 
 ; 
 use 
  
 Data::Uniqid 
  
 qw(uniqid) 
 ; 
 # Keywords from the user. 
 use 
  
 constant 
  
 KEYWORD_TEXT_EXACT 
  
 = 
>  
 "example of exact match" 
 ; 
 use 
  
 constant 
  
 KEYWORD_TEXT_PHRASE 
  
 = 
>  
 "example of phrase match" 
 ; 
 use 
  
 constant 
  
 KEYWORD_TEXT_BROAD 
  
 = 
>  
 "example of broad match" 
 ; 
 # Geo targeting from the user. 
 use 
  
 constant 
  
 GEO_LOCATION_1 
  
 = 
>  
 "Buenos Aires" 
 ; 
 use 
  
 constant 
  
 GEO_LOCATION_2 
  
 = 
>  
 "San Isidro" 
 ; 
 use 
  
 constant 
  
 GEO_LOCATION_3 
  
 = 
>  
 "Mar del Plata" 
 ; 
 # LOCALE and COUNTRY_CODE are used for geo targeting. 
 # LOCALE is using ISO 639-1 format. If an invalid LOCALE is given, 
 # 'es' is used by default. 
 use 
  
 constant 
  
 LOCALE 
  
 = 
>  
 "es" 
 ; 
 # A list of country codes can be referenced here: 
 # https://developers.google.com/google-ads/api/reference/data/geotargets 
 use 
  
 constant 
  
 COUNTRY_CODE 
  
 = 
>  
 "AR" 
 ; 
 use 
  
 constant 
  
 IMAGE_URL 
  
 = 
>  
 "https://gaagl.page.link/bjYi" 
 ; 
 sub 
  
 add_responsive_search_ad_full 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # If a customizer attribute name is provided, create the customizer 
  
 # attribute and link it to the customer. 
  
 # For more information on customizer attributes, visit: 
  
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads 
  
 if 
  
 ( 
 defined 
  
 $customizer_attribute_name 
 ) 
  
 { 
  
 my 
  
 $customizer_attribute_resource_name 
  
 = 
  
 create_customizer_attribute 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ); 
  
 link_customizer_attribute_to_customer 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_resource_name 
 ); 
  
 } 
  
 # Create a budget, which can be shared by multiple campaigns. 
  
 my 
  
 $campaign_budget 
  
 = 
  
 create_campaign_budget 
 ( 
 $api_client 
 , 
  
 $customer_id 
 ); 
  
 # Create a search campaign. 
  
 my 
  
 $campaign_resource_name 
  
 = 
  
 create_campaign 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_budget 
 ); 
  
 # Create an empty ad group. 
  
 my 
  
 $ad_group_resource_name 
  
 = 
  
 create_ad_group 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ); 
  
 # Create a responsive search ad within the ad group we just created. 
  
 create_ad_group_ad 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 , 
  
 $customizer_attribute_name 
 ); 
  
 # Create 3 keywords of match type EXACT, PHRASE, and BROAD, and add them 
  
 # as criteria on our ad group. 
  
 add_keywords 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 ); 
  
 # Create geo targets and add them as criteria on our campaign. 
  
 add_geo_targeting 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ); 
  
 return 
  
 1 
 ; 
 } 
 # Creates a customizer attribute with the given customizer attribute name. 
 sub 
  
 create_customizer_attribute 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $customizer_attribute 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CustomizerAttribute 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 $customizer_attribute_name 
 , 
  
 # Specify 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. 
  
 type 
  
 = 
>  
 PRICE 
  
 }); 
  
 # Create a customizer attribute operation for creating a customizer attribute. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CustomizerAttributeService:: 
 CustomizerAttributeOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $customizer_attribute 
  
 }); 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomizerAttributeService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 my 
  
 $resource_name 
  
 = 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Added a customizer attribute with resource name '%s'.\n" 
 , 
  
 $resource_name 
 ; 
  
 return 
  
 $resource_name 
 ; 
 } 
 # Links the customizer attribute to the customer. 
 sub 
  
 link_customizer_attribute_to_customer 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a customer customizer with the value to be used in the responsive search ad. 
  
 my 
  
 $customer_customizer 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CustomerCustomizer 
 - 
> new 
 ({ 
  
 customizerAttribute 
  
 = 
>  
 $customizer_attribute_resource_name 
 , 
  
 # Specify '100USD' as a text value. The ad customizer will dynamically replace 
  
 # the placeholder with this value when the ad serves. 
  
 value 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 CustomizerValue 
 - 
> new 
 ({ 
  
 type 
  
 = 
>  
 PRICE 
 , 
  
 stringValue 
  
 = 
>  
 "100USD" 
  
 })}); 
  
 # Create a customer customizer operation. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CustomerCustomizerService:: 
 CustomerCustomizerOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $customer_customizer 
  
 }); 
  
 # Issue a mutate request to add the customer customizer and print its information. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomerCustomizerService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 printf 
  
 "Added a customer customizer with resource name '%s'.\n" 
 , 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
 } 
 # Creates an AdTextAsset. 
 sub 
  
 create_ad_text_asset 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $text 
 , 
  
 $pinned_field 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_text_asset 
  
 = 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 $text 
  
 }); 
  
 if 
  
 ( 
 defined 
  
 $pinned_field 
 ) 
  
 { 
  
 $ad_text_asset 
 - 
> { 
 pinnedField 
 } 
  
 = 
  
 $pinned_field 
 ; 
  
 } 
  
 return 
  
 $ad_text_asset 
 ; 
 } 
 # Creates an AdTextAsset with a customizer in the text. 
 sub 
  
 create_ad_text_asset_with_customizer 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customizer_attribute_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_text_asset 
  
 = 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Just {CUSTOMIZER.$customizer_attribute_resource_name:10USD}" 
 ); 
  
 return 
  
 $ad_text_asset 
 ; 
 } 
 # Creates a campaign budget. 
 sub 
  
 create_campaign_budget 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a campaign budget. 
  
 my 
  
 $campaign_budget 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CampaignBudget 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Campaign budget " 
  
 . 
  
 uniqid 
 (), 
  
 amountMicros 
  
 = 
>  
 50000000 
 , 
  
 deliveryMethod 
  
 = 
>  
 STANDARD 
  
 }); 
  
 # Create a campaign budget operation. 
  
 my 
  
 $campaign_budget_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CampaignBudgetService:: 
 CampaignBudgetOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign_budget 
  
 }); 
  
 # Issue a mutate request to add the campaign budget. 
  
 my 
  
 $campaign_budgets_response 
  
 = 
  
 $api_client 
 - 
> CampaignBudgetService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $campaign_budget_operation 
 ]}); 
  
 my 
  
 $campaign_budget_resource_name 
  
 = 
  
 $campaign_budgets_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 return 
  
 $campaign_budget_resource_name 
 ; 
 } 
 # Creates a campaign. 
 sub 
  
 create_campaign 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_budget 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a campaign. 
  
 my 
  
 $campaign 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 Campaign 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Testing RSA via API " 
  
 . 
  
 uniqid 
 (), 
  
 campaignBudget 
  
 = 
>  
 $campaign_budget 
 , 
  
 # Recommendation: Set the campaign to PAUSED when creating it to prevent 
  
 # the ads from immediately serving. Set to ENABLED once you've added 
  
 # targeting and the ads are ready to serve. 
  
 status 
  
 = 
>  
 PAUSED 
 , 
  
 advertisingChannelType 
  
 = 
>  
 SEARCH 
 , 
  
 # Set the bidding strategy and budget. 
  
 # The bidding strategy for Maximize Clicks is TargetSpend. 
  
 # The target_spend_micros is deprecated so don't put any value. 
  
 # See other bidding strategies you can select in the link below. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
  
 targetSpend 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 TargetSpend 
 - 
> new 
 (), 
  
 # Set the campaign network options 
  
 networkSettings 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Resources:: 
 NetworkSettings 
 - 
> new 
 ({ 
  
 targetGoogleSearch 
  
 = 
>  
 "true" 
 , 
  
 targetSearchNetwork 
  
 = 
>  
 "true" 
 , 
  
 # Enable Display Expansion on Search campaigns. See 
  
 # https://support.google.com/google-ads/answer/7193800 to learn more. 
  
 targetContentNetwork 
  
 = 
>  
 "true" 
 , 
  
 targetPartnerSearchNetwork 
  
 = 
>  
 "false" 
  
 } 
  
 ), 
  
 # Optional: Set the start date. The campaign starts tomorrow. 
  
 # startDate => strftime("%Y%m%d", localtime(time + 60 * 60 * 24)), 
  
 # Optional: Set the end date. The campaign runs for 30 days. 
  
 # endDate => strftime("%Y%m%d", localtime(time + 60 * 60 * 24 * 30)), 
  
 }); 
  
 # Create a campaign operation. 
  
 my 
  
 $campaign_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CampaignService:: 
 CampaignOperation 
 - 
>  
 new 
 ({ 
  
 create 
  
 = 
>  
 $campaign 
  
 }); 
  
 # Issue a mutate request to add the campaign. 
  
 my 
  
 $campaigns_response 
  
 = 
  
 $api_client 
 - 
> CampaignService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $campaign_operation 
 ]}); 
  
 my 
  
 $resource_name 
  
 = 
  
 $campaigns_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Created App campaign with resource name: '%s'.\n" 
 , 
  
 $resource_name 
 ; 
  
 return 
  
 $resource_name 
 ; 
 } 
 # Creates an ad group. 
 sub 
  
 create_ad_group 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create an ad group, setting an optional CPC value. 
  
 my 
  
 $ad_group 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroup 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Testing RSA via API " 
  
 . 
  
 uniqid 
 (), 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::AdGroupStatusEnum:: 
 ENABLED 
 , 
  
 campaign 
  
 = 
>  
 $campaign_resource_name 
 , 
  
 type 
  
 = 
>  
 SEARCH_STANDARD 
 , 
  
 # If you want to set up a max CPC bid, uncomment the line below. 
  
 # cpcBidMicros => 10000000 
  
 }); 
  
 # Create an ad group operation. 
  
 my 
  
 $ad_group_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupService:: 
 AdGroupOperation 
 - 
>  
 new 
 ({ 
 create 
  
 = 
>  
 $ad_group 
 }); 
  
 # Add the ad group. 
  
 my 
  
 $ad_groups_response 
  
 = 
  
 $api_client 
 - 
> AdGroupService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $ad_group_operation 
 ]}); 
  
 my 
  
 $ad_group_resource_name 
  
 = 
  
 $ad_groups_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Created ad group '%s'.\n" 
 , 
  
 $ad_group_resource_name 
 ; 
  
 return 
  
 $ad_group_resource_name 
 ; 
 } 
 # Creates an ad group ad. 
 sub 
  
 create_ad_group_ad 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Set a pinning to always choose this asset for HEADLINE_1. Pinning is optional; if no 
  
 # pinning is set, then headlines and descriptions will be rotated and the ones that perform 
  
 # best will be used more often. 
  
 my 
  
 $pinned_headline 
  
 = 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 1 testing" 
 , 
  
 HEADLINE_1 
 ); 
  
 my 
  
 $ad_group_ad 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupAd 
 - 
> new 
 ({ 
  
 adGroup 
  
 = 
>  
 $ad_group_resource_name 
 , 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::AdGroupAdStatusEnum:: 
 ENABLED 
 , 
  
 ad 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Resources:: 
 Ad 
 - 
> new 
 ({ 
  
 # Set responsive search ad info. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/ResponsiveSearchAdInfo 
  
 responsiveSearchAd 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 ResponsiveSearchAdInfo 
 - 
> new 
 ({ 
  
 headlines 
  
 = 
>  
 [ 
  
 $pinned_headline 
 , 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 2 testing" 
 ), 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 3 testing" 
 ), 
  
 ], 
  
 descriptions 
  
 = 
>  
 [ 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Desc 1 testing" 
 ), 
  
 defined 
  
 $customizer_attribute_name 
  
 ? 
  
 create_ad_text_asset_with_customizer 
 ( 
 $api_client 
 , 
  
 $customizer_attribute_name 
 ) 
  
 : 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Desc 2 testing" 
 ), 
  
 ], 
  
 # First and second part of text that can be appended to the URL in the ad. 
  
 # If you use the examples below, the ad will show 
  
 # https://www.example.com/all-inclusive/deals 
  
 path1 
  
 = 
>  
 "all-inclusive" 
 , 
  
 path2 
  
 = 
>  
 "deals" 
  
 } 
  
 ), 
  
 finalUrls 
  
 = 
>  
 [ 
 "https://www.example.com" 
 ]})}); 
  
 # Create an ad group ad operation. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService:: 
 AdGroupAdOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group_ad 
  
 }); 
  
 # Issue a mutate request to add the ad group ad and print its information. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> AdGroupAdService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 printf 
  
 "Created responsive search ad with resource name '%s'.\n" 
 , 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
 } 
 # Creates keywords of 3 keyword match types: EXACT, PHRASE, and BROAD. 
 # EXACT: ads may show on searches that ARE the same meaning as your keyword. 
 # PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
 # BROAD: ads may show on searches that RELATE to your keyword. 
 # For smart bidding, BROAD is the recommended one. 
 sub 
  
 add_keywords 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $operations 
  
 = 
  
 [] 
 ; 
  
 # Create a hash of keyword match types to keyword text to simplify ad group 
  
 # criteria construction. 
  
 my 
  
 $keywords 
  
 = 
  
 { 
  
 EXACT 
 () 
  
 = 
>  
 KEYWORD_TEXT_EXACT 
 , 
  
 BROAD 
 () 
  
 = 
>  
 KEYWORD_TEXT_BROAD 
 , 
  
 PHRASE 
 () 
  
 = 
>  
 KEYWORD_TEXT_PHRASE 
 , 
  
 }; 
  
 foreach 
  
 my 
  
 $keyword 
  
 ( 
 keys 
  
 %$keywords 
 ) 
  
 { 
  
 my 
  
 $keyword_info 
  
 = 
  
 Google::Ads::GoogleAds::V21::Common:: 
 KeywordInfo 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 $keywords 
 - 
> { 
 $keyword 
 }, 
  
 matchType 
  
 = 
>  
 $keyword 
 , 
  
 }); 
  
 my 
  
 $ad_group_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupCriterion 
 - 
> new 
 ({ 
  
 adGroup 
  
 = 
>  
 $ad_group_resource_name 
 , 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::AdGroupCriterionStatusEnum:: 
 ENABLED 
 , 
  
 keyword 
  
 = 
>  
 $keyword_info 
 , 
  
 # Uncomment the below line if you want to change this keyword to a negative target. 
  
 # negative => "true", 
  
 # Optional repeated field. 
  
 # finalUrls => ["https://www.example.com"], 
  
 }); 
  
 my 
  
 $ad_group_criterion_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCriterionService:: 
 AdGroupCriterionOperation 
  
 - 
> new 
 ({ 
 create 
  
 = 
>  
 $ad_group_criterion 
 }); 
  
 push 
  
 @$operations 
 , 
  
 $ad_group_criterion_operation 
 ; 
  
 } 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> AdGroupCriterionService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 $operations 
  
 }); 
  
 foreach 
  
 my 
  
 $result 
  
 ( 
 @ 
 { 
 $response 
 - 
> { 
 results 
 }}) 
  
 { 
  
 printf 
  
 "Created keyword with resource name: '%s'.\n" 
 , 
  
 $result 
 - 
> { 
 resourceName 
 }; 
  
 } 
 } 
 # Creates geo targets. 
 sub 
  
 add_geo_targeting 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $suggest_response 
  
 = 
  
 $api_client 
 - 
> GeoTargetConstantService 
 () 
 - 
> suggest 
 ({ 
  
 locale 
  
 = 
>  
 LOCALE 
 , 
  
 countryCode 
  
 = 
>  
 COUNTRY_CODE 
 , 
  
 locationNames 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Services::GeoTargetConstantService:: 
 LocationNames 
  
 - 
> new 
 ({ 
  
 names 
  
 = 
>  
 [ 
 GEO_LOCATION_1 
 , 
  
 GEO_LOCATION_2 
 , 
  
 GEO_LOCATION_3 
 ]})}); 
  
 my 
  
 $operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $geo_target_constant_suggestion 
  
 ( 
  
 @ 
 { 
 $suggest_response 
 - 
> { 
 geoTargetConstantSuggestions 
 }}) 
  
 { 
  
 printf 
  
 "geo target constant: '%s' is found in locale '%s' with reach %d" 
  
 . 
  
 " for the search term '%s'.\n" 
 , 
  
 $geo_target_constant_suggestion 
 - 
> { 
 geoTargetConstant 
 }{ 
 resourceName 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 locale 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 reach 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 searchTerm 
 }; 
  
 # Create the campaign criterion for location targeting. 
  
 my 
  
 $campaign_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CampaignCriterion 
 - 
> new 
 ({ 
  
 location 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 LocationInfo 
 - 
> new 
 ({ 
  
 geoTargetConstant 
  
 = 
>  
 $geo_target_constant_suggestion 
 - 
> { 
 geoTargetConstant 
 }{ 
 resourceName 
 } 
  
 } 
  
 ), 
  
 campaign 
  
 = 
>  
 $campaign_resource_name 
  
 }); 
  
 push 
  
 @$operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::CampaignCriterionService:: 
 CampaignCriterionOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign_criterion 
  
 }); 
  
 } 
  
 # Return if operations is empty. 
  
 if 
  
 ( 
 scalar 
  
 @$operations 
  
 == 
  
 0 
 ) 
  
 { 
  
 return 
 ; 
  
 } 
  
 my 
  
 $campaign_criterion_response 
  
 = 
  
 $api_client 
 - 
> CampaignCriterionService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 $operations 
  
 }); 
  
 my 
  
 $campaign_criterion_results 
  
 = 
  
 $campaign_criterion_response 
 - 
> { 
 results 
 }; 
  
 printf 
  
 "Added %d campaign criteria:\n" 
 , 
  
 scalar 
  
 @$campaign_criterion_results 
 ; 
  
 foreach 
  
 my 
  
 $campaign_criterion_result 
  
 ( 
 @$campaign_criterion_results 
 ) 
  
 { 
  
 printf 
  
 "\t%s\n" 
 , 
  
 $campaign_criterion_result 
 - 
> { 
 resourceName 
 }; 
  
 } 
 } 
 # Don't run the example if the file is being included. 
 if 
  
 ( 
 abs_path 
 ( 
 $0 
 ) 
  
 ne 
  
 abs_path 
 ( 
 __FILE__ 
 )) 
  
 { 
  
 return 
  
 1 
 ; 
 } 
 # Get Google Ads Client, credentials will be read from ~/googleads.properties. 
 my 
  
 $api_client 
  
 = 
  
 Google::Ads::GoogleAds:: 
 Client 
 - 
> new 
 (); 
 # By default examples are set to die on any server returned fault. 
 $api_client 
 - 
> set_die_on_faults 
 ( 
 1 
 ); 
 my 
  
 $customer_id 
 ; 
 my 
  
 $customizer_attribute_name 
 ; 
 # Parameters passed on the command line will override any parameters set in code. 
 GetOptions 
 ( 
  
 "customer_id=s" 
  
 = 
>  
 \ 
 $customer_id 
 , 
  
 "customizer_attribute_name=s" 
  
 = 
>  
 \ 
 $customizer_attribute_name 
 , 
 ); 
 # Print the help message if the parameters are not initialized in the code nor 
 # in the command line. 
 pod2usage 
 ( 
 2 
 ) 
  
 if 
  
 not 
  
 check_params 
 ( 
 $customer_id 
 ); 
 # Call the example. 
 add_responsive_search_ad_full 
 ( 
 $api_client 
 , 
  
 $customer_id 
  
 =~ 
  
 s/-//g 
 r 
 , 
  
 $customizer_attribute_name 
 ); 
 =pod 
 =head1 NAME 
 add_responsive_search_ad_full 
 =head1 DESCRIPTION 
 This example shows how to create a complete Responsive Search ad. 
 Includes creation of: budget, campaign, ad group, ad group ad, keywords, 
 and geo targeting. More details on Responsive Search ads can be found here: 
 https://support.google.com/google-ads/answer/7684791 
 =head1 SYNOPSIS 
 add_responsive_search_ad_full.pl [options] 
 -help                           Show the help message. 
 -customer_id                    The Google Ads customer ID. 
 -customizer_attribute_name      [optional] The name of the customizer attribute. 
 =cut 
  
  

Best Practices

  • Pause new campaigns or ads during setup: This prevents them from serving while incomplete, creating a better user experience and campaign performance from the start.
  • Use shared negative keyword lists : These help you exclude irrelevant search queries, improving traffic quality and ad spend efficiency.
  • Implement conversion tracking : This lets you measure actions that align with your business goals (like sales or sign-ups) and optimize your campaigns accordingly.
Design a Mobile Site
View Site in Mobile | Classic
Share by: