Extensions Samples

The code samples below provide examples of common extension functions using the AdWords API. Client Library.

Add Google My Business location extensions

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

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201710;
using Google.Api.Ads.Common.Lib;

using System;

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

  /// <summary>
  /// This code example adds a feed that syncs feed items from a Google
  /// My Business (GMB) account and associates the feed with a customer.
  /// </summary>
  public class AddGoogleMyBusinessLocationExtensions : ExampleBase {

    /// <summary>
    /// The placeholder type for location extensions. See the Placeholder
    /// reference page for a list of all the placeholder types and fields.
    ///
    /// https://developers.google.com/adwords/api/docs/appendix/placeholders
    /// </summary>
    private const int PLACEHOLDER_LOCATION = 7;

    /// <summary>
    /// Returns a description about the code example.
    /// </summary>
    public override string Description {
      get {
        return "This code example adds a feed that syncs feed items from a Google My Business " +
            "(GMB) account and associates the feed with a customer.";
      }
    }

    /// <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) {
      AddGoogleMyBusinessLocationExtensions codeExample =
          new AddGoogleMyBusinessLocationExtensions();
      Console.WriteLine(codeExample.Description);

      AdWordsUser user = new AdWordsUser();

      try {
        // The email address of either an owner or a manager of the GMB account.
        string gmbEmailAddress = "INSERT_GMB_EMAIL_ADDRESS_HERE";

        // Refresh the access token so that there's a valid access token.
        user.OAuthProvider.RefreshAccessToken();

        // If the gmbEmailAddress above is the same user you used to generate
        // your AdWords API refresh token, leave the assignment below unchanged.
        // Otherwise, to obtain an access token for your GMB account, run the
        // OAuth Token generator utility while logged in as the same user as
        // gmbEmailAddress. Copy and paste the AccessToken value into the
        // assignment below.
        string gmbAccessToken = user.OAuthProvider.AccessToken;

        // If the gmbEmailAddress above is for a GMB manager instead of the GMB
        // account owner, then set businessAccountIdentifier to the +Page ID of
        // a location for which the manager has access. See the location
        // extensions guide at
        // https://developers.google.com/adwords/api/docs/guides/feed-services-locations
        // for details.
        String businessAccountIdentifier = null;
        codeExample.Run(user, gmbEmailAddress, gmbAccessToken, businessAccountIdentifier);
      } 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="gmbEmailAddress">The email address for Google My Business
    /// account.</param>
    /// <param name="gmbAccessToken">The OAuth2 access token for Google
    /// My Business account.</param>
    /// <param name="businessAccountIdentifier">The account identifier for
    /// Google My Business account.</param>
    public void Run(AdWordsUser user, string gmbEmailAddress, string gmbAccessToken,
        string businessAccountIdentifier) {
      Feed gmbFeed = CreateGmbFeed(user, gmbEmailAddress, gmbAccessToken,
          businessAccountIdentifier);
      AddCustomerFeed(user, gmbFeed);
    }

    /// <summary>
    /// Create a feed that will sync to the Google My Business account
    /// specified by gmbEmailAddress.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <param name="gmbEmailAddress">The GMB email address.</param>
    /// <param name="gmbAccessToken">The GMB access token.</param>
    /// <param name="businessAccountIdentifier">The GMB account identifier.</param>
    /// <returns>The newly created GMB feed.</returns>
    private static Feed CreateGmbFeed(AdWordsUser user, string gmbEmailAddress,
        string gmbAccessToken, string businessAccountIdentifier) {
      using (FeedService feedService = (FeedService) user.GetService(
          AdWordsService.v201710.FeedService)) {

        // Create a feed that will sync to the Google My Business account
        // specified by gmbEmailAddress. Do not add FeedAttributes to this object,
        // as AdWords will add them automatically because this will be a
        // system generated feed.
        Feed gmbFeed = new Feed();
        gmbFeed.name = String.Format("Google My Business feed #{0}",
            ExampleUtilities.GetRandomString());

        PlacesLocationFeedData feedData = new PlacesLocationFeedData();
        feedData.emailAddress = gmbEmailAddress;
        feedData.businessAccountIdentifier = businessAccountIdentifier;

        // Optional: specify labels to filter Google My Business listings. If
        // specified, only listings that have any of the labels set are
        // synchronized into FeedItems.
        feedData.labelFilters = new string[] { "Stores in New York City" };

        OAuthInfo oAuthInfo = new OAuthInfo();
        oAuthInfo.httpMethod = "GET";

        // Permissions for the AdWords API scope will also cover GMB.
        oAuthInfo.httpRequestUrl = user.Config.GetDefaultOAuth2Scope();
        oAuthInfo.httpAuthorizationHeader = string.Format("Bearer {0}", gmbAccessToken);
        feedData.oAuthInfo = oAuthInfo;

        gmbFeed.systemFeedGenerationData = feedData;

        // Since this feed's feed items will be managed by AdWords,
        // you must set its origin to ADWORDS.
        gmbFeed.origin = FeedOrigin.ADWORDS;

        // Create an operation to add the feed.
        FeedOperation feedOperation = new FeedOperation();
        feedOperation.operand = gmbFeed;
        feedOperation.@operator = Operator.ADD;

        try {
          // Add the feed. Since it is a system generated feed, AdWords will
          // automatically:
          // 1. Set up the FeedAttributes on the feed.
          // 2. Set up a FeedMapping that associates the FeedAttributes of the
          //    feed with the placeholder fields of the LOCATION placeholder
          //    type.
          FeedReturnValue addFeedResult = feedService.mutate(
              new FeedOperation[] { feedOperation });
          Feed addedFeed = addFeedResult.value[0];
          Console.WriteLine("Added GMB feed with ID {0}", addedFeed.id);
          return addedFeed;
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create GMB feed.", e);
        }
      }
    }

    /// <summary>
    /// Add a CustomerFeed that associates the feed with this customer for
    /// the LOCATION placeholder type.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="feed">The GMB feed.</param>
    void AddCustomerFeed(AdWordsUser user, Feed feed) {
      using (CustomerFeedService customerFeedService = (CustomerFeedService) user.GetService(
          AdWordsService.v201710.CustomerFeedService)) {

        // Add a CustomerFeed that associates the feed with this customer for
        // the LOCATION placeholder type.
        CustomerFeed customerFeed = new CustomerFeed();
        customerFeed.feedId = feed.id;
        customerFeed.placeholderTypes = new int[] { PLACEHOLDER_LOCATION };

        // Create a matching function that will always evaluate to true.
        Function customerMatchingFunction = new Function();
        ConstantOperand constOperand = new ConstantOperand();
        constOperand.type = ConstantOperandConstantType.BOOLEAN;
        constOperand.booleanValue = true;
        customerMatchingFunction.lhsOperand = new FunctionArgumentOperand[] { constOperand };
        customerMatchingFunction.@operator = FunctionOperator.IDENTITY;
        customerFeed.matchingFunction = customerMatchingFunction;

        // Create an operation to add the customer feed.
        CustomerFeedOperation customerFeedOperation = new CustomerFeedOperation();
        customerFeedOperation.operand = customerFeed;
        customerFeedOperation.@operator = Operator.ADD;

        // After the completion of the Feed ADD operation above the added feed
        // will not be available for usage in a CustomerFeed until the sync
        // between the AdWords and GMB accounts completes.  The loop below
        // will retry adding the CustomerFeed up to ten times with an
        // exponential back-off policy.
        CustomerFeed addedCustomerFeed = null;

        AdWordsAppConfig config = new AdWordsAppConfig();
        config.RetryCount = 10;

        ErrorHandler errorHandler = new ErrorHandler(config);
        try {
          do {
            try {
              CustomerFeedReturnValue customerFeedResult =
                  customerFeedService.mutate(
                      new CustomerFeedOperation[] { customerFeedOperation });
              addedCustomerFeed = customerFeedResult.value[0];

              Console.WriteLine("Added CustomerFeed for feed ID {0} and placeholder type {1}",
                  addedCustomerFeed.feedId, addedCustomerFeed.placeholderTypes[0]);
              break;
            } catch (AdWordsApiException e) {
              ApiException apiException = (ApiException) e.ApiException;
              foreach (ApiError error in apiException.errors) {
                if (error is CustomerFeedError) {
                  if ((error as CustomerFeedError).reason ==
                      CustomerFeedErrorReason.MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE) {
                    errorHandler.DoExponentialBackoff();
                    errorHandler.IncrementRetriedAttempts();
                  } else {
                    throw;
                  }
                }
              }
            }
          } while (errorHandler.HaveMoreRetryAttemptsLeft());
          // OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at
          // the Campaign level.  This will be similar to the CampaignFeed in the
          // AddSiteLinks example, except you can also filter based on the
          // business name and category of each FeedItem by using a
          // FeedAttributeOperand in your matching function.

          // OPTIONAL: Create an AdGroupFeed for even more fine grained control
          // over which feed items are used at the AdGroup level.
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create customer feed.", e);
        }
      }
    }
  }
}

Add prices

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

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

using System;
using System.Collections.Generic;

using DayOfWeek = Google.Api.Ads.AdWords.v201710.DayOfWeek;

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

  /// <summary>
  /// This code example adds a price extension and associates it with an
  /// account. Campaign targeting is also set using the specified campaign ID.
  /// To get campaigns, run AddCampaigns.cs.
  /// </summary>
  public class AddPrices : 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) {
      AddPrices codeExample = new AddPrices();
      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 adds a price extension and associates it with an account. " +
            "Campaign targeting is also set using the specified campaign ID. To get campaigns, " +
            "run AddCampaigns.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign to which sitelinks will
    /// be added.</param>
    public void Run(AdWordsUser user, long campaignId) {
      using (CustomerExtensionSettingService customerExtensionSettingService =
          (CustomerExtensionSettingService) user.GetService(
               AdWordsService.v201710.CustomerExtensionSettingService)) {

        // Create the price extension feed item.
        PriceFeedItem priceFeedItem = new PriceFeedItem() {
          priceExtensionType = PriceExtensionType.SERVICES,

          // Price qualifier is optional.
          priceQualifier = PriceExtensionPriceQualifier.FROM,
          trackingUrlTemplate = "http://tracker.example.com/?u={lpurl}",
          language = "en",

          campaignTargeting = new FeedItemCampaignTargeting() {
            TargetingCampaignId = campaignId,
          },
          scheduling = new FeedItemSchedule[] {
            new FeedItemSchedule() {
              dayOfWeek = DayOfWeek.SATURDAY,
              startHour = 10,
              startMinute = MinuteOfHour.ZERO,
              endHour = 22,
              endMinute = MinuteOfHour.ZERO
            },
            new FeedItemSchedule() {
              dayOfWeek = DayOfWeek.SUNDAY,
              startHour = 10,
              startMinute = MinuteOfHour.ZERO,
              endHour = 18,
              endMinute = MinuteOfHour.ZERO
            }
          }
        };

        // To create a price extension, at least three table rows are needed.
        List<PriceTableRow> priceTableRows = new List<PriceTableRow>();
        String currencyCode = "USD";
        priceTableRows.Add(
            CreatePriceTableRow(
                "Scrubs",
                "Body Scrub, Salt Scrub",
                "http://www.example.com/scrubs",
                "http://m.example.com/scrubs",
                60000000,
                currencyCode,
                PriceExtensionPriceUnit.PER_HOUR));
        priceTableRows.Add(
            CreatePriceTableRow(
                "Hair Cuts",
                "Once a month",
                "http://www.example.com/haircuts",
                "http://m.example.com/haircuts",
                75000000,
                currencyCode,
                PriceExtensionPriceUnit.PER_MONTH));
        priceTableRows.Add(
            CreatePriceTableRow(
                "Skin Care Package",
                "Four times a month",
                "http://www.example.com/skincarepackage",
                null,
                250000000,
                currencyCode,
                PriceExtensionPriceUnit.PER_MONTH));

        priceFeedItem.tableRows = priceTableRows.ToArray();

        // Create your campaign extension settings. This associates the sitelinks
        // to your campaign.
        CustomerExtensionSetting customerExtensionSetting = new CustomerExtensionSetting() {
          extensionType = FeedType.PRICE,
          extensionSetting = new ExtensionSetting() {
            extensions = new ExtensionFeedItem[] { priceFeedItem }
          }
        };

        CustomerExtensionSettingOperation operation = new CustomerExtensionSettingOperation() {
          operand = customerExtensionSetting,
          @operator = Operator.ADD
        };

        try {
          // Add the extensions.
          CustomerExtensionSettingReturnValue retVal =
              customerExtensionSettingService.mutate(
                  new CustomerExtensionSettingOperation[] { operation });
          if (retVal.value != null && retVal.value.Length > 0) {
            CustomerExtensionSetting newExtensionSetting = retVal.value[0];
            Console.WriteLine("Extension setting with type '{0}' was added.",
                newExtensionSetting.extensionType);
          } else {
            Console.WriteLine("No extension settings were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create extension settings.", e);
        }
      }
    }

    /// <summary>
    /// Creates a price table row.
    /// </summary>
    /// <param name="header">The row header.</param>
    /// <param name="description">The description text.</param>
    /// <param name="finalUrl">The final URL.</param>
    /// <param name="finalMobileUrl">The mobile final URL, or null if this field
    /// should not be set.</param>
    /// <param name="priceInMicros">The price in micros.</param>
    /// <param name="currencyCode">The currency code.</param>
    /// <param name="priceUnit">The price unit.</param>
    /// <returns>A price table row for creating price extension.</returns>
    private static PriceTableRow CreatePriceTableRow(String header, String description,
        String finalUrl, String finalMobileUrl, long priceInMicros, String currencyCode,
        PriceExtensionPriceUnit priceUnit) {
      PriceTableRow retval = new PriceTableRow() {
        header = header,
        description = description,
        finalUrls = new UrlList() {
          urls = new String[] { finalUrl }
        },
        price = new MoneyWithCurrency() {
          currencyCode = currencyCode,
          money = new Money() {
            microAmount = priceInMicros
          }
        },
        priceUnit = priceUnit
      };

      // Optional: set the mobile final URLs.
      if (!string.IsNullOrEmpty(finalMobileUrl)) {
        retval.finalMobileUrls = new UrlList() {
          urls = new String[] { finalMobileUrl }
        };
      }
      return retval;
    }
  }
}

Add sitelinks to a campaign

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

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

using System;
using System.Collections.Generic;

using DayOfWeek = Google.Api.Ads.AdWords.v201710.DayOfWeek;

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

  /// <summary>
  /// This code example adds sitelinks to a campaign. To create a campaign,
  /// run AddCampaign.cs.
  /// </summary>
  public class AddSitelinks : 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) {
      AddSitelinks codeExample = new AddSitelinks();
      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 adds sitelinks to a campaign. To create a campaign, run " +
            "AddCampaign.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign to which sitelinks will
    /// be added.</param>
    public void Run(AdWordsUser user, long campaignId) {
      using (CampaignExtensionSettingService campaignExtensionSettingService =
          (CampaignExtensionSettingService) user.GetService(
               AdWordsService.v201710.CampaignExtensionSettingService)) {

        Customer customer = null;
        using (CustomerService customerService = (CustomerService) user.GetService(
            AdWordsService.v201710.CustomerService)) {
          // Find the matching customer and its time zone. The getCustomers method
          // will return a single Customer object corresponding to the session's
          // clientCustomerId.
          customer = customerService.getCustomers()[0];
          Console.WriteLine("Found customer ID {0:###-###-####} with time zone '{1}'.",
              customer.customerId, customer.dateTimeZone);
        }
        List<ExtensionFeedItem> extensions = new List<ExtensionFeedItem>();

        // Create your sitelinks.
        SitelinkFeedItem sitelink1 = new SitelinkFeedItem() {
          sitelinkText = "Store Hours",
          sitelinkFinalUrls = new UrlList() {
            urls = new string[] { "http://www.example.com/storehours" }
          }
        };
        extensions.Add(sitelink1);

        DateTime startOfThanksGiving = new DateTime(DateTime.Now.Year, 11, 20, 0, 0, 0);
        DateTime endOfThanksGiving = new DateTime(DateTime.Now.Year, 11, 27, 23, 59, 59);

        // Add check to make sure we don't create a sitelink with end date in the
        // past.
        if (DateTime.Now < endOfThanksGiving) {
          // Show the Thanksgiving specials link only from 20 - 27 Nov.
          SitelinkFeedItem sitelink2 = new SitelinkFeedItem() {
            sitelinkText = "Thanksgiving Specials",
            sitelinkFinalUrls = new UrlList() {
              urls = new string[] { "http://www.example.com/thanksgiving" }
            },
            startTime = string.Format("{0} {1}", startOfThanksGiving.ToString("yyyyMMdd HHmmss"),
                customer.dateTimeZone),
            endTime = string.Format("{0} {1}", endOfThanksGiving.ToString("yyyyMMdd HHmmss"),
                customer.dateTimeZone),

            // Target this sitelink for United States only. See
            // https://developers.google.com/adwords/api/docs/appendix/geotargeting
            // for valid geolocation codes.
            geoTargeting = new Location() {
              id = 2840
            },

            // Restrict targeting only to people physically within the United States.
            // Otherwise, this could also show to people interested in the United States
            // but not physically located there.
            geoTargetingRestriction = new FeedItemGeoRestriction() {
              geoRestriction = GeoRestriction.LOCATION_OF_PRESENCE
            }
          };
          extensions.Add(sitelink2);
        }
        // Show the wifi details primarily for high end mobile users.
        SitelinkFeedItem sitelink3 = new SitelinkFeedItem() {
          sitelinkText = "Wifi available",
          sitelinkFinalUrls = new UrlList() {
            urls = new string[] { "http://www.example.com/mobile/wifi" }
          },
          devicePreference = new FeedItemDevicePreference() {
            // See https://developers.google.com/adwords/api/docs/appendix/platforms
            // for device criteria IDs.
            devicePreference = 30001
          },

          // Target this sitelink for the keyword "free wifi".
          keywordTargeting = new Keyword() {
            text = "free wifi",
            matchType = KeywordMatchType.BROAD
          }
        };
        extensions.Add(sitelink3);

        // Show the happy hours link only during Mon - Fri 6PM to 9PM.
        SitelinkFeedItem sitelink4 = new SitelinkFeedItem() {
          sitelinkText = "Happy hours",
          sitelinkFinalUrls = new UrlList() {
            urls = new string[] { "http://www.example.com/happyhours" },
          },
          scheduling = new FeedItemSchedule[] {
            new FeedItemSchedule() {
                dayOfWeek = DayOfWeek.MONDAY,
                startHour = 18,
                startMinute = MinuteOfHour.ZERO,
                endHour = 21,
                endMinute = MinuteOfHour.ZERO
            },
            new FeedItemSchedule() {
                dayOfWeek = DayOfWeek.TUESDAY,
                startHour = 18,
                startMinute = MinuteOfHour.ZERO,
                endHour = 21,
                endMinute = MinuteOfHour.ZERO
            },
            new FeedItemSchedule() {
                dayOfWeek = DayOfWeek.WEDNESDAY,
                startHour = 18,
                startMinute = MinuteOfHour.ZERO,
                endHour = 21,
                endMinute = MinuteOfHour.ZERO
            },
            new FeedItemSchedule() {
                dayOfWeek = DayOfWeek.THURSDAY,
                startHour = 18,
                startMinute = MinuteOfHour.ZERO,
                endHour = 21,
                endMinute = MinuteOfHour.ZERO
            },
            new FeedItemSchedule() {
                dayOfWeek = DayOfWeek.FRIDAY,
                startHour = 18,
                startMinute = MinuteOfHour.ZERO,
                endHour = 21,
                endMinute = MinuteOfHour.ZERO
            }
          }
        };
        extensions.Add(sitelink4);

        // Create your campaign extension settings. This associates the sitelinks
        // to your campaign.
        CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting();
        campaignExtensionSetting.campaignId = campaignId;
        campaignExtensionSetting.extensionType = FeedType.SITELINK;
        campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
          extensions = extensions.ToArray()
        };

        CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation() {
          operand = campaignExtensionSetting,
          @operator = Operator.ADD
        };

        try {
          // Add the extensions.
          CampaignExtensionSettingReturnValue retVal = campaignExtensionSettingService.mutate(
              new CampaignExtensionSettingOperation[] { operation });

          // Display the results.
          if (retVal.value != null && retVal.value.Length > 0) {
            CampaignExtensionSetting newExtensionSetting = retVal.value[0];
            Console.WriteLine("Extension setting with type = {0} was added to campaign ID {1}.",
                newExtensionSetting.extensionType, newExtensionSetting.campaignId);
          } else {
            Console.WriteLine("No extension settings were created.");
          }
        } catch (Exception e) {
          throw new System.ApplicationException("Failed to create extension settings.", e);
        }
      }
    }
  }
}

Add sitelinks to a campaign using feeds

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

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

using System;
using System.Collections.Generic;

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

  /// <summary>
  /// This code example adds sitelinks to a campaign using feed services.
  /// To create a campaign, run AddCampaign.cs. To add sitelinks using the
  /// simpler ExtensionSetting services, see AddSitelinks.cs.
  /// </summary>
  public class AddSitelinksUsingFeeds : ExampleBase {

    /// <summary>
    /// Holds data about sitelinks in a feed.
    /// </summary>
    private class SitelinksDataHolder {

      /// <summary>
      /// The sitelink feed item IDs.
      /// </summary>
      private List<long> feedItemIds = new List<long>();

      /// <summary>
      /// Gets the sitelink feed item IDs.
      /// </summary>
      public List<long> FeedItemIds {
        get {
          return feedItemIds;
        }
      }

      /// <summary>
      /// Gets or sets the feed ID.
      /// </summary>
      public long FeedId {
        get;
        set;
      }

      /// <summary>
      /// Gets or sets the link text feed attribute ID.
      /// </summary>
      public long LinkTextFeedAttributeId {
        get;
        set;
      }

      /// <summary>
      /// Gets or sets the link URL feed attribute ID.
      /// </summary>
      public long LinkFinalUrlFeedAttributeId {
        get;
        set;
      }

      /// <summary>
      /// Gets or sets the line 2 feed attribute ID.
      /// </summary>
      public long Line2FeedAttributeId {
        get;
        set;
      }

      /// <summary>
      /// Gets or sets the line 3 feed attribute ID.
      /// </summary>
      public long Line3FeedAttributeId {
        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) {
      AddSitelinksUsingFeeds codeExample = new AddSitelinksUsingFeeds();
      Console.WriteLine(codeExample.Description);
      try {
        long campaignId = long.Parse("INSERT_CAMPAIGN_ID_HERE");
        string feedName = "INSERT_FEED_NAME_HERE";
        codeExample.Run(new AdWordsUser(), campaignId, 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 sitelinks to a campaign using feed services. To create a " +
            "campaign, run AddCampaign.cs. To add sitelinks using the simpler ExtensionSetting " +
            "services, see AddSitelinks.cs.";
      }
    }

    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign with which sitelinks are associated.
    /// </param>
    /// <param name="feedName">Name of the feed to be created.</param>
    public void Run(AdWordsUser user, long campaignId, string feedName) {
      SitelinksDataHolder sitelinksData = new SitelinksDataHolder();
      createSitelinksFeed(user, sitelinksData, feedName);
      createSitelinksFeedItems(user, sitelinksData);
      createSitelinksFeedMapping(user, sitelinksData);
      createSitelinksCampaignFeed(user, sitelinksData, campaignId);
    }

    private static void createSitelinksFeed(AdWordsUser user, SitelinksDataHolder sitelinksData,
        string feedName) {
      using (FeedService feedService = (FeedService) user.GetService(
          AdWordsService.v201710.FeedService)) {

        // Create attributes.
        FeedAttribute textAttribute = new FeedAttribute();
        textAttribute.type = FeedAttributeType.STRING;
        textAttribute.name = "Link Text";

        FeedAttribute finalUrlAttribute = new FeedAttribute();
        finalUrlAttribute.type = FeedAttributeType.URL_LIST;
        finalUrlAttribute.name = "Link Final URLs";

        FeedAttribute line2Attribute = new FeedAttribute();
        line2Attribute.type = FeedAttributeType.STRING;
        line2Attribute.name = "Line 2";

        FeedAttribute line3Attribute = new FeedAttribute();
        line3Attribute.type = FeedAttributeType.STRING;
        line3Attribute.name = "Line 3";

        // Create the feed.
        Feed sitelinksFeed = new Feed();
        sitelinksFeed.name = feedName;
        sitelinksFeed.attributes = new FeedAttribute[] { textAttribute, finalUrlAttribute,
          line2Attribute, line3Attribute };
        sitelinksFeed.origin = FeedOrigin.USER;

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

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

        Feed savedFeed = result.value[0];
        sitelinksData.FeedId = savedFeed.id;

        FeedAttribute[] savedAttributes = savedFeed.attributes;
        sitelinksData.LinkTextFeedAttributeId = savedAttributes[0].id;
        sitelinksData.LinkFinalUrlFeedAttributeId = savedAttributes[1].id;
        sitelinksData.Line2FeedAttributeId = savedAttributes[2].id;
        sitelinksData.Line3FeedAttributeId = savedAttributes[3].id;

        Console.WriteLine("Feed with name {0} and ID {1} with linkTextAttributeId {2}, " +
            "linkFinalUrlAttributeId {3}, line2AttributeId {4} and line3AttributeId {5} " +
            "was created.", savedFeed.name, savedFeed.id, savedAttributes[0].id,
            savedAttributes[1].id, savedAttributes[2].id, savedAttributes[3].id);
      }
    }

    private static void createSitelinksFeedItems(
        AdWordsUser user, SitelinksDataHolder siteLinksData) {
      using (FeedItemService feedItemService =
          (FeedItemService) user.GetService(AdWordsService.v201710.FeedItemService)) {

        // Create operations to add FeedItems.
        FeedItemOperation home =
            newSitelinkFeedItemAddOperation(siteLinksData,
            "Home", "http://www.example.com", "Home line 2", "Home line 3");
        FeedItemOperation stores =
            newSitelinkFeedItemAddOperation(siteLinksData,
            "Stores", "http://www.example.com/stores", "Stores line 2", "Stores line 3");
        FeedItemOperation onSale =
            newSitelinkFeedItemAddOperation(siteLinksData,
            "On Sale", "http://www.example.com/sale", "On Sale line 2", "On Sale line 3");
        FeedItemOperation support =
            newSitelinkFeedItemAddOperation(siteLinksData,
            "Support", "http://www.example.com/support", "Support line 2", "Support line 3");
        FeedItemOperation products =
            newSitelinkFeedItemAddOperation(siteLinksData,
            "Products", "http://www.example.com/prods", "Products line 2", "Products line 3");

        // This site link is using geographical targeting by specifying the
        // criterion ID for California.
        FeedItemOperation aboutUs =
            newSitelinkFeedItemAddOperation(siteLinksData,
                "About Us", "http://www.example.com/about", "About Us line 2",
                "About Us line 3", 21137);

        FeedItemOperation[] operations =
            new FeedItemOperation[] { home, stores, onSale, support, products, aboutUs };

        FeedItemReturnValue result = feedItemService.mutate(operations);
        foreach (FeedItem item in result.value) {
          Console.WriteLine("FeedItem with feedItemId {0} was added.", item.feedItemId);
          siteLinksData.FeedItemIds.Add(item.feedItemId);
        }
      }
    }

    // See the Placeholder reference page for a list of all the placeholder types and fields.
    // https://developers.google.com/adwords/api/docs/appendix/placeholders.html
    private const int PLACEHOLDER_SITELINKS = 1;

    // See the Placeholder reference page for a list of all the placeholder types and fields.
    private const int PLACEHOLDER_FIELD_SITELINK_LINK_TEXT = 1;

    private const int PLACEHOLDER_FIELD_SITELINK_FINAL_URL = 5;
    private const int PLACEHOLDER_FIELD_LINE_2_TEXT = 3;
    private const int PLACEHOLDER_FIELD_LINE_3_TEXT = 4;

    private static void createSitelinksFeedMapping(AdWordsUser user,
        SitelinksDataHolder sitelinksData) {
      using (FeedMappingService feedMappingService =
          (FeedMappingService) user.GetService(AdWordsService.v201710.FeedMappingService)) {

        // Map the FeedAttributeIds to the fieldId constants.
        AttributeFieldMapping linkTextFieldMapping = new AttributeFieldMapping();
        linkTextFieldMapping.feedAttributeId = sitelinksData.LinkTextFeedAttributeId;
        linkTextFieldMapping.fieldId = PLACEHOLDER_FIELD_SITELINK_LINK_TEXT;

        AttributeFieldMapping linkFinalUrlFieldMapping = new AttributeFieldMapping();
        linkFinalUrlFieldMapping.feedAttributeId = sitelinksData.LinkFinalUrlFeedAttributeId;
        linkFinalUrlFieldMapping.fieldId = PLACEHOLDER_FIELD_SITELINK_FINAL_URL;

        AttributeFieldMapping line2FieldMapping = new AttributeFieldMapping();
        line2FieldMapping.feedAttributeId = sitelinksData.Line2FeedAttributeId;
        line2FieldMapping.fieldId = PLACEHOLDER_FIELD_LINE_2_TEXT;

        AttributeFieldMapping line3FieldMapping = new AttributeFieldMapping();
        line3FieldMapping.feedAttributeId = sitelinksData.Line3FeedAttributeId;
        line3FieldMapping.fieldId = PLACEHOLDER_FIELD_LINE_3_TEXT;

        // Create the FieldMapping and operation.
        FeedMapping feedMapping = new FeedMapping();
        feedMapping.placeholderType = PLACEHOLDER_SITELINKS;
        feedMapping.feedId = sitelinksData.FeedId;
        feedMapping.attributeFieldMappings = new AttributeFieldMapping[] {
        linkTextFieldMapping, linkFinalUrlFieldMapping, line2FieldMapping, line3FieldMapping };

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

        // Save the field mapping.
        FeedMappingReturnValue result =
            feedMappingService.mutate(new FeedMappingOperation[] { operation });

        foreach (FeedMapping savedFeedMapping in result.value) {
          Console.WriteLine(
              "Feed mapping with ID {0} and placeholderType {1} was saved for feed with ID {2}.",
              savedFeedMapping.feedMappingId, savedFeedMapping.placeholderType,
              savedFeedMapping.feedId);
        }
      }
    }

    private static void createSitelinksCampaignFeed(AdWordsUser user,
        SitelinksDataHolder sitelinksData, long campaignId) {
      using (CampaignFeedService campaignFeedService =
          (CampaignFeedService) user.GetService(AdWordsService.v201710.CampaignFeedService)) {

        // Construct a matching function that associates the sitelink feeditems
        // to the campaign, and set the device preference to Mobile. See the
        // matching function guide at
        // https://developers.google.com/adwords/api/docs/guides/feed-matching-functions
        // for more details.
        string matchingFunctionString = string.Format(@"
          AND(
            IN(FEED_ITEM_ID, {{{0}}}),
            EQUALS(CONTEXT.DEVICE, 'Mobile')
          )",
            string.Join(",", sitelinksData.FeedItemIds));

        CampaignFeed campaignFeed = new CampaignFeed() {
          feedId = sitelinksData.FeedId,
          campaignId = campaignId,
          matchingFunction = new Function() {
            functionString = matchingFunctionString
          },
          // Specifying placeholder types on the CampaignFeed allows the same feed
          // to be used for different placeholders in different Campaigns.
          placeholderTypes = new int[] { PLACEHOLDER_SITELINKS }
        };

        CampaignFeedOperation operation = new CampaignFeedOperation();
        operation.operand = campaignFeed;
        operation.@operator = Operator.ADD;

        CampaignFeedReturnValue result = campaignFeedService.mutate(
            new CampaignFeedOperation[] { operation });

        foreach (CampaignFeed savedCampaignFeed in result.value) {
          Console.WriteLine("Campaign with ID {0} was associated with feed with ID {1}",
              savedCampaignFeed.campaignId, savedCampaignFeed.feedId);
        }
      }
    }

    private static FeedItemOperation newSitelinkFeedItemAddOperation(
        SitelinksDataHolder sitelinksData, String text, String finalUrl,
        string line2, string line3) {
      return newSitelinkFeedItemAddOperation(sitelinksData, text, finalUrl, line2, line3, null);
    }

    private static FeedItemOperation newSitelinkFeedItemAddOperation(
        SitelinksDataHolder sitelinksData, String text, String finalUrl, string line2,
        string line3, long? locationId) {
      // Create the FeedItemAttributeValues for our text values.
      FeedItemAttributeValue linkTextAttributeValue = new FeedItemAttributeValue();
      linkTextAttributeValue.feedAttributeId = sitelinksData.LinkTextFeedAttributeId;
      linkTextAttributeValue.stringValue = text;

      FeedItemAttributeValue linkFinalUrlAttributeValue = new FeedItemAttributeValue();
      linkFinalUrlAttributeValue.feedAttributeId = sitelinksData.LinkFinalUrlFeedAttributeId;
      linkFinalUrlAttributeValue.stringValues = new string[] { finalUrl };

      FeedItemAttributeValue line2AttributeValue = new FeedItemAttributeValue();
      line2AttributeValue.feedAttributeId = sitelinksData.Line2FeedAttributeId;
      line2AttributeValue.stringValue = line2;

      FeedItemAttributeValue line3AttributeValue = new FeedItemAttributeValue();
      line3AttributeValue.feedAttributeId = sitelinksData.Line3FeedAttributeId;
      line3AttributeValue.stringValue = line3;

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

      // OPTIONAL: Use geographical targeting on a feed item.
      // The IDs can be found in the documentation or retrieved with the
      // LocationCriterionService.
      if (locationId != null) {
        item.geoTargeting = new Location() {
          id = locationId.Value,
        };

        // OPTIONAL: Restrict targeting only to people physically within the location.
        item.geoTargetingRestriction = new FeedItemGeoRestriction() {
          geoRestriction = GeoRestriction.LOCATION_OF_PRESENCE
        };
      }

      item.attributeValues =
          new FeedItemAttributeValue[] { linkTextAttributeValue, linkFinalUrlAttributeValue,
            line2AttributeValue, line3AttributeValue };

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

      return operation;
    }
  }
}

Send feedback about...

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