Campaign Management Samples

The code samples below provide examples for managing campaigns using the AdWords API. Client Library.

Add a campaign group and sets a performance target for that group

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.Linq;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example adds a campaign group and sets a performance target for that group. To
  /// get campaigns, run GetCampaigns.cs. To download reports, run
  /// DownloadCriteriaReportWithAwql.cs.
  /// </summary>
  public class AddCampaignGroupsAndPerformanceTargets : ExampleBase {

    /// <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) {
      AddCampaignGroupsAndPerformanceTargets codeExample =
          new AddCampaignGroupsAndPerformanceTargets();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId1 = long.Parse("INSERT_CAMPAIGN_ID1_HERE");
        long campaignId2 = long.Parse("INSERT_CAMPAIGN_ID2_HERE");
        codeExample.Run(new AdWordsUser(), campaignId1, campaignId2);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example adds a campaign group and sets a performance target for " +
            "that group. To get campaigns, run GetCampaigns.cs. To download reports, run " +
            "DownloadCriteriaReportWithAwql.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId1">Id of the campaign to be added to the campaign group.</param>
    /// <param name="campaignId2">Id of the campaign to be added to the campaign group.</param>
    public void Run(AdWordsUser user, long campaignId1, long campaignId2) {
      CampaignGroup campaignGroup = CreateCampaignGroup(user);
      AddCampaignsToGroup(user, campaignGroup.id, new long[] { campaignId1, campaignId2 });
      CreatePerformanceTarget(user, campaignGroup.id);
      Console.WriteLine("Campaign group and its performance target were setup successfully.");
    }

    /// <summary>
    /// Create a campaign group.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns>The campaign group.</returns>
    private static CampaignGroup CreateCampaignGroup(AdWordsUser user) {
      // Get the CampaignGroupService.
      CampaignGroupService campaignGroupService =
          (CampaignGroupService) user.GetService(AdWordsService.v201708.CampaignGroupService);

      // Create the campaign group.
      CampaignGroup campaignGroup = new CampaignGroup();
      campaignGroup.name = "Mars campaign group - " + ExampleUtilities.GetShortRandomString();

      // Create the operation.
      CampaignGroupOperation operation = new CampaignGroupOperation();
      operation.operand = campaignGroup;
      operation.@operator = Operator.ADD;

      try {
        CampaignGroupReturnValue retval = campaignGroupService.mutate(
            new CampaignGroupOperation[] { operation });

        // Display the results.
        CampaignGroup newCampaignGroup = retval.value[0];
        Console.WriteLine("Campaign group with ID = '{0}' and name = '{1}' was created.",
            newCampaignGroup.id, newCampaignGroup.name);
        return newCampaignGroup;
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add campaign group.", e);
      }
    }

    /// <summary>
    /// Adds multiple campaigns to a campaign group.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignGroupId">The campaign group ID.</param>
    /// <param name="campaignIds">IDs of the campaigns to be added to the campaign group.</param>
    private static void AddCampaignsToGroup(AdWordsUser user, long campaignGroupId,
        long[] campaignIds) {
      // Get the CampaignService.
      CampaignService campaignService = (CampaignService) user.GetService(
          AdWordsService.v201708.CampaignService);

      List<CampaignOperation> operations = new List<CampaignOperation>();

      for (int i = 0; i < campaignIds.Length; i++) {
        Campaign campaign = new Campaign();
        campaign.id = campaignIds[i];
        campaign.campaignGroupId = campaignGroupId;

        CampaignOperation operation = new CampaignOperation();
        operation.operand = campaign;
        operation.@operator = Operator.SET;
        operations.Add(operation);
      }

      try {
        CampaignReturnValue retval = campaignService.mutate(operations.ToArray());
        List<long> updatedCampaignIds = new List<long>();
        retval.value.ToList().ForEach(
            updatedCampaign => updatedCampaignIds.Add(updatedCampaign.id));

        // Display the results.
        Console.WriteLine("The following campaign IDs were added to the campaign group " +
          "with ID '{0}':\n\t{1}'", campaignGroupId, string.Join(", ", updatedCampaignIds));
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add campaigns to campaign group.", e);
      }
    }

    /// <summary>
    /// Creates a performance target for the campaign group.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignGroupId">Campaign group ID.</param>
    /// <returns>The newly created performance target.</returns>
    private static CampaignGroupPerformanceTarget CreatePerformanceTarget(AdWordsUser user,
        long campaignGroupId) {
      // Get the CampaignGroupPerformanceTargetService.
      CampaignGroupPerformanceTargetService campaignGroupPerformanceTargetService =
          (CampaignGroupPerformanceTargetService) user.GetService(
              AdWordsService.v201708.CampaignGroupPerformanceTargetService);

      // Create the performance target.
      CampaignGroupPerformanceTarget campaignGroupPerformanceTarget =
        new CampaignGroupPerformanceTarget();
      campaignGroupPerformanceTarget.campaignGroupId = campaignGroupId;

      PerformanceTarget performanceTarget = new PerformanceTarget();
      // Keep the CPC for the campaigns < $3.
      performanceTarget.efficiencyTargetType = EfficiencyTargetType.CPC_LESS_THAN_OR_EQUAL_TO;
      performanceTarget.efficiencyTargetValue = 3000000;

      // Keep the maximum spend under $50.
      performanceTarget.spendTargetType = SpendTargetType.MAXIMUM;
      Money maxSpend = new Money();
      maxSpend.microAmount = 500000000;
      performanceTarget.spendTarget = maxSpend;

      // Aim for at least 3000 clicks.
      performanceTarget.volumeTargetValue = 3000;
      performanceTarget.volumeGoalType = VolumeGoalType.MAXIMIZE_CLICKS;

      // Start the performance target today, and run it for the next 90 days.
      System.DateTime startDate = System.DateTime.Now;
      System.DateTime endDate = startDate.AddDays(90);

      performanceTarget.startDate = startDate.ToString("yyyyMMdd");
      performanceTarget.endDate = endDate.ToString("yyyyMMdd");

      campaignGroupPerformanceTarget.performanceTarget = performanceTarget;

      // Create the operation.
      CampaignGroupPerformanceTargetOperation operation =
          new CampaignGroupPerformanceTargetOperation();
      operation.operand = campaignGroupPerformanceTarget;
      operation.@operator = Operator.ADD;

      try {
        CampaignGroupPerformanceTargetReturnValue retval =
            campaignGroupPerformanceTargetService.mutate(
                new CampaignGroupPerformanceTargetOperation[] { operation });

        // Display the results.
        CampaignGroupPerformanceTarget newCampaignPerfTarget = retval.value[0];

        Console.WriteLine("Campaign performance target with id = '{0}' was added for " +
            "campaign group ID '{1}'.", newCampaignPerfTarget.id,
            newCampaignPerfTarget.campaignGroupId);
        return newCampaignPerfTarget;
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create campaign performance target.", e);
      }
    }
  }
}

Add a label to multiple campaigns

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example adds a label to multiple campaigns.
  /// </summary>
  public class AddCampaignLabels : ExampleBase {

    /// <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) {
      AddCampaignLabels codeExample = new AddCampaignLabels();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId1 = long.Parse("INSERT_CAMPAIGN_ID1_HERE");
        long campaignId2 = long.Parse("INSERT_CAMPAIGN_ID2_HERE");
        long labelId = long.Parse("INSERT_LABEL_ID_HERE");
        codeExample.Run(new AdWordsUser(), campaignId1, campaignId2, labelId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example adds a label to multiple campaigns.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId1">Id of the campaign to which labels are
    /// added.</param>
    /// <param name="campaignId2">Id of the campaign to which labels are
    /// added.</param>
    /// <param name="labelId">ID of the label to apply.</param>
    public void Run(AdWordsUser user, long campaignId1, long campaignId2, long labelId) {
      try {
        // Get the CampaignService.
        CampaignService campaignService =
            (CampaignService) user.GetService(AdWordsService.v201708.CampaignService);

        // Create label operations.
        List<CampaignLabelOperation> operations = new List<CampaignLabelOperation>();

        foreach (long campaignId in new long[] { campaignId1, campaignId2 }) {
          CampaignLabel campaignLabel = new CampaignLabel();
          campaignLabel.campaignId = campaignId;
          campaignLabel.labelId = labelId;

          CampaignLabelOperation operation = new CampaignLabelOperation();
          operation.operand = campaignLabel;
          operation.@operator = Operator.ADD;

          operations.Add(operation);
        }
        CampaignLabelReturnValue retval = campaignService.mutateLabel(
        operations.ToArray());

        // Display campaign labels.
        if (retval != null && retval.value != null) {
          foreach (CampaignLabel newCampaignLabel in retval.value) {
            Console.WriteLine("Campaign label for campaign ID {0} and label ID {1} was added.\n",
                newCampaignLabel.campaignId, newCampaignLabel.labelId);
          }
        } else {
          Console.WriteLine("No campaign labels were added.");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add campaign label.", e);
      }
    }
  }
}

Add complete campaigns using batch jobs

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.BatchJob.v201708;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.Threading;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code sample illustrates how to use BatchJobService to create multiple
  /// complete campaigns, including ad groups and keywords.
  /// </summary>
  public class AddCompleteCampaignsUsingBatchJob : ExampleBase {

    /// <summary>
    /// The last ID that was automatically generated.
    /// </summary>
    private static long LAST_ID = -1;

    /// <summary>
    /// The number of campaigns to be added.
    /// </summary>
    private const long NUMBER_OF_CAMPAIGNS_TO_ADD = 2;

    /// <summary>
    /// The number of ad groups to be added per campaign.
    /// </summary>
    private const long NUMBER_OF_ADGROUPS_TO_ADD = 2;

    /// <summary>
    /// The number of keywords to be added per campaign.
    /// </summary>
    private const long NUMBER_OF_KEYWORDS_TO_ADD = 5;

    /// <summary>
    /// The polling interval base to be used for exponential backoff.
    /// </summary>
    private const int POLL_INTERVAL_SECONDS_BASE = 30;

    /// <summary>
    /// The maximum milliseconds to wait for completion.
    /// </summary>
    private const int TIME_TO_WAIT_FOR_COMPLETION = 15 * 60 * 1000; // 15 minutes

    /// <summary>
    /// Create a temporary ID generator that will produce a sequence of descending
    /// negative numbers.
    /// </summary>
    /// <returns></returns>
    private static long NextId() {
      return Interlocked.Decrement(ref LAST_ID);
    }

    /// <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) {
      AddCompleteCampaignsUsingBatchJob codeExample = new AddCompleteCampaignsUsingBatchJob();
      Console.WriteLine(codeExample.Description);
      try {
        codeExample.Run(new AdWordsUser());
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code sample illustrates how to use BatchJobService to create multiple " +
            "complete campaigns, including ad groups and keywords.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    public void Run(AdWordsUser user) {
      // Get the BatchJobService.
      BatchJobService batchJobService = (BatchJobService) user.GetService(
          AdWordsService.v201708.BatchJobService);

      try {
        // Create a BatchJob.
        BatchJobOperation addOp = new BatchJobOperation() {
          @operator = Operator.ADD,
          operand = new BatchJob()
        };

        BatchJob batchJob = batchJobService.mutate(new BatchJobOperation[] { addOp }).value[0];

        // Get the upload URL from the new job.
        string uploadUrl = batchJob.uploadUrl.url;

        Console.WriteLine("Created BatchJob with ID {0}, status '{1}' and upload URL {2}.",
            batchJob.id, batchJob.status, batchJob.uploadUrl.url);

        // Create the mutate request that will be sent to the upload URL.
        List<Operation> operations = new List<Operation>();

        // Create and add an operation to create a new budget.
        BudgetOperation budgetOperation = BuildBudgetOperation();
        operations.Add(budgetOperation);

        // Create and add operations to create new campaigns.
        List<CampaignOperation> campaignOperations =
            BuildCampaignOperations(budgetOperation.operand.budgetId);
        operations.AddRange(campaignOperations);

        // Create and add operations to create new ad groups.
        List<AdGroupOperation> adGroupOperations = new List<AdGroupOperation>();
        foreach (CampaignOperation campaignOperation in campaignOperations) {
          adGroupOperations.AddRange(BuildAdGroupOperations(campaignOperation.operand.id));
        }
        operations.AddRange(adGroupOperations);

        // Create and add operations to create new ad group ads (expanded text ads).
        foreach (AdGroupOperation adGroupOperation in adGroupOperations) {
          operations.AddRange(BuildAdGroupAdOperations(adGroupOperation.operand.id));
        }

        // Create and add operations to create new ad group criteria (keywords).
        foreach (AdGroupOperation adGroupOperation in adGroupOperations) {
          operations.AddRange(BuildAdGroupCriterionOperations(adGroupOperation.operand.id));
        }

        BatchJobUtilities batchJobUploadHelper = new BatchJobUtilities(user);

        // Create a resumable Upload URL to upload the operations.
        string resumableUploadUrl = batchJobUploadHelper.GetResumableUploadUrl(uploadUrl);

        // Use the BatchJobUploadHelper to upload all operations.
        batchJobUploadHelper.Upload(resumableUploadUrl, operations);

        bool isCompleted = batchJobUploadHelper.WaitForPendingJob(batchJob.id,
          TIME_TO_WAIT_FOR_COMPLETION, delegate(BatchJob waitBatchJob, long timeElapsed) {
            Console.WriteLine("[{0} seconds]: Batch job ID {1} has status '{2}'.",
                              timeElapsed / 1000, waitBatchJob.id, waitBatchJob.status);
            batchJob = waitBatchJob;
            return false;
          });

        if (!isCompleted) {
          throw new TimeoutException("Job is still in pending state after waiting for " +
             TIME_TO_WAIT_FOR_COMPLETION + " seconds.");
        }

        if (batchJob.processingErrors != null) {
          foreach (BatchJobProcessingError processingError in batchJob.processingErrors) {
            Console.WriteLine("  Processing error: {0}, {1}, {2}, {3}, {4}",
                processingError.ApiErrorType, processingError.trigger,
                processingError.errorString, processingError.fieldPath,
                processingError.reason);
          }
        }

        if (batchJob.downloadUrl != null && batchJob.downloadUrl.url != null) {
          BatchJobMutateResponse mutateResponse = batchJobUploadHelper.Download(
              batchJob.downloadUrl.url);
          Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url);
          foreach (MutateResult mutateResult in mutateResponse.rval) {
            String outcome = mutateResult.errorList == null ? "SUCCESS" : "FAILURE";
            Console.WriteLine("  Operation [{0}] - {1}", mutateResult.index, outcome);
          }
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add campaigns using batch job.", e);
      }
    }

    /// <summary>
    /// Builds the operation for creating an ad within an ad group.
    /// </summary>
    /// <param name="adGroupId">ID of the ad group for which ads are created.</param>
    /// <returns>A list of operations for creating ads.</returns>
    private static List<AdGroupAdOperation> BuildAdGroupAdOperations(long adGroupId) {
      List<AdGroupAdOperation> operations = new List<AdGroupAdOperation>();
      AdGroupAd adGroupAd = new AdGroupAd() {
        adGroupId = adGroupId,
        ad = new ExpandedTextAd() {
          headlinePart1 = "Luxury Cruise to Mars",
          headlinePart2 = "Visit the Red Planet in style.",
          description = "Low-gravity fun for everyone!",
          finalUrls = new String[] { "http://www.example.com/1" }
        }
      };

      AdGroupAdOperation operation = new AdGroupAdOperation() {
        operand = adGroupAd,
        @operator = Operator.ADD
      };
      operations.Add(operation);
      return operations;
    }

    /// <summary>
    /// Builds the operations for creating keywords within an ad group.
    /// </summary>
    /// <param name="adGroupId">ID of the ad group for which keywords are
    /// created.</param>
    /// <returns>A list of operations for creating keywords.</returns>
    private static List<AdGroupCriterionOperation> BuildAdGroupCriterionOperations(
        long adGroupId) {
      List<AdGroupCriterionOperation> adGroupCriteriaOperations =
          new List<AdGroupCriterionOperation>();

      // Create AdGroupCriterionOperations to add keywords.

      for (int i = 0; i < NUMBER_OF_KEYWORDS_TO_ADD; i++) {
        // Create Keyword.
        String text = String.Format("mars{0}", i);

        // Make 50% of keywords invalid to demonstrate error handling.
        if ((i % 2) == 0) {
          text = text + "!!!";
        }

        // Create AdGroupCriterionOperation.
        AdGroupCriterionOperation operation = new AdGroupCriterionOperation() {
          operand = new BiddableAdGroupCriterion() {
            adGroupId = adGroupId,
            criterion = new Keyword() {
              text = text,
              matchType = KeywordMatchType.BROAD
            }
          },
          @operator = Operator.ADD
        };

        // Add to list.
        adGroupCriteriaOperations.Add(operation);
      }
      return adGroupCriteriaOperations;
    }

    /// <summary>
    /// Builds the operations for creating ad groups within a campaign.
    /// </summary>
    /// <param name="campaignId">ID of the campaign for which ad groups are
    /// created.</param>
    /// <returns>A list of operations for creating ad groups.</returns>
    private static List<AdGroupOperation> BuildAdGroupOperations(long campaignId) {
      List<AdGroupOperation> operations = new List<AdGroupOperation>();
      for (int i = 0; i < NUMBER_OF_ADGROUPS_TO_ADD; i++) {
        AdGroup adGroup = new AdGroup() {
          campaignId = campaignId,
          id = NextId(),
          name = "Batch Ad Group # " + ExampleUtilities.GetRandomString(),
          biddingStrategyConfiguration = new BiddingStrategyConfiguration() {
            bids = new Bids[] {
                new CpcBid() {
                  bid = new Money() {
                    microAmount = 10000000L
                  }
                }
              }
          }
        };

        AdGroupOperation operation = new AdGroupOperation() {
          operand = adGroup,
          @operator = Operator.ADD
        };

        operations.Add(operation);
      }
      return operations;
    }

    /// <summary>
    /// Builds the operations for creating new campaigns.
    /// </summary>
    /// <param name="budgetId">ID of the budget to be used for the campaign.
    /// </param>
    /// <returns>A list of operations for creating campaigns.</returns>
    private static List<CampaignOperation> BuildCampaignOperations(long budgetId) {
      List<CampaignOperation> operations = new List<CampaignOperation>();

      for (int i = 0; i < NUMBER_OF_CAMPAIGNS_TO_ADD; i++) {
        Campaign campaign = new Campaign() {
          name = "Batch Campaign " + ExampleUtilities.GetRandomString(),

          // Recommendation: Set the campaign to PAUSED when creating it to prevent
          // the ads from immediately serving. Set to ENABLED once you've added
          // targeting and the ads are ready to serve.
          status = CampaignStatus.PAUSED,
          id = NextId(),
          advertisingChannelType = AdvertisingChannelType.SEARCH,
          budget = new Budget() {
            budgetId = budgetId
          },
          biddingStrategyConfiguration = new BiddingStrategyConfiguration() {
            biddingStrategyType = BiddingStrategyType.MANUAL_CPC,

            // You can optionally provide a bidding scheme in place of the type.
            biddingScheme = new ManualCpcBiddingScheme() {
              enhancedCpcEnabled = false
            }
          }
        };

        CampaignOperation operation = new CampaignOperation() {
          operand = campaign,
          @operator = Operator.ADD
        };
        operations.Add(operation);
      }
      return operations;
    }

    /// <summary>
    /// Builds an operation for creating a budget.
    /// </summary>
    /// <returns>The operation for creating a budget.</returns>
    private static BudgetOperation BuildBudgetOperation() {
      Budget budget = new Budget() {
        budgetId = NextId(),
        name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString(),
        amount = new Money() {
          microAmount = 50000000L,
        },
        deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD,
      };

      BudgetOperation budgetOperation = new BudgetOperation() {
        operand = budget,
        @operator = Operator.ADD
      };
      return budgetOperation;
    }
  }
}

Add a draft

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example illustrates how to create a draft and access its
  /// associated draft campaign. See the Campaign Drafts and Experiments guide
  /// for more information:
  /// https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
  /// </summary>
  public class AddDraft : ExampleBase {

    /// <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) {
      AddDraft codeExample = new AddDraft();
      Console.WriteLine(codeExample.Description);
      try {
        long baseCampaignId = long.Parse("INSERT_BASE_CAMPAIGN_ID_HERE");
        codeExample.Run(new AdWordsUser(), baseCampaignId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example illustrates how to create a draft and access its associated " +
            "draft campaign. See the Campaign Drafts and Experiments guide for more " +
            "information: " +
            "https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="baseCampaignId">Id of the campaign to use as base of the
    /// draft.</param>
    public void Run(AdWordsUser user, long baseCampaignId) {
      // Get the DraftService.
      DraftService draftService = (DraftService) user.GetService(
          AdWordsService.v201708.DraftService);
      Draft draft = new Draft() {
        baseCampaignId = baseCampaignId,
        draftName = "Test Draft #" + ExampleUtilities.GetRandomString()
      };

      DraftOperation draftOperation = new DraftOperation() {
        @operator = Operator.ADD,
        operand = draft
      };

      try {
        draft = draftService.mutate(new DraftOperation[] {draftOperation}).value[0];

        Console.WriteLine("Draft with ID {0}, base campaign ID {1} and draft campaign ID " +
            "{2} created.", draft.draftId, draft.baseCampaignId, draft.draftCampaignId);

        // Once the draft is created, you can modify the draft campaign as if it
        // were a real campaign. For example, you may add criteria, adjust bids,
        // or even include additional ads. Adding a criterion is shown here.
        CampaignCriterionService campaignCriterionService =
          (CampaignCriterionService) user.GetService(
              AdWordsService.v201708.CampaignCriterionService);
        Language language = new Language() {
          id = 1003L // Spanish
        };

        // Make sure to use the draftCampaignId when modifying the virtual draft
        // campaign.
        CampaignCriterion campaignCriterion = new CampaignCriterion() {
          campaignId = draft.draftCampaignId,
          criterion = language
        };

        CampaignCriterionOperation criterionOperation = new CampaignCriterionOperation() {
          @operator = Operator.ADD,
          operand = campaignCriterion
        };

        campaignCriterion = campaignCriterionService.mutate(
            new CampaignCriterionOperation[] {criterionOperation}).value[0];
        Console.WriteLine("Draft updated to include criteria in draft campaign ID {0}.",
            draft.draftCampaignId);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create draft campaign and add " +
            "criteria.", e);
      }
    }
  }
}

Add keywords using an incremental batch job

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Util.BatchJob.v201708;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Google.Api.Ads.AdWords.Lib;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code sample illustrates how to perform asynchronous requests using
  /// BatchJobService and incremental uploads of operations. It also
  /// demonstrates how to cancel a running batch job.
  /// </summary>
  public class AddKeywordsUsingIncrementalBatchJob : ExampleBase {
    private const long NUMBER_OF_KEYWORDS_TO_ADD = 100;

    // The chunk size to use when uploading operations.
    private const int CHUNK_SIZE = 4 * 1024 * 1024;

    /// <summary>
    /// The maximum milliseconds to wait for completion.
    /// </summary>
    private const int TIME_TO_WAIT_FOR_COMPLETION = 15 * 60 * 1000; // 15 minutes

    /// <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) {
      AddKeywordsUsingIncrementalBatchJob codeExample = new AddKeywordsUsingIncrementalBatchJob();
      Console.WriteLine(codeExample.Description);
      try {
        long adGroupId = long.Parse("INSERT_ADGROUP_ID_HERE");
        codeExample.Run(new AdWordsUser(), adGroupId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code sample illustrates how to perform asynchronous requests using " +
            "BatchJobService and incremental uploads of operations. It also demonstrates " +
            "how to cancel a running batch job.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad groups to which keywords are
    /// added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the MutateJobService.
      BatchJobService batchJobService = (BatchJobService) user.GetService(
          AdWordsService.v201708.BatchJobService);

      BatchJobOperation addOp = new BatchJobOperation() {
        @operator = Operator.ADD,
        operand = new BatchJob()
      };

      try {
        BatchJob batchJob = batchJobService.mutate(new BatchJobOperation[] { addOp }).value[0];

        Console.WriteLine("Created BatchJob with ID {0}, status '{1}' and upload URL {2}.",
            batchJob.id, batchJob.status, batchJob.uploadUrl.url);

        List<AdGroupCriterionOperation> operations = CreateOperations(adGroupId);

        // Create a BatchJobUtilities instance for uploading operations. Use a
        // chunked upload.
        BatchJobUtilities batchJobUploadHelper = new BatchJobUtilities(user, true, CHUNK_SIZE);

        // Create a resumable Upload URL to upload the operations.
        string resumableUploadUrl = batchJobUploadHelper.GetResumableUploadUrl(
            batchJob.uploadUrl.url);

        // Use the BatchJobUploadHelper to upload all operations.
        batchJobUploadHelper.Upload(resumableUploadUrl, operations.ToArray());

        // A flag to determine if the job was requested to be cancelled. This
        // typically comes from the user.
        bool wasCancelRequested = false;

        bool isComplete = batchJobUploadHelper.WaitForPendingJob(batchJob.id,
          TIME_TO_WAIT_FOR_COMPLETION, delegate(BatchJob waitBatchJob, long timeElapsed) {
            Console.WriteLine("[{0} seconds]: Batch job ID {1} has status '{2}'.",
                              timeElapsed / 1000, waitBatchJob.id, waitBatchJob.status);
            batchJob = waitBatchJob;
            return wasCancelRequested;
          });

        // Optional: Cancel the job if it has not completed after waiting for
        // TIME_TO_WAIT_FOR_COMPLETION.
        bool shouldWaitForCancellation = false;
        if (!isComplete && wasCancelRequested) {
          BatchJobError cancellationError = null;
          try {
            batchJobUploadHelper.TryToCancelJob(batchJob.id);
          } catch (AdWordsApiException e) {
            cancellationError = GetBatchJobError(e);
          }
          if (cancellationError == null) {
            Console.WriteLine("Successfully requested job cancellation.");
            shouldWaitForCancellation = true;
          } else {
            Console.WriteLine("Job cancellation failed. Error says: {0}.",
                cancellationError.reason);
          }

          if (shouldWaitForCancellation) {
            isComplete = batchJobUploadHelper.WaitForPendingJob(batchJob.id,
              TIME_TO_WAIT_FOR_COMPLETION, delegate(BatchJob waitBatchJob, long timeElapsed) {
                Console.WriteLine("[{0} seconds]: Batch job ID {1} has status '{2}'.",
                                  timeElapsed / 1000, waitBatchJob.id, waitBatchJob.status);
                batchJob = waitBatchJob;
                return false;
              });
          }
        }

        if (!isComplete) {
          throw new TimeoutException("Job is still in pending state after waiting for " +
              TIME_TO_WAIT_FOR_COMPLETION + " seconds.");
        }

        if (batchJob.processingErrors != null) {
          foreach (BatchJobProcessingError processingError in batchJob.processingErrors) {
            Console.WriteLine("  Processing error: {0}, {1}, {2}, {3}, {4}",
                processingError.ApiErrorType, processingError.trigger,
                processingError.errorString, processingError.fieldPath,
                processingError.reason);
          }
        }

        if (batchJob.downloadUrl != null && batchJob.downloadUrl.url != null) {
          BatchJobMutateResponse mutateResponse = batchJobUploadHelper.Download(
              batchJob.downloadUrl.url);
          Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url);
          foreach (MutateResult mutateResult in mutateResponse.rval) {
            String outcome = mutateResult.errorList == null ? "SUCCESS" : "FAILURE";
            Console.WriteLine("  Operation [{0}] - {1}", mutateResult.index, outcome);
          }
        } else {
          Console.WriteLine("No results available for download.");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create keywords using batch job.", e);
      }
    }

    /// <summary>
    /// Gets the batch job error.
    /// </summary>
    /// <param name="e">The AdWords API Exception.</param>
    /// <returns>The underlying batch job error if available, null otherwise.</returns>
    private BatchJobError GetBatchJobError(AdWordsApiException e) {
      return (e.ApiException as ApiException).GetAllErrorsByType<BatchJobError>().
          FirstOrDefault();
    }

    /// <summary>
    /// Creates the operations for uploading via batch job.
    /// </summary>
    /// <param name="adGroupId">The ad group ID.</param>
    /// <returns>The list of operations.</returns>
    private static List<AdGroupCriterionOperation> CreateOperations(long adGroupId) {
      List<AdGroupCriterionOperation> operations = new List<AdGroupCriterionOperation>();

      // Create AdGroupCriterionOperations to add keywords, and upload every 10 operations
      // incrementally.
      for (int i = 0; i < NUMBER_OF_KEYWORDS_TO_ADD; i++) {
        // Create Keyword.
        String text = String.Format("mars{0}", i);

        // Make 10% of keywords invalid to demonstrate error handling.
        if (i % 10 == 0) {
          text = text + "!!!";
        }

        // Create BiddableAdGroupCriterion.
        BiddableAdGroupCriterion bagc = new BiddableAdGroupCriterion() {
          adGroupId = adGroupId,
          criterion = new Keyword() {
            text = text,
            matchType = KeywordMatchType.BROAD
          }
        };

        // Create AdGroupCriterionOperation.
        AdGroupCriterionOperation agco = new AdGroupCriterionOperation() {
          operand = bagc,
          @operator = Operator.ADD
        };

        // Add to the list of operations.
        operations.Add(agco);
      }
      return operations;
    }
  }
}

Add a trial

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.Threading;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example illustrates how to create a trial and wait for it to
  /// complete. See the Campaign Drafts and Experiments guide for more
  /// information:
  /// https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
  /// </summary>
  public class AddTrial : ExampleBase {

    /// <summary>
    /// The polling interval base to be used for exponential backoff.
    /// </summary>
    private const int POLL_INTERVAL_SECONDS_BASE = 30;

    /// <summary>
    /// The maximum number of retries.
    /// </summary>
    private const long MAX_RETRIES = 5;

    /// <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) {
      AddTrial codeExample = new AddTrial();
      Console.WriteLine(codeExample.Description);
      try {
        long draftId = long.Parse("INSERT_DRAFT_ID_HERE");
        long baseCampaignId = long.Parse("INSERT_BASE_CAMPAIGN_ID_HERE");
        codeExample.Run(new AdWordsUser(), draftId, baseCampaignId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example illustrates how to create a trial and wait for it to " +
            "complete. See the Campaign Drafts and Experiments guide for more information: " +
            "https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="baseCampaignId">Id of the campaign to use as base of the
    /// trial.</param>
    /// <param name="draftId">Id of the draft.</param>
    public void Run(AdWordsUser user, long draftId, long baseCampaignId) {
      // Get the TrialService.
      TrialService trialService = (TrialService) user.GetService(
        AdWordsService.v201708.TrialService);

      Trial trial = new Trial() {
        draftId = draftId,
        baseCampaignId = baseCampaignId,
        name = "Test Trial #" + ExampleUtilities.GetRandomString(),
        trafficSplitPercent = 50
      };

      TrialOperation trialOperation = new TrialOperation() {
        @operator = Operator.ADD,
        operand = trial
      };
      try {
        long trialId = trialService.mutate(new TrialOperation[] { trialOperation }).value[0].id;

        // Since creating a trial is asynchronous, we have to poll it to wait
        // for it to finish.
        Selector trialSelector = new Selector() {
          fields = new string[] {
            Trial.Fields.Id, Trial.Fields.Status, Trial.Fields.BaseCampaignId,
            Trial.Fields.TrialCampaignId
          },
          predicates = new Predicate[] {
            Predicate.Equals(Trial.Fields.Id, trialId)
          }
        };

        trial = null;
        bool isPending = true;
        int pollAttempts = 0;

        do {
          int sleepMillis = (int) Math.Pow(2, pollAttempts) *
              POLL_INTERVAL_SECONDS_BASE * 1000;
          Console.WriteLine("Sleeping {0} millis...", sleepMillis);
          Thread.Sleep(sleepMillis);

          trial = trialService.get(trialSelector).entries[0];

          Console.WriteLine("Trial ID {0} has status '{1}'.", trial.id, trial.status);
          pollAttempts++;
          isPending = (trial.status == TrialStatus.CREATING);
        } while (isPending && pollAttempts <= MAX_RETRIES);

        if (trial.status == TrialStatus.ACTIVE) {
          // The trial creation was successful.
          Console.WriteLine("Trial created with ID {0} and trial campaign ID {1}.",
              trial.id, trial.trialCampaignId);
        } else if (trial.status == TrialStatus.CREATION_FAILED) {
          // The trial creation failed, and errors can be fetched from the
          // TrialAsyncErrorService.
          Selector errorsSelector = new Selector() {
            fields = new string[] {
              TrialAsyncError.Fields.TrialId, TrialAsyncError.Fields.AsyncError
            },
            predicates = new Predicate[] {
              Predicate.Equals(TrialAsyncError.Fields.TrialId, trial.id)
            }
          };

          TrialAsyncErrorService trialAsyncErrorService =
              (TrialAsyncErrorService) user.GetService(
                  AdWordsService.v201708.TrialAsyncErrorService);

          TrialAsyncErrorPage trialAsyncErrorPage = trialAsyncErrorService.get(errorsSelector);
          if (trialAsyncErrorPage.entries == null || trialAsyncErrorPage.entries.Length == 0) {
            Console.WriteLine("Could not retrieve errors for trial {0}.", trial.id);
          } else {
            Console.WriteLine("Could not create trial ID {0} for draft ID {1} due to the " +
                "following errors:", trial.id, draftId);
            int i = 0;
            foreach (TrialAsyncError error in trialAsyncErrorPage.entries) {
              ApiError asyncError = error.asyncError;
              Console.WriteLine("Error #{0}: errorType='{1}', errorString='{2}', trigger='{3}'," +
                " fieldPath='{4}'", i++, asyncError.ApiErrorType, asyncError.errorString,
                asyncError.trigger, asyncError.fieldPath);
            }
          }
        } else {
            // Most likely, the trial is still being created. You can continue
            // polling, but we have limited the number of attempts in the
            // example.
            Console.WriteLine("Timed out waiting to create trial from draft ID {0} with " +
                "base campaign ID {1}.", draftId, baseCampaignId);
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create trial from draft.", e);
      }
    }
  }
}

Get all disapproved ads in an ad group

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {
  /// <summary>
  /// This code example retrieves all the disapproved ads in a given campaign.
  /// </summary>
  public class GetAllDisapprovedAds : ExampleBase {
    /// <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) {
      GetAllDisapprovedAds codeExample = new GetAllDisapprovedAds();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId = long.Parse("INSERT_CAMPAIGN_ID_HERE");
        codeExample.Run(new AdWordsUser(), campaignId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example retrieves all the disapproved ads in a given campaign.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign for which disapproved ads
    /// are retrieved.</param>
    public void Run(AdWordsUser user, long campaignId) {
      // Get the AdGroupAdService.
      AdGroupAdService service =
          (AdGroupAdService) user.GetService(AdWordsService.v201708.AdGroupAdService);

      // Create the selector.
      Selector selector = new Selector() {
        fields = new string[] {
          Ad.Fields.Id, AdGroupAd.Fields.PolicySummary
        },
        predicates = new Predicate[] {
          Predicate.Equals(AdGroup.Fields.CampaignId, campaignId),
          Predicate.Equals(AdGroupAdPolicySummary.Fields.CombinedApprovalStatus, 
              PolicyApprovalStatus.DISAPPROVED.ToString())
        },
        paging = Paging.Default
      };

      AdGroupAdPage page = new AdGroupAdPage();
      int disapprovedAdsCount = 0;

      try {
        do {
          // Get the disapproved ads.
          page = service.get(selector);

          // Display the results.
          if (page != null && page.entries != null) {
            foreach (AdGroupAd adGroupAd in page.entries) {
              AdGroupAdPolicySummary policySummary = adGroupAd.policySummary;
              disapprovedAdsCount++;
              Console.WriteLine("Ad with ID {0} and type '{1}' was disapproved with the " +
                  "following policy topic entries: ", adGroupAd.ad.id, adGroupAd.ad.AdType);
              foreach (PolicyTopicEntry policyTopicEntry in policySummary.policyTopicEntries) {
                Console.WriteLine("  topic id: {0}, topic name: '{1}'",
                    policyTopicEntry.policyTopicId, policyTopicEntry.policyTopicName);
              }
            }
          }

          selector.paging.IncreaseOffset();
        } while (selector.paging.startIndex < page.totalNumEntries);
        Console.WriteLine("Number of disapproved ads found: {0}", disapprovedAdsCount);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to get disapproved ads.", e);
      }
    }
  }
}

Get all disapproved ads in an ad group using AWQL

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example retrieves all the disapproved ads in a given campaign
  /// using AWQL. See https://developers.google.com/adwords/api/docs/guides/awql
  /// for AWQL documentation.
  /// </summary>
  public class GetAllDisapprovedAdsWithAwql : ExampleBase {

    /// <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) {
      GetAllDisapprovedAdsWithAwql codeExample = new GetAllDisapprovedAdsWithAwql();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId = long.Parse("INSERT_CAMPAIGN_ID_HERE");
        codeExample.Run(new AdWordsUser(), campaignId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example retrieves all the disapproved ads in a given campaign using " +
            "AWQL. See https://developers.google.com/adwords/api/docs/guides/awql for AWQL " +
            "documentation.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign for which disapproved ads
    /// are retrieved.</param>
    public void Run(AdWordsUser user, long campaignId) {
      // Get the AdGroupAdService.
      AdGroupAdService service =
          (AdGroupAdService) user.GetService(AdWordsService.v201708.AdGroupAdService);

      // Get all the disapproved ads for this campaign.
      string query = string.Format("SELECT Id, PolicySummary WHERE CampaignId = {0} and " +
          "CombinedApprovalStatus = DISAPPROVED ORDER BY Id", campaignId);

      int offset = 0;
      int pageSize = 500;

      AdGroupAdPage page = new AdGroupAdPage();
      int disapprovedAdsCount = 0;

      try {
        do {
          string queryWithPaging = string.Format("{0} LIMIT {1}, {2}", query, offset, pageSize);

          // Get the disapproved ads.
          page = service.query(queryWithPaging);

          // Display the results.
          if (page != null && page.entries != null) {
            foreach (AdGroupAd adGroupAd in page.entries) {
              AdGroupAdPolicySummary policySummary = adGroupAd.policySummary;
              disapprovedAdsCount++;
              Console.WriteLine("Ad with ID {0} and type '{1}' was disapproved with the " +
                  "following policy topic entries: ", adGroupAd.ad.id, adGroupAd.ad.AdType);
              foreach (PolicyTopicEntry policyTopicEntry in policySummary.policyTopicEntries) {
                Console.WriteLine("  topic id: {0}, topic name: '{1}'",
                    policyTopicEntry.policyTopicId, policyTopicEntry.policyTopicName);
              }
            }
          }
          offset += pageSize;
        } while (offset < page.totalNumEntries);

        Console.WriteLine("Number of disapproved ads found: {0}", disapprovedAdsCount);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to get disapproved ads.", e);
      }
    }
  }
}

Get all campaigns with a specific label

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example gets all campaigns with a specific label. To add a
  /// label to campaigns, run AddCampaignLabels.cs.
  /// </summary>
  public class GetCampaignsByLabel : ExampleBase {

    /// <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) {
      GetCampaignsByLabel codeExample = new GetCampaignsByLabel();
      Console.WriteLine(codeExample.Description);
      try {
        long labelId = long.Parse("INSERT_LABEL_ID_HERE");
        codeExample.Run(new AdWordsUser(), labelId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example gets all campaigns with a specific label. To add a label " +
            "to campaigns, run AddCampaignLabels.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="labelId">ID of the label.</param>
    public void Run(AdWordsUser user, long labelId) {
      // Get the CampaignService.
      CampaignService campaignService =
          (CampaignService) user.GetService(AdWordsService.v201708.CampaignService);

      // Create the selector.
      Selector selector = new Selector() {
        fields = new string[] { 
          Campaign.Fields.Id, Campaign.Fields.Name, Campaign.Fields.Labels
        },
        predicates = new Predicate[] {
          // Labels filtering is performed by ID. You can use CONTAINS_ANY to
          // select campaigns with any of the label IDs, CONTAINS_ALL to select
          // campaigns with all of the label IDs, or CONTAINS_NONE to select
          // campaigns with none of the label IDs.
          Predicate.ContainsAny(Campaign.Fields.Labels, new string[] { labelId.ToString() })
        },
        paging = Paging.Default
      };

      CampaignPage page = new CampaignPage();

      try {
        do {
          // Get the campaigns.
          page = campaignService.get(selector);

          // Display the results.
          if (page != null && page.entries != null) {
            int i = selector.paging.startIndex;
            foreach (Campaign campaign in page.entries) {
              List<string> labelNames = new List<string>();
              foreach (Label label in campaign.labels) {
                labelNames.Add(label.name);
              }

              Console.WriteLine("{0}) Campaign with id = '{1}', name = '{2}' and labels = '{3}'" +
                  " was found.", i + 1, campaign.id, campaign.name,
                  string.Join(", ", labelNames.ToArray()));
              i++;
            }
          }
          selector.paging.IncreaseOffset();
        } while (selector.paging.startIndex < page.totalNumEntries);
        Console.WriteLine("Number of campaigns found: {0}", page.totalNumEntries);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to retrieve campaigns by label", e);
      }
    }
  }
}

Graduate a trial

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.Threading;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {

  /// <summary>
  /// This code example illustrates how to graduate a trial. See the Campaign
  /// Drafts and Experiments guide for more information: 
  /// https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments
  /// </summary>
  public class GraduateTrial : ExampleBase {

    /// <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) {
      GraduateTrial codeExample = new GraduateTrial();
      Console.WriteLine(codeExample.Description);
      try {
        long trialId = long.Parse("INSERT_TRIAL_ID_HERE");
        codeExample.Run(new AdWordsUser(), trialId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example illustrates how to graduate a trial. See the Campaign " +
            "Drafts and Experiments guide for more information: " +
            "https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="trialId">Id of the trial to be graduated.</param>
    public void Run(AdWordsUser user, long trialId) {
      // Get the TrialService and BudgetService.
      TrialService trialService = (TrialService) user.GetService(
          AdWordsService.v201708.TrialService);
      BudgetService budgetService = (BudgetService) user.GetService(
          AdWordsService.v201708.BudgetService);

      try {
        // To graduate a trial, you must specify a different budget from the
        // base campaign. The base campaign (in order to have had a trial based
        // on it) must have a non-shared budget, so it cannot be shared with
        // the new independent campaign created by graduation.
        Budget budget = new Budget() {
          name = "Budget #" + ExampleUtilities.GetRandomString(),
          amount = new Money() {
            microAmount = 50000000L
          },
          deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD
        };

        BudgetOperation budgetOperation = new BudgetOperation() {
          @operator = Operator.ADD,
          operand = budget
        };

        // Add budget.
        long budgetId = budgetService.mutate(
            new BudgetOperation[] {budgetOperation}).value[0].budgetId;

        Trial trial = new Trial() {
          id = trialId,
          budgetId = budgetId,
          status = TrialStatus.GRADUATED
        };

        TrialOperation trialOperation = new TrialOperation() {
          @operator = Operator.SET,
          operand = trial
        };

        // Update the trial.
        trial = trialService.mutate(new TrialOperation[] {trialOperation}).value[0];

        // Graduation is a synchronous operation, so the campaign is already
        // ready. If you promote instead, make sure to see the polling scheme
        // demonstrated in AddTrial.cs to wait for the asynchronous operation
        // to finish.
        Console.WriteLine("Trial ID {0} graduated. Campaign ID {1} was given a new budget " +
            "ID {2} and is no longer dependent on this trial.", trial.id, trial.trialCampaignId,
            budgetId);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to graduate trial.", e);
      }
    }
  }
}

Set ad parameters

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {
  /// <summary>
  /// This code example illustrates how to create a text ad with ad parameters.
  /// To add an ad group, run AddAdGroup.cs. To add a keyword, run
  /// run AddKeyword.cs.
  /// </summary>
  public class SetAdParameters : ExampleBase {
    /// <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) {
      SetAdParameters codeExample = new SetAdParameters();
      Console.WriteLine(codeExample.Description);
      try {
        long adGroupId = long.Parse("INSERT_ADGROUP_ID_HERE");
        long criterionId = long.Parse("INSERT_CRITERION_ID_HERE");
        codeExample.Run(new AdWordsUser(), adGroupId, criterionId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example illustrates how to create a text ad with ad parameters." +
            " To add an ad group, run AddAdGroup.cs. To add a keyword, run AddKeyword.vb.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group that contains the criterion.
    /// </param>
    /// <param name="criterionId">Id of the keyword for which the ad
    /// parameters are set.</param>
    public void Run(AdWordsUser user, long adGroupId, long criterionId) {
      // Get the AdGroupAdService.
      AdGroupAdService adGroupAdService = (AdGroupAdService) user.GetService(
          AdWordsService.v201708.AdGroupAdService);

      // Get the AdParamService.
      AdParamService adParamService = (AdParamService) user.GetService(
          AdWordsService.v201708.AdParamService);

      // Create the expanded text ad.
      ExpandedTextAd expandedTextAd = new ExpandedTextAd();
      expandedTextAd.headlinePart1 = "Mars Cruises";
      expandedTextAd.headlinePart2 = "Low-gravity fun for {param1:cheap}.";
      expandedTextAd.description = "Only {param2:a few} seats left!";
      expandedTextAd.finalUrls = new string[] { "http://www.example.com" };

      AdGroupAd adOperand = new AdGroupAd();
      adOperand.adGroupId = adGroupId;
      adOperand.status = AdGroupAdStatus.ENABLED;
      adOperand.ad = expandedTextAd;

      // Create the operation.
      AdGroupAdOperation adOperation = new AdGroupAdOperation();
      adOperation.operand = adOperand;
      adOperation.@operator = Operator.ADD;

      // Create the text ad.
      AdGroupAdReturnValue retVal = adGroupAdService.mutate(
          new AdGroupAdOperation[] {adOperation});

      // Display the results.
      if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
        Console.WriteLine("Expanded text ad with id ='{0}' was successfully added.",
            retVal.value[0].ad.id);
      } else {
        throw new System.ApplicationException("Failed to create expanded text ads.");
      }

      // Create the ad param for price.
      AdParam priceParam = new AdParam();
      priceParam.adGroupId = adGroupId;
      priceParam.criterionId = criterionId;
      priceParam.paramIndex = 1;
      priceParam.insertionText = "$100";

      // Create the ad param for seats.
      AdParam seatParam = new AdParam();
      seatParam.adGroupId = adGroupId;
      seatParam.criterionId = criterionId;
      seatParam.paramIndex = 2;
      seatParam.insertionText = "50";

      // Create the operations.
      AdParamOperation priceOperation = new AdParamOperation();
      priceOperation.@operator = Operator.SET;
      priceOperation.operand = priceParam;

      AdParamOperation seatOperation = new AdParamOperation();
      seatOperation.@operator = Operator.SET;
      seatOperation.operand = seatParam;

      try {
        // Set the ad parameters.
        AdParam [] newAdParams = adParamService.mutate(new AdParamOperation[]
            {priceOperation, seatOperation});

        // Display the results.
        if (newAdParams != null) {
          Console.WriteLine("Ad parameters were successfully updated.");
        } else {
          Console.WriteLine("No ad parameters were set.");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to set ad parameters.", e);
      }
    }
  }
}

Set bid modifier

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {
  /// <summary>
  /// This code example sets a bid modifier for the mobile platform on given
  /// campaign. The campaign must be an enhanced type of campaign. To get
  /// campaigns, run GetCampaigns.cs. To enhance a campaign, run
  /// SetCampaignEnhanced.cs.
  /// </summary>
  public class SetBidModifier : ExampleBase {
    /// <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) {
      SetBidModifier codeExample = new SetBidModifier();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId = long.Parse("INSERT_CAMPAIGN_ID_HERE");
        double bidModifier = double.Parse("INSERT_BID_MODIFIER_HERE");
        codeExample.Run(new AdWordsUser(), campaignId, bidModifier);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example sets a bid modifier for the mobile platform on given " +
            "campaign. The campaign must be an enhanced type of campaign. To get campaigns, " +
            "run GetCampaigns.cs. To enhance a campaign, run SetCampaignEnhanced.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign whose bid should be modified.
    /// </param>
    /// <param name="bidModifier">The bid modifier.</param>
    public void Run(AdWordsUser user, long campaignId, double bidModifier) {
      // Get the CampaignCriterionService.
      CampaignCriterionService campaignCriterionService =
          (CampaignCriterionService) user.GetService(
              AdWordsService.v201708.CampaignCriterionService);

      // Create mobile platform. The ID can be found in the documentation.
      // https://developers.google.com/adwords/api/docs/appendix/platforms
      Platform mobile = new Platform();
      mobile.id = 30001;

      // Create criterion with modified bid.
      CampaignCriterion criterion = new CampaignCriterion();
      criterion.campaignId = campaignId;
      criterion.criterion = mobile;
      criterion.bidModifier = bidModifier;

      // Create SET operation.
      CampaignCriterionOperation operation = new CampaignCriterionOperation();
      operation.@operator = Operator.SET;
      operation.operand = criterion;

      try {
        // Update campaign criteria.
        CampaignCriterionReturnValue result = campaignCriterionService.mutate(
            new CampaignCriterionOperation[] {operation});

        // Display campaign criteria.
        if (result.value != null) {
          foreach (CampaignCriterion newCriterion in result.value) {
            Console.WriteLine("Campaign criterion with campaign id '{0}', criterion id '{1}', " +
                "and type '{2}' was modified with bid {3:F2}.", newCriterion.campaignId,
                newCriterion.criterion.id, newCriterion.criterion.type, newCriterion.bidModifier);
          }
        } else {
          Console.WriteLine("No campaign criteria were modified.");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to set bid modifier for campaign.", e);
      }
    }
  }
}

Validate text ad

// Copyright 2017, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201708;

using System;
using System.Collections.Generic;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201708 {
  /// <summary>
  /// This code example shows how to use the validateOnly header to validate
  /// an expanded text ad. No objects will be created, but exceptions will
  /// still be thrown.
  /// </summary>
  public class ValidateTextAd : ExampleBase {
    /// <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) {
      ValidateTextAd codeExample = new ValidateTextAd();
      Console.WriteLine(codeExample.Description);
      try {
        long adGroupId = long.Parse("INSERT_ADGROUP_ID_HERE");
        codeExample.Run(new AdWordsUser(), adGroupId);
      } catch (Exception e) {
        Console.WriteLine("An exception occurred while running this code example. {0}",
            ExampleUtilities.FormatException(e));
      }
    }

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example shows how to use the validateOnly header to validate an " +
            "expanded text ad. No objects will be created, but exceptions will still be thrown.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group to which text ads are
    /// added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the AdGroupAdService.
      AdGroupAdService adGroupAdService =
          (AdGroupAdService) user.GetService(AdWordsService.v201708.AdGroupAdService);

      // Set the validateOnly headers.
      adGroupAdService.RequestHeader.validateOnly = true;

      // Create your expanded text ad.
      ExpandedTextAd expandedTextAd = new ExpandedTextAd() {
        headlinePart1 = "Luxury Cruise to Mars",
        headlinePart2 = "Visit the Red Planet in style.",
        description = "Low-gravity fun for everyone!!",
        finalUrls = new string[] { "http://www.example.com" }
      };

      AdGroupAd adGroupAd = new AdGroupAd() {
        adGroupId = adGroupId,
        ad = expandedTextAd
      };

      AdGroupAdOperation operation = new AdGroupAdOperation() {
        @operator = Operator.ADD,
        operand = adGroupAd
      };

      try {
        adGroupAdService.mutate(new AdGroupAdOperation[] {operation});
        // Since validation is ON, result will be null.
        Console.WriteLine("Expanded text ad validated successfully.");
      } catch (AdWordsApiException e) {
        // This block will be hit if there is a validation error from the server.
        Console.WriteLine("There were validation error(s) while adding expanded text ad.");

        if (e.ApiException != null) {
          foreach (ApiError error in ((ApiException) e.ApiException).errors) {
            Console.WriteLine("  Error type is '{0}' and fieldPath is '{1}'.",
                error.ApiErrorType, error.fieldPath);
          }
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to validate expanded text ad.", e);
      }
    }
  }
}

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.