The AdWords API will sunset on April 27, 2022. Migrate to the Google Ads API to take advantage of the latest Google Ads features.

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.v201809;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809
                    .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.v201809.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.v201809.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.v201809.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.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809
                    .AdGroupBidModifierService))
            {
                // Mobile criterion ID.
                long criterionId = 30001;

                // Create the adgroup bid modifier.
                AdGroupBidModifier adGroupBidModifier = new AdGroupBidModifier
                {
                    bidModifier = bidModifier,
                    adGroupId = adGroupId
                };

                Platform platform = new Platform
                {
                    id = criterionId
                };

                adGroupBidModifier.criterion = platform;

                AdGroupBidModifierOperation operation = new AdGroupBidModifierOperation
                {
                    @operator = Operator.ADD,
                    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 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.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.FeedService))
            {
                // Create attributes.
                FeedAttribute urlAttribute = new FeedAttribute
                {
                    type = FeedAttributeType.URL_LIST,
                    name = "Page URL"
                };

                FeedAttribute labelAttribute = new FeedAttribute
                {
                    type = FeedAttributeType.STRING_LIST,
                    name = "Label"
                };

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

                // Create operation.
                FeedOperation operation = new FeedOperation
                {
                    operand = sitelinksFeed,
                    @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.v201809.FeedMappingService))
            {
                // Map the FeedAttributeIds to the fieldId constants.
                AttributeFieldMapping urlFieldMapping = new AttributeFieldMapping
                {
                    feedAttributeId = feedDetails.urlAttributeId,
                    fieldId = DSA_PAGE_URLS_FIELD_ID
                };

                AttributeFieldMapping labelFieldMapping = new AttributeFieldMapping
                {
                    feedAttributeId = feedDetails.labelAttributeId,
                    fieldId = DSA_LABEL_FIELD_ID
                };

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

                FeedMappingOperation operation = new FeedMappingOperation
                {
                    operand = feedMapping,
                    @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.v201809.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
            {
                feedAttributeId = details.urlAttributeId,

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

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

            // Create the feed item and operation.
            FeedItem item = new FeedItem
            {
                feedId = details.feedId,

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

            FeedItemOperation operation = new FeedItemOperation
            {
                operand = item,
                @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.v201809.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
                {
                    id = campaignId,
                    settings = campaignSettings
                };

                CampaignOperation operation = new CampaignOperation
                {
                    operand = campaignToUpdate,
                    @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.v201809
                    .AdGroupCriterionService))
            {
                // Create a webpage criterion.
                Webpage webpage = new Webpage();

                WebpageParameter parameter = new WebpageParameter
                {
                    criterionName = "Test criterion"
                };
                webpage.parameter = parameter;

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

                BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion
                {
                    adGroupId = adGroupId,
                    criterion = webpage
                };

                // Set a custom bid for this criterion.
                BiddingStrategyConfiguration biddingStrategyConfiguration =
                    new BiddingStrategyConfiguration
                    {
                        bids = new Bids[]
                        {
                            new CpcBid()
                            {
                                bid = new Money()
                                {
                                    microAmount = 1500000
                                }
                            }
                        }
                    };

                criterion.biddingStrategyConfiguration = biddingStrategyConfiguration;

                AdGroupCriterionOperation operation = new AdGroupCriterionOperation
                {
                    operand = criterion,
                    @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.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.BudgetService))
            {
                // Create the campaign budget.
                Budget budget = new Budget
                {
                    name = "Interplanetary Cruise Budget #" + ExampleUtilities.GetRandomString(),
                    deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD,
                    amount = new Money
                    {
                        microAmount = 500000
                    }
                };

                BudgetOperation budgetOperation = new BudgetOperation
                {
                    @operator = Operator.ADD,
                    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.v201809.CampaignService))
            {
                // Create a Dynamic Search Ads campaign.
                Campaign campaign = new Campaign
                {
                    name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString(),
                    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.
                    status = CampaignStatus.PAUSED
                };

                BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration
                {
                    biddingStrategyType = BiddingStrategyType.MANUAL_CPC
                };
                campaign.biddingStrategyConfiguration = biddingConfig;

                campaign.budget = new Budget
                {
                    budgetId = budget.budgetId
                };

                // Required: Set the campaign's Dynamic Search Ads settings.
                DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting
                {
                    // Required: Set the domain name and language.
                    domainName = "example.com",
                    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
                {
                    @operator = Operator.ADD,
                    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.v201809.AdGroupService))
            {
                // Create the ad group.
                AdGroup adGroup = new AdGroup
                {
                    // Required: Set the ad group's type to Dynamic Search Ads.
                    adGroupType = AdGroupType.SEARCH_DYNAMIC_ADS,

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

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

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

                CpcBid cpcBid = new CpcBid
                {
                    bid = new Money
                    {
                        microAmount = 3000000
                    }
                };

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

                adGroup.biddingStrategyConfiguration = biddingConfig;

                // Create the operation.
                AdGroupOperation operation = new AdGroupOperation
                {
                    @operator = Operator.ADD,
                    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.v201809.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.
                    description = "Buy your tickets now!",
                    description2 = "Discount ends soon"
                };

                // Create the ad group ad.
                AdGroupAd adGroupAd = new AdGroupAd
                {
                    adGroupId = adGroupId,
                    ad = expandedDSA,

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

                // Create the operation.
                AdGroupAdOperation operation = new AdGroupAdOperation
                {
                    @operator = Operator.ADD,
                    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.v201809
                    .AdGroupCriterionService))
            {
                // Create a webpage criterion for special offers for mars cruise.
                WebpageParameter param = new WebpageParameter
                {
                    criterionName = "Special offers for mars"
                };

                WebpageCondition urlCondition = new WebpageCondition
                {
                    operand = WebpageConditionOperand.URL,
                    argument = "/marscruise/special"
                };

                WebpageCondition titleCondition = new WebpageCondition
                {
                    operand = WebpageConditionOperand.PAGE_TITLE,
                    argument = "Special Offer"
                };

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

                Webpage webpage = new Webpage
                {
                    parameter = param
                };

                // Create biddable ad group criterion.
                BiddableAdGroupCriterion biddableAdGroupCriterion = new BiddableAdGroupCriterion
                {
                    adGroupId = adGroupId,
                    criterion = webpage,
                    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
                {
                    @operator = Operator.ADD,
                    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.v201809;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.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
                {
                    key = "season",
                    value = "christmas"
                };

                CustomParameter promoCodeParameter = new CustomParameter
                {
                    key = "promocode",
                    value = "NYC123"
                };

                expandedTextAd.urlCustomParameters = new CustomParameters
                {
                    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
                {
                    adGroupId = adGroupId,
                    ad = expandedTextAd,

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

                // Create the operation.
                AdGroupAdOperation operation = new AdGroupAdOperation
                {
                    @operator = Operator.ADD,
                    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.v201809;
using Google.Api.Ads.Common.Util;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.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
                {
                    mediaId = UploadImage(user, "https://goo.gl/mtt54n").mediaId
                };

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

                GmailTeaser teaser = new GmailTeaser
                {
                    headline = "Dream",
                    description = "Create your own adventure",
                    businessName = "Interplanetary Ships",
                    logoImage = logoImage
                };

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

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

                // Creates ad group ad operation and add it to the list.
                AdGroupAdOperation operation = new AdGroupAdOperation
                {
                    operand = adGroupAd,
                    @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.v201809.MediaService))
            {
                Image image = new Image
                {
                    data = MediaUtilities.GetAssetDataFromUrl(url, user.Config),
                    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.v201809;
using Google.Api.Ads.Common.Util;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.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.v201809;
using Google.Api.Ads.Common.Util;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.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.v201809.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.v201809;
using Google.Api.Ads.Common.Util;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.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.
                        marketingImage = new Image()
                        {
                            mediaId = UploadImage(user, "https://goo.gl/3b9Wfh")
                        },
                        shortHeadline = "Travel",
                        longHeadline = "Travel the World",
                        description = "Take to the air!",
                        businessName = "Google",
                        finalUrls = new string[]
                        {
                            "http://www.example.com"
                        },

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

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

                        // Optional: Set dynamic display ad settings, composed of landscape logo
                        // image, promotion text, and price prefix.
                        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.v201809.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.v201809;
using Google.Api.Ads.Common.Util;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.CampaignService))
            {
                Campaign campaign = new Campaign
                {
                    name = "Shopping campaign #" + ExampleUtilities.GetRandomString(),
                    // Dynamic remarketing campaigns are only available on the Google Display
                    // Network.
                    advertisingChannelType = AdvertisingChannelType.DISPLAY,
                    status = CampaignStatus.PAUSED
                };

                Budget budget = new 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
                    {
                        biddingStrategyType = BiddingStrategyType.MANUAL_CPC
                    };
                campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

                ShoppingSetting setting = new ShoppingSetting
                {
                    // Campaigns with numerically higher priorities take precedence over those with
                    // lower priorities.
                    campaignPriority = 0,

                    // Set the Merchant Center account ID from which to source products.
                    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.
                    salesCountry = "ZZ",

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

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

                CampaignOperation op = new CampaignOperation
                {
                    operand = campaign,
                    @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.v201809.AdGroupService))
            {
                AdGroup group = new AdGroup
                {
                    name = "Dynamic remarketing ad group",
                    campaignId = campaign.id,
                    status = AdGroupStatus.ENABLED
                };

                AdGroupOperation op = new AdGroupOperation
                {
                    operand = group,
                    @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.v201809
                    .AdGroupCriterionService))
            {
                CriterionUserList userList = new CriterionUserList
                {
                    userListId = userListId
                };
                BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion
                {
                    criterion = userList,
                    adGroupId = adGroup.id
                };

                AdGroupCriterionOperation op = new AdGroupCriterionOperation
                {
                    operand = adGroupCriterion,
                    @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.v201809.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.
                    marketingImage = UploadImage(user, "https://goo.gl/3b9Wfh"),

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

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

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

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

                    // Optional: Create a square marketing image and set it to the 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
                {
                    ad = ad,
                    adGroupId = adGroup.id
                };

                AdGroupAdOperation op = new AdGroupAdOperation
                {
                    operand = adGroupAd,
                    @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
            {
                landscapeLogoImage = logo,
                pricePrefix = "as low as",
                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.v201809.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.v201809;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.CampaignService))
            {
                // Create the campaign.
                Campaign campaign = new 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.
                    status = CampaignStatus.PAUSED,

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

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

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

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

                // Set the campaign's budget.
                campaign.budget = new 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
                {
                    appId = "com.labpixies.colordrips",
                    appVendor = MobileApplicationVendor.VENDOR_GOOGLE_MARKET,
                    description1 = "A cool puzzle game",
                    description2 = "Remove connected blocks",
                    description3 = "3 difficulty levels",
                    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.
                    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
                {
                    positiveGeoTargetType =
                        GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE,
                    negativeGeoTargetType = GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE
                };

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

                // Create the operation.
                CampaignOperation operation = new CampaignOperation
                {
                    @operator = Operator.ADD,
                    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.v201809.BudgetService))
            {
                // Create the campaign budget.
                Budget budget = new Budget
                {
                    name =
                        "Interplanetary Cruise App Budget #" + ExampleUtilities.GetRandomString(),
                    deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD,
                    amount = new Money
                    {
                        microAmount = 5000000
                    },

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

                BudgetOperation budgetOperation = new BudgetOperation
                {
                    @operator = Operator.ADD,
                    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.v201809
                    .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.v201809;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809.SharedSetService))
            {
                SharedSetOperation operation = new SharedSetOperation
                {
                    @operator = Operator.ADD
                };
                SharedSet sharedSet = new SharedSet
                {
                    name = "API Negative keyword list - " + ExampleUtilities.GetRandomString(),
                    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.v201809
                    .SharedCriterionService))
            {
                List<SharedCriterionOperation> operations = new List<SharedCriterionOperation>();
                foreach (string keywordText in keywordTexts)
                {
                    Keyword keyword = new Keyword
                    {
                        text = keywordText,
                        matchType = KeywordMatchType.BROAD
                    };

                    SharedCriterion sharedCriterion = new SharedCriterion
                    {
                        criterion = keyword,
                        negative = true,
                        sharedSetId = sharedSetId
                    };
                    SharedCriterionOperation operation = new SharedCriterionOperation
                    {
                        @operator = Operator.ADD,
                        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.v201809
                    .CampaignSharedSetService))
            {
                CampaignSharedSet campaignSharedSet = new CampaignSharedSet
                {
                    campaignId = campaignId,
                    sharedSetId = sharedSetId
                };

                CampaignSharedSetOperation operation = new CampaignSharedSetOperation
                {
                    @operator = Operator.ADD,
                    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.v201809;

using System;
using System.Collections.Generic;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809
                    .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.v201809
                    .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.v201809
                    .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.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809
                    .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.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <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.v201809
                    .BiddingStrategyService))
            {
                // Create a portfolio bidding strategy.
                SharedBiddingStrategy portfolioBiddingStrategy = new SharedBiddingStrategy
                {
                    name = name
                };

                TargetSpendBiddingScheme biddingScheme = new TargetSpendBiddingScheme
                {
                    // Optionally set additional bidding scheme parameters.
                    bidCeiling = new Money
                    {
                        microAmount = bidCeiling
                    },

                    spendTarget = new Money
                    {
                        microAmount = spendTarget
                    }
                };

                portfolioBiddingStrategy.biddingScheme = biddingScheme;

                // Create operation.
                BiddingStrategyOperation operation = new BiddingStrategyOperation
                {
                    @operator = Operator.ADD,
                    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.v201809.BudgetService))
            {
                // Create a shared budget
                Budget budget = new Budget
                {
                    name = name,
                    amount = new Money
                    {
                        microAmount = amount
                    },
                    deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD,
                    isExplicitlyShared = true
                };

                // Create operation.
                BudgetOperation operation = new BudgetOperation
                {
                    operand = budget,
                    @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.v201809.CampaignService))
            {
                // Create campaign.
                Campaign campaign = new Campaign
                {
                    name = name,
                    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.
                    status = CampaignStatus.PAUSED,

                    // Set the budget.
                    budget = new Budget
                    {
                        budgetId = sharedBudgetId
                    }
                };

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

                campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

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

                // Create operation.
                CampaignOperation operation = new CampaignOperation
                {
                    operand = campaign,
                    @operator = Operator.ADD
                };

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