Java
// Copyright 2020 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. package com.google.ads.googleads.examples.advancedoperations; import static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime; import com.beust.jcommander.Parameter; import com.google.ads.googleads.examples.utils.ArgumentNames; import com.google.ads.googleads.examples.utils.CodeSampleParams; import com.google.ads.googleads.lib.GoogleAdsClient; import com.google.ads.googleads.lib.utils.FieldMasks; import com.google.ads.googleads.v11.common.WebpageConditionInfo; import com.google.ads.googleads.v11.common.WebpageInfo; import com.google.ads.googleads.v11.enums.DsaPageFeedCriterionFieldEnum.DsaPageFeedCriterionField; import com.google.ads.googleads.v11.enums.FeedAttributeTypeEnum.FeedAttributeType; import com.google.ads.googleads.v11.enums.FeedMappingCriterionTypeEnum.FeedMappingCriterionType; import com.google.ads.googleads.v11.enums.WebpageConditionOperandEnum.WebpageConditionOperand; import com.google.ads.googleads.v11.errors.GoogleAdsError; import com.google.ads.googleads.v11.errors.GoogleAdsException; import com.google.ads.googleads.v11.resources.AdGroupCriterion; import com.google.ads.googleads.v11.resources.AttributeFieldMapping; import com.google.ads.googleads.v11.resources.Campaign; import com.google.ads.googleads.v11.resources.Campaign.DynamicSearchAdsSetting; import com.google.ads.googleads.v11.resources.Feed; import com.google.ads.googleads.v11.resources.FeedAttribute; import com.google.ads.googleads.v11.resources.FeedItem; import com.google.ads.googleads.v11.resources.FeedItemAttributeValue; import com.google.ads.googleads.v11.resources.FeedMapping; import com.google.ads.googleads.v11.services.AdGroupCriterionOperation; import com.google.ads.googleads.v11.services.AdGroupCriterionServiceClient; import com.google.ads.googleads.v11.services.CampaignOperation; import com.google.ads.googleads.v11.services.CampaignServiceClient; import com.google.ads.googleads.v11.services.FeedItemOperation; import com.google.ads.googleads.v11.services.FeedItemServiceClient; import com.google.ads.googleads.v11.services.FeedMappingOperation; import com.google.ads.googleads.v11.services.FeedMappingServiceClient; import com.google.ads.googleads.v11.services.FeedOperation; import com.google.ads.googleads.v11.services.FeedServiceClient; import com.google.ads.googleads.v11.services.GoogleAdsRow; import com.google.ads.googleads.v11.services.GoogleAdsServiceClient; import com.google.ads.googleads.v11.services.GoogleAdsServiceClient.SearchPagedResponse; import com.google.ads.googleads.v11.services.MutateAdGroupCriteriaResponse; import com.google.ads.googleads.v11.services.MutateCampaignsResponse; import com.google.ads.googleads.v11.services.MutateFeedItemResult; import com.google.ads.googleads.v11.services.MutateFeedItemsResponse; import com.google.ads.googleads.v11.services.MutateFeedMappingsResponse; import com.google.ads.googleads.v11.services.MutateFeedsResponse; import com.google.ads.googleads.v11.services.SearchGoogleAdsRequest; import com.google.ads.googleads.v11.utils.ResourceNames; import com.google.common.collect.ImmutableList; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Adds a page feed with URLs for a Dynamic Search Ads Campaign. */ // DEPRECATION WARNING! // Feed-services based DSA page feeds are deprecated and being replaced with assets. See // AddDynamicPageFeedAsset.java. public class AddDynamicPageFeed { private static final int PAGE_SIZE = 1_000; private static class AddDynamicPageFeedParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true) private Long campaignId; @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true) private Long adGroupId; } public static void main(String[] args) { AddDynamicPageFeedParams params = new AddDynamicPageFeedParams(); if (!params.parseArguments(args)) { // Either pass the required parameters for this example on the command line, or insert them // into the code here. See the parameter class definition above for descriptions. params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE"); params.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE"); params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE"); } GoogleAdsClient googleAdsClient = null; try { googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build(); } catch (FileNotFoundException fnfe) { System.err.printf( "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe); System.exit(1); } catch (IOException ioe) { System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe); System.exit(1); } try { new AddDynamicPageFeed() .runExample(googleAdsClient, params.customerId, params.campaignId, params.adGroupId); } catch (GoogleAdsException gae) { // GoogleAdsException is the base class for most exceptions thrown by an API request. // Instances of this exception have a message and a GoogleAdsFailure that contains a // collection of GoogleAdsErrors that indicate the underlying causes of the // GoogleAdsException. System.err.printf( "Request ID %s failed due to GoogleAdsException. Underlying errors:%n", gae.getRequestId()); int i = 0; for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) { System.err.printf(" Error %d: %s%n", i++, googleAdsError); } System.exit(1); } } /** * Runs the example. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param campaignId the campaign ID. * @param adGroupId the ad group ID. * @throws GoogleAdsException if an API request failed with one or more service errors. */ private void runExample( GoogleAdsClient googleAdsClient, long customerId, long campaignId, long adGroupId) { // The label for the DSA page URLs. String dsaPageUrlLabel = "discounts"; // Creates the page feed details. This code example creates a new feed, but you can // fetch and re-use an existing feed. String feedResourceName = createFeed(googleAdsClient, customerId); Map<String, Long> feedDetails = getFeed(googleAdsClient, customerId, feedResourceName); createFeedMapping(googleAdsClient, customerId, feedDetails, feedResourceName); createFeedItems(googleAdsClient, customerId, feedDetails, feedResourceName, dsaPageUrlLabel); // Associates the page feed with the campaign. updateCampaignDsaSetting(googleAdsClient, customerId, feedResourceName, campaignId); // Optional: Targets web pages matching the feed's label in the ad group. addDsaTarget(googleAdsClient, customerId, adGroupId, dsaPageUrlLabel); System.out.printf("Dynamic page feed setup is complete for campaign with ID %d.%n", campaignId); } /** * Creates a feed. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID in which to create the feed. * @return the resource name of the newly created feed. */ private static String createFeed(GoogleAdsClient googleAdsClient, long customerId) { // Creates a URL attribute. FeedAttribute urlAttribute = FeedAttribute.newBuilder().setType(FeedAttributeType.URL_LIST).setName("Page URL").build(); // Creates a label attribute. FeedAttribute labelAttribute = FeedAttribute.newBuilder().setType(FeedAttributeType.STRING_LIST).setName("Label").build(); // Creates the feed. Feed feed = Feed.newBuilder() .setName("DSA Feed #" + getPrintableDateTime()) .addAllAttributes(ImmutableList.of(urlAttribute, labelAttribute)) .build(); // Creates a feed operation for creating a feed. FeedOperation feedOperation = FeedOperation.newBuilder().setCreate(feed).build(); // Creates a feed service client. try (FeedServiceClient feedServiceClient = googleAdsClient.getLatestVersion().createFeedServiceClient()) { // Adds the feed. MutateFeedsResponse feedResponse = feedServiceClient.mutateFeeds(Long.toString(customerId), ImmutableList.of(feedOperation)); String feedResourceName = feedResponse.getResults(0).getResourceName(); System.out.printf("Added feed named '%s'.%n", feedResourceName); return feedResourceName; } } /** * Retrieves details about a feed. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param feedResourceName the resource name of the feed. * @return a map of the names and IDs of feed attributes. */ private static Map<String, Long> getFeed( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName) { String query = String.format( "SELECT feed.attributes FROM feed WHERE feed.resource_name = '%s'", feedResourceName); // Creates the request. SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setPageSize(PAGE_SIZE) .setQuery(query) .build(); // Creates the service client. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Issues the search request. SearchPagedResponse response = googleAdsServiceClient.search(request); // Gets the first result because we only need the single feed item we created previously. GoogleAdsRow googleAdsRow = response.getPage().getResponse().getResults(0); // Gets the attributes list from the feed and creates a map with keys of each attribute and // values of each corresponding ID. List<FeedAttribute> feedAttributes = googleAdsRow.getFeed().getAttributesList(); // Creates a map to return. Map<String, Long> feedDetails = new HashMap<>(); // Adds each of the feed attributes and IDs to the map. for (FeedAttribute feedAttribute : feedAttributes) { feedDetails.put(feedAttribute.getName(), feedAttribute.getId()); } return feedDetails; } } /** * Creates a feed mapping for a given feed. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param feedDetails a map of the names and IDs of feed attributes. * @param feedResourceName the resource name of the feed. */ private static void createFeedMapping( GoogleAdsClient googleAdsClient, long customerId, Map<String, Long> feedDetails, String feedResourceName) { // Maps the feed attribute IDs to the field ID constants. AttributeFieldMapping urlFieldMapping = AttributeFieldMapping.newBuilder() .setFeedAttributeId(feedDetails.get("Page URL")) .setDsaPageFeedField(DsaPageFeedCriterionField.PAGE_URL) .build(); AttributeFieldMapping labelFieldMapping = AttributeFieldMapping.newBuilder() .setFeedAttributeId(feedDetails.get("Label")) .setDsaPageFeedField(DsaPageFeedCriterionField.LABEL) .build(); // Creates the feed mapping. FeedMapping feedMapping = FeedMapping.newBuilder() .setCriterionType(FeedMappingCriterionType.DSA_PAGE_FEED) .setFeed(feedResourceName) .addAllAttributeFieldMappings(ImmutableList.of(urlFieldMapping, labelFieldMapping)) .build(); // Creates the operation. FeedMappingOperation operation = FeedMappingOperation.newBuilder().setCreate(feedMapping).build(); // Creates the service client. try (FeedMappingServiceClient feedMappingServiceClient = googleAdsClient.getLatestVersion().createFeedMappingServiceClient()) { // Adds the feed mapping. MutateFeedMappingsResponse response = feedMappingServiceClient.mutateFeedMappings( Long.toString(customerId), ImmutableList.of(operation)); // Displays the results. System.out.printf( "Created feed maping with resource name '%s'.%n", response.getResults(0).getResourceName()); } } /** * Creates feed items for a given feed. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param feedDetails a map of the names and IDs of feed attributes. * @param feedResourceName the resource name of the feed. * @param dsaPageUrlLabel the label for the DSA page URLs. */ private static void createFeedItems( GoogleAdsClient googleAdsClient, long customerId, Map<String, Long> feedDetails, String feedResourceName, String dsaPageUrlLabel) { List<String> urls = ImmutableList.of( "http://www.example.com/discounts/rental-cars", "http://www.example.com/discounts/hotel-deals", "http://www.example.com/discounts/flight-deals"); // Creates a value for the label attribute. FeedItemAttributeValue labelAttributeValue = FeedItemAttributeValue.newBuilder() .setFeedAttributeId(feedDetails.get("Label")) .addAllStringValues(ImmutableList.of(dsaPageUrlLabel)) .build(); // Creates one operation per URL. List<FeedItemOperation> feedItemOperations = new ArrayList<>(); for (String url : urls) { // Creates a url attribute. FeedItemAttributeValue urlAttributeValue = FeedItemAttributeValue.newBuilder() .setFeedAttributeId(feedDetails.get("Page URL")) .addAllStringValues(ImmutableList.of(url)) .build(); // Creates a feed item. FeedItem feedItem = FeedItem.newBuilder() .setFeed(feedResourceName) .addAllAttributeValues(ImmutableList.of(urlAttributeValue, labelAttributeValue)) .build(); // Creates an operation and adds it to the list of operations. FeedItemOperation feedItemOperation = FeedItemOperation.newBuilder().setCreate(feedItem).build(); feedItemOperations.add(feedItemOperation); } // Creates the service client. try (FeedItemServiceClient feedItemServiceClient = googleAdsClient.getLatestVersion().createFeedItemServiceClient()) { // Adds the feed items. MutateFeedItemsResponse response = feedItemServiceClient.mutateFeedItems(Long.toString(customerId), feedItemOperations); // Displays the results. for (MutateFeedItemResult result : response.getResultsList()) { System.out.printf("Created feed item with resource name '%s'.%n", result.getResourceName()); } } } /** * Updates a campaign to set the DSA feed. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param feedResourceName the resource name of the feed. * @param campaignId the campaign ID of the campaign to update. */ private static void updateCampaignDsaSetting( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName, long campaignId) { // Retrieves the existing dynamic search ads settings for the campaign. DynamicSearchAdsSetting dsaSetting = getDsaSetting(googleAdsClient, customerId, campaignId); dsaSetting.toBuilder().addAllFeeds(ImmutableList.of(feedResourceName)).build(); // Creates the campaign object to update. Campaign campaign = Campaign.newBuilder() .setResourceName(ResourceNames.campaign(customerId, campaignId)) .setDynamicSearchAdsSetting(dsaSetting) .build(); // Creates the update operation and sets the update mask. CampaignOperation operation = CampaignOperation.newBuilder() .setUpdate(campaign) .setUpdateMask(FieldMasks.allSetFieldsOf(campaign)) .build(); // Creates the service client. try (CampaignServiceClient campaignServiceClient = googleAdsClient.getLatestVersion().createCampaignServiceClient()) { // Updates the campaign. MutateCampaignsResponse response = campaignServiceClient.mutateCampaigns( Long.toString(customerId), ImmutableList.of(operation)); // Displays the results. System.out.printf( "Updated campaign with resource name '%s'.%n", response.getResults(0).getResourceName()); } } /** * Returns the DSA settings for a campaign. Throws an error if the campaign does not exist or is * not a DSA campaign. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param campaignId the campaign ID of the campaign to update. * @return the DSA settings for the campaign. */ private static DynamicSearchAdsSetting getDsaSetting( GoogleAdsClient googleAdsClient, long customerId, long campaignId) { // Creates the query. String query = String.format( "SELECT campaign.id, " + " campaign.name, " + " campaign.dynamic_search_ads_setting.use_supplied_urls_only " + "FROM campaign " + "WHERE campaign.id = '%s'", campaignId); // Creates the request. SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setPageSize(PAGE_SIZE) .setQuery(query) .build(); // Creates the service client. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Issues the search request. SearchPagedResponse response = googleAdsServiceClient.search(request); // Throws an exception if the campaign is not a DSA campaign. // The server will return an error when trying to update the campaign with the DSA feed in // the following step if the campaign is not a DSA campaign. However, this // exception is easier to interpret. if (!response .getPage() .getResponse() .getResults(0) .getCampaign() .hasDynamicSearchAdsSetting()) { throw new IllegalArgumentException("Campaign with ID '%s' is not a DSA campaign."); } // Retrieves and returns the DSA setting. return response .getPage() .getResponse() .getResults(0) .getCampaign() .getDynamicSearchAdsSetting(); } } /** * Creates an ad group criterion targeting the DSA label. * * @param googleAdsClient the Google Ads API client. * @param customerId the customer ID. * @param adGroupId the ad group ID. * @param dsaPageUrlLabel the label for the DSA page URLs. */ private static void addDsaTarget( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, String dsaPageUrlLabel) { String adGroupResourceName = ResourceNames.adGroup(customerId, adGroupId); // Creates the webpage condition info that targets an advertiser's webpages based on the // custom label specified by the dsaPageUrlLabel (e.g. "discounts"). WebpageConditionInfo webpageConditionInfo = WebpageConditionInfo.newBuilder() .setOperand(WebpageConditionOperand.CUSTOM_LABEL) .setArgument(dsaPageUrlLabel) .build(); // Creates the webpage info, or criterion for targeting webpages of an advertiser's website. WebpageInfo webpageInfo = WebpageInfo.newBuilder() .setCriterionName("Test Criterion") .addAllConditions(ImmutableList.of(webpageConditionInfo)) .build(); // Creates the ad group criterion. AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() .setAdGroup(adGroupResourceName) .setWebpage(webpageInfo) .setCpcBidMicros(1_500_000) .build(); // Creates the operation. AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build(); // Creates the service client. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Adds the ad group criterion. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), ImmutableList.of(operation)); // Displays the results. System.out.printf( "Created ad group criterion with resource name '%s'.%n", response.getResults(0).getResourceName()); } } }
C#
// Copyright 2019 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.V11.Common; using Google.Ads.GoogleAds.V11.Errors; using Google.Ads.GoogleAds.V11.Resources; using Google.Ads.GoogleAds.V11.Services; using System; using System.Collections.Generic; using System.Linq; using static Google.Ads.GoogleAds.V11.Enums.DsaPageFeedCriterionFieldEnum.Types; using static Google.Ads.GoogleAds.V11.Enums.FeedAttributeTypeEnum.Types; using static Google.Ads.GoogleAds.V11.Enums.FeedMappingCriterionTypeEnum.Types; using static Google.Ads.GoogleAds.V11.Enums.WebpageConditionOperandEnum.Types; using static Google.Ads.GoogleAds.V11.Resources.Campaign.Types; namespace Google.Ads.GoogleAds.Examples.V11 { /// <summary> /// This code example adds a page feed to specify precisely which URLs to use with your /// Dynamic Search Ads. /// </summary> [Obsolete("Feed-services based DSA page feeds are deprecated and being replaced with " + "assets. See AddDynamicPageFeedAsset.cs.")] public class AddDynamicPageFeed : ExampleBase { /// <summary> /// Command line options for running the <see cref="AddDynamicPageFeed"/> example. /// </summary> public class Options : OptionsBase { /// <summary> /// The Google Ads customer ID for which the call is made. /// </summary> [Option("customerId", Required = true, HelpText = "The Google Ads customer ID for which the call is made.")] public long CustomerId { get; set; } /// <summary> /// ID of the campaign for which dynamic page feeds are added. /// </summary> [Option("campaignId", Required = true, HelpText = "ID of the campaign for which dynamic page feeds are added.")] public long CampaignId { get; set; } /// <summary> /// ID of the ad group for which dynamic page feeds are added. /// </summary> [Option("adGroupId", Required = true, HelpText = "ID of the ad group for which dynamic page feeds are added.")] public long AdGroupId { 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); AddDynamicPageFeed codeExample = new AddDynamicPageFeed(); Console.WriteLine(codeExample.Description); codeExample.Run(new GoogleAdsClient(), options.CustomerId, options.CampaignId, options.AdGroupId); } /// <summary> /// Returns a description about the code example. /// </summary> public override string Description => "This code example adds a page feed to specify precisely which URLs to use with " + "your Dynamic Search Ads."; /// <summary> /// Runs the code example. /// </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="campaignId">ID of the campaign for which dynamic page feeds are added. /// </param> /// <param name="adGroupId">ID of the ad group for which dynamic page feeds are added. /// </param> public void Run(GoogleAdsClient client, long customerId, long campaignId, long adGroupId) { try { string dsaPageUrlLabel = "discounts"; // Get the page feed details. This code example creates a new feed, but you can // fetch and re-use an existing feed. string feedResourceName = CreateFeed(client, customerId); Dictionary<DsaPageFeedCriterionField, FeedAttribute> feedAttributes = GetFeed(client, customerId, feedResourceName); CreateFeedMapping(client, customerId, feedResourceName, feedAttributes); CreateFeedItems(client, customerId, feedResourceName, feedAttributes, dsaPageUrlLabel); // Associates the page feed with the campaign. UpdateCampaignDsaSetting(client, customerId, feedResourceName, campaignId); // Optional: Targets web pages matching the feed's label in the ad group. AddDsaTarget(client, customerId, adGroupId, dsaPageUrlLabel); Console.WriteLine($"Dynamic page feed setup is complete for campaign " + $"ID {campaignId}"); } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } } /// <summary> /// Creates the feed. /// </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 resource name of the newly created feed.</returns> private string CreateFeed(GoogleAdsClient client, long customerId) { // Get the FeedService. FeedServiceClient feedService = client.GetService(Services.V11.FeedService); // Create a URL attribute. FeedAttribute urlAttribute = new FeedAttribute() { Type = FeedAttributeType.UrlList, Name = "Page URL" }; // Create a label attribute. FeedAttribute labelAttribute = new FeedAttribute() { Type = FeedAttributeType.StringList, Name = "Label" }; // Create the feed. Feed feed = new Feed() { Name = "DSA Feed #" + ExampleUtilities.GetRandomString(), Attributes = { urlAttribute, labelAttribute } }; // Create the operation. FeedOperation operation = new FeedOperation() { Create = feed }; // Add the feed. MutateFeedsResponse response = feedService.MutateFeeds(customerId.ToString(), new[] { operation }); string feedResourceName = response.Results[0].ResourceName; // Display the result. Console.WriteLine($"Feed with resource name '{feedResourceName}' was created."); return feedResourceName; } /// <summary> /// Retrieves details about a feed. /// </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="feedResourceName">The feed resource name.</param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> private Dictionary<DsaPageFeedCriterionField, FeedAttribute> GetFeed( GoogleAdsClient client, long customerId, string feedResourceName) { // Get the GoogleAdsService. GoogleAdsServiceClient googleAdsService = client.GetService( Services.V11.GoogleAdsService); // Construct the query. String query = $"SELECT feed.attributes FROM feed WHERE feed.resource_name" + $" = '{feedResourceName}'"; // Construct the request. SearchGoogleAdsRequest request = new SearchGoogleAdsRequest() { CustomerId = customerId.ToString(), Query = query }; // Issue the search request. Feed feed = googleAdsService.Search(customerId.ToString(), query).First().Feed; Dictionary<DsaPageFeedCriterionField, FeedAttribute> retval = new Dictionary<DsaPageFeedCriterionField, FeedAttribute>(); foreach (FeedAttribute attribute in feed.Attributes) { DsaPageFeedCriterionField key; switch (attribute.Name) { case "Page URL": key = DsaPageFeedCriterionField.PageUrl; break; case "Label": key = DsaPageFeedCriterionField.Label; break; default: throw new Exception("Unable to map attribute name to DSA page feed" + " criterion."); } retval[key] = attribute; } return retval; } /// <summary> /// Creates a feed mapping for a given feed. /// </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="feedResourceName">The feed resource for which feed mapping is created. /// </param> /// <param name="feedAttributes">The feed attributes.</param> private void CreateFeedMapping(GoogleAdsClient client, long customerId, string feedResourceName, Dictionary<DsaPageFeedCriterionField, FeedAttribute> feedAttributes) { // Get the FeedMappingService. FeedMappingServiceClient feedMappingService = client.GetService( Services.V11.FeedMappingService); FeedMapping feedMapping = new FeedMapping() { CriterionType = FeedMappingCriterionType.DsaPageFeed, Feed = feedResourceName, // Map the FeedAttributeId to the fieldId constants. AttributeFieldMappings = { new AttributeFieldMapping() { FeedAttributeId = feedAttributes[DsaPageFeedCriterionField.PageUrl].Id, DsaPageFeedField = DsaPageFeedCriterionField.PageUrl }, new AttributeFieldMapping() { FeedAttributeId = feedAttributes[DsaPageFeedCriterionField.Label].Id, DsaPageFeedField = DsaPageFeedCriterionField.Label } } }; // Create the operation. FeedMappingOperation operation = new FeedMappingOperation() { Create = feedMapping }; // Add the FeedMapping. MutateFeedMappingsResponse response = feedMappingService.MutateFeedMappings(customerId.ToString(), new[] { operation }); // Display the results. foreach (MutateFeedMappingResult result in response.Results) { Console.WriteLine($"Created feed mapping with resource name" + $" '{result.ResourceName}'"); } } /// <summary> /// Creates feed items for a given feed. /// </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="feedResourceName">The feed resource for which feed items are created. /// </param> /// <param name="feedAttributes">The feed attributes.</param> /// <param name="dsaPageUrlLabel">The DSA page URL label.</param> private void CreateFeedItems(GoogleAdsClient client, long customerId, string feedResourceName, Dictionary<DsaPageFeedCriterionField, FeedAttribute> feedAttributes, string dsaPageUrlLabel) { // Get the FeedItemService. FeedItemServiceClient feedItemService = client.GetService( Services.V11.FeedItemService); List<string> urls = new List<string> { "http://www.example.com/discounts/rental-cars", "http://www.example.com/discounts/hotel-deals", "http://www.example.com/discounts/flight-deals" }; List<FeedItemOperation> operations = new List<FeedItemOperation>(); foreach (string url in urls) { // Create a feed item. FeedItem feedItem = new FeedItem() { Feed = feedResourceName, AttributeValues = { // Create a url attribute. new FeedItemAttributeValue() { FeedAttributeId = feedAttributes[DsaPageFeedCriterionField.PageUrl].Id, StringValue = url }, // Creates a label attribute. new FeedItemAttributeValue() { FeedAttributeId = feedAttributes[DsaPageFeedCriterionField.Label].Id, StringValue = dsaPageUrlLabel } } }; operations.Add(new FeedItemOperation() { Create = feedItem }); } // Add the feed items. MutateFeedItemsResponse response = feedItemService.MutateFeedItems(customerId.ToString(), operations); // Display the results. foreach (MutateFeedItemResult result in response.Results) { Console.WriteLine($"Created feed items with resource " + $"name '{result.ResourceName}'."); } } /// <summary> /// Updates a campaign to set the DSA feed. /// </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="feedResourceName">The DSA feed resource name</param> /// <param name="campaignId">ID of the campaign for which DSA settings are updated.</param> private void UpdateCampaignDsaSetting(GoogleAdsClient client, long customerId, string feedResourceName, long campaignId) { // Get the CampaignService. CampaignServiceClient campaignService = client.GetService( Services.V11.CampaignService); DynamicSearchAdsSetting dsaSetting = GetDsaSetting(client, customerId, campaignId); dsaSetting.Feeds.Add(feedResourceName); // Create the campaign. Campaign campaign = new Campaign() { ResourceName = ResourceNames.Campaign(customerId, campaignId), DynamicSearchAdsSetting = dsaSetting }; // Create the operation. CampaignOperation operation = new CampaignOperation() { Update = campaign, UpdateMask = FieldMasks.AllSetFieldsOf(campaign) }; // Update the campaign. MutateCampaignsResponse response = campaignService.MutateCampaigns(customerId.ToString(), new[] { operation }); // Display the results. foreach (MutateCampaignResult mutateCampaignResult in response.Results) { Console.WriteLine($"Updated campaign with resourceName: " + $"'{mutateCampaignResult.ResourceName}'."); } } /// <summary> /// Returns the DSA settings for a campaign. Throws an error if the campaign does not /// exist or is not a DSA 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="campaignId">ID of the campaign for which DSA settings are fetched.</param> /// <returns>The DSA settings.</returns> private DynamicSearchAdsSetting GetDsaSetting(GoogleAdsClient client, long customerId, long campaignId) { // Get the GoogleAdsService. GoogleAdsServiceClient googleAdsService = client.GetService( Services.V11.GoogleAdsService); // Creates the query. // You must request all DSA fields in order to update the DSA settings in the // following step. string query = $@"SELECT campaign.id, campaign.name, campaign.dynamic_search_ads_setting.use_supplied_urls_only FROM campaign WHERE campaign.id = {campaignId}"; GoogleAdsRow result = googleAdsService.Search( customerId.ToString(), query).FirstOrDefault(); if (result == null) { throw new Exception("No campaign found with ID: " + campaignId); } // Gets the DSA settings. DynamicSearchAdsSetting dynamicSearchAdsSetting = result.Campaign.DynamicSearchAdsSetting; // Throws an exception if the campaign is not a DSA campaign. if (dynamicSearchAdsSetting == null) { throw new Exception($"Campaign with ID {campaignId} is not a DSA campaign."); } return dynamicSearchAdsSetting; } private void AddDsaTarget(GoogleAdsClient client, long customerId, long adGroupId, string dsaPageUrlLabel) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService( Services.V11.AdGroupCriterionService); // Create the webpage condition info. WebpageConditionInfo webpageConditionInfo = new WebpageConditionInfo() { Operand = WebpageConditionOperand.CustomLabel, Argument = dsaPageUrlLabel, }; // Creates the webpage info. WebpageInfo webpageInfo = new WebpageInfo() { CriterionName = "Test Criterion", Conditions = { webpageConditionInfo } }; // Creates the ad group criterion. AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), Webpage = webpageInfo, CpcBidMicros = 1_500_000 }; // Create the operation. AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { Create = adGroupCriterion }; // Add the ad group criterion. MutateAdGroupCriteriaResponse mutateAdGroupCriteriaResponse = adGroupCriterionService.MutateAdGroupCriteria(customerId.ToString(), new[] { operation }); // Display the results. foreach (MutateAdGroupCriterionResult result in mutateAdGroupCriteriaResponse.Results) { Console.WriteLine($"Created ad group criterion with resource name " + $"'{result.ResourceName}'."); } } } }
PHP
<?php /** * Copyright 2019 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. */ namespace Google\Ads\GoogleAds\Examples\AdvancedOperations; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Examples\Utils\Helper; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V11\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V11\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V11\GoogleAdsException; use Google\Ads\GoogleAds\Util\FieldMasks; use Google\Ads\GoogleAds\Util\V11\ResourceNames; use Google\Ads\GoogleAds\V11\Common\WebpageConditionInfo; use Google\Ads\GoogleAds\V11\Common\WebpageInfo; use Google\Ads\GoogleAds\V11\Enums\DsaPageFeedCriterionFieldEnum\DsaPageFeedCriterionField; use Google\Ads\GoogleAds\V11\Enums\FeedAttributeTypeEnum\FeedAttributeType; use Google\Ads\GoogleAds\V11\Enums\FeedMappingCriterionTypeEnum\FeedMappingCriterionType; use Google\Ads\GoogleAds\V11\Enums\FeedOriginEnum\FeedOrigin; use Google\Ads\GoogleAds\V11\Enums\WebpageConditionOperandEnum\WebpageConditionOperand; use Google\Ads\GoogleAds\V11\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V11\Resources\AdGroupCriterion; use Google\Ads\GoogleAds\V11\Resources\AttributeFieldMapping; use Google\Ads\GoogleAds\V11\Resources\Campaign; use Google\Ads\GoogleAds\V11\Resources\Campaign\DynamicSearchAdsSetting; use Google\Ads\GoogleAds\V11\Resources\Feed; use Google\Ads\GoogleAds\V11\Resources\FeedAttribute; use Google\Ads\GoogleAds\V11\Resources\FeedItem; use Google\Ads\GoogleAds\V11\Resources\FeedItemAttributeValue; use Google\Ads\GoogleAds\V11\Resources\FeedMapping; use Google\Ads\GoogleAds\V11\Services\AdGroupCriterionOperation; use Google\Ads\GoogleAds\V11\Services\CampaignOperation; use Google\Ads\GoogleAds\V11\Services\FeedItemOperation; use Google\Ads\GoogleAds\V11\Services\FeedMappingOperation; use Google\Ads\GoogleAds\V11\Services\FeedOperation; use Google\ApiCore\ApiException; /** * This code example adds a page feed to specify precisely which URLs to use with your Dynamic * Search Ads campaign. */ // DEPRECATION WARNING! // Feed-services based DSA page feeds are deprecated and being replaced with assets. See // AddDynamicPageFeedAsset.php. class AddDynamicPageFeed { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; private const CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE'; private const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'; private const PAGE_SIZE = 1000; public static function main() { // Either pass the required parameters for this example on the command line, or insert them // into the constants above. $options = (new ArgumentParser())->parseCommandArguments([ ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT, ArgumentNames::CAMPAIGN_ID => GetOpt::REQUIRED_ARGUMENT, ArgumentNames::AD_GROUP_ID => GetOpt::REQUIRED_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. $googleAdsClient = (new GoogleAdsClientBuilder())->fromFile() ->withOAuth2Credential($oAuth2Credential) ->build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID, $options[ArgumentNames::CAMPAIGN_ID] ?: self::CAMPAIGN_ID, $options[ArgumentNames::AD_GROUP_ID] ?: self::AD_GROUP_ID ); } catch (GoogleAdsException $googleAdsException) { printf( "Request with ID '%s' has failed.%sGoogle Ads failure details:%s", $googleAdsException->getRequestId(), PHP_EOL, PHP_EOL ); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( "ApiException was thrown with message '%s'.%s", $apiException->getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $campaignId the campaign ID * @param int $adGroupId the ad group ID */ public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, int $campaignId, int $adGroupId ) { $dsaPageUrlLabel = 'discounts'; // Creates the page feed details. This code example creates a new feed, but you can // fetch and re-use an existing feed. $feedDetails = self::createFeed($googleAdsClient, $customerId); self::createFeedMapping($googleAdsClient, $customerId, $feedDetails); self::createFeedItems($googleAdsClient, $customerId, $feedDetails, $dsaPageUrlLabel); // Associates the page feed with the campaign. self::updateCampaignDsaSetting($googleAdsClient, $customerId, $feedDetails, $campaignId); // Optional: Targets web pages matching the feed's label in the ad group. self::addDsaTarget($googleAdsClient, $customerId, $adGroupId, $dsaPageUrlLabel); printf("Dynamic page feed setup is complete for campaign ID %d.%s", $campaignId, PHP_EOL); } /** * Creates a feed. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID in which to create the feed * @return array the names and IDs of feed attributes */ private static function createFeed( GoogleAdsClient $googleAdsClient, int $customerId ) { // Creates a URL attribute. $urlAttribute = new FeedAttribute([ 'type' => FeedAttributeType::URL_LIST, 'name' => 'Page URL' ]); // Creates a label attribute. $labelAttribute = new FeedAttribute([ 'type' => FeedAttributeType::STRING_LIST, 'name' => 'Label' ]); // Creates the feed. $feed = new Feed([ 'name' => 'DSA Feed #' . Helper::getPrintableDatetime(), 'attributes' => [$urlAttribute, $labelAttribute], 'origin' => FeedOrigin::USER ]); // Creates a feed operation for creating a feed. $feedOperation = new FeedOperation(); $feedOperation->setCreate($feed); // Issues a mutate request to add the feed. $feedServiceClient = $googleAdsClient->getFeedServiceClient(); $feedResponse = $feedServiceClient->mutateFeeds($customerId, [$feedOperation]); $feedResourceName = $feedResponse->getResults()[0]->getResourceName(); printf("Added feed named '%s'.%s", $feedResourceName, PHP_EOL); return self::getFeed($googleAdsClient, $customerId, $feedResourceName); } /** * Retrieves details about a feed. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param string $feedResourceName the resource name of the feed * @return array the feed details containing the feed's resource name and the feed attributes' * names and values */ private static function getFeed( GoogleAdsClient $googleAdsClient, int $customerId, string $feedResourceName ) { $query = "SELECT feed.attributes FROM feed WHERE feed.resource_name = '$feedResourceName'"; $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $response = $googleAdsServiceClient->search($customerId, $query, ['pageSize' => self::PAGE_SIZE]); $feedAttributes = $response->getIterator()->current()->getFeed()->getAttributes(); $feedDetails = ['resource_name' => $feedResourceName]; foreach ($feedAttributes as $feedAttribute) { /** @var FeedAttribute $feedAttribute */ $feedDetails[$feedAttribute->getName()] = $feedAttribute->getId(); } return $feedDetails; } /** * Creates a feed mapping for a given feed. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param array $feedDetails the names and IDs of feed attributes */ private static function createFeedMapping( GoogleAdsClient $googleAdsClient, int $customerId, array $feedDetails ) { // Maps the feed attribute IDs to the field ID constants. $urlFieldMapping = new AttributeFieldMapping([ 'feed_attribute_id' => $feedDetails['Page URL'], 'dsa_page_feed_field' => DsaPageFeedCriterionField::PAGE_URL ]); $labelFieldMapping = new AttributeFieldMapping([ 'feed_attribute_id' => $feedDetails['Label'], 'dsa_page_feed_field' => DsaPageFeedCriterionField::LABEL ]); // Creates the feed mapping. $feedMapping = new FeedMapping([ 'criterion_type' => FeedMappingCriterionType::DSA_PAGE_FEED, 'feed' => $feedDetails['resource_name'], 'attribute_field_mappings' => [$urlFieldMapping, $labelFieldMapping] ]); // Creates the operation. $feedMappingOperation = new FeedMappingOperation(); $feedMappingOperation->setCreate($feedMapping); // Issues a mutate request to add the feed mapping. $feedMappingServiceClient = $googleAdsClient->getFeedMappingServiceClient(); $response = $feedMappingServiceClient->mutateFeedMappings( $customerId, [$feedMappingOperation] ); // Displays the results. foreach ($response->getResults() as $result) { printf( "Created feed mapping with resource name '%s'.%s", $result->getResourceName(), PHP_EOL ); } } /** * Creates feed items for a given feed. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param array $feedDetails the names and IDs of feed attributes * @param string $dsaPageUrlLabel the label for the DSA page URLs */ private static function createFeedItems( GoogleAdsClient $googleAdsClient, int $customerId, array $feedDetails, string $dsaPageUrlLabel ) { $urls = [ 'http://www.example.com/discounts/rental-cars', 'http://www.example.com/discounts/hotel-deals', 'http://www.example.com/discounts/flight-deals' ]; // Creates a label attribute. $labelAttributeValue = new FeedItemAttributeValue([ 'feed_attribute_id' => $feedDetails['Label'], 'string_values' => [$dsaPageUrlLabel] ]); // Creates one operation per URL. $feedItemOperations = []; foreach ($urls as $url) { // Creates a url attribute. $urlAttributeValue = new FeedItemAttributeValue([ 'feed_attribute_id' => $feedDetails['Page URL'], 'string_values' => [$url] ]); // Creates a feed item. $feedItem = new FeedItem([ 'feed' => $feedDetails['resource_name'], 'attribute_values' => [$urlAttributeValue, $labelAttributeValue] ]); // Creates an operation and adds it to the list of operations. $feedItemOperation = new FeedItemOperation(); $feedItemOperation->setCreate($feedItem); $feedItemOperations[] = $feedItemOperation; } // Adds the feed items. $feedItemServiceClient = $googleAdsClient->getFeedItemServiceClient(); $response = $feedItemServiceClient->mutateFeedItems($customerId, $feedItemOperations); // Displays the results. foreach ($response->getResults() as $result) { printf( "Created feed item with resource name '%s'.%s", $result->getResourceName(), PHP_EOL ); } } /** * Updates a campaign to set the DSA feed. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param array $feedDetails the names and IDs of feed attributes * @param int $campaignId the campaign ID of the campaign to update */ private static function updateCampaignDsaSetting( GoogleAdsClient $googleAdsClient, int $customerId, array $feedDetails, int $campaignId ) { // Retrieves the existing dynamic search ads settings for the campaign. $dsaSetting = self::getDsaSetting( $googleAdsClient, $customerId, $campaignId ); $dsaSetting->setFeeds([$feedDetails['resource_name']]); // Creates the campaign object to be updated. $campaign = new Campaign([ 'resource_name' => ResourceNames::forCampaign($customerId, $campaignId), 'dynamic_search_ads_setting' => $dsaSetting ]); // Creates the update operation and sets the update mask. $campaignOperation = new CampaignOperation(); $campaignOperation->setUpdate($campaign); $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign)); // Updates the campaign. $campaignServiceClient = $googleAdsClient->getCampaignServiceClient(); $response = $campaignServiceClient->mutateCampaigns( $customerId, [$campaignOperation] ); // Displays the results. $campaignResourceName = $response->getResults()[0]->getResourceName(); printf( "Updated campaign with resourceName: '%s'.%s", $campaignResourceName, PHP_EOL ); } /** * Returns the DSA settings for a campaign. Throws an error if the campaign does not exist or * is not a DSA campaign. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $campaignId the campaign ID of the campaign to update * @return DynamicSearchAdsSetting the DSA settings for the campaign */ private static function getDsaSetting( GoogleAdsClient $googleAdsClient, int $customerId, int $campaignId ) { // Creates the query. $query = "SELECT campaign.id, campaign.name, " . "campaign.dynamic_search_ads_setting.use_supplied_urls_only " . "FROM campaign where campaign.id = $campaignId"; $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $response = $googleAdsServiceClient->search( $customerId, $query, ['pageSize' => self::PAGE_SIZE, 'returnTotalResultsCount' => true] ); // Throws an exception if a campaign with the provided ID does not exist. if ($response->getPage()->getResponseObject()->getTotalResultsCount() === 0) { throw new \InvalidArgumentException("No campaign found with ID $campaignId"); } /** @var Campaign $campaign */ $campaign = $response->getPage()->getResponseObject()->getResults()[0]->getCampaign(); $dynamicSearchAdsSetting = $campaign->getDynamicSearchAdsSetting(); // Throws an exception if the campaign is not a DSA campaign. if (is_null($dynamicSearchAdsSetting)) { throw new \InvalidArgumentException( "Campaign with ID $campaignId is not a DSA campaign." ); } return $dynamicSearchAdsSetting; } /** * Creates an ad group criterion targeting the DSA label. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $adGroupId the ad group ID * @param string $dsaPageUrlLabel the label for the DSA page URLs */ public static function addDsaTarget( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId, string $dsaPageUrlLabel ) { // Creates the webpage condition info. $webPageConditionInfo = new WebpageConditionInfo([ 'operand' => WebpageConditionOperand::CUSTOM_LABEL, 'argument' => $dsaPageUrlLabel ]); // Creates the webpage info. $webPageInfo = new WebpageInfo([ 'criterion_name' => 'Test Criterion', 'conditions' => [$webPageConditionInfo] ]); // Creates the ad group criterion. $adGroupCriterion = new AdGroupCriterion([ 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId), 'webpage' => $webPageInfo, 'cpc_bid_micros' => 1500000 ]); // Creates the operation. $adGroupCriterionOperation = new AdGroupCriterionOperation(); $adGroupCriterionOperation->setCreate($adGroupCriterion); $adGroupCriterionServiceClient = $googleAdsClient->getAdGroupCriterionServiceClient(); $response = $adGroupCriterionServiceClient->mutateAdGroupCriteria( $customerId, [$adGroupCriterionOperation] ); $adGroupCriterionResourceName = $response->getResults()[0]->getResourceName(); printf( "Created ad group criterion with resource name '%s'.%s", $adGroupCriterionResourceName, PHP_EOL ); } } AddDynamicPageFeed::main();
Python
#!/usr/bin/env python # Copyright 2019 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 adds a page feed with URLs for a Dynamic Search Ads Campaign. The page feed specifies precisely which URLs to use with the campaign. To use a Dynamic Search Ads Campaign run add_dynamic_search_ads_campaign.py. To get campaigns run basic_operations/get_campaigns.py. """ # DEPRECATION WARNING! # Feed-services based DSA page feeds are deprecated and being replaced with # assets, see: advanced_operations/add_dynamic_page_feed_asset.py for an # example of how to create page feeds using assets. For details on the # deprecation schedule for feed-based page feeds, see our developer blog: # https://ads-developers.googleblog.com import argparse import sys import uuid from google.api_core import protobuf_helpers from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException # Class to keep track of page feed details. class FeedDetails(object): def __init__(self, resource_name, url_attribute_id, label_attribute_id): self.resource_name = resource_name self.url_attribute_id = url_attribute_id self.label_attribute_id = label_attribute_id def main(client, customer_id, campaign_id, ad_group_id): """The main method that creates all necessary entities for the example. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. campaign_id: a campaign ID str. ad_group_id: an ad group ID str. """ dsa_page_url_label = "discounts" # Get the page feed resource name. This code example creates a new feed, # but you can fetch and re-use an existing feed. feed_resource_name = _create_feed(client, customer_id) # We need to look up the attribute name and ID for the feed we just # created so that we can give them back to the API for construction of # feed mappings in the next function. feed_details = _get_feed_details(client, customer_id, feed_resource_name) _create_feed_mapping(client, customer_id, feed_details) _create_feed_items(client, customer_id, feed_details, dsa_page_url_label) # Associate the page feed with the campaign. _update_campaign_dsa_setting(client, customer_id, campaign_id, feed_details) ad_group_service = client.get_service("AdGroupService") ad_group_resource_name = ad_group_service.ad_group_path( customer_id, ad_group_id ) # Optional: Target web pages matching the feed's label in the ad group. _add_dsa_targeting( client, customer_id, ad_group_resource_name, dsa_page_url_label ) def _create_feed(client, customer_id): """Creates a page feed with URLs Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. Returns: A FeedDetails instance with information about the newly created feed. """ # Retrieve a new feed operation object. feed_operation = client.get_type("FeedOperation") # Create a new feed. feed = feed_operation.create feed.name = f"DSA Feed #{uuid.uuid4()}" feed.origin = client.enums.FeedOriginEnum.USER feed_attribute_type_enum = client.enums.FeedAttributeTypeEnum # Create the feed's attributes. feed_attribute_url = client.get_type("FeedAttribute") feed_attribute_url.type_ = feed_attribute_type_enum.URL_LIST feed_attribute_url.name = "Page URL" feed_attribute_label = client.get_type("FeedAttribute") feed_attribute_label.type_ = feed_attribute_type_enum.STRING_LIST feed_attribute_label.name = "Label" feed.attributes.extend([feed_attribute_url, feed_attribute_label]) # Retrieve the feed service. feed_service = client.get_service("FeedService") # Send the feed operation and add the feed. response = feed_service.mutate_feeds( customer_id=customer_id, operations=[feed_operation] ) return response.results[0].resource_name def _get_feed_details(client, customer_id, resource_name): """Makes a search request to retrieve the attributes of a single feed. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. resource_name: the str resource_name of a feed. Returns: A FeedDetails instance with information about the feed that was retrieved in the search request. """ query = f""" SELECT feed.attributes FROM feed WHERE feed.resource_name = "{resource_name}" LIMIT 1 """ ga_service = client.get_service("GoogleAdsService") search_request = client.get_type("SearchGoogleAdsRequest") search_request.customer_id = customer_id search_request.query = query response = ga_service.search(request=search_request) # Maps specific fields in each row in the response to a dict. This would # overwrite the same fields in the dict for each row, but we know we'll # only one row will be returned. for row in response: attribute_lookup = { attribute.name: attribute.id for attribute in row.feed.attributes } return FeedDetails( resource_name, attribute_lookup["Page URL"], attribute_lookup["Label"] ) def _create_feed_mapping(client, customer_id, feed_details): """Creates feed mapping using the given feed details Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. feed_details: a FeedDetails instance with feed attribute information """ # Retrieve a new feed mapping operation object. feed_mapping_operation = client.get_type("FeedMappingOperation") # Create a new feed mapping. feed_mapping = feed_mapping_operation.create feed_mapping.criterion_type = ( client.enums.FeedMappingCriterionTypeEnum.DSA_PAGE_FEED ) feed_mapping.feed = feed_details.resource_name dsa_page_feed_field_enum = client.enums.DsaPageFeedCriterionFieldEnum url_field_mapping = client.get_type("AttributeFieldMapping") url_field_mapping.feed_attribute_id = feed_details.url_attribute_id url_field_mapping.dsa_page_feed_field = dsa_page_feed_field_enum.PAGE_URL feed_mapping.attribute_field_mappings.append(url_field_mapping) label_field_mapping = client.get_type("AttributeFieldMapping") label_field_mapping.feed_attribute_id = feed_details.label_attribute_id label_field_mapping.dsa_page_feed_field = dsa_page_feed_field_enum.LABEL feed_mapping.attribute_field_mappings.append(label_field_mapping) # Retrieve the feed mapping service. feed_mapping_service = client.get_service("FeedMappingService") # Submit the feed mapping operation and add the feed mapping. response = feed_mapping_service.mutate_feed_mappings( customer_id=customer_id, operations=[feed_mapping_operation] ) resource_name = response.results[0].resource_name # Display the results. print(f"Feed mapping created with resource_name: '{resource_name}'") def _create_feed_items(client, customer_id, feed_details, label): """Creates feed items with the given feed_details and label Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. feed_details: a FeedDetails instance with feed attribute information label: a Dynamic Search Ad URL label str. """ # See https://support.google.com/google-ads/answer/7166527 for page feed URL # recommendations and rules. urls = [ "http://www.example.com/discounts/rental-cars", "http://www.example.com/discounts/hotel-deals", "http://www.example.com/discounts/flight-deals", ] def map_feed_urls(url): feed_item_operation = client.get_type("FeedItemOperation") feed_item = feed_item_operation.create feed_item.feed = feed_details.resource_name url_attribute_value = client.get_type("FeedItemAttributeValue") url_attribute_value.feed_attribute_id = feed_details.url_attribute_id label_attribute_value = client.get_type("FeedItemAttributeValue") label_attribute_value.feed_attribute_id = ( feed_details.label_attribute_id ) feed_item.attribute_values.extend( [url_attribute_value, label_attribute_value] ) url_attribute_value.string_values.append(url) label_attribute_value.string_values.append(label) return feed_item_operation # Create a new feed item operation for each of the URLs in the url list. feed_item_operations = list(map(map_feed_urls, urls)) # Retrieve the feed item service. feed_item_service = client.get_service("FeedItemService") # Submit the feed item operations and add the feed items. response = feed_item_service.mutate_feed_items( customer_id=customer_id, operations=feed_item_operations ) # Display the results. for feed_item in response.results: print( f"Created feed item with resource_name: '{feed_item.resource_name}'" ) def _update_campaign_dsa_setting( client, customer_id, campaign_id, feed_details ): """Updates the given campaign with the given feed details. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. campaign_id: a campaign ID str; feed_details: a FeedDetails instance with feed attribute information. """ query = f""" SELECT campaign.id, campaign.name, campaign.dynamic_search_ads_setting.use_supplied_urls_only FROM campaign WHERE campaign.id = {campaign_id} LIMIT 1 """ ga_service = client.get_service("GoogleAdsService") search_request = client.get_type("SearchGoogleAdsRequest") search_request.customer_id = customer_id search_request.query = query results = ga_service.search(request=search_request) campaign = None for row in results: campaign = row.campaign if not campaign: raise ValueError(f"Campaign with id #{campaign_id} not found") # Retrieve a new campaign operation campaign_operation = client.get_type("CampaignOperation") # Copy the retrieved campaign onto the new campaign operation. client.copy_from(campaign_operation.update, campaign) updated_campaign = campaign_operation.update # Use a page feed to specify precisely which URLs to use with your Dynamic # Search ads. updated_campaign.dynamic_search_ads_setting.feeds.append( feed_details.resource_name ) client.copy_from( campaign_operation.update_mask, protobuf_helpers.field_mask(campaign._pb, updated_campaign._pb), ) # Retrieve the campaign service. campaign_service = client.get_service("CampaignService") # Submit the campaign operation and update the campaign. response = campaign_service.mutate_campaigns( customer_id=customer_id, operations=[campaign_operation] ) resource_name = response.results[0].resource_name # Display the results. print(f"Updated campaign #{resource_name}") def _add_dsa_targeting(client, customer_id, ad_group_resource_name, label): """Adds Dynamic Search Ad targeting criteria to the given ad group. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID str. ad_group_resource_name: a resource_name str for an Ad Group. label: a Dynamic Search Ad URL label str. """ # Retrieve a new ad group criterion operation object. ad_group_criterion_operation = client.get_type("AdGroupCriterionOperation") # Create a new ad group criterion. ad_group_criterion = ad_group_criterion_operation.create ad_group_criterion.ad_group = ad_group_resource_name # Set the custom bid for this criterion. ad_group_criterion.cpc_bid_micros = 1500000 ad_group_criterion.webpage.criterion_name = "Test criterion" # Add a condition for label=specified_label_name webpage_criterion_info = client.get_type( "WebpageConditionInfo" ) # ad_group_criterion.webpage.conditions.add() webpage_criterion_info.argument = label webpage_criterion_info.operand = ( client.enums.WebpageConditionOperandEnum.CUSTOM_LABEL ) ad_group_criterion.webpage.conditions.append(webpage_criterion_info) # Retrieve the ad group criterion service. ad_group_criterion_service = client.get_service("AdGroupCriterionService") response = ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=[ad_group_criterion_operation] ) resource_name = response.results[0].resource_name # Display the results. print(f"Created ad group criterion with resource_name: '{resource_name}'") if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client = GoogleAdsClient.load_from_storage(version="v10") parser = argparse.ArgumentParser( description=( "Adds a page feed with URLs for a Dynamic Search Ads Campaign." ) ) # 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.", ) parser.add_argument( "-i", "--campaign_id", type=str, required=True, help="The campaign ID." ) parser.add_argument( "-a", "--ad_group_id", type=str, required=True, help="The ad group ID." ) args = parser.parse_args() try: main( googleads_client, args.customer_id, args.campaign_id, args.ad_group_id, ) 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'\tError with message "{error.message}".') if error.location: for field_path_element in error.location.field_path_elements: print(f"\t\tOn field: {field_path_element.field_name}") sys.exit(1)
Ruby
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2019, Google Inc. All Rights Reserved. # # License:: 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 code example adds a page feed to specify precisely which URLs to use with # your Dynamic Search Ads campaign. To use a Dynamic Search Ads campaign, run # add_dynamic_search_ads_campaign.rb. To get campaigns, run get_campaigns.rb. # # DEPRECATION WARNING! # Feed-services based DSA page feeds are deprecated and being replaced with # assets. See add_dynamic_page_feed_asset.rb. require 'optparse' require 'google/ads/google_ads' FeedDetails = Struct.new( :resource_name, :url_attribute_id, :label_attribute_id ) def add_dynamic_page_feed(customer_id, campaign_id, ad_group_id) client = Google::Ads::GoogleAds::GoogleAdsClient.new dsa_page_url_label = "discounts" feed_details = create_feed(client, customer_id) create_feed_mapping(client, customer_id, feed_details) create_feed_items(client, customer_id, feed_details, dsa_page_url_label) update_campaign_dsa_setting(client, customer_id, campaign_id, feed_details) ad_group_resource_name = client.path.ad_group(customer_id, ad_group_id) add_dsa_targeting( client, customer_id, ad_group_resource_name, dsa_page_url_label ) end def create_feed(client, customer_id) feed_attribute_url = client.resource.feed_attribute do |a| a.type = :URL_LIST a.name = "Page URL" end feed_attribute_label = client.resource.feed_attribute do |a| a.type = :STRING_LIST a.name = "Label" end feed = client.resource.feed do |f| f.name = "DSA Feed #{(Time.now.to_f * 1000).to_i}" f.attributes << feed_attribute_url f.attributes << feed_attribute_label f.origin = :USER end operation = client.operation.create_resource.feed(feed) response = client.service.feed.mutate_feeds( customer_id: customer_id, operations: [operation], ) feed_id = response.results.first.resource_name # We need to look up the attribute name and IDs for the feed we just created # so that we can give them back to the API for construction of feed mappings # in the next function. query = <<~EOD SELECT feed.attributes FROM feed WHERE feed.resource_name = '#{feed_id}' LIMIT 100 EOD response = client.service.google_ads.search( customer_id: customer_id, query: query, ) # Hash.[] takes an aray of pairs and turns them in to a hash with keys # equal to the first item, and values equal to the second item, we get two # items back one with ["Page URL", id_for_url] and another with # ["Label", id_for_label], so this expression gives us a convenient way to # look them back up attribute_lookup = Hash[ response.first.feed.attributes.map { |attribute| [attribute.name, attribute.id] } ] # Finally, construct a FeedDetails object so that we have a nice small # wrapper around the details we care about for the next phase. FeedDetails.new( feed_id, attribute_lookup.fetch("Page URL"), attribute_lookup.fetch("Label"), ) end def create_feed_mapping(client, customer_id, feed_details) url_field_mapping = client.resource.attribute_field_mapping do |mapping| mapping.feed_attribute_id = feed_details.url_attribute_id mapping.dsa_page_feed_field = :PAGE_URL end label_field_mapping = client.resource.attribute_field_mapping do |mapping| mapping.feed_attribute_id = feed_details.label_attribute_id mapping.dsa_page_feed_field = :LABEL end feed_mapping = client.resource.feed_mapping do |mapping| mapping.criterion_type = :DSA_PAGE_FEED mapping.feed = feed_details.resource_name mapping.attribute_field_mappings << url_field_mapping mapping.attribute_field_mappings << label_field_mapping end operation = client.operation.create_resource.feed_mapping(feed_mapping) response = client.service.feed_mapping.mutate_feed_mappings( customer_id: customer_id, operations: [operation], ) puts "Feed mapping created with id #{response.results.first.resource_name}" end def create_feed_items(client, customer_id, feed_details, label) urls = [ "http://www.example.com/discounts/rental-cars", "http://www.example.com/discounts/hotel-deals", "http://www.example.com/discounts/flight-deals", ] feed_items = urls.map { |url| client.resource.feed_item do |fi| fi.feed = feed_details.resource_name fi.attribute_values << client.resource.feed_item_attribute_value do |val| val.feed_attribute_id = feed_details.url_attribute_id val.string_values << url end fi.attribute_values << client.resource.feed_item_attribute_value do |val| val.feed_attribute_id = feed_details.label_attribute_id val.string_values << label end end } ops = feed_items.map { |fi| client.operation.create_resource.feed_item(fi) } response = client.service.feed_item.mutate_feed_items( customer_id: customer_id, operations: ops, ) response.results.each do |result| puts "Created feed item with id #{result.resource_name}" end end def update_campaign_dsa_setting(client, customer_id, campaign_id, feed_details) query = <<~EOD SELECT campaign.id, campaign.name, campaign.dynamic_search_ads_setting.feeds FROM campaign WHERE campaign.id = #{campaign_id} LIMIT 1000 EOD response = client.service.google_ads.search( customer_id: customer_id, query: query, ) result = response.first if result.nil? raise "Campaign with id #{id} not found" end campaign = result.campaign op = client.operation.update_resource.campaign(campaign) do campaign.dynamic_search_ads_setting.feeds << feed_details.resource_name end response = client.service.campaign.mutate_campaigns( customer_id: customer_id, operations: [op], ) puts "Updated campaign #{response.results.first.resource_name}" end def add_dsa_targeting(client, customer_id, ad_group_resource_name, label) webpage_condition_info = client.resource.webpage_condition_info do |wci| wci.operand = :CUSTOM_LABEL wci.argument = label end webpage_criterion = client.resource.webpage_info do |wi| wi.criterion_name = "Test criterion" wi.conditions << webpage_condition_info end ad_group_criterion = client.resource.ad_group_criterion do |agc| agc.ad_group = ad_group_resource_name agc.webpage = webpage_criterion agc.cpc_bid_micros = 1_500_000 end op = client.operation.create_resource.ad_group_criterion(ad_group_criterion) response = client.service.ad_group_criterion.mutate_ad_group_criteria( customer_id: customer_id, operations: [op], ) puts "Created ad group criterion with id: #{response.results.first.resource_name}" end if __FILE__ == $0 options = {} # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE' options[:campaign_id] = 'INSERT_CAMPAIGN_ID_HERE' options[:ad_group_id] = 'INSERT_AD_GROUP_ID_HERE' OptionParser.new do |opts| opts.banner = sprintf('Usage: %s [options]', File.basename(__FILE__)) opts.separator '' opts.separator 'Options:' opts.on('-C', '--customer-id CUSTOMER-ID', String, 'Customer ID') do |v| options[:customer_id] = v end opts.on('-c', '--campaign-id CAMPAIGN-ID', String, 'Campaign ID') do |v| options[:campaign_id] = v end opts.on('-A', '--ad-group-id AD-GROUP-ID', String, 'Ad Group ID') do |v| options[:ad_group_id] = v end opts.separator '' opts.separator 'Help:' opts.on_tail('-h', '--help', 'Show this message') do puts opts exit end end.parse! begin add_dynamic_page_feed( options.fetch(:customer_id).tr("-", ""), options.fetch(:campaign_id), options.fetch(:ad_group_id), ) rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e e.failure.errors.each do |error| STDERR.printf("Error with message: %s\n", error.message) if error.location error.location.field_path_elements.each do |field_path_element| STDERR.printf("\tOn field: %s\n", field_path_element.field_name) end end error.error_code.to_h.each do |k, v| next if v == :UNSPECIFIED STDERR.printf("\tType: %s\n\tCode: %s\n", k, v) end end raise end end
Perl
#!/usr/bin/perl -w # # Copyright 2019, 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 page feed to specify precisely which URLs to use with your # dynamic search ads campaign. # # DEPRECATION WARNING! # Feed-services based DSA page feeds are deprecated and being replaced with assets. # See add_dynamic_page_feed_asset.pl. 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::Utils::FieldMasks; use Google::Ads::GoogleAds::V11::Resources::FeedAttribute; use Google::Ads::GoogleAds::V11::Resources::Feed; use Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping; use Google::Ads::GoogleAds::V11::Resources::FeedMapping; use Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue; use Google::Ads::GoogleAds::V11::Resources::FeedItem; use Google::Ads::GoogleAds::V11::Resources::Campaign; use Google::Ads::GoogleAds::V11::Resources::AdGroupCriterion; use Google::Ads::GoogleAds::V11::Common::WebpageConditionInfo; use Google::Ads::GoogleAds::V11::Common::WebpageInfo; use Google::Ads::GoogleAds::V11::Enums::FeedAttributeTypeEnum qw(URL_LIST STRING_LIST); use Google::Ads::GoogleAds::V11::Enums::FeedOriginEnum qw(USER); use Google::Ads::GoogleAds::V11::Enums::DsaPageFeedCriterionFieldEnum qw(PAGE_URL LABEL); use Google::Ads::GoogleAds::V11::Enums::FeedMappingCriterionTypeEnum qw(DSA_PAGE_FEED); use Google::Ads::GoogleAds::V11::Enums::WebpageConditionOperandEnum qw(CUSTOM_LABEL); use Google::Ads::GoogleAds::V11::Services::FeedService::FeedOperation; use Google::Ads::GoogleAds::V11::Services::FeedMappingService::FeedMappingOperation; use Google::Ads::GoogleAds::V11::Services::FeedItemService::FeedItemOperation; use Google::Ads::GoogleAds::V11::Services::CampaignService::CampaignOperation; use Google::Ads::GoogleAds::V11::Services::AdGroupCriterionService::AdGroupCriterionOperation; use Google::Ads::GoogleAds::V11::Services::GoogleAdsService::SearchGoogleAdsRequest; use Google::Ads::GoogleAds::V11::Utils::ResourceNames; use Getopt::Long qw(:config auto_help); use Pod::Usage; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); use constant PAGE_SIZE => 1000; # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. my $customer_id = "INSERT_CUSTOMER_ID_HERE"; my $campaign_id = "INSERT_CAMPAIGN_ID_HERE"; my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; sub add_dynamic_page_feed { my ($api_client, $customer_id, $campaign_id, $ad_group_id) = @_; my $dsa_page_url_label = "discounts"; # Create the page feed details. This example creates a new feed, but you can # fetch and re-use an existing feed. my $feed_details = create_feed($api_client, $customer_id); create_feed_mapping($api_client, $customer_id, $feed_details); create_feed_items($api_client, $customer_id, $feed_details, $dsa_page_url_label); # Associate the page feed with the campaign. update_campaign_dsa_setting($api_client, $customer_id, $feed_details, $campaign_id); # Optional: Target web pages matching the feed's label in the ad group. add_dsa_target($api_client, $customer_id, $ad_group_id, $dsa_page_url_label); print "Dynamic page feed setup is complete for campaign ID $campaign_id.\n"; return 1; } # Creates a feed. sub create_feed { my ($api_client, $customer_id) = @_; # Create a URL attribute. my $url_attribute = Google::Ads::GoogleAds::V11::Resources::FeedAttribute->new({ type => URL_LIST, name => "Page URL" }); # Create a label attribute. my $label_attribute = Google::Ads::GoogleAds::V11::Resources::FeedAttribute->new({ type => STRING_LIST, name => "Label" }); # Create the feed. my $feed = Google::Ads::GoogleAds::V11::Resources::Feed->new({ name => "DSA Feed #" . uniqid(), attributes => [$url_attribute, $label_attribute], origin => USER }); # Create a feed operation for creating a feed. my $feed_operation = Google::Ads::GoogleAds::V11::Services::FeedService::FeedOperation->new( {create => $feed}); # Add the feed. my $feeds_response = $api_client->FeedService()->mutate({ customerId => $customer_id, operations => [$feed_operation]}); my $feed_resource_name = $feeds_response->{results}[0]{resourceName}; printf "Created feed with resource name: '%s'.\n", $feed_resource_name; return get_feed($api_client, $customer_id, $feed_resource_name); } # Retrieves details about a feed. sub get_feed { my ($api_client, $customer_id, $feed_resource_name) = @_; my $search_query = sprintf "SELECT feed.attributes FROM feed WHERE feed.resource_name = '%s'", $feed_resource_name; my $search_response = $api_client->GoogleAdsService()->search({ customerId => $customer_id, query => $search_query, pageSize => PAGE_SIZE }); my $feed_attributes = $search_response->{results}[0]{feed}{attributes}; my $feed_details = {resourceName => $feed_resource_name}; foreach my $feed_attribute (@$feed_attributes) { $feed_details->{$feed_attribute->{name}} = $feed_attribute->{id}; } return $feed_details; } # Creates a feed mapping for a given feed. sub create_feed_mapping { my ($api_client, $customer_id, $feed_details) = @_; # Map the feed attribute IDs to the field ID constants. my $url_field_mapping = Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping->new({ feedAttributeId => $feed_details->{'Page URL'}, dsaPageFeedField => PAGE_URL }); my $label_field_mapping = Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping->new({ feedAttributeId => $feed_details->{Label}, dsaPageFeedField => LABEL }); # Create the feed mapping. my $feed_mapping = Google::Ads::GoogleAds::V11::Resources::FeedMapping->new({ criterionType => DSA_PAGE_FEED, feed => $feed_details->{resourceName}, attributeFieldMappings => [$url_field_mapping, $label_field_mapping]}); # Create the feed mapping operation. my $feed_mapping_operation = Google::Ads::GoogleAds::V11::Services::FeedMappingService::FeedMappingOperation ->new({ create => $feed_mapping }); my $feed_mappings_response = $api_client->FeedMappingService()->mutate({ customerId => $customer_id, operations => [$feed_mapping_operation]}); printf "Created feed mapping with resource name: '%s'.\n", $feed_mappings_response->{results}[0]{resourceName}; } # Creates feed items for a given feed. sub create_feed_items { my ($api_client, $customer_id, $feed_details, $dsa_page_url_label) = @_; my $urls = [ "http://www.example.com/discounts/rental-cars", "http://www.example.com/discounts/hotel-deals", "http://www.example.com/discounts/flight-deals" ]; # Create a label attribute. my $label_attribute_value = Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue->new({ feedAttributeId => $feed_details->{Label}, stringValue => $dsa_page_url_label }); # Create one operation per URL. my $feed_item_operations = []; foreach my $url (@$urls) { # Create a url attribute. my $url_attribute_value = Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue->new({ feedAttributeId => $feed_details->{'Page URL'}, stringValue => $url }); # Create a feed item. my $feed_item = Google::Ads::GoogleAds::V11::Resources::FeedItem->new({ feed => $feed_details->{resourceName}, attributeValues => [$url_attribute_value, $label_attribute_value]}); push @$feed_item_operations, Google::Ads::GoogleAds::V11::Services::FeedItemService::FeedItemOperation ->new({ create => $feed_item }); } # Add the feed items. my $feed_items_response = $api_client->FeedItemService()->mutate({ customerId => $customer_id, operations => $feed_item_operations }); foreach my $feed_item_result (@{$feed_items_response->{results}}) { printf "Created feed item with resource name: '%s'.\n", $feed_item_result->{resourceName}; } } # Updates a campaign to set the DSA feed. sub update_campaign_dsa_setting { my ($api_client, $customer_id, $feed_details, $campaign_id) = @_; # Retrieve the existing dynamic search ads settings for the campaign. my $dsa_setting = get_dsa_setting($api_client, $customer_id, $campaign_id); my $feed_resource_name = $feed_details->{resourceName}; $dsa_setting->{feeds} = [$feed_resource_name]; # Create the campaign object to be updated. my $campaign = Google::Ads::GoogleAds::V11::Resources::Campaign->new({ resourceName => Google::Ads::GoogleAds::V11::Utils::ResourceNames::campaign( $customer_id, $campaign_id ), dynamicSearchAdsSetting => $dsa_setting }); # Create the update operation and set the update mask. my $campaign_operation = Google::Ads::GoogleAds::V11::Services::CampaignService::CampaignOperation-> new({ update => $campaign, updateMask => Google::Ads::GoogleAds::Utils::FieldMasks::all_set_fields_of($campaign)} ); # Update the campaign. my $campaigns_response = $api_client->CampaignService()->mutate({ customerId => $customer_id, operations => [$campaign_operation]}); printf "Updated campaign with resource name: '%s'.\n", $campaigns_response->{results}[0]{resourceName}; } # Returns the DSA settings for a campaign. Dies if the campaign does not # exist or is not a DSA campaign. sub get_dsa_setting { my ($api_client, $customer_id, $campaign_id) = @_; # Create the query. # You must request all DSA fields in order to update the DSA settings in the # following step. my $search_query = "SELECT campaign.id, campaign.name, " . "campaign.dynamic_search_ads_setting.use_supplied_urls_only " . "FROM campaign where campaign.id = $campaign_id"; my $search_response = $api_client->GoogleAdsService()->search({ customerId => $customer_id, query => $search_query, pageSize => PAGE_SIZE }); # Die if a campaign with the provided ID does not exist. die "No campaign found with ID $campaign_id.\n" if scalar @{$search_response->{results}} == 0; my $dynamic_search_ads_setting = $search_response->{results}[0]{campaign}{dynamicSearchAdsSetting}; # Die if the campaign is not a DSA campaign. die "Campaign with ID $campaign_id is not a DSA campaign.\n" if not $dynamic_search_ads_setting; return $dynamic_search_ads_setting; } # Creates an ad group criterion targeting the DSA label. sub add_dsa_target { my ($api_client, $customer_id, $ad_group_id, $dsa_page_url_label) = @_; my $ad_group_resource_name = Google::Ads::GoogleAds::V11::Utils::ResourceNames::ad_group($customer_id, $ad_group_id); # Create the webpage condition info. my $web_page_condition_info = Google::Ads::GoogleAds::V11::Common::WebpageConditionInfo->new({ operand => CUSTOM_LABEL, argument => $dsa_page_url_label }); # Create the webpage info. my $web_page_info = Google::Ads::GoogleAds::V11::Common::WebpageInfo->new({ criterionName => "Test Criterion", conditions => [$web_page_condition_info]}); # Create the ad group criterion. my $ad_group_criterion = Google::Ads::GoogleAds::V11::Resources::AdGroupCriterion->new({ adGroup => $ad_group_resource_name, webpage => $web_page_info, cpcBidMicros => 1500000 }); # Create the operation. my $ad_group_criterion_operation = Google::Ads::GoogleAds::V11::Services::AdGroupCriterionService::AdGroupCriterionOperation ->new({ create => $ad_group_criterion }); my $ad_group_criteria_response = $api_client->AdGroupCriterionService()->mutate({ customerId => $customer_id, operations => [$ad_group_criterion_operation]}); printf "Created ad group criterion with resource name: '%s'.\n", $ad_group_criteria_response->{results}[0]{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); # Parameters passed on the command line will override any parameters set in code. GetOptions( "customer_id=s" => \$customer_id, "campaign_id=i" => \$campaign_id, "ad_group_id=i" => \$ad_group_id ); # 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, $campaign_id, $ad_group_id); # Call the example. add_dynamic_page_feed($api_client, $customer_id =~ s/-//gr, $campaign_id, $ad_group_id); =pod =head1 NAME add_dynamic_page_feed =head1 DESCRIPTION This example adds a page feed to specify precisely which URLs to use with your dynamic search ads campaign. DEPRECATION WARNING! Feed-services based DSA page feeds are deprecated and being replaced with assets. See add_dynamic_page_feed_asset.pl. =head1 SYNOPSIS add_dynamic_page_feed.pl [options] -help Show the help message. -customer_id The Google Ads customer ID. -campaign_id The campaign ID. -ad_group_id The ad group ID. =cut