Advanced Operations Samples

The code samples below provide examples of common advanced operations using the AdWords API. Client Library.

Add an ad customizer feed

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example adds an ad customizer feed. Then it adds an ad in two
  /// different ad groups that uses the feed to populate dynamic data.
  /// </summary>
  public class AddAdCustomizers : 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) {
      AddAdCustomizers codeExample = new AddAdCustomizers();
      Console.WriteLine(codeExample.Description);
      try {
        long adGroupId1 = long.Parse("INSERT_ADGROUP_ID_HERE");
        long adGroupId2 = long.Parse("INSERT_ADGROUP_ID_HERE");
        string feedName = "INSERT_FEED_NAME_HERE";
        codeExample.Run(new AdWordsUser(), adGroupId1, adGroupId2, feedName);
      } 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 an ad customizer feed. Then it adds an ad in two " +
            "different ad groups that uses the feed to populate dynamic data.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId1">Id of the first adgroup to which ads with ad
    /// customizers are added.</param>
    /// <param name="adGroupId2">Id of the second adgroup to which ads with ad
    /// customizers are added.</param>
    /// <param name="feedName">Name of the feed to be created.</param>
    public void Run(AdWordsUser user, long adGroupId1, long adGroupId2, string feedName) {
      try {
        // Create a customizer feed. One feed per account can be used for all ads.
        AdCustomizerFeed adCustomizerFeed = CreateCustomizerFeed(user, feedName);

        // Add feed items containing the values we'd like to place in ads.
        CreateCustomizerFeedItems(user, new long[] { adGroupId1, adGroupId2 }, adCustomizerFeed);

        // All set! We can now create ads with customizations.
        CreateAdsWithCustomizations(user, new long[] { adGroupId1, adGroupId2 }, feedName);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add ad customizers.", e);
      }
    }

    /// <summary>
    /// Creates a new Feed for ad customizers.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="feedName">Name of the feed to be created.</param>
    /// <returns>A new Ad customizer feed.</returns>
    private static AdCustomizerFeed CreateCustomizerFeed(AdWordsUser user, string feedName) {
      using (AdCustomizerFeedService adCustomizerFeedService =
          (AdCustomizerFeedService) user.GetService(
              AdWordsService.v201806.AdCustomizerFeedService)) {
        AdCustomizerFeed feed = new AdCustomizerFeed() {
          feedName = feedName,
          feedAttributes = new AdCustomizerFeedAttribute[] {
            new AdCustomizerFeedAttribute() {
              name = "Name",
              type = AdCustomizerFeedAttributeType.STRING
            },
            new AdCustomizerFeedAttribute() {
              name = "Price",
              type = AdCustomizerFeedAttributeType.PRICE
            },
            new AdCustomizerFeedAttribute() {
              name = "Date",
              type = AdCustomizerFeedAttributeType.DATE_TIME
            },
          }
        };

        AdCustomizerFeedOperation feedOperation = new AdCustomizerFeedOperation() {
          operand = feed,
          @operator = (Operator.ADD)
        };

        AdCustomizerFeed addedFeed = adCustomizerFeedService.mutate(
            new AdCustomizerFeedOperation[] { feedOperation }).value[0];

        Console.WriteLine("Created ad customizer feed with ID = {0} and name = '{1}' and " +
            "attributes: ", addedFeed.feedId, addedFeed.feedName);

        foreach (AdCustomizerFeedAttribute feedAttribute in addedFeed.feedAttributes) {
          Console.WriteLine("  ID: {0}, name: '{1}', type: {2}",
              feedAttribute.id, feedAttribute.name, feedAttribute.type);
        }
        return addedFeed;
      }
    }

    /// <summary>
    /// Restricts the feed item to an ad group.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <param name="feedItem">The feed item.</param>
    /// <param name="adGroupId">The ad group ID.</param>
    private static void RestrictFeedItemToAdGroup(AdWordsUser user,
        FeedItem feedItem, long? adGroupId) {
      FeedItemAdGroupTarget adGroupTarget = new FeedItemAdGroupTarget() {
        feedId = feedItem.feedId,
        feedItemId = feedItem.feedItemId,
        adGroupId = adGroupId.Value
      };

      using (FeedItemTargetService feedItemTargetService = (FeedItemTargetService) user.GetService(
          AdWordsService.v201802.FeedItemTargetService)) {
        FeedItemTargetOperation operation = new FeedItemTargetOperation() {
          @operator = Operator.ADD,
          operand = adGroupTarget
        };

        FeedItemTargetReturnValue retval = feedItemTargetService.mutate(
            new FeedItemTargetOperation[] { operation });
        FeedItemAdGroupTarget newAdGroupTarget = (FeedItemAdGroupTarget) retval.value[0];
        Console.WriteLine("Feed item target for feed ID {0} and feed item ID {1}" +
            " was created to restrict serving to ad group ID {2}",
            newAdGroupTarget.feedId, newAdGroupTarget.feedItemId, newAdGroupTarget.adGroupId);
      }
    }

    /// <summary>
    /// Creates feed items with the values to use in ad customizations for each
    /// ad group in <code>adGroupIds</code>.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupIds">IDs of adgroups to which ad customizations are
    /// made.</param>
    /// <param name="adCustomizerFeed">The ad customizer feed.</param>
    private static void CreateCustomizerFeedItems(AdWordsUser user, long[] adGroupIds,
        AdCustomizerFeed adCustomizerFeed) {
      using (FeedItemService feedItemService = (FeedItemService) user.GetService(
          AdWordsService.v201806.FeedItemService)) {
        List<FeedItemOperation> feedItemOperations = new List<FeedItemOperation>();

        DateTime marsDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
        feedItemOperations.Add(CreateFeedItemAddOperation(adCustomizerFeed, "Mars", "$1234.56",
            marsDate.ToString("yyyyMMdd HHmmss")));

        DateTime venusDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 15);
        feedItemOperations.Add(CreateFeedItemAddOperation(adCustomizerFeed, "Venus", "$1450.00",
            venusDate.ToString("yyyyMMdd HHmmss")));

        FeedItemReturnValue feedItemReturnValue = feedItemService.mutate(
            feedItemOperations.ToArray());

        foreach (FeedItem addedFeedItem in feedItemReturnValue.value) {
          Console.WriteLine("Added feed item with ID {0}", addedFeedItem.feedItemId);
        }

        // Add feed item targeting to restrict the feed item to specific ad groups.
        RestrictFeedItemToAdGroup(user, feedItemReturnValue.value[0], adGroupIds[0]);
        RestrictFeedItemToAdGroup(user, feedItemReturnValue.value[1], adGroupIds[1]);
      }
    }

    /// <summary>
    /// Creates a FeedItemOperation that will create a FeedItem with the
    /// specified values when sent to FeedItemService.mutate.
    /// </summary>
    /// <param name="adCustomizerFeed">The ad customizer feed.</param>
    /// <param name="name">The value for the name attribute of the FeedItem.
    /// </param>
    /// <param name="price">The value for the price attribute of the FeedItem.
    /// </param>
    /// <param name="date">The value for the date attribute of the FeedItem.
    /// </param>
    /// <returns>A new FeedItemOperation for adding a FeedItem.</returns>
    private static FeedItemOperation CreateFeedItemAddOperation(AdCustomizerFeed adCustomizerFeed,
        string name, string price, String date) {
      FeedItem feedItem = new FeedItem() {
        feedId = adCustomizerFeed.feedId,

        // FeedAttributes appear in the same order as they were created
        // - Name, Price, Date. See CreateCustomizerFeed method for details.
        attributeValues = new FeedItemAttributeValue[] {
          new FeedItemAttributeValue() {
            feedAttributeId = adCustomizerFeed.feedAttributes[0].id,
            stringValue = name
          },

          new FeedItemAttributeValue() {
            feedAttributeId = adCustomizerFeed.feedAttributes[1].id,
            stringValue = price
          },

          new FeedItemAttributeValue() {
            feedAttributeId = adCustomizerFeed.feedAttributes[2].id,
            stringValue = date
          }
        },

      };

      return new FeedItemOperation() {
        operand = feedItem,
        @operator = Operator.ADD
      };
    }

    /// <summary>
    /// Creates text ads that use ad customizations for the specified ad group
    /// IDs.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupIds">IDs of the ad groups to which customized ads
    /// are added.</param>
    /// <param name="feedName">Name of the feed to be used.</param>
    private static void CreateAdsWithCustomizations(AdWordsUser user, long[] adGroupIds,
        string feedName) {
      using (AdGroupAdService adGroupAdService = (AdGroupAdService) user.GetService(
          AdWordsService.v201806.AdGroupAdService)) {
        ExpandedTextAd expandedTextAd = new ExpandedTextAd() {
          headlinePart1 = string.Format("Luxury Cruise to {{={0}.Name}}", feedName),
          headlinePart2 = string.Format("Only {{={0}.Price}}", feedName),
          description = string.Format("Offer ends in {{=countdown({0}.Date)}}!", feedName),
          finalUrls = new string[] { "http://www.example.com" }
        };

        // We add the same ad to both ad groups. When they serve, they will show
        // different values, since they match different feed items.
        List<AdGroupAdOperation> adGroupAdOperations = new List<AdGroupAdOperation>();
        foreach (long adGroupId in adGroupIds) {
          AdGroupAd adGroupAd = new AdGroupAd() {
            adGroupId = adGroupId,
            ad = expandedTextAd
          };

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

          adGroupAdOperations.Add(adGroupAdOperation);
        }

        AdGroupAdReturnValue adGroupAdReturnValue = adGroupAdService.mutate(
            adGroupAdOperations.ToArray());

        foreach (AdGroupAd addedAd in adGroupAdReturnValue.value) {
          Console.WriteLine("Created an ad with ID {0}, type '{1}' and status '{2}'.",
              addedAd.ad.id, addedAd.ad.AdType, addedAd.status);
        }
      }
    }
  }
}

Add an ad group level bid modifier

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

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

using System;

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

  /// <summary>
  /// This code example illustrates how to add ad group level mobile bid
  /// modifier override.
  /// </summary>
  public class AddAdGroupBidModifier : 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) {
      AddAdGroupBidModifier codeExample = new AddAdGroupBidModifier();
      Console.WriteLine(codeExample.Description);
      try {
        long adGroupId = long.Parse("INSERT_ADGROUP_ID_HERE");
        double bidModifier = double.Parse("INSERT_ADGROUP_BID_MODIFIER_HERE");
        codeExample.Run(new AdWordsUser(), adGroupId, 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 illustrates how to add ad group level mobile bid modifier " +
            "override.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the adgroup for which bid modifier is
    /// set.</param>
    /// <param name="bidModifier">The mobile bid modifier for adgroup</param>
    public void Run(AdWordsUser user, long adGroupId, double bidModifier) {
      using (AdGroupBidModifierService adGroupBidModifierService =
          (AdGroupBidModifierService) user.GetService(
              AdWordsService.v201806.AdGroupBidModifierService)) {

        // Mobile criterion ID.
        long criterionId = 30001;

        // Create the adgroup bid modifier.
        AdGroupBidModifier adGroupBidModifier = new AdGroupBidModifier();
        adGroupBidModifier.bidModifier = bidModifier;
        adGroupBidModifier.adGroupId = adGroupId;

        Platform platform = new Platform();
        platform.id = criterionId;

        adGroupBidModifier.criterion = platform;

        AdGroupBidModifierOperation operation = new AdGroupBidModifierOperation();
        operation.@operator = Operator.ADD;
        operation.operand = adGroupBidModifier;

        try {
          // Add ad group level mobile bid modifier.
          AdGroupBidModifierReturnValue retval = adGroupBidModifierService.mutate(
              new AdGroupBidModifierOperation[] { operation });

          // Display the results.
          if (retval != null && retval.value != null && retval.value.Length > 0) {
            AdGroupBidModifier newBidModifier = retval.value[0];
            Console.WriteLine("AdGroup ID {0}, Criterion ID {1} was updated with ad group level " +
                "modifier: {2}", newBidModifier.adGroupId, newBidModifier.criterion.id,
                newBidModifier.bidModifier);
          } else {
            Console.WriteLine("No bid modifiers were added to the adgroup.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to add bid modifiers to adgroup.", e);
        }
      }
    }
  }
}

Add a click-to-download template ad to an ad group

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;

using System;

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

  /// <summary>
  /// This code example creates a click-to-download ad, also known as an
  /// app promotion ad to a given ad group. To list ad groups, run
  /// GetAdGroups.cs.
  /// </summary>
  public class AddClickToDownloadAd : 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) {
      AddClickToDownloadAd codeExample = new AddClickToDownloadAd();
      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 creates a click-to-download ad, also known as an app " +
            "promotion ad to a given ad group. To list ad groups, run GetAdGroups.cs.";
      }
    }

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

        // Create the template ad.
        TemplateAd clickToDownloadAppAd = new TemplateAd();

        clickToDownloadAppAd.name = "Ad for demo game";
        clickToDownloadAppAd.templateId = 353;
        clickToDownloadAppAd.finalUrls = new string[] {
          "http://play.google.com/store/apps/details?id=com.example.demogame"
      };
        clickToDownloadAppAd.displayUrl = "play.google.com";

        // Create the template elements for the ad. You can refer to
        // https://developers.google.com/adwords/api/docs/appendix/templateads
        // for the list of avaliable template fields.
        TemplateElementField headline = new TemplateElementField();
        headline.name = "headline";
        headline.fieldText = "Enjoy your drive in Mars";
        headline.type = TemplateElementFieldType.TEXT;

        TemplateElementField description1 = new TemplateElementField();
        description1.name = "description1";
        description1.fieldText = "Realistic physics simulation";
        description1.type = TemplateElementFieldType.TEXT;

        TemplateElementField description2 = new TemplateElementField();
        description2.name = "description2";
        description2.fieldText = "Race against players online";
        description2.type = TemplateElementFieldType.TEXT;

        TemplateElementField appId = new TemplateElementField();
        appId.name = "appId";
        appId.fieldText = "com.example.demogame";
        appId.type = TemplateElementFieldType.TEXT;

        TemplateElementField appStore = new TemplateElementField();
        appStore.name = "appStore";
        appStore.fieldText = "2";
        appStore.type = TemplateElementFieldType.ENUM;

        // Optionally specify a landscape image. The image needs to be in a BASE64
        // encoded form. Here we download a demo image and encode it for this ad.
        byte[] imageData = MediaUtilities.GetAssetDataFromUrl("https://goo.gl/9JmyKk",
            user.Config);
        Image image = new Image();
        image.data = imageData;
        TemplateElementField landscapeImage = new TemplateElementField();
        landscapeImage.name = "landscapeImage";
        landscapeImage.fieldMedia = image;
        landscapeImage.type = TemplateElementFieldType.IMAGE;

        TemplateElement adData = new TemplateElement();
        adData.uniqueName = "adData";
        adData.fields = new TemplateElementField[] {headline, description1, description2, appId,
          appStore, landscapeImage};

        clickToDownloadAppAd.templateElements = new TemplateElement[] { adData };

        // Create the adgroupad.
        AdGroupAd clickToDownloadAppAdGroupAd = new AdGroupAd();
        clickToDownloadAppAdGroupAd.adGroupId = adGroupId;
        clickToDownloadAppAdGroupAd.ad = clickToDownloadAppAd;

        // Optional: Set the status.
        clickToDownloadAppAdGroupAd.status = AdGroupAdStatus.PAUSED;

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

        try {
          // Create the ads.
          AdGroupAdReturnValue retval = adGroupAdService.mutate(
              new AdGroupAdOperation[] { operation });

          // Display the results.
          if (retval != null && retval.value != null) {
            foreach (AdGroupAd adGroupAd in retval.value) {
              Console.WriteLine("New click-to-download ad with id = \"{0}\" and url = \"{1}\" " +
                  "was created.", adGroupAd.ad.id, adGroupAd.ad.finalUrls[0]);
            }
          } else {
            Console.WriteLine("No click-to-download ads were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create click-to-download ad.", e);
        }
      }
    }
  }
}

Add a page feed specifying URLs for a DSA campaign

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

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

using System;

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

  /// <summary>
  /// This code example adds a page feed to specify precisely which URLs to use with your
  /// Dynamic Search Ads campaign. To create a Dynamic Search Ads campaign, run
  /// AddDynamicSearchAdsCampaign.cs. To get campaigns, run GetCampaigns.cs.
  /// </summary>
  public class AddDynamicPageFeed : ExampleBase {

    /// <summary>
    /// The criterion type to be used for DSA page feeds.
    /// </summary>
    /// <remarks>DSA page feeds use criterionType field instead of the placeholderType field unlike
    /// most other feed types.</remarks>
    private const int DSA_PAGE_FEED_CRITERION_TYPE = 61;

    /// <summary>
    /// ID that corresponds to the page URLs.
    /// </summary>
    private const int DSA_PAGE_URLS_FIELD_ID = 1;

    /// <summary>
    /// ID that corresponds to the labels.
    /// </summary>
    private const int DSA_LABEL_FIELD_ID = 2;

    /// <summary>
    /// Class to keep track of DSA page feed details.
    /// </summary>
    private class DSAFeedDetails {
      public long feedId { get; set; }
      public long urlAttributeId { get; set; }
      public long labelAttributeId { get; set; }
    }

    /// <summary>
    /// Main method, to run this code example as a standalone application.
    /// </summary>
    /// <param name="args">The command line arguments.</param>
    public static void Main(string[] args) {
      AddDynamicPageFeed codeExample = new AddDynamicPageFeed();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId = long.Parse("INSERT_CAMPAIGN_ID_HERE");
        long adGroupId = long.Parse("INSERT_ADGROUP_ID_HERE");
        codeExample.Run(new AdWordsUser(), campaignId, 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 adds a page feed to specify precisely which URLs to use " +
            "with your Dynamic Search Ads campaign. To create a Dynamic Search Ads campaign, " +
            "run AddDynamicSearchAdsCampaign.cs. To get campaigns, run GetCampaigns.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">The DSA campaign ID.</param>
    /// <param name="adGroupId">The DSA ad group ID.</param>
    public void Run(AdWordsUser user, long campaignId, long adGroupId) {
      string dsaPageUrlLabel = "discounts";

      // Get the page feed details. This code example creates a new feed, but you can
      // fetch and re-use an existing feed.
      DSAFeedDetails feedDetails = CreateFeed(user);
      CreateFeedMapping(user, feedDetails);
      CreateFeedItems(user, feedDetails, dsaPageUrlLabel);

      // Associate the page feed with the campaign.
      UpdateCampaignDsaSetting(user, campaignId, feedDetails.feedId);

      // Optional: Target web pages matching the feed's label in the ad group.
      AddDsaTargeting(user, adGroupId, dsaPageUrlLabel);

      Console.WriteLine("Dynamic page feed setup is complete for campaign ID '{0}'.",
          campaignId);
    }

    /// <summary>
    /// Creates the feed for DSA page URLs.
    /// </summary>
    /// <param name="user">The AdWords User.</param>
    /// <returns>The feed details.</returns>
    private static DSAFeedDetails CreateFeed(AdWordsUser user) {
      using (FeedService feedService = (FeedService) user.GetService(
          AdWordsService.v201806.FeedService)) {

        // Create attributes.
        FeedAttribute urlAttribute = new FeedAttribute();
        urlAttribute.type = FeedAttributeType.URL_LIST;
        urlAttribute.name = "Page URL";

        FeedAttribute labelAttribute = new FeedAttribute();
        labelAttribute.type = FeedAttributeType.STRING_LIST;
        labelAttribute.name = "Label";

        // Create the feed.
        Feed sitelinksFeed = new Feed();
        sitelinksFeed.name = "DSA Feed " + ExampleUtilities.GetRandomString();
        sitelinksFeed.attributes = new FeedAttribute[] { urlAttribute, labelAttribute };
        sitelinksFeed.origin = FeedOrigin.USER;

        // Create operation.
        FeedOperation operation = new FeedOperation();
        operation.operand = sitelinksFeed;
        operation.@operator = Operator.ADD;

        try {
          // Add the feed.
          FeedReturnValue result = feedService.mutate(new FeedOperation[] { operation });

          Feed savedFeed = result.value[0];
          return new DSAFeedDetails {
            feedId = savedFeed.id,
            urlAttributeId = savedFeed.attributes[0].id,
            labelAttributeId = savedFeed.attributes[1].id,
          };
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create DSA feed.", e);
        }
      }
    }

    /// <summary>
    /// Creates the feed mapping for DSA page feeds.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="feedDetails">The feed details.</param>
    private static void CreateFeedMapping(AdWordsUser user, DSAFeedDetails feedDetails) {
      using (FeedMappingService feedMappingService =
          (FeedMappingService) user.GetService(AdWordsService.v201806.FeedMappingService)) {

        // Map the FeedAttributeIds to the fieldId constants.
        AttributeFieldMapping urlFieldMapping = new AttributeFieldMapping();
        urlFieldMapping.feedAttributeId = feedDetails.urlAttributeId;
        urlFieldMapping.fieldId = DSA_PAGE_URLS_FIELD_ID;

        AttributeFieldMapping labelFieldMapping = new AttributeFieldMapping();
        labelFieldMapping.feedAttributeId = feedDetails.labelAttributeId;
        labelFieldMapping.fieldId = DSA_LABEL_FIELD_ID;

        // Create the FieldMapping and operation.
        FeedMapping feedMapping = new FeedMapping();
        feedMapping.criterionType = DSA_PAGE_FEED_CRITERION_TYPE;
        feedMapping.feedId = feedDetails.feedId;
        feedMapping.attributeFieldMappings = new AttributeFieldMapping[] {
          urlFieldMapping, labelFieldMapping
        };

        FeedMappingOperation operation = new FeedMappingOperation();
        operation.operand = feedMapping;
        operation.@operator = Operator.ADD;

        try {
          // Add the field mapping.
          feedMappingService.mutate(new FeedMappingOperation[] { operation });
          return;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create feed mapping.", e);
        }
      }
    }

    /// <summary>
    /// Creates the page URLs in the DSA page feed.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="feedDetails">The feed details.</param>
    /// <param name="labelName">The pagefeed url label.</param>
    private static void CreateFeedItems(AdWordsUser user, DSAFeedDetails feedDetails,
        string labelName) {
      using (FeedItemService feedItemService = (FeedItemService) user.GetService(
          AdWordsService.v201806.FeedItemService)) {

        FeedItemOperation[] operations = new FeedItemOperation[] {
          CreateDsaUrlAddOperation(feedDetails, "http://www.example.com/discounts/rental-cars",
              labelName),
          CreateDsaUrlAddOperation(feedDetails, "http://www.example.com/discounts/hotel-deals",
              labelName),
          CreateDsaUrlAddOperation(feedDetails, "http://www.example.com/discounts/flight-deals",
              labelName),
        };
        feedItemService.mutate(operations);
      }
    }

    /// <summary>
    /// Creates the DSA URL add operation.
    /// </summary>
    /// <param name="details">The page feed details.</param>
    /// <param name="url">The DSA page feed URL.</param>
    /// <param name="label">DSA page feed label.</param>
    /// <returns>The DSA URL add operation.</returns>
    private static FeedItemOperation CreateDsaUrlAddOperation(DSAFeedDetails details, string url,
        string label) {
      // Create the FeedItemAttributeValues for our text values.
      FeedItemAttributeValue urlAttributeValue = new FeedItemAttributeValue();
      urlAttributeValue.feedAttributeId = details.urlAttributeId;

      // See https://support.google.com/adwords/answer/7166527 for page feed URL recommendations
      // and rules.
      urlAttributeValue.stringValues = new string[] { url };

      FeedItemAttributeValue labelAttributeValue = new FeedItemAttributeValue();
      labelAttributeValue.feedAttributeId = details.labelAttributeId;
      labelAttributeValue.stringValues = new string[] { label };

      // Create the feed item and operation.
      FeedItem item = new FeedItem();
      item.feedId = details.feedId;

      item.attributeValues = new FeedItemAttributeValue[] {
        urlAttributeValue, labelAttributeValue
      };

      FeedItemOperation operation = new FeedItemOperation();
      operation.operand = item;
      operation.@operator = Operator.ADD;

      return operation;
    }

    /// <summary>
    /// Updates the campaign DSA setting to add DSA pagefeeds.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">The Campaign ID.</param>
    /// <param name="feedId">The page feed ID.</param>
    private static void UpdateCampaignDsaSetting(AdWordsUser user, long campaignId, long feedId) {
      using (CampaignService campaignService = (CampaignService) user.GetService(
          AdWordsService.v201806.CampaignService)) {

        Selector selector = new Selector() {
          fields = new string[] { Campaign.Fields.Id, Campaign.Fields.Settings },
          predicates = new Predicate[]{
          Predicate.Equals(Campaign.Fields.Id, campaignId)
        },
          paging = Paging.Default
        };

        CampaignPage page = campaignService.get(selector);

        if (page == null || page.entries == null || page.entries.Length == 0) {
          throw new System.ApplicationException(string.Format(
              "Failed to retrieve campaign with ID = {0}.", campaignId));
        }
        Campaign campaign = page.entries[0];

        if (campaign.settings == null) {
          throw new System.ApplicationException("This is not a DSA campaign.");
        }

        DynamicSearchAdsSetting dsaSetting = null;
        Setting[] campaignSettings = campaign.settings;

        for (int i = 0; i < campaign.settings.Length; i++) {
          Setting setting = campaignSettings[i];
          if (setting is DynamicSearchAdsSetting) {
            dsaSetting = (DynamicSearchAdsSetting) setting;
            break;
          }
        }

        if (dsaSetting == null) {
          throw new System.ApplicationException("This is not a DSA campaign.");
        }

        // Use a page feed to specify precisely which URLs to use with your
        // Dynamic Search Ads.
        dsaSetting.pageFeed = new PageFeed() {
          feedIds = new long[] {
            feedId
          },
        };

        // Optional: Specify whether only the supplied URLs should be used with your
        // Dynamic Search Ads.
        dsaSetting.useSuppliedUrlsOnly = true;

        Campaign campaignToUpdate = new Campaign();
        campaignToUpdate.id = campaignId;
        campaignToUpdate.settings = campaignSettings;

        CampaignOperation operation = new CampaignOperation();
        operation.operand = campaignToUpdate;
        operation.@operator = Operator.SET;

        try {
          CampaignReturnValue retval = campaignService.mutate(
              new CampaignOperation[] { operation });
          Campaign updatedCampaign = retval.value[0];
          Console.WriteLine("DSA page feed for campaign ID '{0}' was updated with feed ID '{1}'.",
              updatedCampaign.id, feedId);
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to set page feed for campaign.", e);
        }
      }
    }

    /// <summary>
    /// Set custom targeting for the page feed URLs based on a list of labels.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Ad group ID.</param>
    /// <param name="labelName">The label name.</param>
    /// <returns>The newly created webpage criterion.</returns>
    private static BiddableAdGroupCriterion AddDsaTargeting(AdWordsUser user, long adGroupId,
        string labelName) {
      using (AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(
              AdWordsService.v201806.AdGroupCriterionService)) {

        // Create a webpage criterion.
        Webpage webpage = new Webpage();

        WebpageParameter parameter = new WebpageParameter();
        parameter.criterionName = "Test criterion";
        webpage.parameter = parameter;

        // Add a condition for label=specified_label_name.
        WebpageCondition condition = new WebpageCondition();
        condition.operand = WebpageConditionOperand.CUSTOM_LABEL;
        condition.argument = labelName;
        parameter.conditions = new WebpageCondition[] { condition };

        BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
        criterion.adGroupId = adGroupId;
        criterion.criterion = webpage;

        // Set a custom bid for this criterion.
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration();

        biddingStrategyConfiguration.bids = new Bids[] {
        new CpcBid() {
          bid = new Money() {
            microAmount = 1500000
          }
        }
      };

        criterion.biddingStrategyConfiguration = biddingStrategyConfiguration;

        AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
        operation.operand = criterion;
        operation.@operator = Operator.ADD;

        try {
          AdGroupCriterionReturnValue retval = adGroupCriterionService.mutate(
              new AdGroupCriterionOperation[] { operation });
          BiddableAdGroupCriterion newCriterion = (BiddableAdGroupCriterion) retval.value[0];

          Console.WriteLine("Web page criterion with ID = {0} and status = {1} was created.",
            newCriterion.criterion.id, newCriterion.userStatus);
          return newCriterion;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create webpage criterion for " +
              "custom page feed label.", e);
        }
      }
    }
  }
}

Add a DSA campaign

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

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

using System;

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

  /// <summary>
  /// This code example adds a Dynamic Search Ads campaign. To get campaigns, run GetCampaigns.cs.
  /// </summary>
  public class AddDynamicSearchAdsCampaign : 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) {
      AddDynamicSearchAdsCampaign codeExample = new AddDynamicSearchAdsCampaign();
      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 example adds a Dynamic Search Ads campaign. To get campaigns, " +
            "run GetCampaigns.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    public void Run(AdWordsUser user) {
      Budget budget = CreateBudget(user);
      Campaign campaign = CreateCampaign(user, budget);
      AdGroup adGroup = CreateAdGroup(user, campaign.id);
      CreateExpandedDSA(user, adGroup.id);
      AddWebPageCriteria(user, adGroup.id);
      Console.WriteLine("Dynamic Search Ads campaign setup is complete.");
    }

    /// <summary>
    /// Creates the budget.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns>The newly created budget.</returns>
    private static Budget CreateBudget(AdWordsUser user) {
      using (BudgetService budgetService =
          (BudgetService) user.GetService(AdWordsService.v201806.BudgetService)) {
        // Create the campaign budget.
        Budget budget = new Budget();
        budget.name = "Interplanetary Cruise Budget #" + ExampleUtilities.GetRandomString();
        budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
        budget.amount = new Money();
        budget.amount.microAmount = 500000;

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

        try {
          BudgetReturnValue budgetRetval = budgetService.mutate(
              new BudgetOperation[] { budgetOperation });
          Budget newBudget = budgetRetval.value[0];
          Console.WriteLine("Budget with ID = '{0}' and name = '{1}' was created.",
              newBudget.budgetId, newBudget.name);
          budgetService.Close();
          return newBudget;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to add budget.", e);
        }
      }
    }


    /// <summary>
    /// Creates the campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="budget">The campaign budget.</param>
    /// <returns>The newly created campaign.</returns>
    private static Campaign CreateCampaign(AdWordsUser user, Budget budget) {
      using (CampaignService campaignService =
          (CampaignService) user.GetService(AdWordsService.v201806.CampaignService)) {
        // Create a Dynamic Search Ads campaign.
        Campaign campaign = new Campaign();
        campaign.name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString();
        campaign.advertisingChannelType = AdvertisingChannelType.SEARCH;

        // Recommendation: Set the campaign to PAUSED when creating it to prevent
        // the ads from immediately serving. Set to ENABLED once you've added
        // targeting and the ads are ready to serve.
        campaign.status = CampaignStatus.PAUSED;

        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
        biddingConfig.biddingStrategyType = BiddingStrategyType.MANUAL_CPC;
        campaign.biddingStrategyConfiguration = biddingConfig;

        campaign.budget = new Budget();
        campaign.budget.budgetId = budget.budgetId;

        // Required: Set the campaign's Dynamic Search Ads settings.
        DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
        // Required: Set the domain name and language.
        dynamicSearchAdsSetting.domainName = "example.com";
        dynamicSearchAdsSetting.languageCode = "en";

        // Set the campaign settings.
        campaign.settings = new Setting[] { dynamicSearchAdsSetting };

        // Optional: Set the start date.
        campaign.startDate = DateTime.Now.AddDays(1).ToString("yyyyMMdd");

        // Optional: Set the end date.
        campaign.endDate = DateTime.Now.AddYears(1).ToString("yyyyMMdd");

        // Create the operation.
        CampaignOperation operation = new CampaignOperation();
        operation.@operator = Operator.ADD;
        operation.operand = campaign;

        try {
          // Add the campaign.
          CampaignReturnValue retVal = campaignService.mutate(
              new CampaignOperation[] { operation });

          // Display the results.
          Campaign newCampaign = retVal.value[0];
          Console.WriteLine("Campaign with id = '{0}' and name = '{1}' was added.",
            newCampaign.id, newCampaign.name);
          return newCampaign;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to add campaigns.", e);
        }
      }
    }


    /// <summary>
    /// Creates an ad group.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">The campaign ID.</param>
    /// <returns>the newly created ad group.</returns>
    private static AdGroup CreateAdGroup(AdWordsUser user, long campaignId) {
      using (AdGroupService adGroupService =
          (AdGroupService) user.GetService(AdWordsService.v201806.AdGroupService)) {
        // Create the ad group.
        AdGroup adGroup = new AdGroup();

        // Required: Set the ad group's type to Dynamic Search Ads.
        adGroup.adGroupType = AdGroupType.SEARCH_DYNAMIC_ADS;

        adGroup.name = string.Format("Earth to Mars Cruises #{0}",
          ExampleUtilities.GetRandomString());
        adGroup.campaignId = campaignId;
        adGroup.status = AdGroupStatus.PAUSED;

        // Recommended: Set a tracking URL template for your ad group if you want to use URL
        // tracking software.
        adGroup.trackingUrlTemplate = "http://tracker.example.com/traveltracker/{escapedlpurl}";

        // Set the ad group bids.
        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();

        CpcBid cpcBid = new CpcBid();
        cpcBid.bid = new Money();
        cpcBid.bid.microAmount = 3000000;

        biddingConfig.bids = new Bids[] { cpcBid };

        adGroup.biddingStrategyConfiguration = biddingConfig;

        // Create the operation.
        AdGroupOperation operation = new AdGroupOperation();
        operation.@operator = Operator.ADD;
        operation.operand = adGroup;

        try {
          // Create the ad group.
          AdGroupReturnValue retVal = adGroupService.mutate(new AdGroupOperation[] { operation });

          // Display the results.
          AdGroup newAdGroup = retVal.value[0];
          Console.WriteLine("Ad group with id = '{0}' and name = '{1}' was created.",
            newAdGroup.id, newAdGroup.name);
          return newAdGroup;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create ad group.", e);
        }
      }
    }


    /// <summary>
    /// Creates an expanded Dynamic Search Ad.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">ID of the ad group in which ad is created.</param>
    /// <returns>The newly created ad.</returns>
    private static ExpandedDynamicSearchAd CreateExpandedDSA(AdWordsUser user, long adGroupId) {
      using (AdGroupAdService adGroupAdService =
          (AdGroupAdService) user.GetService(AdWordsService.v201806.AdGroupAdService)) {
        // Create an Expanded Dynamic Search Ad. This ad will have its headline, display URL and
        // final URL auto-generated at serving time according to domain name specific information
        // provided by DynamicSearchAdsSetting at the campaign level.
        ExpandedDynamicSearchAd expandedDSA = new ExpandedDynamicSearchAd();
        // Set the ad description.
        expandedDSA.description = "Buy your tickets now!";

        // Create the ad group ad.
        AdGroupAd adGroupAd = new AdGroupAd();
        adGroupAd.adGroupId = adGroupId;
        adGroupAd.ad = expandedDSA;

        // Optional: Set the status.
        adGroupAd.status = AdGroupAdStatus.PAUSED;

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

        try {
          // Create the ad.
          AdGroupAdReturnValue retval = adGroupAdService.mutate(
              new AdGroupAdOperation[] { operation });

          // Display the results.
          AdGroupAd newAdGroupAd = retval.value[0];
          ExpandedDynamicSearchAd newAd = newAdGroupAd.ad as ExpandedDynamicSearchAd;
          Console.WriteLine("Expanded Dynamic Search Ad with ID '{0}' and description '{1}' " +
              "was added.", newAd.id, newAd.description);
          return newAd;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create Expanded Dynamic Search Ad.", e);
        }
      }
    }


    /// <summary>
    /// Adds a web page criterion to target Dynamic Search Ads.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">The ad group ID.</param>
    /// <returns>The newly created web page criterion.</returns>
    private static BiddableAdGroupCriterion AddWebPageCriteria(AdWordsUser user, long adGroupId) {
      using (AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(
                AdWordsService.v201806.AdGroupCriterionService)) {
        // Create a webpage criterion for special offers for mars cruise.
        WebpageParameter param = new WebpageParameter();
        param.criterionName = "Special offers for mars";

        WebpageCondition urlCondition = new WebpageCondition();
        urlCondition.operand = WebpageConditionOperand.URL;
        urlCondition.argument = "/marscruise/special";

        WebpageCondition titleCondition = new WebpageCondition();
        titleCondition.operand = WebpageConditionOperand.PAGE_TITLE;
        titleCondition.argument = "Special Offer";

        param.conditions = new WebpageCondition[] { urlCondition, titleCondition };

        Webpage webpage = new Webpage();
        webpage.parameter = param;

        // Create biddable ad group criterion.
        BiddableAdGroupCriterion biddableAdGroupCriterion = new BiddableAdGroupCriterion();
        biddableAdGroupCriterion.adGroupId = adGroupId;
        biddableAdGroupCriterion.criterion = webpage;
        biddableAdGroupCriterion.userStatus = UserStatus.PAUSED;

        // Optional: set a custom bid.
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration();
        CpcBid bid = new CpcBid() {
          bid = new Money() {
            microAmount = 10000000L
          }
        };
        biddingStrategyConfiguration.bids = new Bids[] { bid };
        biddableAdGroupCriterion.biddingStrategyConfiguration = biddingStrategyConfiguration;

        // Create the operation.
        AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
        operation.@operator = Operator.ADD;
        operation.operand = biddableAdGroupCriterion;

        try {
          AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(
              new AdGroupCriterionOperation[] { operation });

          BiddableAdGroupCriterion newCriterion = (BiddableAdGroupCriterion) result.value[0];
          Console.WriteLine("Webpage criterion with ID = '{0}' was added to ad group ID '{1}'.",
              newCriterion.criterion.id, newCriterion.adGroupId);
          return newCriterion;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create webpage criterion.", e);
        }
      }
    }

  }
}

Add an expanded text ad with Upgraded URLs

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example adds an expanded text ad that uses advanced features
  /// of upgraded URLs.
  /// </summary>
  public class AddExpandedTextAdWithUpgradedUrls : 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) {
      AddExpandedTextAdWithUpgradedUrls codeExample = new AddExpandedTextAdWithUpgradedUrls();
      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 adds an expanded text ad that uses advanced features of " +
            "upgraded URLs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">ID of the ad group to which ad is added.
    /// </param>
    public void Run(AdWordsUser user, long adGroupId) {
      using (AdGroupAdService adGroupAdService =
          (AdGroupAdService) user.GetService(AdWordsService.v201806.AdGroupAdService)) {

        // Create the 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!",
        };

        // Specify a tracking URL for 3rd party tracking provider. You may
        // specify one at customer, campaign, ad group, ad, criterion or
        // feed item levels.
        expandedTextAd.trackingUrlTemplate =
            "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}";

        // Since your tracking URL has two custom parameters, provide their
        // values too. This can be provided at campaign, ad group, ad, criterion
        // or feed item levels.
        CustomParameter seasonParameter = new CustomParameter();
        seasonParameter.key = "season";
        seasonParameter.value = "christmas";

        CustomParameter promoCodeParameter = new CustomParameter();
        promoCodeParameter.key = "promocode";
        promoCodeParameter.value = "NYC123";

        expandedTextAd.urlCustomParameters = new CustomParameters();
        expandedTextAd.urlCustomParameters.parameters =
            new CustomParameter[] { seasonParameter, promoCodeParameter };

        // Specify a list of final URLs. This field cannot be set if URL field is
        // set. This may be specified at ad, criterion and feed item levels.
        expandedTextAd.finalUrls = new string[] {
          "http://www.example.com/cruise/space/",
          "http://www.example.com/locations/mars/"
        };

        // Specify a list of final mobile URLs. This field cannot be set if URL
        // field is set, or finalUrls is unset. This may be specified at ad,
        // criterion and feed item levels.
        expandedTextAd.finalMobileUrls = new string[] {
          "http://mobile.example.com/cruise/space/",
          "http://mobile.example.com/locations/mars/"
        };

        AdGroupAd adGroupAd = new AdGroupAd();
        adGroupAd.adGroupId = adGroupId;
        adGroupAd.ad = expandedTextAd;

        // Optional: Set the status.
        adGroupAd.status = AdGroupAdStatus.PAUSED;

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

        AdGroupAdReturnValue retVal = null;

        try {
          // Create the ads.
          retVal = adGroupAdService.mutate(new AdGroupAdOperation[] { operation });

          // Display the results.
          if (retVal != null && retVal.value != null) {
            ExpandedTextAd newExpandedTextAd = retVal.value[0].ad as ExpandedTextAd;

            Console.WriteLine("Expanded text ad with ID '{0}' and headline '{1} - {2}' was added.",
                newExpandedTextAd.id, newExpandedTextAd.headlinePart1,
                newExpandedTextAd.headlinePart2);

            Console.WriteLine("Upgraded URL properties:");

            Console.WriteLine("  Final URLs: {0}", string.Join(", ", newExpandedTextAd.finalUrls));
            Console.WriteLine("  Final Mobile URLs: {0}",
                string.Join(", ", newExpandedTextAd.finalMobileUrls));
            Console.WriteLine("  Tracking URL template: {0}",
                newExpandedTextAd.trackingUrlTemplate);

            List<string> parameters = new List<string>();
            foreach (CustomParameter customParam in
                newExpandedTextAd.urlCustomParameters.parameters) {
              parameters.Add(string.Format("{0}={1}", customParam.key, customParam.value));
            }
            Console.WriteLine("  Custom parameters: {0}", string.Join(", ", parameters.ToArray()));
          } else {
            Console.WriteLine("No expanded text ads were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create expanded text ad.", e);
        }
      }
    }
  }
}

Add a Gmail ad to an ad group

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;
using System;

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

  /// <summary>
  /// This code example adds a Gmail ad to a given ad group. The ad group's
  /// campaign needs to have an AdvertisingChannelType of DISPLAY and
  /// AdvertisingChannelSubType of DISPLAY_GMAIL_AD.
  /// To get ad groups, run GetAdGroups.cs.
  /// </summary>
  public class AddGmailAd : 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) {
      AddGmailAd codeExample = new AddGmailAd();
      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 adds a Gmail ad to a given ad group. The ad group's campaign " +
            "needs to have an AdvertisingChannelType of DISPLAY and AdvertisingChannelSubType " +
            "of DISPLAY_GMAIL_AD. To get ad groups, run GetAdGroups.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the adgroup to which ads are added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      using (AdGroupAdService adGroupAdService = (AdGroupAdService) user.GetService(
          AdWordsService.v201806.AdGroupAdService)) {
        // This ad format does not allow the creation of an image using the
        // Image.data field. An image must first be created using the
        // MediaService, and Image.mediaId must be populated when creating the
        // ad.
        Image logoImage = new Image();
        logoImage.mediaId = UploadImage(user, "https://goo.gl/mtt54n").mediaId;

        Image marketingImage = new Image();
        marketingImage.mediaId = UploadImage(user, "https://goo.gl/3b9Wfh").mediaId;

        GmailTeaser teaser = new GmailTeaser();
        teaser.headline = "Dream";
        teaser.description = "Create your own adventure";
        teaser.businessName = "Interplanetary Ships";
        teaser.logoImage = logoImage;

        // Creates a Gmail ad.
        GmailAd gmailAd = new GmailAd();
        gmailAd.teaser = teaser;
        gmailAd.marketingImage = marketingImage;
        gmailAd.marketingImageHeadline = "Travel";
        gmailAd.marketingImageDescription = "Take to the skies!";
        gmailAd.finalUrls = new string[] { "http://www.example.com/" };

        // Creates ad group ad for the Gmail ad.
        AdGroupAd adGroupAd = new AdGroupAd();
        adGroupAd.adGroupId = adGroupId;
        adGroupAd.ad = gmailAd;
        // Optional: Set additional settings.
        adGroupAd.status = AdGroupAdStatus.PAUSED;

        // Creates ad group ad operation and add it to the list.
        AdGroupAdOperation operation = new AdGroupAdOperation();
        operation.operand = adGroupAd;
        operation.@operator = Operator.ADD;

        try {
          // Adds a responsive display ad on the server.
          AdGroupAdReturnValue result = adGroupAdService.mutate(
              new AdGroupAdOperation[] { operation });

          if (result == null || result.value == null || result.value.Length == 0) {
            Console.WriteLine("No Gmail ads were added.");
            return;
          }
          // Prints out some information for each created Gmail ad.
          foreach (AdGroupAd newAdGroupAd in result.value) {
            Console.WriteLine("A Gmail ad with ID {0} and headline '{1}' was added.",
                newAdGroupAd.ad.id, (newAdGroupAd.ad as GmailAd).teaser.headline);
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to add Gmail ads.", e);
        }
      }
    }

    /// <summary>
    /// Uploads an image to the server.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="url">The URL of image to upload.</param>
    /// <returns>The created image.</returns>
    private static Media UploadImage(AdWordsUser user, string url) {
      using (MediaService mediaService = (MediaService) user.GetService(
          AdWordsService.v201806.MediaService)) {
        Image image = new Image();
        image.data = MediaUtilities.GetAssetDataFromUrl(url, user.Config);
        image.type = MediaMediaType.IMAGE;
        return mediaService.upload(new Media[] { image })[0];
      }
    }
  }
}

Add an HTML 5 ad to an ad group

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;

using System;

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

  /// <summary>
  /// This code example adds an HTML5 ad to a given ad group. To get ad groups,
  /// run GetAdGroups.cs.
  /// </summary>
  public class AddHtml5Ad : 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) {
      AddHtml5Ad codeExample = new AddHtml5Ad();
      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 adds an HTML5 ad to a given ad group. To get ad groups, run " +
            "GetAdGroups.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the first adgroup to which ad is added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      using (AdGroupAdService adGroupAdService = (AdGroupAdService) user.GetService(
          AdWordsService.v201806.AdGroupAdService)) {

        // Create the HTML5 template ad. See
        // https://developers.google.com/adwords/api/docs/guides/template-ads#html5_ads
        // for more details.
        TemplateAd html5Ad = new TemplateAd() {
          name = "Ad for HTML5",
          templateId = 419,
          finalUrls = new string[] { "http://example.com/html5" },
          displayUrl = "www.example.com/html5",
          dimensions = new Dimensions() {
            width = 300,
            height = 250
          }
        };

        // The HTML5 zip file contains all the HTML, CSS, and images needed for the
        // HTML5 ad. For help on creating an HTML5 zip file, check out Google Web
        // Designer (https://www.google.com/webdesigner/).
        byte[] html5Zip = MediaUtilities.GetAssetDataFromUrl("https://goo.gl/9Y7qI2", user.Config);

        // Create a media bundle containing the zip file with all the HTML5 components.
        MediaBundle mediaBundle = new MediaBundle() {
          // You may also upload an HTML5 zip using MediaService.upload() method
          // set the mediaId field. See UploadMediaBundle.cs for an example on
          // how to upload HTML5 zip files.
          data = html5Zip,
          entryPoint = "carousel/index.html",
          type = MediaMediaType.MEDIA_BUNDLE
        };

        // Create the template elements for the ad. You can refer to
        // https://developers.google.com/adwords/api/docs/appendix/templateads
        // for the list of available template fields.
        html5Ad.templateElements = new TemplateElement[] {
        new TemplateElement() {
          uniqueName = "adData",
          fields = new TemplateElementField[] {
            new TemplateElementField() {
              name = "Custom_layout",
              fieldMedia = mediaBundle,
              type = TemplateElementFieldType.MEDIA_BUNDLE
            },
            new TemplateElementField() {
              name = "layout",
              fieldText = "Custom",
              type = TemplateElementFieldType.ENUM
            },
          },
        }
      };

        // Create the AdGroupAd.
        AdGroupAd html5AdGroupAd = new AdGroupAd() {
          adGroupId = adGroupId,
          ad = html5Ad,
          // Additional properties (non-required).
          status = AdGroupAdStatus.PAUSED
        };
        AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation() {
          @operator = Operator.ADD,
          operand = html5AdGroupAd
        };

        try {
          // Add HTML5 ad.
          AdGroupAdReturnValue result =
            adGroupAdService.mutate(new AdGroupAdOperation[] { adGroupAdOperation });

          // Display results.
          if (result != null && result.value != null && result.value.Length > 0) {
            foreach (AdGroupAd adGroupAd in result.value) {
              Console.WriteLine("New HTML5 ad with id \"{0}\" and display url \"{1}\" was added.",
                adGroupAd.ad.id, adGroupAd.ad.displayUrl);
            }
          } else {
            Console.WriteLine("No HTML5 ads were added.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create HTML5 ad.", e);
        }
      }
    }
  }
}

Add a multi-asset responsive display ad to an ad group

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;

using System;

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

  /// <summary>
  /// This code example adds a responsive display ad (MultiAssetResponsiveDisplayAd)
  /// to an ad group. Image assets are uploaded using AssetService. To get ad groups,
  /// run GetAdGroups.cs.
  /// </summary>
  public class AddMultiAssetResponsiveDisplayAd : 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) {
      AddMultiAssetResponsiveDisplayAd codeExample = new AddMultiAssetResponsiveDisplayAd();
      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 adds a responsive display ad " +
            "(MultiAssetResponsiveDisplayAd) to an ad group. Image assets are uploaded using " +
            "AssetService. To get ad groups, run GetAdGroups.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group to which ads are added.
    /// </param>
    public void Run(AdWordsUser user, long adGroupId) {
      using (AdGroupAdService adGroupAdService =
          (AdGroupAdService) user.GetService(AdWordsService.v201806.AdGroupAdService)) {
        try {
          // Create the ad.
          MultiAssetResponsiveDisplayAd ad = new MultiAssetResponsiveDisplayAd() {
            headlines = new AssetLink[] {
              new AssetLink() {
                // Text assets can be specified directly in the asset field when creating the ad.
                asset = new TextAsset() {
                  assetText = "Travel to Mars",
                },
              },
              new AssetLink() {
                asset = new TextAsset() {
                  assetText = "Travel to Jupiter",
                },
              },
              new AssetLink() {
                asset = new TextAsset() {
                  assetText = "Travel to Pluto",
                },
              },
            },
            descriptions = new AssetLink[] {
              new AssetLink() {
                asset = new TextAsset() {
                  assetText = "Visit the planet in a luxury spaceship.",
                },
              },
              new AssetLink() {
                asset = new TextAsset() {
                  assetText = "See the planet in style.",
                },
              },
            },
            businessName = "Galactic Luxury Cruises",
            longHeadline = new AssetLink() {
              asset = new TextAsset() {
                assetText = "Visit the planet in a luxury spaceship.",
              },
            },

            // This ad format does not allow the creation of an image asset by setting
            // the asset.imageData field. An image asset must first be created using the
            // AssetService, and asset.assetId must be populated when creating the ad.
            marketingImages = new AssetLink[] {
              new AssetLink() {
                asset = new ImageAsset() {
                  assetId = UploadImageAsset(user, "https://goo.gl/3b9Wfh")
                },
              }
            },
            squareMarketingImages = new AssetLink[] {
              new AssetLink() {
                asset = new ImageAsset() {
                  assetId = UploadImageAsset(user, "https://goo.gl/mtt54n")
                },
              }
            },
            finalUrls = new string[] { "http://www.example.com" },

            // Optional: set call to action text.
            callToActionText = "Shop Now",

            // Set color settings using hexadecimal values. Set allowFlexibleColor to false
            // if you want your ads to render by always using your colors strictly.
            mainColor = "#0000ff",
            accentColor = "#ffff00",
            allowFlexibleColor = false,

            // Set the format setting that the ad will be served in.
            formatSetting = DisplayAdFormatSetting.NON_NATIVE,

            // Optional: Set dynamic display ad settings, composed of landscape logo
            // image, promotion text, and price prefix.
            dynamicSettingsPricePrefix = "as low as",
            dynamicSettingsPromoText = "Free shipping!",
            logoImages = new AssetLink[] {
              new AssetLink() {
                asset = new ImageAsset() {
                  assetId = UploadImageAsset(user, "https://goo.gl/mtt54n")
                },
              }
            }
          };

          // Create the ad group ad.
          AdGroupAd adGroupAd = new AdGroupAd() {
            ad = ad,
            adGroupId = adGroupId
          };

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

          // Make the mutate request.
          AdGroupAdReturnValue result = adGroupAdService.mutate(
              new AdGroupAdOperation[] { operation });

          // Display results.
          if (result != null && result.value != null) {
            foreach (AdGroupAd newAdGroupAd in result.value) {
              MultiAssetResponsiveDisplayAd newAd = newAdGroupAd.ad
                  as MultiAssetResponsiveDisplayAd;
              Console.WriteLine("Responsive display ad with ID '{0}' and long headline '{1}'" +
                  " was added.", newAd.id, (newAd.longHeadline.asset as TextAsset).assetText);
            }
          } else {
            Console.WriteLine("No responsive display ads were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create responsive display ad.", e);
        }
      }
    }

    /// <summary>
    /// Uploads the image from the specified <paramref name="url"/>.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="url">The image URL.</param>
    /// <returns>ID of the uploaded image.</returns>
    private static long UploadImageAsset(AdWordsUser user, String url) {
      using (AssetService assetService = (AssetService) user.GetService(
          AdWordsService.v201806.AssetService)) {
        // Create the image asset.
        ImageAsset imageAsset = new ImageAsset() {
          // Optional: Provide a unique friendly name to identify your asset. If you specify
          // the assetName field, then both the asset name and the image being uploaded should be
          // unique, and should not match another ACTIVE asset in this customer account.
          // assetName = "Image asset " + ExampleUtilities.GetRandomString(),
          imageData = MediaUtilities.GetAssetDataFromUrl(url, user.Config),
        };

        // Create the operation.
        AssetOperation operation = new AssetOperation() {
          @operator = Operator.ADD,
          operand = imageAsset
        };

        // Create the asset and return the ID.
        return assetService.mutate(new AssetOperation[] { operation }).value[0].assetId;
      }
    }
  }
}

   

Add a responsive display ad

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;

using System;

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

  /// <summary>
  /// This code example adds an image representing the ad using the MediaService
  /// and then adds a responsive display ad to an ad group. To get ad groups,
  /// run GetAdGroups.cs.
  /// </summary>
  public class AddResponsiveDisplayAd : 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) {
      AddResponsiveDisplayAd codeExample = new AddResponsiveDisplayAd();
      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 adds an image representing the ad using the MediaService " +
            "and then adds a responsive display ad to an ad group. To get ad groups, " +
            "run GetAdGroups.cs.";
      }
    }

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

        try {
          // Create a responsive display ad.
          ResponsiveDisplayAd responsiveDisplayAd = new ResponsiveDisplayAd();

          // This ad format does not allow the creation of an image using the
          // Image.data field. An image must first be created using the MediaService,
          // and Image.mediaId must be populated when creating the ad.
          responsiveDisplayAd.marketingImage = new Image() {
            mediaId = UploadImage(user, "https://goo.gl/3b9Wfh")
          };
          responsiveDisplayAd.shortHeadline = "Travel";
          responsiveDisplayAd.longHeadline = "Travel the World";
          responsiveDisplayAd.description = "Take to the air!";
          responsiveDisplayAd.businessName = "Google";
          responsiveDisplayAd.finalUrls = new string[] { "http://www.example.com" };

          // Optional: Create a square marketing image using MediaService, and set it
          // to the ad.
          responsiveDisplayAd.squareMarketingImage = new Image() {
            mediaId = UploadImage(user, "https://goo.gl/mtt54n"),
          };

          // Optional: set call to action text.
          responsiveDisplayAd.callToActionText = "Shop Now";

          // Optional: Set dynamic display ad settings, composed of landscape logo
          // image, promotion text, and price prefix.
          responsiveDisplayAd.dynamicDisplayAdSettings = CreateDynamicDisplayAdSettings(user);

          // Whitelisted accounts only: Set color settings using hexadecimal values.
          // Set allowFlexibleColor to false if you want your ads to render by always
          // using your colors strictly.

          // responsiveDisplayAd.mainColor = "#0000ff";
          // responsiveDisplayAd.accentColor = "#ffff00";
          // responsiveDisplayAd.allowFlexibleColor = false;

          // Whitelisted accounts only: Set the format setting that the ad will be
          // served in.

          // responsiveDisplayAd.formatSetting = DisplayAdFormatSetting.NON_NATIVE;

          // Create ad group ad.
          AdGroupAd adGroupAd = new AdGroupAd() {
            adGroupId = adGroupId,
            ad = responsiveDisplayAd,
            status = AdGroupAdStatus.PAUSED
          };

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

          // Make the mutate request.
          AdGroupAdReturnValue result = adGroupAdService.mutate(
              new AdGroupAdOperation[] { operation });

          // Display results.
          if (result != null && result.value != null) {
            foreach (AdGroupAd newAdGroupAd in result.value) {
              ResponsiveDisplayAd newAd = newAdGroupAd.ad as ResponsiveDisplayAd;
              Console.WriteLine("Responsive display ad with ID '{0}' and short headline '{1}'" +
                  " was added.", newAd.id, newAd.shortHeadline);
            }
          } else {
            Console.WriteLine("No responsive display ads were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create responsive display ad.", e);
        }
      }
    }

    /// <summary>
    /// Creates the dynamic display ad settings.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns></returns>
    private static DynamicSettings CreateDynamicDisplayAdSettings(AdWordsUser user) {
      long logoImageMediaId = UploadImage(user, "https://goo.gl/dEvQeF");
      Image logo = new Image() {
        mediaId = logoImageMediaId
      };

      return new DynamicSettings() {
        landscapeLogoImage = logo,
        pricePrefix = "as low as",
        promoText = "Free shipping!"
      };
    }

    /// <summary>
    /// Uploads the image from the specified <paramref name="url"/>.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="url">The image URL.</param>
    /// <returns>ID of the uploaded image.</returns>
    private static long UploadImage(AdWordsUser user, String url) {
      using (MediaService mediaService =
          (MediaService) user.GetService(AdWordsService.v201806.MediaService)) {

        // Create the image.
        Image image = new Image() {
          data = MediaUtilities.GetAssetDataFromUrl(url, user.Config),
          type = MediaMediaType.IMAGE
        };

        // Upload the image and return the ID.
        return mediaService.upload(new Media[] { image })[0].mediaId;
      }
    }
  }
}

   

Add a Shopping dynamic remarketing campaign

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201806;
using Google.Api.Ads.Common.Util;
using System;

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

  /// <summary>
  /// This code example adds a Shopping dynamic remarketing campaign for the Display Network
  /// via the following steps:
  /// <list type="bullet">
  ///   <item>
  ///     <description>Creates a new Display Network campaign.</description>
  ///   </item>
  ///   <item>
  ///     <description>Links the campaign with Merchant Center.</description>
  ///   </item>
  ///   <item>
  ///     <description>Links the user list to the ad group.</description>
  ///   </item>
  ///   <item>
  ///     <description>Creates a responsive display ad to render the dynamic text.</description>
  ///   </item>
  /// </list>
  /// </summary>
  public class AddShoppingDynamicRemarketingCampaign : 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) {
      AddShoppingDynamicRemarketingCampaign codeExample =
          new AddShoppingDynamicRemarketingCampaign();
      Console.WriteLine(codeExample.Description);
      try {

        // The ID of the merchant center account from which to source product feed data.
        long merchantId = long.Parse("INSERT_MERCHANT_CENTER_ID_HERE");

        // The ID of a shared budget to associate with the campaign.
        long budgetId = long.Parse("INSERT_BUDGET_ID_HERE");

        // The ID of a user list to target.
        long userListId = long.Parse("INSERT_USER_LIST_ID_HERE");
        codeExample.Run(new AdWordsUser(), merchantId, budgetId, userListId);
      } 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 Shopping dynamic remarketing campaign for the " +
            "Display Network via the following steps:\n" +
            "*  Creates a new Display Network campaign.\n" +
            "*  Links the campaign with Merchant Center.\n" +
            "*  Links the user list to the ad group.\n" +
            "*  Creates a responsive display ad to render the dynamic text.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="merchantId">The ID of the merchant center account from which to source
    /// product feed data.</param>
    /// <param name="budgetId">The ID of a shared budget to associate with the campaign.</param>
    /// <param name="userListId">The ID of a user list to target.</param>
    public void Run(AdWordsUser user, long merchantId, long budgetId, long userListId) {
      try {
        Campaign campaign = CreateCampaign(user, merchantId, budgetId);
        Console.WriteLine("Campaign with name '{0}' and ID {1} was added.",
            campaign.name, campaign.id);

        AdGroup adGroup = CreateAdGroup(user, campaign);
        Console.WriteLine("Ad group with name '{0}' and ID {1} was added.",
            adGroup.name, adGroup.id);

        AdGroupAd adGroupAd = CreateAd(user, adGroup);
        Console.WriteLine("Responsive display ad with ID {0} was added.", adGroupAd.ad.id);

        AttachUserList(user, adGroup, userListId);
        Console.WriteLine("User list with ID {0} was attached to ad group with ID {1}.",
            userListId, adGroup.id);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create Shopping dynamic remarketing " +
            "campaign for the Display Network.", e);
      }
    }

    /// <summary>
    /// Creates a Shopping dynamic remarketing campaign object (not including ad group level and
    /// below). This creates a Display campaign with the merchant center feed attached.
    /// Merchant Center is used for the product information in combination with a user list
    /// which contains hits with <code>ecomm_prodid</code> specified. See
    /// <a href="https://developers.google.com/adwords-remarketing-tag/parameters#retail">
    /// the guide</a> for more detail.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="merchantId">The ID of the Merchant Center account.</param>
    /// <param name="budgetId">The ID of the budget to use for the campaign.</param>
    /// <returns>The campaign that was created.</returns>
    private static Campaign CreateCampaign(AdWordsUser user, long merchantId, long budgetId) {
      using (CampaignService campaignService =
          (CampaignService) user.GetService(AdWordsService.v201806.CampaignService)) {
        Campaign campaign = new Campaign();
        campaign.name = "Shopping campaign #" + ExampleUtilities.GetRandomString();
        // Dynamic remarketing campaigns are only available on the Google Display Network.
        campaign.advertisingChannelType = AdvertisingChannelType.DISPLAY;
        campaign.status = CampaignStatus.PAUSED;

        Budget budget = new Budget();
        budget.budgetId = budgetId;
        campaign.budget = budget;

        // This example uses a Manual CPC bidding strategy, but you should select the strategy
        // that best aligns with your sales goals. More details here:
        //   https://support.google.com/adwords/answer/2472725
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration();
        biddingStrategyConfiguration.biddingStrategyType = BiddingStrategyType.MANUAL_CPC;
        campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

        ShoppingSetting setting = new ShoppingSetting();
        // Campaigns with numerically higher priorities take precedence over those with lower
        // priorities.
        setting.campaignPriority = 0;

        // Set the Merchant Center account ID from which to source products.
        setting.merchantId = merchantId;

        // Display Network campaigns do not support partition by country. The only supported
        // value is "ZZ". This signals that products from all countries are available in the
        // campaign. The actual products which serve are based on the products tagged in the
        // user list entry.
        setting.salesCountry = "ZZ";

        // Optional: Enable local inventory ads (items for sale in physical stores.)
        setting.enableLocal = true;

        campaign.settings = new Setting[] { setting };

        CampaignOperation op = new CampaignOperation();
        op.operand = campaign;
        op.@operator = Operator.ADD;

        CampaignReturnValue result = campaignService.mutate(new CampaignOperation[] { op });
        return result.value[0];
      }
    }

    /// <summary>
    /// Creates an ad group in the specified campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaign">The campaign to which the ad group should be attached.</param>
    /// <returns>The ad group that was created.</returns>
    private static AdGroup CreateAdGroup(AdWordsUser user, Campaign campaign) {
      using (AdGroupService adGroupService =
          (AdGroupService) user.GetService(AdWordsService.v201806.AdGroupService)) {
        AdGroup group = new AdGroup();
        group.name = "Dynamic remarketing ad group";
        group.campaignId = campaign.id;
        group.status = AdGroupStatus.ENABLED;

        AdGroupOperation op = new AdGroupOperation();
        op.operand = group;
        op.@operator = Operator.ADD;
        AdGroupReturnValue result = adGroupService.mutate(new AdGroupOperation[] { op });
        return result.value[0];
      }
    }

    /// <summary>
    /// Attach a user list to an ad group. The user list provides positive targeting and feed
    /// information to drive the dynamic content of the ad.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <param name="adGroup">The ad group which will have the user list attached.</param>
    /// <param name="userListId">The user list to use for targeting and dynamic content.</param>
    /// <remarks>User lists must be attached at the ad group level for positive targeting in
    /// Shopping dynamic remarketing campaigns.</remarks>
    private static void AttachUserList(AdWordsUser user, AdGroup adGroup, long userListId) {
      using (AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(
              AdWordsService.v201806.AdGroupCriterionService)) {
        CriterionUserList userList = new CriterionUserList();
        userList.userListId = userListId;
        BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion();
        adGroupCriterion.criterion = userList;
        adGroupCriterion.adGroupId = adGroup.id;

        AdGroupCriterionOperation op = new AdGroupCriterionOperation();
        op.operand = adGroupCriterion;
        op.@operator = Operator.ADD;

        adGroupCriterionService.mutate(new AdGroupCriterionOperation[] { op });
      }
    }

    /// <summary>
    /// Creates an ad for serving dynamic content in a remarketing campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroup">The ad group under which to create the ad.</param>
    /// <returns>The ad that was created.</returns>
    private static AdGroupAd CreateAd(AdWordsUser user, AdGroup adGroup) {
      using (AdGroupAdService adService = (AdGroupAdService) user.GetService(
          AdWordsService.v201806.AdGroupAdService)) {
        ResponsiveDisplayAd ad = new ResponsiveDisplayAd();

        // This ad format does not allow the creation of an image using the
        // Image.data field. An image must first be created using the MediaService,
        // and Image.mediaId must be populated when creating the ad.
        ad.marketingImage = UploadImage(user, "https://goo.gl/3b9Wfh");

        ad.shortHeadline = "Travel";
        ad.longHeadline = "Travel the World";
        ad.description = "Take to the air!";
        ad.businessName = "Interplanetary Cruises";
        ad.finalUrls = new string[] { "http://www.example.com/" };

        // Optional: Call to action text.
        // Valid texts: https://support.google.com/adwords/answer/7005917
        ad.callToActionText = "Apply Now";

        // Optional: Set dynamic display ad settings, composed of landscape logo
        // image, promotion text, and price prefix.
        ad.dynamicDisplayAdSettings = CreateDynamicDisplayAdSettings(user);

        // Optional: Create a logo image and set it to the ad.
        ad.logoImage = UploadImage(user, "https://goo.gl/mtt54n");

        // Optional: Create a square marketing image and set it to the ad.
        ad.squareMarketingImage = UploadImage(user, "https://goo.gl/mtt54n");

        // Whitelisted accounts only: Set color settings using hexadecimal values.
        // Set allowFlexibleColor to false if you want your ads to render by always
        // using your colors strictly.
        // ad.mainColor = "#0000ff";
        // ad.accentColor = "#ffff00";
        // ad.allowFlexibleColor = false;

        // Whitelisted accounts only: Set the format setting that the ad will be
        // served in.
        // ad.formatSetting = DisplayAdFormatSetting.NON_NATIVE;

        AdGroupAd adGroupAd = new AdGroupAd();
        adGroupAd.ad = ad;
        adGroupAd.adGroupId = adGroup.id;

        AdGroupAdOperation op = new AdGroupAdOperation();
        op.operand = adGroupAd;
        op.@operator = Operator.ADD;

        AdGroupAdReturnValue result = adService.mutate(new AdGroupAdOperation[] { op });
        return result.value[0];
      }
    }

    /// <summary>
    /// Creates the additional content (images, promo text, etc.) supported by dynamic ads.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns>The DynamicSettings object to be used.</returns>
    private static DynamicSettings CreateDynamicDisplayAdSettings(AdWordsUser user) {
      Image logo = UploadImage(user, "https://goo.gl/dEvQeF");

      DynamicSettings dynamicSettings = new DynamicSettings();
      dynamicSettings.landscapeLogoImage = logo;
      dynamicSettings.pricePrefix = "as low as";
      dynamicSettings.promoText = "Free shipping!";
      return dynamicSettings;
    }

    /// <summary>
    /// Uploads the image from the specified <paramref name="url"/>.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="url">The image URL.</param>
    /// <returns>ID of the uploaded image.</returns>
    private static Image UploadImage(AdWordsUser user, string url) {
      using (MediaService mediaService =
          (MediaService) user.GetService(AdWordsService.v201806.MediaService)) {
        // Create the image.
        Image image = new Image() {
          data = MediaUtilities.GetAssetDataFromUrl(url, user.Config),
          type = MediaMediaType.IMAGE
        };

        // Upload the image and return the ID.
        return (Image) mediaService.upload(new Media[] { image })[0];
      }
    }
  }
}

Add a universal app campaign

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example adds a universal app campaign. To get campaigns, run GetCampaigns.cs.
  /// To upload image assets for this campaign, use UploadImage.cs.
  /// </summary>
  public class AddUniversalAppCampaign : 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) {
      AddUniversalAppCampaign codeExample = new AddUniversalAppCampaign();
      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 example adds a universal app campaign. To get campaigns, run " +
            "GetCampaigns.cs. To upload image assets for this campaign, use UploadImage.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    public void Run(AdWordsUser user) {
      using (CampaignService campaignService =
          (CampaignService) user.GetService(AdWordsService.v201806.CampaignService)) {

        // Create the campaign.
        Campaign campaign = new Campaign();
        campaign.name = "Interplanetary Cruise App #" + 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.
        campaign.status = CampaignStatus.PAUSED;

        // Set the advertising channel and subchannel types for universal app campaigns.
        campaign.advertisingChannelType = AdvertisingChannelType.MULTI_CHANNEL;
        campaign.advertisingChannelSubType = AdvertisingChannelSubType.UNIVERSAL_APP_CAMPAIGN;

        // Set the campaign's bidding strategy. Universal app campaigns
        // only support TARGET_CPA bidding strategy.
        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
        biddingConfig.biddingStrategyType = BiddingStrategyType.TARGET_CPA;

        // Set the target CPA to $1 / app install.
        TargetCpaBiddingScheme biddingScheme = new TargetCpaBiddingScheme();
        biddingScheme.targetCpa = new Money();
        biddingScheme.targetCpa.microAmount = 1000000;

        biddingConfig.biddingScheme = biddingScheme;
        campaign.biddingStrategyConfiguration = biddingConfig;

        // Set the campaign's budget.
        campaign.budget = new Budget();
        campaign.budget.budgetId = CreateBudget(user).budgetId;

        // Optional: Set the start date.
        campaign.startDate = DateTime.Now.AddDays(1).ToString("yyyyMMdd");

        // Optional: Set the end date.
        campaign.endDate = DateTime.Now.AddYears(1).ToString("yyyyMMdd");

        // Set the campaign's assets and ad text ideas. These values will be used to
        // generate ads.
        UniversalAppCampaignSetting universalAppSetting = new UniversalAppCampaignSetting();
        universalAppSetting.appId = "com.labpixies.colordrips";
        universalAppSetting.appVendor = MobileApplicationVendor.VENDOR_GOOGLE_MARKET;
        universalAppSetting.description1 = "A cool puzzle game";
        universalAppSetting.description2 = "Remove connected blocks";
        universalAppSetting.description3 = "3 difficulty levels";
        universalAppSetting.description4 = "4 colorful fun skins";

        // Optional: You can set up to 20 image assets for your campaign.
        // See UploadImage.cs for an example on how to upload images.
        //
        // universalAppSetting.imageMediaIds = new long[] { INSERT_IMAGE_MEDIA_ID_HERE };

        // Optimize this campaign for getting new users for your app.
        universalAppSetting.universalAppBiddingStrategyGoalType =
            UniversalAppBiddingStrategyGoalType.OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME;

        // Optional: If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal
        // type, then also specify your in-app conversion types so AdWords can
        // focus your campaign on people who are most likely to complete the
        // corresponding in-app actions.
        // Conversion type IDs can be retrieved using ConversionTrackerService.get.
        //
        // campaign.selectiveOptimization = new SelectiveOptimization();
        // campaign.selectiveOptimization.conversionTypeIds =
        //    new long[] { INSERT_CONVERSION_TYPE_ID_1_HERE, INSERT_CONVERSION_TYPE_ID_2_HERE };

        // Optional: Set the campaign settings for Advanced location options.
        GeoTargetTypeSetting geoSetting = new GeoTargetTypeSetting();
        geoSetting.positiveGeoTargetType =
            GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE;
        geoSetting.negativeGeoTargetType =
            GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE;

        campaign.settings = new Setting[] { universalAppSetting, geoSetting };

        // Create the operation.
        CampaignOperation operation = new CampaignOperation();
        operation.@operator = Operator.ADD;
        operation.operand = campaign;

        try {
          // Add the campaign.
          CampaignReturnValue retVal = campaignService.mutate(
              new CampaignOperation[] { operation });

          // Display the results.
          if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
            foreach (Campaign newCampaign in retVal.value) {
              Console.WriteLine("Universal app campaign with name = '{0}' and id = '{1}' " +
                  "was added.", newCampaign.name, newCampaign.id);

              // Optional: Set the campaign's location and language targeting. No other targeting
              // criteria can be used for universal app campaigns.
              SetCampaignTargetingCriteria(user, newCampaign);
            }
          } else {
            Console.WriteLine("No universal app campaigns were added.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to add universal app campaigns.", e);
        }
      }
    }

    /// <summary>
    /// Creates the budget for the campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns>The budget.</returns>
    private Budget CreateBudget(AdWordsUser user) {
      // Get the BudgetService.
      using (BudgetService budgetService =
          (BudgetService) user.GetService(AdWordsService.v201806.BudgetService)) {

        // Create the campaign budget.
        Budget budget = new Budget();
        budget.name = "Interplanetary Cruise App Budget #" + ExampleUtilities.GetRandomString();
        budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
        budget.amount = new Money();
        budget.amount.microAmount = 5000000;

        // Universal app campaigns don't support shared budgets.
        budget.isExplicitlyShared = false;

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

        BudgetReturnValue budgetRetval = budgetService.mutate(
          new BudgetOperation[] { budgetOperation });
        Budget newBudget = budgetRetval.value[0];

        Console.WriteLine("Budget with ID = '{0}' and name = '{1}' was created.",
            newBudget.budgetId, newBudget.name);
        return newBudget;
      }
    }

    /// <summary>
    /// Sets the campaign's targeting criteria.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaign">The campaign for which targeting criteria is
    /// created.</param>
    private void SetCampaignTargetingCriteria(AdWordsUser user, Campaign campaign) {
      using (CampaignCriterionService campaignCriterionService =
          (CampaignCriterionService) user.GetService(
              AdWordsService.v201806.CampaignCriterionService)) {

        // Create locations. The IDs can be found in the documentation or
        // retrieved with the LocationCriterionService.
        Location california = new Location() {
          id = 21137L
        };

        Location mexico = new Location() {
          id = 2484L
        };

        // Create languages. The IDs can be found in the documentation or
        // retrieved with the ConstantDataService.
        Language english = new Language() {
          id = 1000L
        };

        Language spanish = new Language() {
          id = 1003L
        };

        List<Criterion> criteria = new List<Criterion>() {
        california, mexico, english, spanish };

        // Create operations to add each of the criteria above.
        List<CampaignCriterionOperation> operations = new List<CampaignCriterionOperation>();
        foreach (Criterion criterion in criteria) {
          CampaignCriterionOperation operation = new CampaignCriterionOperation() {
            operand = new CampaignCriterion() {
              campaignId = campaign.id,
              criterion = criterion
            },
            @operator = Operator.ADD
          };

          operations.Add(operation);
        }

        // Set the campaign targets.
        CampaignCriterionReturnValue retVal = campaignCriterionService.mutate(
            operations.ToArray());

        if (retVal != null && retVal.value != null) {
          // Display the added campaign targets.
          foreach (CampaignCriterion criterion in retVal.value) {
            Console.WriteLine("Campaign criteria of type '{0}' and id '{1}' was added.",
                              criterion.criterion.CriterionType, criterion.criterion.id);
          }
        }
      }
    }
  }
}

Create a negative broad match keywords list and attach it to a campaign

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example creates a shared keyword list, adds keywords to the list
  /// and attaches it to an existing campaign. To get the list of campaigns,
  /// run GetCampaigns.cs.
  /// </summary>
  public class CreateAndAttachSharedKeywordSet : 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) {
      CreateAndAttachSharedKeywordSet codeExample = new CreateAndAttachSharedKeywordSet();
      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 creates a shared keyword list, adds keywords to the list " +
            "and attaches it to an existing campaign. To get the list of campaigns, run " +
            "GetCampaigns.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign to which keywords are added.</param>
    public void Run(AdWordsUser user, long campaignId) {
      try {
        // Create a shared set.
        SharedSet sharedSet = CreateSharedKeywordSet(user);

        Console.WriteLine("Shared set with id = {0}, name = {1}, type = {2}, status = {3} " +
            "was created.", sharedSet.sharedSetId, sharedSet.name, sharedSet.type,
            sharedSet.status);

        // Add new keywords to the shared set.
        string[] keywordTexts = new string[] { "mars cruise", "mars hotels" };
        SharedCriterion[] sharedCriteria = AddKeywordsToSharedSet(user, sharedSet.sharedSetId,
            keywordTexts);
        foreach (SharedCriterion sharedCriterion in sharedCriteria) {
          Keyword keyword = sharedCriterion.criterion as Keyword;
          Console.WriteLine("Added keyword with id = {0}, text = {1}, matchtype = {2} to " +
              "shared set with id = {3}.", keyword.id, keyword.text, keyword.matchType,
              sharedSet.sharedSetId);
        }

        // Attach the shared set to the campaign.
        CampaignSharedSet attachedSharedSet = AttachSharedSetToCampaign(user, campaignId,
            sharedSet.sharedSetId);

        Console.WriteLine("Attached shared set with id = {0} to campaign id {1}.",
            attachedSharedSet.sharedSetId, attachedSharedSet.campaignId);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create shared keyword set and attach " +
            "it to a campaign.", e);
      }
    }

    /// <summary>
    /// Create a shared keyword set.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <returns>The shared set.</returns>
    public SharedSet CreateSharedKeywordSet(AdWordsUser user) {
      using (SharedSetService sharedSetService = (SharedSetService)
          user.GetService(AdWordsService.v201806.SharedSetService)) {
        SharedSetOperation operation = new SharedSetOperation();
        operation.@operator = Operator.ADD;
        SharedSet sharedSet = new SharedSet();
        sharedSet.name = "API Negative keyword list - " + ExampleUtilities.GetRandomString();
        sharedSet.type = SharedSetType.NEGATIVE_KEYWORDS;
        operation.operand = sharedSet;

        SharedSetReturnValue retval = sharedSetService.mutate(
            new SharedSetOperation[] { operation });
        return retval.value[0];
      }
    }

    /// <summary>
    /// Adds a set of keywords to a shared set.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="sharedSetId">The shared set id.</param>
    /// <param name="keywordTexts">The keywords to be added to the shared set.</param>
    /// <returns>The newly added set of shared criteria.</returns>
    public SharedCriterion[] AddKeywordsToSharedSet(AdWordsUser user, long sharedSetId,
        string[] keywordTexts) {
      using (SharedCriterionService sharedCriterionService = (SharedCriterionService)
          user.GetService(AdWordsService.v201806.SharedCriterionService)) {

        List<SharedCriterionOperation> operations = new List<SharedCriterionOperation>();
        foreach (string keywordText in keywordTexts) {
          Keyword keyword = new Keyword();
          keyword.text = keywordText;
          keyword.matchType = KeywordMatchType.BROAD;

          SharedCriterion sharedCriterion = new SharedCriterion();
          sharedCriterion.criterion = keyword;
          sharedCriterion.negative = true;
          sharedCriterion.sharedSetId = sharedSetId;
          SharedCriterionOperation operation = new SharedCriterionOperation();
          operation.@operator = Operator.ADD;
          operation.operand = sharedCriterion;
          operations.Add(operation);
        }

        SharedCriterionReturnValue retval = sharedCriterionService.mutate(operations.ToArray());
        return retval.value;
      }
    }

    /// <summary>
    /// Attaches a shared set to a campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">The campaign id.</param>
    /// <param name="sharedSetId">The shared set id.</param>
    /// <returns>A CampaignSharedSet object that represents a binding between
    /// the specified campaign and the shared set.</returns>
    public CampaignSharedSet AttachSharedSetToCampaign(AdWordsUser user, long campaignId,
        long sharedSetId) {
      using (CampaignSharedSetService campaignSharedSetService = (CampaignSharedSetService)
          user.GetService(AdWordsService.v201806.CampaignSharedSetService)) {

        CampaignSharedSet campaignSharedSet = new CampaignSharedSet();
        campaignSharedSet.campaignId = campaignId;
        campaignSharedSet.sharedSetId = sharedSetId;

        CampaignSharedSetOperation operation = new CampaignSharedSetOperation();
        operation.@operator = Operator.ADD;
        operation.operand = campaignSharedSet;

        CampaignSharedSetReturnValue retval = campaignSharedSetService.mutate(
            new CampaignSharedSetOperation[] { operation });
        return retval.value[0];
      }
    }
  }
}

Find and remove shared sets and shared set criteria

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example demonstrates how to find and remove shared sets and
  /// shared set criteria.
  /// </summary>
  public class FindAndRemoveCriteriaFromSharedSet : ExampleBase {

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example demonstrates how to find and remove shared sets and shared " +
            "set criteria.";
      }
    }

    /// <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) {
      FindAndRemoveCriteriaFromSharedSet codeExample = new FindAndRemoveCriteriaFromSharedSet();
      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>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign from which items shared
    /// criteria are removed.</param>
    public void Run(AdWordsUser user, long campaignId) {
      // Get the list of shared sets that are attached to the campaign.
      List<string> sharedSetIds = GetSharedSetIds(user, campaignId);

      // Get the shared criteria in those shared sets.
      List<SharedCriterion> sharedCriteria = GetSharedCriteria(user, sharedSetIds);

      // Remove the shared criteria from the shared sets.
      RemoveSharedCriteria(user, sharedCriteria);
    }

    /// <summary>
    /// Gets the shared set IDs associated with a campaign.
    /// </summary>
    /// <param name="user">The user that owns the campaign.</param>
    /// <param name="campaignId">The campaign identifier.</param>
    /// <returns>The list of shared set IDs associated with the campaign.</returns>
    private List<string> GetSharedSetIds(AdWordsUser user, long campaignId) {
      using (CampaignSharedSetService campaignSharedSetService =
          (CampaignSharedSetService) user.GetService(
              AdWordsService.v201806.CampaignSharedSetService)) {

        Selector selector = new Selector() {
          fields = new string[] {
          CampaignSharedSet.Fields.SharedSetId,
          CampaignSharedSet.Fields.CampaignId,
          CampaignSharedSet.Fields.SharedSetName,
          CampaignSharedSet.Fields.SharedSetType
        },
          predicates = new Predicate[] {
          Predicate.Equals(CampaignSharedSet.Fields.CampaignId, campaignId),
          Predicate.In(CampaignSharedSet.Fields.SharedSetType,
              new string[] { SharedSetType.NEGATIVE_KEYWORDS.ToString() }),
        },
          paging = Paging.Default,
        };

        List<string> sharedSetIds = new List<string>();
        CampaignSharedSetPage page = new CampaignSharedSetPage();

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

            // Display the results.
            if (page != null && page.entries != null) {
              int i = selector.paging.startIndex;
              foreach (CampaignSharedSet campaignSharedSet in page.entries) {
                sharedSetIds.Add(campaignSharedSet.sharedSetId.ToString());
                Console.WriteLine("{0}) Campaign shared set ID {1} and name '{2}' found for " +
                    "campaign ID {3}.\n", i + 1, campaignSharedSet.sharedSetId,
                    campaignSharedSet.sharedSetName, campaignSharedSet.campaignId);
                i++;
              }
            }
            selector.paging.IncreaseOffset();
          } while (selector.paging.startIndex < page.totalNumEntries);
          return sharedSetIds;
        } catch (Exception e) {
          throw new Exception("Failed to get shared set ids for campaign.", e);
        }
      }
    }

    /// <summary>
    /// Gets the shared criteria in a shared set.
    /// </summary>
    /// <param name="user">The user that owns the shared set.</param>
    /// <param name="sharedSetIds">The shared criteria IDs.</param>
    /// <returns>The list of shared criteria.</returns>
    private List<SharedCriterion> GetSharedCriteria(AdWordsUser user,
        List<string> sharedSetIds) {
      using (SharedCriterionService sharedCriterionService =
          (SharedCriterionService) user.GetService(
              AdWordsService.v201806.SharedCriterionService)) {

        Selector selector = new Selector() {
          fields = new string[] {
            SharedSet.Fields.SharedSetId, Criterion.Fields.Id,
            Keyword.Fields.KeywordText, Keyword.Fields.KeywordMatchType,
            Placement.Fields.PlacementUrl
        },
          predicates = new Predicate[] {
            Predicate.In(SharedSet.Fields.SharedSetId, sharedSetIds)
        },
          paging = Paging.Default
        };

        List<SharedCriterion> sharedCriteria = new List<SharedCriterion>();
        SharedCriterionPage page = new SharedCriterionPage();

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

            // Display the results.
            if (page != null && page.entries != null) {
              int i = selector.paging.startIndex;
              foreach (SharedCriterion sharedCriterion in page.entries) {
                switch (sharedCriterion.criterion.type) {
                  case CriterionType.KEYWORD:
                    Keyword keyword = (Keyword) sharedCriterion.criterion;
                    Console.WriteLine("{0}) Shared negative keyword with ID {1} and text '{2}' " +
                        "was found.", i + 1, keyword.id, keyword.text);
                    break;

                  case CriterionType.PLACEMENT:
                    Placement placement = (Placement) sharedCriterion.criterion;
                    Console.WriteLine("{0}) Shared negative placement with ID {1} and URL '{2}' " +
                        "was found.", i + 1, placement.id, placement.url);
                    break;

                  default:
                    Console.WriteLine("{0}) Shared criteria with ID {1} was found.",
                        i + 1, sharedCriterion.criterion.id);
                    break;
                }
                i++;
                sharedCriteria.Add(sharedCriterion);
              }
            }
            selector.paging.IncreaseOffset();
          } while (selector.paging.startIndex < page.totalNumEntries);
          return sharedCriteria;
        } catch (Exception e) {
          throw new Exception("Failed to get shared criteria.", e);
        }
      }
    }

    /// <summary>
    /// Removes a list of shared criteria.
    /// </summary>
    /// <param name="user">The user that owns the shared criteria.</param>
    /// <param name="sharedCriteria">The list shared criteria to be removed.</param>
    private void RemoveSharedCriteria(AdWordsUser user, List<SharedCriterion> sharedCriteria) {
      if (sharedCriteria.Count == 0) {
        Console.WriteLine("No shared criteria to remove.");
        return;
      }

      using (SharedCriterionService sharedCriterionService =
          (SharedCriterionService) user.GetService(
              AdWordsService.v201806.SharedCriterionService)) {

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

        foreach (SharedCriterion sharedCriterion in sharedCriteria) {
          operations.Add(new SharedCriterionOperation() {
            @operator = Operator.REMOVE,
            operand = new SharedCriterion() {
              sharedSetId = sharedCriterion.sharedSetId,
              criterion = new Criterion() {
                id = sharedCriterion.criterion.id
              }
            }
          });
        }
        try {
          SharedCriterionReturnValue sharedCriterionReturnValue = sharedCriterionService.mutate(
              operations.ToArray());

          foreach (SharedCriterion removedCriterion in sharedCriterionReturnValue.value) {
            Console.WriteLine("Shared criterion ID {0} was successfully removed from shared " +
                "set ID {1}.", removedCriterion.criterion.id, removedCriterion.sharedSetId);
          }
        } catch (Exception e) {
          throw new Exception("Failed to remove shared criteria.", e);
        }
      }
    }
  }
}

Get ad group level bid modifiers

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

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

using System;

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

  /// <summary>
  /// This code example illustrates how to retrieve ad group level mobile bid
  /// modifiers for a campaign.
  /// </summary>
  public class GetAdGroupBidModifiers : 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) {
      GetAdGroupBidModifiers codeExample = new GetAdGroupBidModifiers();
      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 illustrates how to retrieve ad group level mobile bid " +
            "modifiers for a campaign.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign.</param>
    public void Run(AdWordsUser user, long campaignId) {
      using (AdGroupBidModifierService adGroupBidModifierService =
          (AdGroupBidModifierService) user.GetService(
              AdWordsService.v201806.AdGroupBidModifierService)) {

        // Get all ad group bid modifiers for the campaign.
        Selector selector = new Selector() {
          fields = new String[] {
          AdGroupBidModifier.Fields.CampaignId, AdGroupBidModifier.Fields.AdGroupId,
          AdGroupBidModifier.Fields.BidModifier, AdGroupBidModifier.Fields.BidModifierSource,
          Criterion.Fields.CriteriaType, Criterion.Fields.Id
        },
          predicates = new Predicate[] {
          Predicate.Equals(AdGroupBidModifier.Fields.CampaignId, campaignId)
        },
          paging = Paging.Default
        };

        AdGroupBidModifierPage page = new AdGroupBidModifierPage();

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

            // Display the results.
            if (page != null && page.entries != null) {
              int i = selector.paging.startIndex;
              foreach (AdGroupBidModifier adGroupBidModifier in page.entries) {
                string bidModifier = (adGroupBidModifier.bidModifierSpecified) ?
                    adGroupBidModifier.bidModifier.ToString() : "UNSET";
                Console.WriteLine("{0}) Campaign ID {1}, AdGroup ID {2}, Criterion ID {3} has " +
                    "ad group level modifier: {4} and source = {5}.",
                    i + 1, adGroupBidModifier.campaignId,
                    adGroupBidModifier.adGroupId, adGroupBidModifier.criterion.id, bidModifier,
                    adGroupBidModifier.bidModifierSource);
                i++;
              }
            }
            selector.paging.IncreaseOffset();
          } while (selector.paging.startIndex < page.totalNumEntries);
          Console.WriteLine("Number of adgroup bid modifiers found: {0}", page.totalNumEntries);
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to retrieve adgroup bid modifiers.", e);
        }
      }
    }
  }
}

Add a portfolio bidding strategy to a campaign

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

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

using System;

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

  /// <summary>
  /// This code example adds a portfolio bidding strategy and uses it to
  /// construct a campaign.
  /// </summary>
  public class UsePortfolioBiddingStrategy : 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) {
      UsePortfolioBiddingStrategy codeExample = new UsePortfolioBiddingStrategy();
      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 example adds a portfolio bidding strategy and uses it to construct " +
            "a campaign.";
      }
    }

    /// <summary>
    /// Runs the specified code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    public void Run(AdWordsUser user) {
      String BIDDINGSTRATEGY_NAME = "Maximize Clicks " + ExampleUtilities.GetRandomString();
      const long BID_CEILING = 2000000;
      const long SPEND_TARGET = 20000000;

      String BUDGET_NAME = "Shared Interplanetary Budget #" + ExampleUtilities.GetRandomString();
      const long BUDGET_AMOUNT = 30000000;

      String CAMPAIGN_NAME = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString();

      try {
        SharedBiddingStrategy portfolioBiddingStrategy = CreateBiddingStrategy(
            user, BIDDINGSTRATEGY_NAME, BID_CEILING, SPEND_TARGET);
        Console.WriteLine("Portfolio bidding strategy with name '{0}' and ID {1} of type " +
            "{2} was created.", portfolioBiddingStrategy.name, portfolioBiddingStrategy.id,
            portfolioBiddingStrategy.biddingScheme.BiddingSchemeType);

        Budget sharedBudget = CreateSharedBudget(user, BUDGET_NAME, BUDGET_AMOUNT);

        Campaign newCampaign = CreateCampaignWithBiddingStrategy(user, CAMPAIGN_NAME,
            portfolioBiddingStrategy.id, sharedBudget.budgetId);

        Console.WriteLine("Campaign with name '{0}', ID {1} and bidding scheme ID {2} was " +
            "created.", newCampaign.name, newCampaign.id,
            newCampaign.biddingStrategyConfiguration.biddingStrategyId);
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to create campaign that uses portfolio " +
            "bidding strategy.", e);
      }
    }

    /// <summary>
    /// Creates the portfolio bidding strategy.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="name">The bidding strategy name.</param>
    /// <param name="bidCeiling">The bid ceiling.</param>
    /// <param name="spendTarget">The spend target.</param>
    /// <returns>The bidding strategy object.</returns>
    private SharedBiddingStrategy CreateBiddingStrategy(AdWordsUser user, String name,
        long bidCeiling,long spendTarget) {
      using (BiddingStrategyService biddingStrategyService =
          (BiddingStrategyService) user.GetService(
              AdWordsService.v201806.BiddingStrategyService)) {

        // Create a portfolio bidding strategy.
        SharedBiddingStrategy portfolioBiddingStrategy = new SharedBiddingStrategy();
        portfolioBiddingStrategy.name = name;

        TargetSpendBiddingScheme biddingScheme = new TargetSpendBiddingScheme();
        // Optionally set additional bidding scheme parameters.
        biddingScheme.bidCeiling = new Money();
        biddingScheme.bidCeiling.microAmount = bidCeiling;

        biddingScheme.spendTarget = new Money();
        biddingScheme.spendTarget.microAmount = spendTarget;

        portfolioBiddingStrategy.biddingScheme = biddingScheme;

        // Create operation.
        BiddingStrategyOperation operation = new BiddingStrategyOperation();
        operation.@operator = Operator.ADD;
        operation.operand = portfolioBiddingStrategy;

        return biddingStrategyService.mutate(
            new BiddingStrategyOperation[] { operation }).value[0];
      }
    }

    /// <summary>
    /// Creates an explicit budget to be used only to create the Campaign.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="name">The budget name.</param>
    /// <param name="amount">The budget amount.</param>
    /// <returns>The budget object.</returns>
    private Budget CreateSharedBudget(AdWordsUser user, String name, long amount) {
      using (BudgetService budgetService = (BudgetService) user.GetService(
          AdWordsService.v201806.BudgetService)) {

        // Create a shared budget
        Budget budget = new Budget();
        budget.name = name;
        budget.amount = new Money();
        budget.amount.microAmount = amount;
        budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
        budget.isExplicitlyShared = true;

        // Create operation.
        BudgetOperation operation = new BudgetOperation();
        operation.operand = budget;
        operation.@operator = Operator.ADD;

        // Make the mutate request.
        return budgetService.mutate(new BudgetOperation[] { operation }).value[0];
      }
    }

    /// <summary>
    /// Creates the campaign with a portfolio bidding strategy.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="name">The campaign name.</param>
    /// <param name="biddingStrategyId">The bidding strategy id.</param>
    /// <param name="sharedBudgetId">The shared budget id.</param>
    /// <returns>The campaign object.</returns>
    private Campaign CreateCampaignWithBiddingStrategy(AdWordsUser user, string name,
        long biddingStrategyId, long sharedBudgetId) {
      using (CampaignService campaignService = (CampaignService) user.GetService(
          AdWordsService.v201806.CampaignService)) {
        // Create campaign.
        Campaign campaign = new Campaign();
        campaign.name = name;
        campaign.advertisingChannelType = AdvertisingChannelType.SEARCH;

        // Recommendation: Set the campaign to PAUSED when creating it to prevent
        // the ads from immediately serving. Set to ENABLED once you've added
        // targeting and the ads are ready to serve.
        campaign.status = CampaignStatus.PAUSED;

        // Set the budget.
        campaign.budget = new Budget();
        campaign.budget.budgetId = sharedBudgetId;

        // Set bidding strategy (required).
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration();
        biddingStrategyConfiguration.biddingStrategyId = biddingStrategyId;

        campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

        // Set network targeting (recommended).
        NetworkSetting networkSetting = new NetworkSetting();
        networkSetting.targetGoogleSearch = true;
        networkSetting.targetSearchNetwork = true;
        networkSetting.targetContentNetwork = true;
        campaign.networkSetting = networkSetting;

        // Create operation.
        CampaignOperation operation = new CampaignOperation();
        operation.operand = campaign;
        operation.@operator = Operator.ADD;

        return campaignService.mutate(new CampaignOperation[] { operation }).value[0];
      }
    }
  }
}

Send feedback about...

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