/// <summary> /// Removes the root of the tree. /// </summary> private void SetRootToEmpty() { ProductPartitionNode root = tree.Root; if (root != null && root.ProductPartitionId >= 0L) { AdGroupCriterion rootCriterion = new AdGroupCriterion() { adGroupId = ADGROUP_ID, criterion = new Criterion() { id = root.ProductPartitionId } }; AdGroupCriterionOperation removeOp = new AdGroupCriterionOperation() { @operator = Operator.REMOVE, operand = rootCriterion }; AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService) user.GetService(AdWordsService.v201601.AdGroupCriterionService); adGroupCriterionService.mutate(new AdGroupCriterionOperation[] { removeOp }); } Assert.DoesNotThrow(delegate() { tree = ProductPartitionTree.DownloadAdGroupTree(user, ADGROUP_ID); }); }
/// <summary> /// Sets the Add action for a new AdGroupCriterion corresponding to the specified ProductCondition, /// and adds it to the helper's list of AdGroupCriterionAction. /// </summary> /// <param name="parent">The parent of the product partition unit that you want to add.</param> /// <param name="condition">The condition or product filter for the new product partition.</param> /// <param name="bidAmount">The bid amount for the new product partition.</param> /// <param name="isNegative">Indicates whether or not to add a NegativeAdGroupCriterion. /// The default value is false, in which case a BiddableAdGroupCriterion will be added.</param> /// <returns>The ad group criterion that was added to the list of PartitionActions.</returns> public AdGroupCriterion AddUnit( AdGroupCriterion parent, ProductCondition condition, double bidAmount, bool isNegative ) { AdGroupCriterion adGroupCriterion; if (isNegative) { adGroupCriterion = new NegativeAdGroupCriterion(); } else { adGroupCriterion = new BiddableAdGroupCriterion() { CriterionBid = new FixedBid() { Bid = new Bid() { Amount = bidAmount } }, DestinationUrl = "http://www.contoso.com/womenshoesale/?season=spring&promocode=PROMO123", }; } adGroupCriterion.Criterion = new ProductPartition() { // If the root node is a unit, it would not have a parent ParentCriterionId = parent != null ? parent.Id : null, Condition = condition, PartitionType = ProductPartitionType.Unit }; adGroupCriterion.AdGroupId = this.adGroupId; var partitionAction = new AdGroupCriterionAction() { Action = ItemAction.Add, AdGroupCriterion = adGroupCriterion }; this.partitionActions.Add(partitionAction); return adGroupCriterion; }
/// <summary> /// Outputs the AdGroupCriterion that contains a ProductPartition. /// </summary> protected void OutputAdGroupCriterionWithProductPartition(AdGroupCriterion adGroupCriterion) { if (adGroupCriterion != null) { OutputStatusMessage(string.Format("AdGroupId: {0}", adGroupCriterion.AdGroupId)); OutputStatusMessage(string.Format("AdGroupCriterion Id: {0}", adGroupCriterion.Id)); OutputStatusMessage(string.Format("AdGroupCriterion Type: {0}", adGroupCriterion.Type)); var biddableAdGroupCriterion = adGroupCriterion as BiddableAdGroupCriterion; if (biddableAdGroupCriterion != null) { OutputStatusMessage(string.Format("DestinationUrl: {0}", biddableAdGroupCriterion.DestinationUrl)); OutputStatusMessage("FinalMobileUrls: "); if (biddableAdGroupCriterion.FinalMobileUrls != null) { foreach (var finalMobileUrl in biddableAdGroupCriterion.FinalMobileUrls) { OutputStatusMessage(string.Format("\t{0}", finalMobileUrl)); } } OutputStatusMessage("FinalUrls: "); if (biddableAdGroupCriterion.FinalUrls != null) { foreach (var finalUrl in biddableAdGroupCriterion.FinalUrls) { OutputStatusMessage(string.Format("\t{0}", finalUrl)); } } OutputStatusMessage(string.Format("TrackingUrlTemplate: {0}", biddableAdGroupCriterion.TrackingUrlTemplate)); OutputStatusMessage("UrlCustomParameters: "); if (biddableAdGroupCriterion.UrlCustomParameters != null && biddableAdGroupCriterion.UrlCustomParameters.Parameters != null) { foreach (var customParameter in biddableAdGroupCriterion.UrlCustomParameters.Parameters) { OutputStatusMessage(string.Format("\tKey: {0}", customParameter.Key)); OutputStatusMessage(string.Format("\tValue: {0}", customParameter.Value)); } } // Output the Campaign Management FixedBid Object OutputFixedBid((FixedBid)biddableAdGroupCriterion.CriterionBid); } else { var negativeAdGroupCriterion = adGroupCriterion as NegativeAdGroupCriterion; if (negativeAdGroupCriterion != null) { } } // Output the Campaign Management ProductPartition Object OutputProductPartition((ProductPartition)adGroupCriterion.Criterion); } }
/// <summary> /// Outputs the AdGroupCriterion that contains a ProductPartition. /// </summary> protected void OutputAdGroupCriterionWithProductPartition(AdGroupCriterion adGroupCriterion) { if (adGroupCriterion != null) { OutputStatusMessage(string.Format("AdGroupId: {0}", adGroupCriterion.AdGroupId)); OutputStatusMessage(string.Format("AdGroupCriterion Id: {0}", adGroupCriterion.Id)); OutputStatusMessage(string.Format("AdGroupCriterion Type: {0}", adGroupCriterion.Type)); var biddableAdGroupCriterion = adGroupCriterion as BiddableAdGroupCriterion; if (biddableAdGroupCriterion != null) { OutputStatusMessage(string.Format("DestinationUrl: {0}", biddableAdGroupCriterion.DestinationUrl)); // Output the Campaign Management FixedBid Object OutputFixedBid((FixedBid)biddableAdGroupCriterion.CriterionBid); } else { var negativeAdGroupCriterion = adGroupCriterion as NegativeAdGroupCriterion; if (negativeAdGroupCriterion != null) { } } // Output the Campaign Management ProductPartition Object OutputProductPartition((ProductPartition)adGroupCriterion.Criterion); } }
/// <summary> /// Creates an AdGroupCriterionOperation for the given criterion /// </summary> /// <param name="criterion">The criterion we want to add</param> private void CreateAddOperation(AdGroupCriterion criterion) { AdGroupCriterionOperation operation = new AdGroupCriterionOperation(); operation.operand = criterion; operation.@operator = Operator.ADD; this.operations.Add(operation); }
/// <summary> /// Sets the Delete action for the specified AdGroupCriterion, /// and adds it to the helper's list of AdGroupCriterionAction. /// </summary> /// <param name="adGroupCriterion">The ad group criterion whose product partition you want to delete.</param> public void DeletePartition(AdGroupCriterion adGroupCriterion) { adGroupCriterion.AdGroupId = this.adGroupId; var partitionAction = new AdGroupCriterionAction() { Action = ItemAction.Delete, AdGroupCriterion = adGroupCriterion }; this.partitionActions.Add(partitionAction); return; }
/// <summary> /// Sets the Add action for a new AdGroupCriterion corresponding to the specified ProductCondition, /// and adds it to the helper's list of AdGroupCriterionAction. /// </summary> /// <param name="parent">The parent of the product partition unit that you want to add.</param> /// <param name="condition">The condition or product filter for the new product partition.</param> /// <param name="bidAmount">The bid amount for the new product partition.</param> /// <param name="isNegative">Indicates whether or not to add a NegativeAdGroupCriterion. /// The default value is false, in which case a BiddableAdGroupCriterion will be added.</param> /// <returns>The ad group criterion that was added to the list of PartitionActions.</returns> public AdGroupCriterion AddUnit( AdGroupCriterion parent, ProductCondition condition, double bidAmount, bool isNegative ) { AdGroupCriterion adGroupCriterion; if (isNegative) { adGroupCriterion = new NegativeAdGroupCriterion(); } else { adGroupCriterion = new BiddableAdGroupCriterion() { CriterionBid = new FixedBid() { Amount = bidAmount }, // This destination URL is used if specified; otherwise, the destination URL is determined // by the corresponding value of the 'Link' that you specified for the product offer // in your Bing Merchant Center catalog. DestinationUrl = null, // You could use a tracking template which would override the campaign level // tracking template. Tracking templates defined for lower level entities // override those set for higher level entities. // In this example we are using the campaign level tracking template. TrackingUrlTemplate = null, // Set custom parameters that are specific to this criterion, // and can be used by the criterion, ad group, campaign, or account level tracking template. // In this example we are using the campaign level tracking template. UrlCustomParameters = new CustomParameters { Parameters = new[] { new CustomParameter() { Key = "promoCode", Value = "PROMO1" }, new CustomParameter() { Key = "season", Value = "summer" }, } } }; } adGroupCriterion.Criterion = new ProductPartition() { // If the root node is a unit, it would not have a parent ParentCriterionId = parent != null ? parent.Id : null, Condition = condition, PartitionType = ProductPartitionType.Unit }; adGroupCriterion.AdGroupId = this.adGroupId; var partitionAction = new AdGroupCriterionAction() { Action = ItemAction.Add, AdGroupCriterion = adGroupCriterion }; this.partitionActions.Add(partitionAction); return(adGroupCriterion); }
/// <summary> /// Displays the result from the mutate operation. /// </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="adGroupId">The ad group to which keywords are added.</param> /// <param name="threadIndex">The thread ID.</param> private async Task CreateKeyword(GoogleAdsClient client, int threadIndex, long customerId, long adGroupId) { await Task.Run(() => { // Get the AdGroupCriterionServiceClient. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V4.AdGroupCriterionService); List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); for (int i = 0; i < NUM_KEYWORDS; i++) { AdGroupCriterion criterion = new AdGroupCriterion() { Keyword = new KeywordInfo() { Text = $"mars cruise thread {threadIndex} seed {i}", MatchType = KeywordMatchType.Exact }, AdGroup = ResourceNames.AdGroup(customerId, adGroupId), Status = AdGroupCriterionStatus.Paused }; // Creates the operation. operations.Add(new AdGroupCriterionOperation() { Create = criterion }); } int retryCount = 0; int retrySeconds = 30; const int NUM_RETRIES = 3; while (retryCount < NUM_RETRIES) { try { // Makes the validateOnly mutate request. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( new MutateAdGroupCriteriaRequest() { CustomerId = customerId.ToString(), Operations = { operations }, PartialFailure = false, ValidateOnly = true }); Console.WriteLine($"[{threadIndex}] Validated {operations.Count} " + $"ad group criteria:"); break; } catch (GoogleAdsException e) { // Checks if any of the errors are QuotaError.RESOURCE_EXHAUSTED or // QuotaError.RESOURCE_TEMPORARILY_EXHAUSTED. // Note: The code assumes that the developer token is approved for // Standard Access. if (e.Failure != null) { bool isRateExceededError = false; e.Failure.Errors .Where(err => err.ErrorCode.QuotaError == QuotaError.ResourceExhausted || err.ErrorCode.QuotaError == QuotaError.ResourceTemporarilyExhausted) .ToList() .ForEach(delegate(GoogleAdsError err) { Console.Error.WriteLine($"[{threadIndex}] Received rate " + $"exceeded error. Message says, \"{err.Message}\"."); isRateExceededError = true; } ); if (isRateExceededError) { Console.Error.WriteLine( $"[{threadIndex}] Will retry after {retrySeconds} seconds."); Thread.Sleep(retrySeconds * 1000); retryCount++; // Uses an exponential backoff policy to avoid polling too // aggressively. retrySeconds *= 2; } } else { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); break; } } finally { if (retryCount == NUM_RETRIES) { throw new Exception($"[{ threadIndex }] Could not recover after " + $"making {retryCount} attempts."); } } } }); }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> /// <param name="campaignId">Id of the campaign to which experiments are /// added.</param> /// <param name="adGroupId">Id of the ad group to which experiments are /// added.</param> /// <param name="criterionId">Id of the criterion for which experiments /// are added.</param> public void Run(AdWordsUser user, long campaignId, long adGroupId, long criterionId) { // Get the ExperimentService. ExperimentService experimentService = (ExperimentService)user.GetService(AdWordsService.v201601.ExperimentService); // Get the AdGroupService. AdGroupService adGroupService = (AdGroupService)user.GetService(AdWordsService.v201601.AdGroupService); // Get the AdGroupCriterionService. AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService(AdWordsService.v201601.AdGroupCriterionService); // Create the experiment. Experiment experiment = new Experiment(); experiment.campaignId = campaignId; experiment.name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString(); experiment.queryPercentage = 10; experiment.startDateTime = DateTime.Now.AddDays(1).ToString("yyyyMMdd HHmmss"); // Optional: Set the end date. experiment.endDateTime = DateTime.Now.AddDays(30).ToString("yyyyMMdd HHmmss"); // Optional: Set the status. experiment.status = ExperimentStatus.ENABLED; // Create the operation. ExperimentOperation experimentOperation = new ExperimentOperation(); experimentOperation.@operator = Operator.ADD; experimentOperation.operand = experiment; try { // Add the experiment. ExperimentReturnValue experimentRetVal = experimentService.mutate( new ExperimentOperation[] { experimentOperation }); // Display the results. if (experimentRetVal != null && experimentRetVal.value != null && experimentRetVal.value. Length > 0) { long experimentId = 0; Experiment newExperiment = experimentRetVal.value[0]; Console.WriteLine("Experiment with name = \"{0}\" and id = \"{1}\" was added.\n", newExperiment.name, newExperiment.id); experimentId = newExperiment.id; // Set ad group for the experiment. AdGroup adGroup = new AdGroup(); adGroup.id = adGroupId; // Create experiment bid multiplier rule that will modify ad group bid // for the experiment. ManualCPCAdGroupExperimentBidMultipliers adGroupBidMultiplier = new ManualCPCAdGroupExperimentBidMultipliers(); adGroupBidMultiplier.maxCpcMultiplier = new BidMultiplier(); adGroupBidMultiplier.maxCpcMultiplier.multiplier = 1.5; // Set experiment data to the ad group. AdGroupExperimentData adGroupExperimentData = new AdGroupExperimentData(); adGroupExperimentData.experimentId = experimentId; adGroupExperimentData.experimentDeltaStatus = ExperimentDeltaStatus.MODIFIED; adGroupExperimentData.experimentBidMultipliers = adGroupBidMultiplier; adGroup.experimentData = adGroupExperimentData; // Create the operation. AdGroupOperation adGroupOperation = new AdGroupOperation(); adGroupOperation.operand = adGroup; adGroupOperation.@operator = Operator.SET; // Update the ad group. AdGroupReturnValue adGroupRetVal = adGroupService.mutate(new AdGroupOperation[] { adGroupOperation }); // Display the results. if (adGroupRetVal != null && adGroupRetVal.value != null && adGroupRetVal.value.Length > 0) { AdGroup updatedAdGroup = adGroupRetVal.value[0]; Console.WriteLine("Ad group with name = \"{0}\", id = \"{1}\" and status = \"{2}\" " + "was updated for the experiment.\n", updatedAdGroup.name, updatedAdGroup.id, updatedAdGroup.status); } else { Console.WriteLine("No ad groups were updated."); } // Set ad group criteria for the experiment. Criterion criterion = new Criterion(); criterion.id = criterionId; BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion(); adGroupCriterion.adGroupId = adGroupId; adGroupCriterion.criterion = criterion; // Create experiment bid multiplier rule that will modify criterion bid // for the experiment. ManualCPCAdGroupCriterionExperimentBidMultiplier bidMultiplier = new ManualCPCAdGroupCriterionExperimentBidMultiplier(); bidMultiplier.maxCpcMultiplier = new BidMultiplier(); bidMultiplier.maxCpcMultiplier.multiplier = 1.5; // Set experiment data to the criterion. BiddableAdGroupCriterionExperimentData adGroupCriterionExperimentData = new BiddableAdGroupCriterionExperimentData(); adGroupCriterionExperimentData.experimentId = experimentId; adGroupCriterionExperimentData.experimentDeltaStatus = ExperimentDeltaStatus.MODIFIED; adGroupCriterionExperimentData.experimentBidMultiplier = bidMultiplier; adGroupCriterion.experimentData = adGroupCriterionExperimentData; // Create the operation. AdGroupCriterionOperation adGroupCriterionOperation = new AdGroupCriterionOperation(); adGroupCriterionOperation.operand = adGroupCriterion; adGroupCriterionOperation.@operator = Operator.SET; // Update the ad group criteria. AdGroupCriterionReturnValue adGroupCriterionRetVal = adGroupCriterionService.mutate( new AdGroupCriterionOperation[] { adGroupCriterionOperation }); // Display the results. if (adGroupCriterionRetVal != null && adGroupCriterionRetVal.value != null && adGroupCriterionRetVal.value.Length > 0) { AdGroupCriterion updatedAdGroupCriterion = adGroupCriterionRetVal.value[0]; Console.WriteLine("Ad group criterion with ad group id = \"{0}\", criterion id = " + "\"{1}\" and type = \"{2}\" was updated for the experiment.\n", updatedAdGroupCriterion.adGroupId, updatedAdGroupCriterion.criterion.id, updatedAdGroupCriterion.criterion.CriterionType); } else { Console.WriteLine("No ad group criteria were updated."); } } else { Console.WriteLine("No experiments were added."); } } catch (Exception e) { throw new System.ApplicationException("Failed to add experiment.", e); } }
/// <summary> /// Outputs the details of the specified product partition node, /// and passes any children to itself recursively. /// </summary> /// <param name="node">The node to output, whether a Subdivision or Unit.</param> /// <param name="childBranches">The child branches or nodes if any exist.</param> /// <param name="treeLevel"> /// The number of descendents from the tree root node. /// Used by this operation to format the tree structure output. /// </param> private void OutputProductPartitionTree( BulkAdGroupProductPartition node, Dictionary <long, List <BulkAdGroupProductPartition> > childBranches, int treeLevel) { AdGroupCriterion adGroupCriterion = node.AdGroupCriterion; OutputStatusMessage(string.Format("{0}{1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(adGroupCriterion.Criterion)).PartitionType) ); OutputStatusMessage(string.Format("{0}ParentCriterionId: {1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(adGroupCriterion.Criterion)).ParentCriterionId) ); OutputStatusMessage(string.Format("{0}Id: {1}", "".PadLeft(treeLevel, '\t'), adGroupCriterion.Id) ); if (((ProductPartition)(adGroupCriterion.Criterion)).PartitionType == ProductPartitionType.Unit) { var biddableAdGroupCriterion = adGroupCriterion as BiddableAdGroupCriterion; if (biddableAdGroupCriterion != null) { OutputStatusMessage(string.Format("{0}Bid Amount: {1}", "".PadLeft(treeLevel, '\t'), ((FixedBid)(biddableAdGroupCriterion.CriterionBid)).Amount) ); OutputStatusMessage(string.Format("{0}DestinationUrl: {1}", "".PadLeft(treeLevel, '\t'), biddableAdGroupCriterion.DestinationUrl) ); OutputStatusMessage(string.Format("{0}TrackingUrlTemplate: {1}", "".PadLeft(treeLevel, '\t'), biddableAdGroupCriterion.TrackingUrlTemplate) ); } else { var negativeAdGroupCriterion = adGroupCriterion as NegativeAdGroupCriterion; if (negativeAdGroupCriterion != null) { OutputStatusMessage(string.Format("{0}Not Bidding on this Condition", "".PadLeft(treeLevel, '\t')) ); } } } var nullAttribute = ((ProductPartition)(adGroupCriterion.Criterion)).ParentCriterionId != null ? "(All other)" : "(Tree Root)"; OutputStatusMessage(string.Format("{0}Attribute: {1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(adGroupCriterion.Criterion)).Condition.Attribute ?? nullAttribute) ); OutputStatusMessage(string.Format("{0}Operand: {1}\n", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(adGroupCriterion.Criterion)).Condition.Operand) ); foreach (BulkAdGroupProductPartition childNode in childBranches[(long)(adGroupCriterion.Id)]) { OutputProductPartitionTree(childNode, childBranches, treeLevel + 1); } }
/// <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="adGroupId">The ID of the ad group.</param> /// <param name="replaceExistingTree">The boolean to indicate whether to replace the /// existing listing group tree on the ad group, if it already exists. The example will /// throw a <code>LISTING_GROUP_ALREADY_EXISTS</code> error if listing group tree already /// exists and this option is not set to true.</param> public void Run(GoogleAdsClient client, long customerId, long adGroupId, bool replaceExistingTree) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V3.AdGroupCriterionService); try { // 1) Optional: Remove the existing listing group tree, if it already exists on the // ad group. if (replaceExistingTree) { RemoveListingGroupTree(client, customerId, adGroupId); } // Create a list of ad group criterion to add List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = CreateListingGroupSubdivisionRoot( customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionRoot }); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.New } }, 200_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionNew }); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.Used } }, 100_000L ); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionUsed }); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = CreateListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { // All sibling nodes must have the same dimension type, even if they // don't contain a bid. ProductCondition = new ProductConditionInfo() } ); // Get the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionOther }); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CoolBrand" } }, 900_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCoolBrand }); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CheapBrand" } }, 10_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCheapBrand }); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() }, 50_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandOther }); // Issues a mutate request to add the ad group criterion to the ad group. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); // Display the results. foreach (MutateAdGroupCriterionResult mutateAdGroupCriterionResult in response.Results) { Console.WriteLine("Added ad group criterion for listing group with resource " + $"name: '{mutateAdGroupCriterionResult.ResourceName}."); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> /// <param name="adGroupId">Id of the ad group to which keywords are added. /// </param> public void Run(AdWordsUser user, long adGroupId) { // Get the AdGroupCriterionService. AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService(AdWordsService.v201506.AdGroupCriterionService); // Set partial failure mode for the service. adGroupCriterionService.RequestHeader.partialFailure = true; List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); // Create the placements. string[] urls = new String[] { "http://mars.google.com", "http:/mars.google.com", "mars.google.com" }; foreach (String url in urls) { Placement placement = new Placement(); placement.url = url; // Create biddable ad group criterion. BiddableAdGroupCriterion placementBiddableAdGroupCriterion = new BiddableAdGroupCriterion(); placementBiddableAdGroupCriterion.adGroupId = adGroupId; placementBiddableAdGroupCriterion.criterion = placement; // Create the operation. AdGroupCriterionOperation placementAdGroupCriterionOperation = new AdGroupCriterionOperation(); placementAdGroupCriterionOperation.operand = placementBiddableAdGroupCriterion; placementAdGroupCriterionOperation.@operator = Operator.ADD; operations.Add(placementAdGroupCriterionOperation); } try { // Create the placements. AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations.ToArray()); // Display the results. if (result != null && result.value != null) { foreach (AdGroupCriterion adGroupCriterionResult in result.value) { if (adGroupCriterionResult.criterion != null) { Console.WriteLine("Placement with ad group id '{0}', and criterion " + "id '{1}', and url '{2}' was added.\n", adGroupCriterionResult.adGroupId, adGroupCriterionResult.criterion.id, ((Placement)adGroupCriterionResult.criterion).url); } } } else { Console.WriteLine("No placements were added."); } // Display the partial failure errors. if (result != null && result.partialFailureErrors != null) { foreach (ApiError apiError in result.partialFailureErrors) { int operationIndex = ErrorUtilities.GetOperationIndex(apiError.fieldPath); if (operationIndex != -1) { AdGroupCriterion adGroupCriterion = operations[operationIndex].operand; Console.WriteLine("Placement with ad group id '{0}' and url '{1}' " + "triggered a failure for the following reason: '{2}'.\n", adGroupCriterion.adGroupId, ((Placement)adGroupCriterion.criterion).url, apiError.errorString); } else { Console.WriteLine("A failure for the following reason: '{0}' has occurred.\n", apiError.errorString); } } } } catch (Exception e) { throw new System.ApplicationException("Failed to add placements in partial failure mode.", e); } }
/// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="adGroupId">ID of the ad group to which keywords are added.</param> /// <param name="keywordText">The keyword text to add to the ad group.</param> public void Run(GoogleAdsClient client, long customerId, long adGroupId, string keywordText) { // Get the AdGroupCriterionServiceClient. AdGroupCriterionServiceClient service = client.GetService( Services.V10.AdGroupCriterionService); if (string.IsNullOrEmpty(keywordText)) { keywordText = DEFAULT_KEYWORD; } // Configures the keyword text and match type settings. KeywordInfo keywordInfo = new KeywordInfo() { Text = keywordText, MatchType = KeywordMatchType.Exact }; // Constructs an ad group criterion using the keyword text info above. AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), Status = AdGroupCriterionStatus.Paused, Keyword = keywordInfo }; AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { Create = adGroupCriterion }; try { try { // Try sending a mutate request to add the keyword. MutateAdGroupCriteriaResponse response = service.MutateAdGroupCriteria( customerId.ToString(), new[] { operation }); Console.WriteLine($"Added a keyword with resource name " + $"'{response.Results[0].ResourceName}'."); } catch (GoogleAdsException ex) { PolicyViolationKey[] exemptPolicyViolationKeys = FetchExemptPolicyViolationKeys(ex); // Try sending exemption requests for creating a keyword. However, if your // keyword contains many policy violations, but not all of them are exemptible, // the request will not be sent. RequestExemption(customerId, service, operation, exemptPolicyViolationKeys); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <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="adGroupId">ID of the ad group to which targeting criteria are added. /// </param> public void Run(GoogleAdsClient client, long customerId, long adGroupId) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V5.AdGroupCriterionService); string adGroupResourceName = ResourceNames.AdGroup(customerId, adGroupId); // Creates a positive ad group criterion for gender. AdGroupCriterion genderAdGroupCriterion = new AdGroupCriterion() { AdGroup = adGroupResourceName, // Targets male. Gender = new GenderInfo() { Type = GenderType.Male } }; // Creates a negative ad group criterion for age range. AdGroupCriterion ageRangeNegativeAdGroupCriterion = new AdGroupCriterion() { AdGroup = adGroupResourceName, // Makes this ad group criterion negative. Negative = true, // Targets the age range of 18 to 24. AgeRange = new AgeRangeInfo() { Type = AgeRangeType.AgeRange1824 } }; // Creates ad group criterion operations for both ad group criteria. AdGroupCriterionOperation[] operations = new AdGroupCriterionOperation[] { new AdGroupCriterionOperation() { Create = genderAdGroupCriterion }, new AdGroupCriterionOperation() { Create = ageRangeNegativeAdGroupCriterion } }; try { // Issues a mutate request to add the ad group criteria and print out some // information. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); Console.WriteLine($"Added {response.Results.Count} demographic ad group" + $" criteria:"); foreach (MutateAdGroupCriterionResult result in response.Results) { Console.WriteLine(result.ResourceName); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <summary> /// Sets the Add action for a new BiddableAdGroupCriterion corresponding to the specified ProductCondition, /// and adds it to the helper's list of AdGroupCriterionAction. /// </summary> /// <param name="parent">The parent of the product partition subdivision that you want to add.</param> /// <param name="condition">The condition or product filter for the new product partition.</param> /// <returns>The ad group criterion that was added to the list of PartitionActions.</returns> public AdGroupCriterion AddSubdivision( AdGroupCriterion parent, ProductCondition condition ) { var biddableAdGroupCriterion = new BiddableAdGroupCriterion() { Id = this.referenceId--, Criterion = new ProductPartition() { // If the root node is a unit, it would not have a parent ParentCriterionId = parent != null ? parent.Id : null, Condition = condition, PartitionType = ProductPartitionType.Subdivision }, CriterionBid = null, AdGroupId = this.adGroupId }; var partitionAction = new AdGroupCriterionAction() { Action = ItemAction.Add, AdGroupCriterion = biddableAdGroupCriterion }; this.partitionActions.Add(partitionAction); return biddableAdGroupCriterion; }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> /// <param name="adGroupId">Id of the ad group to which keywords are added. /// </param> public void Run(AdWordsUser user, long adGroupId) { using (AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService( AdWordsService.v201710.AdGroupCriterionService)) { // Set partial failure mode for the service. adGroupCriterionService.RequestHeader.partialFailure = true; try { List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); // Create the keywords. string[] keywords = new String[] { "mars cruise", "inv@lid cruise", "venus cruise", "b(a)d keyword cruise" }; foreach (String keywordText in keywords) { Keyword keyword = new Keyword(); keyword.text = keywordText; keyword.matchType = KeywordMatchType.BROAD; // Create biddable ad group criterion. BiddableAdGroupCriterion keywordBiddableAdGroupCriterion = new BiddableAdGroupCriterion(); keywordBiddableAdGroupCriterion.adGroupId = adGroupId; keywordBiddableAdGroupCriterion.criterion = keyword; // Create the operation. AdGroupCriterionOperation keywordAdGroupCriterionOperation = new AdGroupCriterionOperation(); keywordAdGroupCriterionOperation.operand = keywordBiddableAdGroupCriterion; keywordAdGroupCriterionOperation.@operator = Operator.ADD; operations.Add(keywordAdGroupCriterionOperation); } // Create the keywords. AdGroupCriterionReturnValue result = adGroupCriterionService.mutate( operations.ToArray()); // Display the results. if (result != null && result.value != null) { foreach (AdGroupCriterion adGroupCriterionResult in result.value) { if (adGroupCriterionResult.criterion != null) { Console.WriteLine("Keyword with ad group id '{0}', criterion id '{1}', and " + "text '{2}' was added.\n", adGroupCriterionResult.adGroupId, adGroupCriterionResult.criterion.id, ((Keyword)adGroupCriterionResult.criterion).text); } } } else { Console.WriteLine("No keywords were added."); } // Display the partial failure errors. if (result != null && result.partialFailureErrors != null) { foreach (ApiError apiError in result.partialFailureErrors) { int operationIndex = apiError.GetOperationIndex(); if (operationIndex != -1) { AdGroupCriterion adGroupCriterion = operations[operationIndex].operand; Console.WriteLine("Keyword with ad group id '{0}' and text '{1}' " + "triggered a failure for the following reason: '{2}'.\n", adGroupCriterion.adGroupId, ((Keyword)adGroupCriterion.criterion).text, apiError.errorString); } else { Console.WriteLine("A failure for the following reason: '{0}' has occurred.\n", apiError.errorString); } } } } catch (Exception e) { throw new System.ApplicationException("Failed to add keywords in partial failure mode.", e); } } }
/// <summary> /// Sets the Add action for a new AdGroupCriterion corresponding to the specified ProductCondition, /// and adds it to the helper's list of AdGroupCriterionAction. /// </summary> /// <param name="parent">The parent of the product partition unit that you want to add.</param> /// <param name="condition">The condition or product filter for the new product partition.</param> /// <param name="bidAmount">The bid amount for the new product partition.</param> /// <param name="isNegative">Indicates whether or not to add a NegativeAdGroupCriterion. /// The default value is false, in which case a BiddableAdGroupCriterion will be added.</param> /// <returns>The ad group criterion that was added to the list of PartitionActions.</returns> public AdGroupCriterion AddUnit( AdGroupCriterion parent, ProductCondition condition, double bidAmount, bool isNegative ) { AdGroupCriterion adGroupCriterion; if (isNegative) { adGroupCriterion = new NegativeAdGroupCriterion(); } else { adGroupCriterion = new BiddableAdGroupCriterion() { CriterionBid = new FixedBid() { Bid = new Bid() { Amount = bidAmount } } }; } adGroupCriterion.Criterion = new ProductPartition() { // If the root node is a unit, it would not have a parent ParentCriterionId = parent != null ? parent.Id : null, Condition = condition, PartitionType = ProductPartitionType.Unit }; adGroupCriterion.AdGroupId = this.adGroupId; var partitionAction = new AdGroupCriterionAction() { Action = ItemAction.Add, AdGroupCriterion = adGroupCriterion }; this.partitionActions.Add(partitionAction); return adGroupCriterion; }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> /// <param name="adGroupId">Id of the ad group that contains the keyword. /// </param> /// <param name="keywordId">Id of the keyword to be updated.</param> public void Run(AdWordsUser user, long adGroupId, long keywordId) { using (AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService( AdWordsService.v201802.AdGroupCriterionService)) { // Since we are not updating any keyword-specific fields, it is enough to // create a criterion object. Criterion criterion = new Criterion { id = keywordId }; // Create ad group criterion. BiddableAdGroupCriterion biddableAdGroupCriterion = new BiddableAdGroupCriterion { adGroupId = adGroupId, criterion = criterion }; // Create the bids. BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration(); CpcBid cpcBid = new CpcBid { bid = new Money { microAmount = 1000000 } }; biddingConfig.bids = new Bids[] { cpcBid }; biddableAdGroupCriterion.biddingStrategyConfiguration = biddingConfig; // Create the operation. AdGroupCriterionOperation operation = new AdGroupCriterionOperation { @operator = Operator.SET, operand = biddableAdGroupCriterion }; try { // Update the keyword. AdGroupCriterionReturnValue retVal = adGroupCriterionService.mutate(new AdGroupCriterionOperation[] { operation }); // Display the results. if (retVal != null && retVal.value != null && retVal.value.Length > 0) { AdGroupCriterion adGroupCriterion = retVal.value[0]; long bidAmount = 0; foreach (Bids bids in (adGroupCriterion as BiddableAdGroupCriterion). biddingStrategyConfiguration.bids) { if (bids is CpcBid) { bidAmount = (bids as CpcBid).bid.microAmount; break; } } Console.WriteLine("Keyword with ad group id = '{0}', id = '{1}' was updated with " + "bid amount = '{2}' micros.", adGroupCriterion.adGroupId, adGroupCriterion.criterion.id, bidAmount); } else { Console.WriteLine("No keyword was updated."); } } catch (Exception e) { throw new System.ApplicationException("Failed to update keyword.", e); } } }
/// <summary> /// Outputs the details of the specified product partition node, /// and passes any children to itself recursively. /// </summary> /// <param name="node">The node to output, whether a Subdivision or Unit.</param> /// <param name="childBranches">The child branches or nodes if any exist.</param> /// <param name="treeLevel"> /// The number of descendents from the tree root node. /// Used by this operation to format the tree structure output. /// </param> private void OutputProductPartitionTree( AdGroupCriterion node, Dictionary<long, List<AdGroupCriterion>> childBranches, int treeLevel) { OutputStatusMessage(String.Format("{0}{1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(node.Criterion)).PartitionType) ); OutputStatusMessage(String.Format("{0}ParentCriterionId: {1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(node.Criterion)).ParentCriterionId) ); OutputStatusMessage(String.Format("{0}Id: {1}", "".PadLeft(treeLevel, '\t'), node.Id) ); if (((ProductPartition)(node.Criterion)).PartitionType == ProductPartitionType.Unit) { var biddableAdGroupCriterion = node as BiddableAdGroupCriterion; if (biddableAdGroupCriterion != null) { OutputStatusMessage(String.Format("{0}Bid Amount: {1}", "".PadLeft(treeLevel, '\t'), ((FixedBid)(biddableAdGroupCriterion.CriterionBid)).Bid.Amount) ); } else { var negativeAdGroupCriterion = node as NegativeAdGroupCriterion; if (negativeAdGroupCriterion != null) { OutputStatusMessage(String.Format("{0}Not Bidding on this Condition", "".PadLeft(treeLevel, '\t')) ); } } } var nullAttribute = ((ProductPartition)(node.Criterion)).ParentCriterionId != null ? "(All other)" : "(Tree Root)"; OutputStatusMessage(String.Format("{0}Attribute: {1}", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(node.Criterion)).Condition.Attribute ?? nullAttribute) ); OutputStatusMessage(String.Format("{0}Operand: {1}\n", "".PadLeft(treeLevel, '\t'), ((ProductPartition)(node.Criterion)).Condition.Operand) ); foreach (AdGroupCriterion childNode in childBranches[(long)(node.Id)]) { OutputProductPartitionTree(childNode, childBranches, treeLevel + 1); } }
/// <summary> /// Creates child nodes on level 1, partitioned by the hotel class info. /// </summary> /// <param name="customerId">The Google Ads customer ID.</param> /// <param name="adGroupId">The ad group ID to which the hotel listing group will be /// added.</param> /// <param name="rootResourceName">The string resource name of the listing group's root node.</param> /// <param name="operations">A list of AdGroupCriterionOperations.</param> /// <param name="percentCpcBidMicroAmount">The CPC bid micro amount to be set on created /// ad group criteria.</param> /// <returns>The string resource name of the "other hotel classes" node, which serves as the /// parent node for the next level of the listing tree.</returns> private string AddLevel1Nodes(long customerId, long adGroupId, string rootResourceName, List <AdGroupCriterionOperation> operations, long percentCpcBidMicroAmount) { // Create listing dimension info for 5-star class hotels. ListingDimensionInfo fiveStarredListingDimensionInfo = new ListingDimensionInfo { HotelClass = new HotelClassInfo { Value = 5 } }; // Create a listing group info for 5-star hotels as a UNIT node. ListingGroupInfo fiveStarredUnit = CreateListingGroupInfo(ListingGroupType.Unit, rootResourceName, fiveStarredListingDimensionInfo); // Create an ad group criterion for 5-star hotels. AdGroupCriterion fiveStarredAdGroupCriterion = CreateAdGroupCriterion(customerId, adGroupId, fiveStarredUnit, percentCpcBidMicroAmount); // Create an operation and add it to the list of operations. operations.Add(new AdGroupCriterionOperation { Create = fiveStarredAdGroupCriterion }); // Decrement the temp ID for the next ad group criterion. nextTempId--; // You can also create more UNIT nodes for other hotel classes by copying the above code // in this method and modifying the value passed to HotelClassInfo(). // For instance, passing 4 instead of 5 in the above code will instead create a UNIT // node of 4-star hotels. // Create hotel class info and dimension info for other hotel classes by *not* // specifying any attributes on those object. ListingDimensionInfo otherHotelsListingDimensionInfo = new ListingDimensionInfo { HotelClass = new HotelClassInfo() }; // Create listing group info for other hotel classes as a SUBDIVISION node, which will // be used as a parent node for children nodes of the next level. ListingGroupInfo otherHotelsSubdivisionListingGroupInfo = CreateListingGroupInfo (ListingGroupType.Subdivision, rootResourceName, otherHotelsListingDimensionInfo); // Create an ad group criterion for other hotel classes. AdGroupCriterion otherHotelsAdGroupCriterion = CreateAdGroupCriterion(customerId, adGroupId, otherHotelsSubdivisionListingGroupInfo, percentCpcBidMicroAmount); // Create an operation and add it to the list of operations. operations.Add(new AdGroupCriterionOperation { Create = otherHotelsAdGroupCriterion }); // Decrement the temp ID for the next ad group criterion. nextTempId--; return(otherHotelsAdGroupCriterion.ResourceName); }