Example #1
0
        /// <summary>
        /// Gets keyword ideas for the list of Seed keywords.
        /// </summary>
        /// <param name="user">The user for which keyword ideas are generated.
        /// </param>
        /// <param name="seedKeywords">The seed keywords for generating ideas.
        /// </param>
        /// <param name="negativeTerms">The list of keywords to exclude.</param>
        /// <returns>A list of keyword ideas.</returns>
        private List <KeywordIdea> GetKeywordIdeas(AdWordsUser user, List <string> seedKeywords,
                                                   SeedKeyword[] negativeTerms)
        {
            // Get the TargetingIdeaService.
            TargetingIdeaService targetingIdeaService =
                (TargetingIdeaService)user.GetService(AdWordsService.v201705.TargetingIdeaService);

            IdeaTextFilterSearchParameter excludedTerms = null;

            if (negativeTerms.Length > 0)
            {
                excludedTerms = GetExcludedKeywordSearchParams(negativeTerms);
            }

            LanguageSearchParameter languageParams = GetLanguageSearchParams();
            LocationSearchParameter locationParams = GetLocationSearchParams();

            List <KeywordIdea> retval = new List <KeywordIdea>();

            for (int i = 0; i < seedKeywords.Count; i += Settings.TIS_KEYWORDS_LIST_SIZE)
            {
                List <string> keywordsToSearch = new List <string>();
                for (int j = i; j < i + Settings.TIS_KEYWORDS_LIST_SIZE && j < seedKeywords.Count; j++)
                {
                    keywordsToSearch.Add(seedKeywords[j]);
                }

                // Create selector.
                TargetingIdeaSelector selector = new TargetingIdeaSelector();
                selector.requestType             = RequestType.IDEAS;
                selector.ideaType                = IdeaType.KEYWORD;
                selector.requestedAttributeTypes = new AttributeType[] {
                    AttributeType.KEYWORD_TEXT,
                    AttributeType.SEARCH_VOLUME,
                    AttributeType.AVERAGE_CPC,
                    AttributeType.COMPETITION
                };

                List <SearchParameter> paramList = new List <SearchParameter>();
                paramList.Add(new RelatedToQuerySearchParameter()
                {
                    queries = keywordsToSearch.ToArray(),
                });

                if (excludedTerms != null)
                {
                    paramList.Add(excludedTerms);
                }
                paramList.Add(locationParams);
                paramList.Add(languageParams);

                selector.searchParameters = paramList.ToArray();

                // Set selector paging (required for targeting idea service).
                Paging            paging = Paging.Default;
                TargetingIdeaPage page   = new TargetingIdeaPage();

                try {
                    do
                    {
                        // Get related keywords.
                        page = targetingIdeaService.get(selector);

                        // Display related keywords.
                        if (page.entries != null && page.entries.Length > 0)
                        {
                            foreach (TargetingIdea targetingIdea in page.entries)
                            {
                                string keyword = null;
                                long   averageMonthlySearches = 0;
                                long   averageCpc             = 0;
                                double competition            = 0f;

                                foreach (Type_AttributeMapEntry entry in targetingIdea.data)
                                {
                                    if (entry.key == AttributeType.KEYWORD_TEXT)
                                    {
                                        StringAttribute temp = (entry.value as StringAttribute);
                                        if (temp != null)
                                        {
                                            keyword = temp.value;
                                        }
                                    }

                                    if (entry.key == AttributeType.SEARCH_VOLUME)
                                    {
                                        LongAttribute temp = (entry.value as LongAttribute);
                                        if (temp != null)
                                        {
                                            averageMonthlySearches = temp.value;
                                        }
                                    }

                                    if (entry.key == AttributeType.AVERAGE_CPC)
                                    {
                                        MoneyAttribute temp = (entry.value as MoneyAttribute);
                                        if (temp != null && temp.value != null)
                                        {
                                            averageCpc = temp.value.microAmount;
                                        }
                                    }

                                    if (entry.key == AttributeType.COMPETITION)
                                    {
                                        DoubleAttribute temp = (entry.value as DoubleAttribute);
                                        if (temp != null)
                                        {
                                            competition = temp.value;
                                        }
                                    }
                                }

                                KeywordIdea keywordIdea = new KeywordIdea()
                                {
                                    KeywordText     = keyword,
                                    AverageSearches = averageMonthlySearches,
                                    AverageCpc      = averageCpc,
                                    Competition     = Math.Round(competition, Settings.ACCURACY,
                                                                 MidpointRounding.AwayFromZero)
                                };
                                retval.Add(keywordIdea);
                            }
                        }
                        selector.paging.IncreaseOffset();
                    } while (selector.paging.startIndex < page.totalNumEntries);
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to retrieve related keywords.", e);
                }
            }
            return(retval);
        }
        /// <summary>
        /// Creates the text ads.
        /// </summary>
        /// <param name="user">The Google Ads user.</param>
        /// <param name="adGroupId">The ad group ID.</param>
        /// <returns>The list of newly created ad group ads.</returns>
        public aw::AdGroupAd[] CreateTextAds(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupAdService.
            using (aw::AdGroupAdService adGroupAdService =
                       (aw::AdGroupAdService)user.GetService(AdWordsService.v201809.AdGroupAdService))
            {
                List <aw::AdGroupAdOperation> operations = new List <aw::AdGroupAdOperation>();

                for (int i = 0; i < NUMBER_OF_ADS; i++)
                {
                    // Create the expanded text ad.
                    aw::ExpandedTextAd expandedTextAd = new aw::ExpandedTextAd
                    {
                        headlinePart1 = "Cruise #" + i.ToString() + " to Mars",
                        headlinePart2 = "Best Space Cruise Line",
                        headlinePart3 = "For Your Loved Ones",
                        description   = "Buy your tickets now!",
                        description2  = "Discount ends soon",
                        finalUrls     = new string[]
                        {
                            "http://www.example.com/" + i
                        }
                    };

                    aw::AdGroupAd expandedTextAdGroupAd = new aw::AdGroupAd
                    {
                        adGroupId = adGroupId,
                        ad        = expandedTextAd,

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

                    // Create the operation.
                    aw::AdGroupAdOperation operation = new aw::AdGroupAdOperation
                    {
                        @operator = aw::Operator.ADD,
                        operand   = expandedTextAdGroupAd
                    };

                    operations.Add(operation);
                }

                // Create the ads.
                aw::AdGroupAdReturnValue retVal = adGroupAdService.mutate(operations.ToArray());

                foreach (aw::AdGroupAd adGroupAd in retVal.value)
                {
                    // Retrieve the newly created ad.
                    aw::ExpandedTextAd newAd = adGroupAd.ad as aw::ExpandedTextAd;

                    // Display the results.
                    Console.WriteLine(
                        "Expanded text ad with ID '{0}' and headline '{1} - {2}' " +
                        "was added.", newAd.id, newAd.headlinePart1, newAd.headlinePart2);
                }

                // Return the newly created ad.
                return(retVal.value);
            }
        }
Example #3
0
        /// <summary>
        /// Creates the Shopping campaign.
        /// </summary>
        /// <param name="user">The AdWords user for which the campaign is created.</param>
        /// <param name="budgetId">The budget ID.</param>
        /// <param name="merchantId">The Merchant Center ID.</param>
        /// <returns>The newly created Shopping campaign.</returns>
        private static Campaign CreateCampaign(AdWordsUser user, long budgetId, long merchantId)
        {
            using (CampaignService campaignService =
                       (CampaignService)user.GetService(AdWordsService.v201806.CampaignService))
            {
                // Create the campaign.
                Campaign campaign = new Campaign
                {
                    name = "Shopping campaign #" + ExampleUtilities.GetRandomString(),

                    // The advertisingChannelType is what makes this a Shopping campaign.
                    advertisingChannelType = AdvertisingChannelType.SHOPPING,

                    // 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 shared budget (required).
                    budget = new Budget
                    {
                        budgetId = budgetId
                    }
                };

                // Set bidding strategy (required).
                BiddingStrategyConfiguration biddingStrategyConfiguration =
                    new BiddingStrategyConfiguration
                {
                    // Note: Showcase ads require that the campaign has a ManualCpc
                    // BiddingStrategyConfiguration.
                    biddingStrategyType = BiddingStrategyType.MANUAL_CPC
                };

                campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

                // All Shopping campaigns need a ShoppingSetting.
                ShoppingSetting shoppingSetting = new ShoppingSetting
                {
                    salesCountry     = "US",
                    campaignPriority = 0,
                    merchantId       = merchantId,

                    // Set to "true" to enable Local Inventory Ads in your campaign.
                    enableLocal = true
                };
                campaign.settings = new Setting[]
                {
                    shoppingSetting
                };

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

                // Make the mutate request.
                CampaignReturnValue retval = campaignService.mutate(new CampaignOperation[]
                {
                    campaignOperation
                });
                return(retval.value[0]);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Get the UserListService.
            AdwordsUserListService userListService =
                (AdwordsUserListService)user.GetService(AdWordsService.v201607.AdwordsUserListService);

            // First rule item group - users who visited the checkout page and had
            // more than one item in their shopping cart.
            StringRuleItem checkoutStringRuleItem = new StringRuleItem();

            checkoutStringRuleItem.key      = new StringKey();
            checkoutStringRuleItem.key.name = "ecomm_pagetype";
            checkoutStringRuleItem.op       = StringRuleItemStringOperator.EQUALS;
            checkoutStringRuleItem.value    = "checkout";

            RuleItem checkoutRuleItem = new RuleItem();

            checkoutRuleItem.Item = checkoutStringRuleItem;

            NumberRuleItem cartSizeNumberRuleItem = new NumberRuleItem();

            cartSizeNumberRuleItem.key      = new NumberKey();
            cartSizeNumberRuleItem.key.name = "cartsize";
            cartSizeNumberRuleItem.op       = NumberRuleItemNumberOperator.GREATER_THAN;
            cartSizeNumberRuleItem.value    = 1;

            RuleItem cartSizeRuleItem = new RuleItem();

            cartSizeRuleItem.Item = cartSizeNumberRuleItem;

            // Combine the two rule items into a RuleItemGroup so AdWords will AND
            // their rules together.
            RuleItemGroup checkoutMultipleItemGroup = new RuleItemGroup();

            checkoutMultipleItemGroup.items = new RuleItem[] { checkoutRuleItem, cartSizeRuleItem };

            // Second rule item group - users who check out within the next 3 months.
            DateRuleItem startDateDateRuleItem = new DateRuleItem();

            startDateDateRuleItem.key      = new DateKey();
            startDateDateRuleItem.key.name = "checkoutdate";
            startDateDateRuleItem.op       = DateRuleItemDateOperator.AFTER;
            startDateDateRuleItem.value    = DateTime.Now.ToString(DATE_FORMAT_STRING);
            RuleItem startDateRuleItem = new RuleItem();

            startDateRuleItem.Item = startDateDateRuleItem;

            DateRuleItem endDateDateRuleItem = new DateRuleItem();

            endDateDateRuleItem.key      = new DateKey();
            endDateDateRuleItem.key.name = "checkoutdate";
            endDateDateRuleItem.op       = DateRuleItemDateOperator.BEFORE;
            endDateDateRuleItem.value    = DateTime.Now.AddMonths(3).ToString(DATE_FORMAT_STRING);
            RuleItem endDateRuleItem = new RuleItem();

            endDateRuleItem.Item = endDateDateRuleItem;

            // Combine the date rule items into a RuleItemGroup.
            RuleItemGroup checkedOutNextThreeMonthsItemGroup = new RuleItemGroup();

            checkedOutNextThreeMonthsItemGroup.items =
                new RuleItem[] { startDateRuleItem, endDateRuleItem };

            // Combine the rule item groups into a Rule so AdWords will OR the groups
            // together.
            Rule rule = new Rule();

            rule.groups = new RuleItemGroup[] { checkoutMultipleItemGroup,
                                                checkedOutNextThreeMonthsItemGroup };

            // Create the user list with no restrictions on site visit date.
            ExpressionRuleUserList expressionUserList = new ExpressionRuleUserList();

            expressionUserList.name = "Expression based user list created at " + DateTime.Now.ToString(
                "yyyyMMdd_HHmmss");
            expressionUserList.description = "Users who checked out in three month window OR visited " +
                                             "the checkout page with more than one item in their cart.";
            expressionUserList.rule = rule;

            // Create the user list restricted to users who visit your site within
            // the next six months.
            DateTime startDate = DateTime.Now;
            DateTime endDate   = startDate.AddMonths(6);

            DateSpecificRuleUserList dateUserList = new DateSpecificRuleUserList();

            dateUserList.name = "Date rule user list created at " +
                                DateTime.Now.ToString("yyyyMMdd_HHmmss");
            dateUserList.description = String.Format("Users who visited the site between {0} and " +
                                                     "{1} and checked out in three month window OR visited the checkout page " +
                                                     "with more than one item in their cart.", startDate.ToString(DATE_FORMAT_STRING),
                                                     endDate.ToString(DATE_FORMAT_STRING));
            dateUserList.rule = rule;

            // Set the start and end dates of the user list.
            dateUserList.startDate = startDate.ToString(DATE_FORMAT_STRING);
            dateUserList.endDate   = endDate.ToString(DATE_FORMAT_STRING);

            // Create operations to add the user lists.
            List <UserListOperation> operations = new List <UserListOperation>();

            foreach (UserList userList in new UserList[] { expressionUserList, dateUserList })
            {
                UserListOperation operation = new UserListOperation();
                operation.operand   = userList;
                operation.@operator = Operator.ADD;
                operations.Add(operation);
            }

            try {
                // Submit the operations.
                UserListReturnValue result = userListService.mutate(operations.ToArray());

                // Display the results.
                foreach (UserList userListResult in result.value)
                {
                    Console.WriteLine("User list added with ID {0}, name '{1}', status '{2}', " +
                                      "list type '{3}', accountUserListStatus '{4}', description '{5}'.",
                                      userListResult.id,
                                      userListResult.name,
                                      userListResult.status,
                                      userListResult.listType,
                                      userListResult.accountUserListStatus,
                                      userListResult.description);
                }
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to add rule based user lists.", e);
            }
        }
Example #5
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="campaignId">Id of the campaign to which sitelinks will
        /// be added.</param>
        public void Run(AdWordsUser user, long campaignId)
        {
            using (CampaignExtensionSettingService campaignExtensionSettingService =
                       (CampaignExtensionSettingService)user.GetService(
                           AdWordsService.v201710.CampaignExtensionSettingService)) {
                Customer customer = null;
                using (CustomerService customerService = (CustomerService)user.GetService(
                           AdWordsService.v201710.CustomerService)) {
                    // Find the matching customer and its time zone. The getCustomers method
                    // will return a single Customer object corresponding to the session's
                    // clientCustomerId.
                    customer = customerService.getCustomers()[0];
                    Console.WriteLine("Found customer ID {0:###-###-####} with time zone '{1}'.",
                                      customer.customerId, customer.dateTimeZone);
                }
                List <ExtensionFeedItem> extensions = new List <ExtensionFeedItem>();

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

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

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

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

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

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

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

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

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

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

                    // Display the results.
                    if (retVal.value != null && retVal.value.Length > 0)
                    {
                        CampaignExtensionSetting newExtensionSetting = retVal.value[0];
                        Console.WriteLine("Extension setting with type = {0} was added to campaign ID {1}.",
                                          newExtensionSetting.extensionType, newExtensionSetting.campaignId);
                    }
                    else
                    {
                        Console.WriteLine("No extension settings were created.");
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to create extension settings.", e);
                }
            }
        }
        /// <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)
        {
            // Get the CampaignService.
            CampaignService campaignService = (CampaignService)user.GetService(
                AdWordsService.v201705.CampaignService);

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

            CampaignPage page = campaignService.get(selector);

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

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

            DynamicSearchAdsSetting dsaSetting = null;

            Setting[] campaignSettings = campaign.settings;

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

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

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

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

            Campaign campaignToUpdate = new Campaign();

            campaignToUpdate.id       = campaignId;
            campaignToUpdate.settings = campaignSettings;

            CampaignOperation operation = new CampaignOperation();

            operation.operand   = campaignToUpdate;
            operation.@operator = Operator.SET;

            try {
                CampaignReturnValue retval          = campaignService.mutate(new CampaignOperation[] { operation });
                Campaign            updatedCampaign = retval.value[0];
                Console.WriteLine("DSA page feed for campaign ID '{0}' was updated with feed ID '{1}'.",
                                  updatedCampaign.id, feedId);
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to set page feed for campaign.", e);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Get the TrafficEstimatorService.
            TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService)user.GetService(
                AdWordsService.v201603.TrafficEstimatorService);

            // Create keywords. Up to 2000 keywords can be passed in a single request.
            Keyword keyword1 = new Keyword();

            keyword1.text      = "mars cruise";
            keyword1.matchType = KeywordMatchType.BROAD;

            Keyword keyword2 = new Keyword();

            keyword2.text      = "cheap cruise";
            keyword2.matchType = KeywordMatchType.PHRASE;

            Keyword keyword3 = new Keyword();

            keyword3.text      = "cruise";
            keyword3.matchType = KeywordMatchType.EXACT;

            Keyword[] keywords = new Keyword[] { keyword1, keyword2, keyword3 };

            // Create a keyword estimate request for each keyword.
            List <KeywordEstimateRequest> keywordEstimateRequests = new List <KeywordEstimateRequest>();

            foreach (Keyword keyword in keywords)
            {
                KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest();
                keywordEstimateRequest.keyword = keyword;
                keywordEstimateRequests.Add(keywordEstimateRequest);
            }

            // Create negative keywords.
            Keyword negativeKeyword1 = new Keyword();

            negativeKeyword1.text      = "moon walk";
            negativeKeyword1.matchType = KeywordMatchType.BROAD;

            KeywordEstimateRequest negativeKeywordEstimateRequest = new KeywordEstimateRequest();

            negativeKeywordEstimateRequest.keyword    = negativeKeyword1;
            negativeKeywordEstimateRequest.isNegative = true;
            keywordEstimateRequests.Add(negativeKeywordEstimateRequest);

            // Create ad group estimate requests.
            AdGroupEstimateRequest adGroupEstimateRequest = new AdGroupEstimateRequest();

            adGroupEstimateRequest.keywordEstimateRequests = keywordEstimateRequests.ToArray();
            adGroupEstimateRequest.maxCpc             = new Money();
            adGroupEstimateRequest.maxCpc.microAmount = 1000000;

            // Create campaign estimate requests.
            CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest();

            campaignEstimateRequest.adGroupEstimateRequests = new AdGroupEstimateRequest[] {
                adGroupEstimateRequest
            };

            // See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
            // for a detailed list of country codes.
            Location countryCriterion = new Location();

            countryCriterion.id = 2840; //US

            // See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
            // for a detailed list of language codes.
            Language languageCriterion = new Language();

            languageCriterion.id = 1000; //en

            campaignEstimateRequest.criteria = new Criterion[] { countryCriterion, languageCriterion };

            // Create the selector.
            TrafficEstimatorSelector selector = new TrafficEstimatorSelector();

            selector.campaignEstimateRequests = new CampaignEstimateRequest[] { campaignEstimateRequest };

            try {
                // Get traffic estimates.
                TrafficEstimatorResult result = trafficEstimatorService.get(selector);

                // Display traffic estimates.
                if (result != null && result.campaignEstimates != null &&
                    result.campaignEstimates.Length > 0)
                {
                    CampaignEstimate campaignEstimate = result.campaignEstimates[0];
                    if (campaignEstimate.adGroupEstimates != null &&
                        campaignEstimate.adGroupEstimates.Length > 0)
                    {
                        AdGroupEstimate adGroupEstimate = campaignEstimate.adGroupEstimates[0];

                        if (adGroupEstimate.keywordEstimates != null)
                        {
                            for (int i = 0; i < adGroupEstimate.keywordEstimates.Length; i++)
                            {
                                Keyword         keyword         = keywordEstimateRequests[i].keyword;
                                KeywordEstimate keywordEstimate = adGroupEstimate.keywordEstimates[i];

                                if (keywordEstimateRequests[i].isNegative)
                                {
                                    continue;
                                }

                                // Find the mean of the min and max values.
                                long   meanAverageCpc      = 0;
                                double meanAveragePosition = 0;
                                float  meanClicks          = 0;
                                long   meanTotalCost       = 0;

                                if (keywordEstimate.min != null && keywordEstimate.max != null)
                                {
                                    if (keywordEstimate.min.averageCpc != null &&
                                        keywordEstimate.max.averageCpc != null)
                                    {
                                        meanAverageCpc = (keywordEstimate.min.averageCpc.microAmount +
                                                          keywordEstimate.max.averageCpc.microAmount) / 2;
                                    }

                                    meanAveragePosition = (keywordEstimate.min.averagePosition +
                                                           keywordEstimate.max.averagePosition) / 2;
                                    meanClicks = (keywordEstimate.min.clicksPerDay +
                                                  keywordEstimate.max.clicksPerDay) / 2;
                                    if (keywordEstimate.min.totalCost != null &&
                                        keywordEstimate.max.totalCost != null)
                                    {
                                        meanTotalCost = (keywordEstimate.min.totalCost.microAmount +
                                                         keywordEstimate.max.totalCost.microAmount) / 2;
                                    }
                                }

                                Console.WriteLine("Results for the keyword with text = '{0}' and match type = " +
                                                  "'{1}':", keyword.text, keyword.matchType);
                                Console.WriteLine("  Estimated average CPC: {0}", meanAverageCpc);
                                Console.WriteLine("  Estimated ad position: {0:0.00}", meanAveragePosition);
                                Console.WriteLine("  Estimated daily clicks: {0}", meanClicks);
                                Console.WriteLine("  Estimated daily cost: {0}", meanTotalCost);
                            }
                        }
                    }
                }
                else
                {
                    Console.WriteLine("No traffic estimates were returned.\n");
                }
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to retrieve traffic estimates.", e);
            }
        }
Example #8
0
        /// <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.v201710.AdGroupAdService)) {
                // Create the template ad.
                TemplateAd clickToDownloadAppAd = new TemplateAd();

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

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

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

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

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

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

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

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

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

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

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

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

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

                    // Display the results.
                    if (retval != null && retval.value != null)
                    {
                        foreach (AdGroupAd adGroupAd in retval.value)
                        {
                            Console.WriteLine("New click-to-download ad with id = \"{0}\" and url = \"{1}\" " +
                                              "was created.", adGroupAd.ad.id, adGroupAd.ad.finalUrls[0]);
                        }
                    }
                    else
                    {
                        Console.WriteLine("No click-to-download ads were created.");
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to create click-to-download ad.", e);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad groups to which keywords are
        /// added.</param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            using (BatchJobService batchJobService = (BatchJobService)user.GetService(
                       AdWordsService.v201802.BatchJobService)) {
                BatchJobOperation addOp = new BatchJobOperation()
                {
                    @operator = Operator.ADD,
                    operand   = new BatchJob()
                };

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

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

                    List <AdGroupCriterionOperation> operations = CreateOperations(adGroupId);

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

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

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

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

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

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

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

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

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

                    if (batchJob.downloadUrl != null && batchJob.downloadUrl.url != null)
                    {
                        BatchJobMutateResponse mutateResponse = batchJobUploadHelper.Download(
                            batchJob.downloadUrl.url);
                        Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url);
                        foreach (MutateResult mutateResult in mutateResponse.rval)
                        {
                            String outcome = mutateResult.errorList == null ? "SUCCESS" : "FAILURE";
                            Console.WriteLine("  Operation [{0}] - {1}", mutateResult.index, outcome);
                        }
                    }
                    else
                    {
                        Console.WriteLine("No results available for download.");
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to create keywords using batch job.", e);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ReportUtilities"/> class.
 /// </summary>
 /// <param name="user">AdWords user to be used along with this
 /// utilities object.</param>
 /// <param name="reportDefinition">The report definition.</param>
 public ReportUtilities(AdWordsUser user, IReportDefinition reportDefinition)
     : this(user, DEFAULT_REPORT_VERSION, reportDefinition)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ReportUtilities" /> class.
 /// </summary>
 /// <param name="user">AdWords user to be used along with this
 /// utilities object.</param>
 /// <param name="query">The AWQL for downloading reports.</param>
 /// <param name="format">The report download format.</param>
 public ReportUtilities(AdWordsUser user, string query, string format)
     : this(user, DEFAULT_REPORT_VERSION, query, format)
 {
 }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group to which criteria are
        /// added.</param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionService adGroupCriterionService =
                (AdGroupCriterionService)user.GetService(AdWordsService.v201603.AdGroupCriterionService);

            // Create biddable ad group criterion for gender
            Gender genderTarget = new Gender();

            // Criterion Id for male. The IDs can be found here
            // https://developers.google.com/adwords/api/docs/appendix/genders
            genderTarget.id = 10;

            BiddableAdGroupCriterion genderBiddableAdGroupCriterion = new BiddableAdGroupCriterion();

            genderBiddableAdGroupCriterion.adGroupId = adGroupId;
            genderBiddableAdGroupCriterion.criterion = genderTarget;

            // Create negative ad group criterion for age range
            AgeRange ageRangeNegative = new AgeRange();

            // Criterion Id for age 18 to 24. The IDs can be found here
            // https://developers.google.com/adwords/api/docs/appendix/ages

            ageRangeNegative.id = 503001;
            NegativeAdGroupCriterion ageRangeNegativeAdGroupCriterion = new NegativeAdGroupCriterion();

            ageRangeNegativeAdGroupCriterion.adGroupId = adGroupId;
            ageRangeNegativeAdGroupCriterion.criterion = ageRangeNegative;

            // Create operations.
            AdGroupCriterionOperation genderBiddableAdGroupCriterionOperation =
                new AdGroupCriterionOperation();

            genderBiddableAdGroupCriterionOperation.operand   = genderBiddableAdGroupCriterion;
            genderBiddableAdGroupCriterionOperation.@operator = Operator.ADD;

            AdGroupCriterionOperation ageRangeNegativeAdGroupCriterionOperation =
                new AdGroupCriterionOperation();

            ageRangeNegativeAdGroupCriterionOperation.operand   = ageRangeNegativeAdGroupCriterion;
            ageRangeNegativeAdGroupCriterionOperation.@operator = Operator.ADD;

            AdGroupCriterionOperation[] operations = new AdGroupCriterionOperation[] {
                genderBiddableAdGroupCriterionOperation, ageRangeNegativeAdGroupCriterionOperation
            };

            try {
                // Add ad group criteria.
                AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations);

                // Display ad group criteria.
                if (result != null && result.value != null)
                {
                    foreach (AdGroupCriterion adGroupCriterionResult in result.value)
                    {
                        Console.WriteLine("Ad group criterion with ad group id \"{0}\", criterion id " +
                                          "\"{1}\", and type \"{2}\" was added.", adGroupCriterionResult.adGroupId,
                                          adGroupCriterionResult.criterion.id,
                                          adGroupCriterionResult.criterion.CriterionType);
                    }
                }
                else
                {
                    Console.WriteLine("No ad group criteria were added.");
                }
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to create ad group criteria.", e);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="downloadFolder">The file to which the report is downloaded.
        /// </param>
        public void Run(AdWordsUser user, string downloadFolder)
        {
            // Increase the number of HTTP connections we can do in parallel.
            System.Net.ServicePointManager.DefaultConnectionLimit = 100;

            try {
                // Start the rate limiter with an initial value of zero, so that all
                // threads block immediately.
                Semaphore rateLimiter = new Semaphore(0, MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Get all the advertiser accounts under this manager account.
                List <long> allCustomerIds = GetDescendantAdvertiserAccounts(user);

                // Create a concurrent queue of customers so that all threads can work
                // on the collection in parallel.
                ConcurrentQueue <long> customerQueue = new ConcurrentQueue <long>(allCustomerIds);

                // Create queues to keep track of successful and failed report downloads.
                ConcurrentQueue <SuccessfulReportDownload> reportsSucceeeded =
                    new ConcurrentQueue <SuccessfulReportDownload>();
                ConcurrentQueue <FailedReportDownload> reportsFailed =
                    new ConcurrentQueue <FailedReportDownload>();

                // Keep an array of events. This is used by the main thread to wait for
                // all worker threads to join.
                ManualResetEvent[] doneEvents = new ManualResetEvent[MAX_NUMBER_OF_THREADS];

                // The list of threads to download reports.
                Thread[] threads = new Thread[MAX_NUMBER_OF_THREADS];

                // The data for each thread.
                ReportDownloadData[] threadData = new ReportDownloadData[MAX_NUMBER_OF_THREADS];

                // The query to be run on each account.
                string query = "SELECT CampaignId, AdGroupId, Impressions, Clicks, Cost from " +
                               "ADGROUP_PERFORMANCE_REPORT where AdGroupStatus IN [ENABLED, PAUSED] " +
                               "DURING LAST_7_DAYS";

                // Initialize the threads and their data.
                for (int i = 0; i < MAX_NUMBER_OF_THREADS; i++)
                {
                    doneEvents[i] = new ManualResetEvent(false);
                    threadData[i] = new ReportDownloadData()
                    {
                        Config            = (AdWordsAppConfig)(user.Config.Clone()),
                        DownloadFolder    = downloadFolder,
                        SignalEvent       = doneEvents[i],
                        ThreadIndex       = i,
                        QuotaLock         = rateLimiter,
                        CustomerIdQueue   = customerQueue,
                        SuccessfulReports = reportsSucceeeded,
                        FailedReports     = reportsFailed
                    };

                    threads[i] = new Thread(threadData[i].ThreadCallback);
                }

                // Start the threads. Since the initial value of rate limiter is zero,
                // all threads will block immediately.
                for (int i = 0; i < threads.Length; i++)
                {
                    threads[i].Start(query);
                }

                // Now reset the rate limiter so all threads can start downloading reports.
                rateLimiter.Release(MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Wait for all threads in pool to complete.
                WaitHandle.WaitAll(doneEvents);
                Console.WriteLine("Download completed, results:");

                Console.WriteLine("Successful reports:");
                while (!reportsSucceeeded.IsEmpty)
                {
                    SuccessfulReportDownload success = null;
                    if (reportsSucceeeded.TryDequeue(out success))
                    {
                        Console.WriteLine("Client ID: {0}, Path: {1}", success.CustomerId, success.Path);
                    }
                }

                Console.WriteLine("Failed reports:");
                while (!reportsFailed.IsEmpty)
                {
                    FailedReportDownload failure = null;
                    if (reportsFailed.TryDequeue(out failure))
                    {
                        Console.WriteLine("Client ID: {0}, Cause: {1}", failure.CustomerId,
                                          failure.Exception.Message);
                    }
                }

                Console.WriteLine("All reports are downloaded.");
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to download reports.", e);
            }
        }
        // [END addCampaignsToGroup] MOE:strip_line

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

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

            campaignGroupPerformanceTarget.campaignGroupId = campaignGroupId;

            PerformanceTarget performanceTarget = new PerformanceTarget();

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

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

            maxSpend.microAmount          = 500000000;
            performanceTarget.spendTarget = maxSpend;

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

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

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

            campaignGroupPerformanceTarget.performanceTarget = performanceTarget;

            // Create the operation.
            CampaignGroupPerformanceTargetOperation operation =
                new CampaignGroupPerformanceTargetOperation();

            operation.operand   = campaignGroupPerformanceTarget;
            operation.@operator = Operator.ADD;

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

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

                Console.WriteLine("Campaign performance target with id = '{0}' was added for " +
                                  "campaign group ID '{1}'.", newCampaignPerfTarget.id,
                                  newCampaignPerfTarget.campaignGroupId);
                return(newCampaignPerfTarget);
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to create campaign performance target.", e);
            }
        }
        /// <summary>
        /// Creates an AdWords Campaign grouped by category
        /// </summary>
        /// <param name="UseSandbox">Call the webservices in the test env</param>
        /// <param name="AffiliateSiteRefId"></param>
        /// <param name="Name">Campaign Name</param>
        /// <param name="Countries">Targeted countires</param>
        /// <param name="Languages">Targeted Languages</param>
        /// <param name="BudgetPeriod">The duration over which to spend the budgetAmount. For most developers, Daily is the only allowable option.</param>
        /// <param name="BudgetAmount">The amount of the budget in micros. Use budgetPeriod to set the duration over which to spend this amount.</param>
        /// <param name="KeywordMaxCpc">The default maximum cost-per-click bid for Keyword criteria in this ad group. See the note on bid amounts for more information on using this field.</param>
        /// <param name="MaxAdsPerGroup">Max Ads to create for each AdGroup</param>
        /// <param name="MaxAdvertiserCompetitionScale">The Max level of competition allowed from advertisers for keyword variations, on a scale from 0 to 5. Set to -1 if data is not available</param>
        /// <param name="MinSearchVolumeScale">The Min amount of searches to allowed related to keyword variations, on a scale from 0 to 5. Set to -1 if data is not available</param>
        /// <param name="DisplayUrl">Display Url to use for each Ad</param>
        /// <param name="destinationUrlPrefix">Destination Url Prefix for the destination Url of the Ads created.</param>
        /// <param name="UseKeywordVariations">Check for Keyword variations</param>
        /// <param name="MaxVariations">Max number of Keyword variations to use.</param>
        /// <param name="AdKeywordType">The type of keyword, indicating how it is targeted. This is not mutable after being set the first time. Values are: Broad=0,Phrase=1,Exact=2</param>
        //public void CreateCampaignGroupByProduct(bool UseSandbox, Guid AffiliateSiteRefId, string Name, String[] Countries, String[] Languages, int BudgetPeriod,
        //                                        Moneyv200906 BudgetAmount, long KeywordMaxCpc, int MaxAdGroups, int MaxAdvertiserCompetitionScale, int MinSearchVolumeScale,
        //                                        string DisplayUrl, string destinationUrlPrefix, bool GetKeywordsFromLandingPage, int MaxVariations, int AdKeywordType)
        //{
        //    // Create a user (reads headers from App.config file).
        //    AdWordsUser user = new AdWordsUser();
        //    if (UseSandbox)
        //        user.UseSandbox();	// use sandbox
        //    AccountService accountService = (AccountService)user.GetService(ApiServices.v13.AccountService);
        //    string[] accounts = accountService.getClientAccounts();
        //    try
        //    {
        //        #region Create Campaign
        //        // Create a new campaign with an ad group.  First create a
        //        // campaign, so we can get its id.
        //        Campaignv200906 newCampaign = new Campaignv200906();
        //        newCampaign.budget.amount = BudgetAmount;
        //        //newCampaign.budget.amountSpecified = true;
        //        newCampaign.budget.period = (BudgetPeriodv200906)Enum.ToObject(typeof(BudgetPeriodv200906), BudgetPeriod);
        //        newCampaign.budget.periodSpecified = true;
        //        // The campaign name is optional.  An error results if a campaign
        //        // of the same name already exists.
        //        newCampaign.name = Name;
        //        //TODO:newCampaign.networkTargeting = new NetworkType[] { NetworkType.SearchNetwork };
        //        // Target the campaign at
        //        CampaignServicev200906 campaignService = (CampaignServicev200906)user.GetService(ApiServices.v200906.CampaignService);
        //        // Set the campaign status to paused, we don't want to start
        //        // paying for this test.
        //        newCampaign.status = CampaignStatusv200906.PAUSED;
        //        // Add this campaign.  The campaign object is returned with ids
        //        // filled in.
        //        // Define an Add operation to add the campaign.
        //        CampaignOperation campaignOperation = new CampaignOperation();
        //        campaignOperation.operatorSpecified = true;
        //        campaignOperation.@operator = CampaignOperatorv200906.ADD;
        //        campaignOperation.operand = newCampaign;
        //        try
        //        {
        //            CampaignReturnValue results =
        //              campaignService.mutate(new CampaignOperation[] { campaignOperation });
        //            if (results != null && results.value != null && results.value.Length > 0)
        //            {
        //                Trace.TraceInformation("New campaign with name = \"{0}\" and id = " + "\"{1}\" was created.", results.value[0].name, results.value[0].id);
        //            }
        //        }
        //        catch (Exception ex)
        //        {
        //            throw new Exception("Failed to create campaign. " + ex.Message);
        //        }
        //        long campaignId = newCampaign.id;
        //        #endregion
        //        #region Targeting
        //        CampaignTargetServicev200906 service = (CampaignTargetServicev200906)user.GetService(ApiServices.v200906.CampaignTargetService);
        //        // Create a language target - for English language.
        //        LanguageTargetv200906 languageTarget = new LanguageTargetv200906();
        //        languageTarget.languageCode = "en";
        //        LanguageTargetList languageTargetList = new LanguageTargetList();
        //        languageTargetList.targets = new LanguageTargetv200906[] { languageTarget };
        //        languageTargetList.campaignId = campaignId;
        //        languageTargetList.campaignIdSpecified = true;
        //        // Create a country target - include US, exclude metrocode 743.
        //        CountryTargetv200906 countryTarget = new CountryTargetv200906();
        //        countryTarget.countryCode = "US";
        //        countryTarget.excludedSpecified = true;
        //        countryTarget.excluded = false;
        //        MetroTargetv200906 metroTarget = new MetroTargetv200906();
        //        metroTarget.excludedSpecified = true;
        //        metroTarget.excluded = true;
        //        metroTarget.metroCode = "743";
        //        GeoTargetList geoTargetList = new GeoTargetList();
        //        geoTargetList.targets = new GeoTargetv200906[] { countryTarget, metroTarget };
        //        geoTargetList.campaignId = campaignId;
        //        geoTargetList.campaignIdSpecified = true;
        //        // Create a network target - Google Search.
        //        NetworkTargetv200906 networkTarget1 = new NetworkTargetv200906();
        //        networkTarget1.networkCoverageTypeSpecified = true;
        //        networkTarget1.networkCoverageType = NetworkCoverageTypev200906.GOOGLE_SEARCH;
        //        NetworkTargetv200906 networkTarget2 = new NetworkTargetv200906();
        //        networkTarget2.networkCoverageTypeSpecified = true;
        //        networkTarget2.networkCoverageType = NetworkCoverageTypev200906.SEARCH_NETWORK;
        //        NetworkTargetList networkTargetList = new NetworkTargetList();
        //        networkTargetList.targets = new NetworkTargetv200906[] { networkTarget1, networkTarget2 };
        //        networkTargetList.campaignId = campaignId;
        //        networkTargetList.campaignIdSpecified = true;
        //        TargetList[] targets =
        //            new TargetList[] { languageTargetList, geoTargetList, networkTargetList };
        //        ArrayList campaignTargetOperations = new ArrayList();
        //        foreach (TargetList target in targets)
        //        {
        //            CampaignTargetOperation ops = new CampaignTargetOperation();
        //            ops.operatorSpecified = true;
        //            ops.@operator = CampaignTargetOperatorv200906.SET;
        //            ops.operand = target;
        //            campaignTargetOperations.Add(ops);
        //        }
        //        try
        //        {
        //            service.mutate((CampaignTargetOperation[])
        //              campaignTargetOperations.ToArray(typeof(CampaignTargetOperation)));
        //            Console.WriteLine("Geo, language, and network targeting were " +
        //                "successfully added to campaign id = \"{0}\".", campaignId);
        //        }
        //        catch (Exception ex)
        //        {
        //            Console.WriteLine("Failed to create campaign targeting. " +
        //                "Exception says \"{0}\"", ex.Message);
        //        }
        //        #endregion
        //        #region Create your Services
        //        //create your services
        //        List<SeedKeyword> keywords = new List<SeedKeyword>();
        //        AdService adService = (AdService)user.GetService(ApiServices.v200906.AdGroupAdService);
        //        KeywordToolService keywordToolService = (KeywordToolService)user.GetService(ApiServices.v13.KeywordToolService);
        //        AdGroupService adgroupService = (AdGroupService)user.GetService(ApiServices.v200906.AdGroupService);
        //        TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService)user.GetService(ApiServices.v13.TrafficEstimatorService);
        //        #endregion
        //        #region Enumerate thru all the categories
        //        //enumerate thru all the categories
        //        foreach (SiteCategory siteCategory in DataRepository.SiteCategoryProvider.GetByAffiliateSiteRefId(AffiliateSiteRefId))
        //        {
        //            int GroupAdCount = 0;
        //            DataRepository.SiteCategoryProvider.DeepLoad(siteCategory, true, DeepLoadType.IncludeChildren, typeof(TList<SiteCategoryCategoryMapping>));
        //            //////Create an ad group by site category
        //            ////AdGroup newAdGroup = new AdGroup();
        //            ////newAdGroup.name = siteCategory.SiteCategory;
        //            ////newAdGroup.keywordMaxCpc = KeywordMaxCpc;
        //            ////newAdGroup.keywordMaxCpcSpecified = true;
        //            ////// Associate this ad group with the newly created campaign.  Send
        //            ////// the request to add the new ad group.
        //            ////AdGroup myAdGroup = adgroupService.addAdGroup(campaignId, newAdGroup);
        //            ////long adGroupId = myAdGroup.id;
        //            #region Enumerate thru the category mappings to get the merchants
        //            //enumerate thru the categoru mappings to get the merchants
        //            foreach (SiteCategoryCategoryMapping catMap in siteCategory.SiteCategoryCategoryMappingCollection)
        //            {
        //                if (GroupAdCount >= MaxAdGroups)
        //                    break;
        //                DataRepository.SiteCategoryCategoryMappingProvider.DeepLoad(catMap, true, DeepLoadType.IncludeChildren, typeof(Category));
        //                DataRepository.CategoryProvider.DeepLoad(catMap.CategoryRefIdSource, true, DeepLoadType.IncludeChildren, typeof(TList<Merchant>));
        //                catMap.CategoryRefIdSource.MerchantCollection.Shuffle();
        //                foreach (Merchant merch in catMap.CategoryRefIdSource.MerchantCollection)
        //                {
        //                    if (GroupAdCount >= MaxAdGroups)
        //                        break;
        //                    DataRepository.MerchantProvider.DeepLoad(merch, true, DeepLoadType.IncludeChildren, typeof(TList<Product>));
        //                    //shuffle the products
        //                    merch.ProductCollection.Shuffle();
        //                    // enumerate thru all the merchant's products
        //                    foreach (Product prod in merch.ProductCollection)
        //                    {
        //                        //Create an ad group by site category
        //                        AdGroup newAdGroup = new AdGroup();
        //                        newAdGroup.name = siteCategory.Name + "-" + prod.Name;
        //                        newAdGroup.keywordMaxCpc = KeywordMaxCpc;
        //                        newAdGroup.keywordMaxCpcSpecified = true;
        //                        Trace.TraceInformation(prod.Name);
        //                        string cleanProdName = StringUtils.ScrubProdName(StringUtils.RemoveDuplicateWords(prod.Name));
        //                        string urlProdName = StringUtils.ScrubProdNameUrl(cleanProdName) + ".aspx";
        //                        int c = 0;
        //                        keywords.Clear();
        //                        string[] rawKeywords = new string[] { "" };
        //                        //check to see if the product record has keywords
        //                        //if (prod.Keywords != null)
        //                        //    rawKeywords = prod.Keywords.Split(',');
        //                        //if (rawKeywords.Length < 2)
        //                        rawKeywords = cleanProdName.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        //                        foreach (string str in rawKeywords)
        //                        {
        //                            int tryInt = 0; //not empty, not a number, and not lower case
        //                            if (str.Trim() != "" && !int.TryParse(str.Trim(), out tryInt)) //&& !isLowerCase(str.Trim().Substring(0, 1).ToCharArray()[0])
        //                            {
        //                                SeedKeyword sw = new SeedKeyword();
        //                                sw.text = StringUtils.ScrubKeywords(str);
        //                                if (sw.text.Trim() != "")
        //                                {
        //                                    sw.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                    sw.negative = false;
        //                                    keywords.Add(sw);
        //                                    c++;
        //                                    if (c == 10) //TODO: fix this to get all words
        //                                        break;
        //                                }
        //                            }
        //                        }
        //                        //Create an add for each product
        //                        //
        //                        // IMPORTANT: create an ad before adding keywords!  Else the
        //                        // minCpc will have a higher value.
        //                        TextAd newTextAd = new TextAd();
        //                        newTextAd.headline = prod.Name;
        //                        while (newTextAd.headline.Length > 25)
        //                        {
        //                            newTextAd.headline = newTextAd.headline.Substring(0, newTextAd.headline.LastIndexOf(" ")).Substring(0, newTextAd.headline.Substring(0, newTextAd.headline.LastIndexOf(" ")).LastIndexOf(" "));
        //                        }
        //                        if (prod.Description.Length > 35)
        //                        {
        //                            string[] words = prod.Description.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        //                            //descriptions are limited to 35 chars
        //                            foreach (string wrd in words)
        //                            {
        //                                string word = StringUtils.ScrubKeywords(wrd);
        //                                if (word.Trim() != "")
        //                                {
        //                                    if (newTextAd.description1 == null || (newTextAd.description1.Length + word.Length) < 35)
        //                                        newTextAd.description1 += word + " ";
        //                                    else if (newTextAd.description2 == null || (newTextAd.description2.Length + word.Length) < 35)
        //                                    {
        //                                        newTextAd.description1 = newTextAd.description1.PadRight(35);
        //                                        newTextAd.description2 += word + " ";
        //                                    }
        //                                    else
        //                                    {
        //                                        newTextAd.description2 = newTextAd.description2.PadRight(35);
        //                                        break;
        //                                    }
        //                                }
        //                            }
        //                            if (newTextAd.description2 == null || (newTextAd.description2.Length + string.Format("{0:c}", prod.Price).Length) < 35)
        //                                newTextAd.description2 += string.Format("{0:c}", prod.Price);
        //                        }
        //                        else
        //                        {
        //                            newTextAd.description1 = prod.Description;
        //                            newTextAd.description2 = string.Format("{0:c}", prod.Price);
        //                        }
        //                        newTextAd.displayUrl = DisplayUrl;
        //                        newTextAd.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                        //newTextAd.adGroupId = adGroupId;
        //                        //don't add it yet, there is a check below to see if it meets criteria
        //                        SeedKeyword[] keywordsArray = new SeedKeyword[] { new SeedKeyword() };
        //                        keywordsArray = keywords.ToArray();
        //                        //add variations if requested
        //                        if (GetKeywordsFromLandingPage)
        //                        {
        //                            SiteKeywordGroups siteKeywordGroups = keywordToolService.getKeywordsFromSite(newTextAd.destinationUrl, false, Languages, Countries);
        //                            int maxVariations = 0;
        //                            bool AdAdded = false;
        //                            // Associate this ad group with the newly created campaign.  Send
        //                            // the request to add the new ad group.
        //                            AdGroup myAdGroup; //= adgroupService.addAdGroup(campaignId, newAdGroup);
        //                            long adGroupId = 0; //= myAdGroup.id;
        //                            if (siteKeywordGroups.keywords != null)
        //                            {
        //                                foreach (SiteKeyword sitekeyword in siteKeywordGroups.keywords)
        //                                {
        //                                    //Trace.TraceInformation("Checking Site Keyword " + maxVariations + ":" + sitekeyword.text);
        //                                    // check for low compitition and high search volumes
        //                                    if (sitekeyword.advertiserCompetitionScale <= MaxAdvertiserCompetitionScale && sitekeyword.lastMonthSearchVolume >= MinSearchVolumeScale)
        //                                    {
        //                                        // Add keywords to the newly created ad group.
        //                                        //add keywords and url to dbs
        //                                        AffiliTrac.Entities.Keywords kws = new AffiliTrac.Entities.Keywords();
        //                                        kws.KeywordRefId = Guid.NewGuid();
        //                                        kws.Keywords = sitekeyword.text;
        //                                        kws.Url = newTextAd.destinationUrl;
        //                                        kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                        DataRepository.KeywordsProvider.Insert(kws);
        //                                        CriterionService criterionService = (CriterionService)user.GetService(ApiServices.v200906.CampaignCriterionService);
        //                                        // check for low compitition and high search volumes
        //                                        #region Create Ad & Keywords from the Product Name
        //                                        if (!AdAdded)
        //                                        {
        //                                            // Associate this ad group with the newly created campaign.  Send
        //                                            // the request to add the new ad group.
        //                                            myAdGroup = adgroupService.addAdGroup(campaignId, newAdGroup);
        //                                            adGroupId = myAdGroup.id;
        //                                            newTextAd.adGroupId = adGroupId;
        //                                            // create the new add
        //                                            try
        //                                            {
        //                                                //we found a keyword that meets criteria so ad the new Ad.
        //                                                Ad[] myAds = adService.addAds(new Ad[] { newTextAd });
        //                                                GroupAdCount++;
        //                                                Trace.TraceInformation("Text ad" + GroupAdCount + ": " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                                //Trace.TraceInformation("Text ad: " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                                AdAdded = true;
        //                                            }
        //                                            catch
        //                                            {
        //                                                //do nothing
        //                                                Trace.TraceError("***Text ad Failed:" + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                            }
        //                                            //Add the Product name as a whole phrase
        //                                            try
        //                                            {
        //                                                //add keywords and url to dbs
        //                                                kws = new AffiliTrac.Entities.Keywords();
        //                                                kws.KeywordRefId = Guid.NewGuid();
        //                                                kws.Keywords = cleanProdName;
        //                                                kws.Url = newTextAd.destinationUrl;
        //                                                kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                                DataRepository.KeywordsProvider.Insert(kws);
        //                                                Keyword newKeyword = new Keyword();
        //                                                newKeyword.adGroupId = adGroupId;
        //                                                newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                                newKeyword.text = cleanProdName;
        //                                                //TODO: Use the Traffic Estimator to determine the
        //                                                // the maxCpc to use
        //                                                newKeyword.maxCpc = KeywordMaxCpc;
        //                                                newKeyword.maxCpcSpecified = true;
        //                                                newKeyword.criterionType = CriterionType.Keyword;
        //                                                newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                                Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                                newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                                criterionService.addCriteria(newCriteria);
        //                                            }
        //                                            catch
        //                                            {
        //                                                //do nothing
        //                                                Trace.TraceError("***Add Criteria Failed: Keyword" + cleanProdName);
        //                                            }
        //                                            //Add the individual product name keywords
        //                                            foreach (SeedKeyword sk in keywordsArray)
        //                                            {
        //                                                try
        //                                                {
        //                                                    //add keywords and url to dbs
        //                                                    kws = new AffiliTrac.Entities.Keywords();
        //                                                    kws.KeywordRefId = Guid.NewGuid();
        //                                                    kws.Keywords = sk.text;
        //                                                    kws.Url = newTextAd.destinationUrl;
        //                                                    kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                                    DataRepository.KeywordsProvider.Insert(kws);
        //                                                    // Add keywords to the newly created ad group.
        //                                                    Keyword newKeyword = new Keyword();
        //                                                    newKeyword.adGroupId = adGroupId;
        //                                                    newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                                    newKeyword.text = sk.text;
        //                                                    //TODO: Use the Traffic Estimator to determine the
        //                                                    // the maxCpc to use
        //                                                    newKeyword.maxCpc = KeywordMaxCpc;
        //                                                    newKeyword.maxCpcSpecified = true;
        //                                                    newKeyword.criterionType = CriterionType.Keyword;
        //                                                    newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                                    Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                                    newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                                    criterionService.addCriteria(newCriteria);
        //                                                }
        //                                                catch
        //                                                {
        //                                                    //do nothing
        //                                                    Trace.TraceError("***Add Criteria Failed: Keyword" + sk.text);
        //                                                }
        //                                            }
        //                                        }
        //                                        #endregion
        //                                        #region Create keywords from the keyword suggestion gotten from the landing page
        //                                        try
        //                                        {
        //                                            Keyword newKeyword = new Keyword();
        //                                            newKeyword = new Keyword();
        //                                            newKeyword.adGroupId = adGroupId;
        //                                            newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                            newKeyword.text = sitekeyword.text;
        //                                            //TODO: Use the Traffic Estimator to determine the
        //                                            // the maxCpc to use
        //                                            newKeyword.maxCpc = KeywordMaxCpc;
        //                                            newKeyword.maxCpcSpecified = true;
        //                                            newKeyword.criterionType = CriterionType.Keyword;
        //                                            newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                            Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                            newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                            criterionService.addCriteria(newCriteria);
        //                                        }
        //                                        catch
        //                                        {
        //                                            //do nothing
        //                                            Trace.TraceError("***Add Criteria Failed: Keyword" + sitekeyword.text);
        //                                        }
        //                                        #endregion
        //                                    }
        //                                    maxVariations++;
        //                                    if (maxVariations > MaxVariations)
        //                                        break;
        //                                }
        //                            }
        //                            //check add variations for product name raw keywords
        //                            try
        //                            {
        //                                KeywordVariations keywordVariations = keywordToolService.getKeywordVariations(keywordsArray, true, Languages, Countries);
        //                                foreach (KeywordVariation keywordVariation in keywordVariations.moreSpecific)
        //                                {
        //                                    if (Languages[0].ToString() == keywordVariation.language && keywordVariation.advertiserCompetitionScale <= MaxAdvertiserCompetitionScale && keywordVariation.lastMonthSearchVolume >= MinSearchVolumeScale)
        //                                    {
        //                                        // Add keywords to the newly created ad group.
        //                                        //add keywords and url to dbs
        //                                        AffiliTrac.Entities.Keywords kws = new AffiliTrac.Entities.Keywords();
        //                                        kws.KeywordRefId = Guid.NewGuid();
        //                                        kws.Keywords = keywordVariation.text;
        //                                        kws.Url = newTextAd.destinationUrl;
        //                                        kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                        DataRepository.KeywordsProvider.Insert(kws);
        //                                        CriterionService criterionService = (CriterionService)user.GetService(ApiServices.v200906.CampaignCriterionService);
        //                                        // check for low compitition and high search volumes
        //                                        #region Create Ad & Keywords from the Product Name
        //                                        if (!AdAdded)
        //                                        {
        //                                            // Associate this ad group with the newly created campaign.  Send
        //                                            // the request to add the new ad group.
        //                                            myAdGroup = adgroupService.addAdGroup(campaignId, newAdGroup);
        //                                            adGroupId = myAdGroup.id;
        //                                            newTextAd.adGroupId = adGroupId;
        //                                            // create the new add
        //                                            try
        //                                            {
        //                                                //we found a keyword that meets criteria so ad the new Ad.
        //                                                Ad[] myAds = adService.addAds(new Ad[] { newTextAd });
        //                                                GroupAdCount++;
        //                                                Trace.TraceInformation("Text ad" + GroupAdCount + ": " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                                //Trace.TraceInformation("Text ad: " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                                AdAdded = true;
        //                                            }
        //                                            catch
        //                                            {
        //                                                //do nothing
        //                                                Trace.TraceError("***Text ad Failed:" + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                            }
        //                                            //Add the Product name as a whole phrase
        //                                            try
        //                                            {
        //                                                //add keywords and url to dbs
        //                                                kws = new AffiliTrac.Entities.Keywords();
        //                                                kws.KeywordRefId = Guid.NewGuid();
        //                                                kws.Keywords = cleanProdName;
        //                                                kws.Url = newTextAd.destinationUrl;
        //                                                kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                                DataRepository.KeywordsProvider.Insert(kws);
        //                                                Keyword newKeyword = new Keyword();
        //                                                newKeyword.adGroupId = adGroupId;
        //                                                newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                                newKeyword.text = cleanProdName;
        //                                                //TODO: Use the Traffic Estimator to determine the
        //                                                // the maxCpc to use
        //                                                newKeyword.maxCpc = KeywordMaxCpc;
        //                                                newKeyword.maxCpcSpecified = true;
        //                                                newKeyword.criterionType = CriterionType.Keyword;
        //                                                newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                                Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                                newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                                criterionService.addCriteria(newCriteria);
        //                                            }
        //                                            catch (Exception ex)
        //                                            {
        //                                                //do nothing
        //                                                Trace.TraceError("***Add Criteria Failed: Keyword" + cleanProdName + ex.Message);
        //                                            }
        //                                            //Add the individual product name keywords
        //                                            foreach (SeedKeyword sk in keywordsArray)
        //                                            {
        //                                                try
        //                                                {
        //                                                    //add keywords and url to dbs
        //                                                    kws = new AffiliTrac.Entities.Keywords();
        //                                                    kws.KeywordRefId = Guid.NewGuid();
        //                                                    kws.Keywords = sk.text;
        //                                                    kws.Url = newTextAd.destinationUrl;
        //                                                    kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                                    DataRepository.KeywordsProvider.Insert(kws);
        //                                                    // Add keywords to the newly created ad group.
        //                                                    Keyword newKeyword = new Keyword();
        //                                                    newKeyword.adGroupId = adGroupId;
        //                                                    newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                                    newKeyword.text = sk.text;
        //                                                    //TODO: Use the Traffic Estimator to determine the
        //                                                    // the maxCpc to use
        //                                                    newKeyword.maxCpc = KeywordMaxCpc;
        //                                                    newKeyword.maxCpcSpecified = true;
        //                                                    newKeyword.criterionType = CriterionType.Keyword;
        //                                                    newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                                    Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                                    newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                                    criterionService.addCriteria(newCriteria);
        //                                                }
        //                                                catch (Exception ex)
        //                                                {
        //                                                    //do nothing
        //                                                    Trace.TraceError("***Add Criteria Failed: Keyword" + cleanProdName + ex.Message);
        //                                                }
        //                                            }
        //                                        }
        //                                        #endregion
        //                                        #region Create keywords from the keyword suggestion gotten from the landing page
        //                                        try
        //                                        {
        //                                            Keyword newKeyword = new Keyword();
        //                                            newKeyword = new Keyword();
        //                                            newKeyword.adGroupId = adGroupId;
        //                                            newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                            newKeyword.text = keywordVariation.text;
        //                                            //TODO: Use the Traffic Estimator to determine the
        //                                            // the maxCpc to use
        //                                            newKeyword.maxCpc = KeywordMaxCpc;
        //                                            newKeyword.maxCpcSpecified = true;
        //                                            newKeyword.criterionType = CriterionType.Keyword;
        //                                            newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                            Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                            newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                            criterionService.addCriteria(newCriteria);
        //                                        }
        //                                        catch (Exception ex)
        //                                        {
        //                                            //do nothing
        //                                            Trace.TraceError("***Add Criteria Failed: Keyword" + cleanProdName + ex.Message);
        //                                        }
        //                                        #endregion
        //                                    }
        //                                }
        //                            }
        //                            catch
        //                            {//this call fails quite a bit so we need the try catch
        //                            }
        //                        }
        //                        else
        //                        {
        //                            #region Create Keywords from the Product Name Only
        //                            //  create the ad
        //                            // Associate this ad group with the newly created campaign.  Send
        //                            // the request to add the new ad group.
        //                            AdGroup myAdGroup = adgroupService.addAdGroup(campaignId, newAdGroup);
        //                            long adGroupId = myAdGroup.id;
        //                            newTextAd.adGroupId = adGroupId;
        //                            try
        //                            {
        //                                //we found a keyword that meets criteria so ad the new Ad.
        //                                Ad[] myAds = adService.addAds(new Ad[] { newTextAd });
        //                                GroupAdCount++;
        //                                Trace.TraceInformation("Text ad" + GroupAdCount + ": " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                                //Trace.TraceInformation("Text ad: " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                            }
        //                            catch
        //                            {
        //                                //do nothing
        //                                Trace.TraceError("***Text ad Failed:" + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
        //                            }
        //                            //Add the Product name as a whole phrase
        //                            CriterionService criterionService = (CriterionService)user.GetService(ApiServices.v200906.CampaignCriterionService);
        //                            //add keywords and url to dbs
        //                            AffiliTrac.Entities.Keywords kws = new AffiliTrac.Entities.Keywords();
        //                            kws.KeywordRefId = Guid.NewGuid();
        //                            kws.Keywords = cleanProdName;
        //                            kws.Url = newTextAd.destinationUrl;
        //                            kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                            DataRepository.KeywordsProvider.Insert(kws);
        //                            try
        //                            {
        //                                Keyword newKeyword = new Keyword();
        //                                newKeyword.adGroupId = adGroupId;
        //                                newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                newKeyword.text = cleanProdName;
        //                                //TODO: Use the Traffic Estimator to determine the
        //                                // the maxCpc to use
        //                                newKeyword.maxCpc = KeywordMaxCpc;
        //                                newKeyword.maxCpcSpecified = true;
        //                                newKeyword.criterionType = CriterionType.Keyword;
        //                                newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                criterionService.addCriteria(newCriteria);
        //                            }
        //                            catch
        //                            {
        //                                //do nothing
        //                                Trace.TraceError("***Add Criteria Failed: Keyword" + cleanProdName);
        //                            }
        //                            //Add the individual product name keywords
        //                            foreach (SeedKeyword sk in keywordsArray)
        //                            {
        //                                //add keywords and url to dbs
        //                                kws = new AffiliTrac.Entities.Keywords();
        //                                kws.KeywordRefId = Guid.NewGuid();
        //                                kws.Keywords = sk.text;
        //                                kws.Url = newTextAd.destinationUrl;
        //                                kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;
        //                                DataRepository.KeywordsProvider.Insert(kws);
        //                                try
        //                                {
        //                                    // Add keywords to the newly created ad group.
        //                                    Keyword newKeyword = new Keyword();
        //                                    newKeyword.adGroupId = adGroupId;
        //                                    newKeyword.type = (KeywordType)Enum.ToObject(typeof(KeywordType), AdKeywordType);
        //                                    newKeyword.text = sk.text;
        //                                    //TODO: Use the Traffic Estimator to determine the
        //                                    // the maxCpc to use
        //                                    newKeyword.maxCpc = KeywordMaxCpc;
        //                                    newKeyword.maxCpcSpecified = true;
        //                                    newKeyword.criterionType = CriterionType.Keyword;
        //                                    newKeyword.destinationUrl = destinationUrlPrefix + siteCategory.PageUrl.Substring(2, siteCategory.PageUrl.IndexOf(".") - 2) + "__" + urlProdName;
        //                                    Criterion[] newCriteria = new Criterion[] { newKeyword };
        //                                    newCriteria[0].destinationUrl = newKeyword.destinationUrl;
        //                                    criterionService.addCriteria(newCriteria);
        //                                }
        //                                catch
        //                                {
        //                                    //do nothing
        //                                    Trace.TraceError("***Add Criteria Failed: Keyword" + sk.text);
        //                                }
        //                            }
        //                            #endregion
        //                        }
        //                        if (GroupAdCount >= MaxAdGroups)
        //                            break;
        //                    }
        //                }
        //            }
        //            #endregion
        //        }
        //        #endregion
        //        #region Log everything created
        //        AdGroup[] adGroups = adgroupService.getAllAdGroups(campaignId);
        //        foreach (AdGroup adGroup in adGroups)
        //        {
        //            Trace.TraceInformation("Ad group: " + adGroup.name);
        //            Ad[] ads = adService.getAllAds(new long[] { adGroup.id });
        //            foreach (Ad ad in ads)
        //            {
        //                if (ad is TextAd)
        //                {
        //                    TextAd textAd = (TextAd)ad;
        //                    Trace.TraceInformation("Text ad: " + textAd.headline + " Text Line1:" + textAd.description1 + " Text Line2:" + textAd.description2);
        //                }
        //            }
        //        }
        //        #endregion
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //}
        /// <summary>
        /// CreateKeywordsByAffiliateSiteRefId
        /// </summary>
        /// <param name="CheckAgainstAdwordsAPI"></param>
        /// <param name="UseSandbox"></param>
        /// <param name="AffiliateSiteRefId"></param>
        /// <param name="destinationUrlPrefix"></param>
        /// <param name="MaxAdvertiserCompetitionScale"></param>
        /// <param name="MinSearchVolumeScale"></param>
        /// <param name="MaxEstimateCpc"></param>
        /// <param name="MinEstimateCpc"></param>
        /// <param name="MaxEstimateClicksPerDay"></param>
        /// <param name="MinEstimateClicksPerDay"></param>
        /// <param name="getVariations"></param>
        /// <param name="getSiteKeywords"></param>
        /// <param name="Languages"></param>
        /// <param name="Countries"></param>
        public VList<SiteCategoryKeywords> CreateKeywordsByAffiliateSiteRefId(bool CheckAgainstAdwordsAPI, bool UseSandbox, Guid AffiliateSiteRefId,
            bool getVariations, bool getSiteKeywords, int maxKeywordsPerEstimate, String[] Languages,
            String[] Countries, decimal maxApiUsageDollars)
        {
            // Create a user (reads headers from App.config file).
            AdWordsUser user = new AdWordsUser();

            VList<SiteCategoryKeywords> reserachList = new VList<SiteCategoryKeywords>();

            //get seo parameters
            SeoParameters seop = DataRepository.SeoParametersProvider.GetByAffiliateSiteRefId(AffiliateSiteRefId)[0];

            if (CheckAgainstAdwordsAPI)
            {
                if (UseSandbox)
                    user.UseSandbox();	// use sandbox

                AccountService accountService = (AccountService)user.GetService(ApiServices.v13.AccountService);
                string[] accounts = accountService.getClientAccounts();
            }

            try
            {
                #region Create your Services
                //create your services
                List<KeywordRequest> keywords = new List<KeywordRequest>();
                //List<SeedKeyword> keywordsForVariation = new List<SeedKeyword>();

                TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService)user.GetService(ApiServices.v13.TrafficEstimatorService);
                AdGroupAdServicev200906 adService = (AdGroupAdServicev200906)user.GetService(ApiServices.v200906.AdGroupAdService);

                KeywordToolService keywordToolService = (KeywordToolService)user.GetService(ApiServices.v13.KeywordToolService);
                AdGroupServicev200906 adgroupService = (AdGroupServicev200906)user.GetService(ApiServices.v200906.AdGroupService);

                #endregion

                #region Enumerate thru all the categories
                bool SiteCategoryKeywordMaxCntReached = false;
                int SiteCategoryKeywordMaxCnt = 0;
                int SiteCategoryAdMaxCnt = 0;
                int SiteCategoryKeywordCnt = 0;

                // calculate max values by budget
                CalculateKeywordCountsPerSiteCategoryByApiBudget(out SiteCategoryKeywordMaxCnt, out SiteCategoryAdMaxCnt);

                //enumerate thru all the categories
                foreach (SiteCategory siteCategory in DataRepository.SiteCategoryProvider.GetByAffiliateSiteRefId(AffiliateSiteRefId))
                {
                    if (SiteCategoryKeywordMaxCntReached)
                    {
                        SiteCategoryKeywordMaxCntReached = false;
                        SiteCategoryKeywordCnt = 0;
                    }

                    DataRepository.SiteCategoryProvider.DeepLoad(siteCategory, true, DeepLoadType.IncludeChildren, typeof(TList<SiteCategoryCategoryMapping>));

                    #region Enumerate thru the category mappings to get the merchants
                    //enumerate thru the categoru mappings to get the merchants
                    foreach (SiteCategoryCategoryMapping catMap in siteCategory.SiteCategoryCategoryMappingCollection)
                    {
                        if (SiteCategoryKeywordMaxCntReached)
                            break;

                        DataRepository.SiteCategoryCategoryMappingProvider.DeepLoad(catMap, true, DeepLoadType.IncludeChildren, typeof(Category));
                        DataRepository.CategoryProvider.DeepLoad(catMap.CategoryRefIdSource, true, DeepLoadType.IncludeChildren, typeof(TList<Merchant>));
                        catMap.CategoryRefIdSource.MerchantCollection.Shuffle();
                        foreach (Merchant merch in catMap.CategoryRefIdSource.MerchantCollection)
                        {
                            if (SiteCategoryKeywordMaxCntReached)
                                break;

                            DataRepository.MerchantProvider.DeepLoad(merch, true, DeepLoadType.IncludeChildren, typeof(TList<Product>));

                            //shuffle the products
                            merch.ProductCollection.Shuffle();

                            // enumerate thru all the merchant's products
                            foreach (Product prod in merch.ProductCollection)
                            {
                                if (SiteCategoryKeywordMaxCntReached)
                                    break;

                                Trace.TraceInformation(prod.Name);
                                //scrub the product name to extract the keywords
                                string cleanProdKeywords = StringUtils.ScrubProdName(StringUtils.RemoveDuplicateWords(prod.Name));

                                string urlProdRefId = siteCategory.ProductUrlPrefix + prod.ProductRefId.ToString();

                                keywords.Clear();

                                //create an array of keywords
                                string[] rawKeywords = new string[] { "" };
                                //seperate into individual keywords
                                rawKeywords = cleanProdKeywords.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                                List<string> cleanKeyword = new List<string>();
                                foreach (string str in rawKeywords)
                                {
                                    int tryInt = 0; //not empty, not a number, and not lower case
                                    if (str.Length > 2 && str.Trim() != "" && !int.TryParse(str.Trim(), out tryInt)) //&& !isLowerCase(str.Trim().Substring(0, 1).ToCharArray()[0])
                                    {
                                        cleanKeyword.Add(StringUtils.ScrubKeywords(str));
                                    }
                                }

                                //seperate into keywords phrases
                                //TODO: KeywordPhraseWordCount use this config
                                for (int i = 0; i < rawKeywords.Length - 1; i++)
                                {
                                    int tryInt = 0; //not empty, not a number, and not lower case
                                    if (rawKeywords[i].Length > 2 && rawKeywords[i].Trim() != "" && !int.TryParse(rawKeywords[i].Trim(), out tryInt) && rawKeywords[i + 1].Length > 2 && rawKeywords[i + 1].Trim() != "" && !int.TryParse(rawKeywords[i + 1].Trim(), out tryInt))
                                    {
                                        cleanKeyword.Add(StringUtils.ScrubKeywords(rawKeywords[i] + " " + StringUtils.ScrubKeywords(rawKeywords[i + 1])));
                                    }
                                }

                                //also add a key word for the entire product name
                                cleanKeyword.Add(prod.Name);

                                foreach (string keyword in cleanKeyword)
                                {
                                    if (DataRepository.KeywordsProvider.GetByUrlKeywords(urlProdRefId, keyword) == null)
                                    {
                                        //add keywords and url to dbs
                                        AffiliTrac.Entities.Keywords kws = new AffiliTrac.Entities.Keywords();
                                        kws.KeywordRefId = Guid.NewGuid();
                                        kws.Keywords = keyword;
                                        kws.Url = urlProdRefId;
                                        kws.ProductRefId = prod.ProductRefId;
                                        kws.SiteCategoryRefId = siteCategory.SiteCategoryRefId;

                                        DataRepository.KeywordsProvider.Insert(kws);
                                        SiteCategoryKeywordCnt += 1;

                                        if (SiteCategoryKeywordCnt >= SiteCategoryKeywordMaxCnt)
                                        {
                                            SiteCategoryKeywordMaxCntReached = true;
                                            break;
                                        }
                                    }
                                }
                            }

                        }
                    }
                    #endregion
                }
                #endregion

                #region Check Traffic Estimates for Keywords
                if (CheckAgainstAdwordsAPI)
                {
                    try
                    {
                        int apiUnitUsage = 0;
                        reserachList = DataRepository.SiteCategoryKeywordsProvider.GetDistinct(AffiliateSiteRefId);
                        foreach (SiteCategoryKeywords kw in reserachList)
                        {
                            //TODO: check usage
                            //if (apiUsage >= maxApiUsage)
                            //    break;

                            KeywordRequest sw = new KeywordRequest();
                            sw.text = kw.Keywords;

                            sw.type = kw.Keywords.IndexOf(' ') > 0 ? KeywordType.Phrase : KeywordType.Broad; //check to see if it's a phrase
                            sw.maxCpc = seop.MaxEstimateCpc;
                            sw.maxCpcSpecified = true;
                            sw.typeSpecified = true;
                            keywords.Add(sw);

                            #region Add Aditional Search types
                            //sw = new KeywordRequest();
                            //sw.text = StringUtils.ScrubKeywords(str);
                            //if (sw.text.Length > 2 && sw.text.Trim() != "")
                            //{
                            //    sw.type = KeywordType.Exact;
                            //    sw.maxCpc = 1000000;
                            //    sw.maxCpcSpecified = true;
                            //    sw.typeSpecified = true;

                            //    keywords.Add(sw);
                            //}

                            //sw = new KeywordRequest();
                            //sw.text = StringUtils.ScrubKeywords(str);
                            //if (sw.text.Length > 2 && sw.text.Trim() != "")
                            //{
                            //    sw.type = KeywordType.Phrase;
                            //    sw.maxCpc = 1000000;
                            //    sw.maxCpcSpecified = true;
                            //    sw.typeSpecified = true;

                            //    keywords.Add(sw);
                            //}
                            #endregion
                        }

                        // check traffic estimates 100 at a time
                        for (int i = 0; i < keywords.Count; i += maxKeywordsPerEstimate)
                        {
                            if (i >= keywords.Count)
                                break;

                            KeywordRequest[] keywordsRequestArray = new KeywordRequest[] { new KeywordRequest() };
                            keywordsRequestArray = keywords.GetRange(i, keywords.Count - i >= maxKeywordsPerEstimate ? maxKeywordsPerEstimate : keywords.Count - i).ToArray();
                            KeywordEstimate[] KeywordEstimates = null;

                            try
                            {
                                KeywordEstimates = trafficEstimatorService.estimateKeywordList(keywordsRequestArray);

                                foreach (KeywordRequest kr in keywordsRequestArray)
                                {
                                    Trace.TraceInformation("Accepted keyword :" + kr.text);
                                }

                                //apiUsage += DataRepository.PpcApiRequestTypesProvider.GetByName("").ApiUnitCostPerItem; //((decimal)keywordsRequestArray.Length * (decimal).20);

                                //Trace.TraceInformation("API Usage :" + apiUsage.ToString("{0:c}"));

                            }
                            catch (Exception ex)
                            {
                                //do nothing
                                Trace.TraceError("***Get Keyword Traffic Estimates Failed: " + ex.Message);
                                foreach (KeywordRequest kr in keywordsRequestArray)
                                {
                                    Trace.TraceInformation("Possible bad keyword :" + kr.text);
                                }

                                // TODO: now go thru and do them individually

                                continue;

                            }

                            if (KeywordEstimates.Length > 0)
                            {
                                int c = 0;
                                foreach (KeywordEstimate keywordEstimate in KeywordEstimates)
                                {
                                    //Trace.TraceInformation("Checking Site Keyword " + maxVariations + ":" + sitekeyword.text);
                                    // check for low compitition and high search volumes

                                    if (UseSandbox || (keywordEstimate.lowerClicksPerDay >= seop.MinEstimateClicksPerDay && keywordEstimate.lowerCpc <= seop.MaxEstimateCpc))
                                    {
                                        // mark MeetsSeoParm on all keyword records with this keyword
                                        TList<Keywords> updateList = DataRepository.KeywordsProvider.GetByKeywords(keywordsRequestArray[c].text);
                                        foreach (Keywords ukw in updateList)
                                        {
                                            ukw.MeetsSeoCriteria = true;
                                        }

                                        DataRepository.KeywordsProvider.Update(updateList);
                                    }

                                    c++;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //do nothing
                        Trace.TraceError("***Get Keyword Traffic Estimates Failed: " + ex.Message);
                    }
                }

                #endregion

                //go get the updated list again
                reserachList = DataRepository.SiteCategoryKeywordsProvider.GetDistinct(AffiliateSiteRefId);

                return reserachList;

            }
            catch (Exception ex)
            {
                Trace.TraceError("Error:" + ex.Message);
                throw ex;
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group to which keywords are added.
        /// </param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            using (AdGroupCriterionService adGroupCriterionService =
                       (AdGroupCriterionService)user.GetService(
                           AdWordsService.v201802.AdGroupCriterionService)) {
                // Set partial failure mode for the service.
                adGroupCriterionService.RequestHeader.partialFailure = true;

                try {
                    List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>();

                    // Create the keywords.
                    string[] keywords = new string[] {
                        "mars cruise", "inv@lid cruise", "venus cruise", "b(a)d keyword cruise"
                    };

                    foreach (string keywordText in keywords)
                    {
                        Keyword keyword = new Keyword {
                            text      = keywordText,
                            matchType = KeywordMatchType.BROAD
                        };

                        // Create biddable ad group criterion.
                        BiddableAdGroupCriterion keywordBiddableAdGroupCriterion =
                            new BiddableAdGroupCriterion {
                            adGroupId = adGroupId,
                            criterion = keyword
                        };

                        // Create the operation.
                        AdGroupCriterionOperation keywordAdGroupCriterionOperation =
                            new AdGroupCriterionOperation {
                            operand   = keywordBiddableAdGroupCriterion,
                            @operator = Operator.ADD
                        };
                        operations.Add(keywordAdGroupCriterionOperation);
                    }

                    // Create the keywords.
                    AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(
                        operations.ToArray());

                    // Display the results.
                    if (result != null && result.value != null)
                    {
                        foreach (AdGroupCriterion adGroupCriterionResult in result.value)
                        {
                            if (adGroupCriterionResult.criterion != null)
                            {
                                Console.WriteLine("Keyword with ad group id '{0}', criterion id '{1}', and " +
                                                  "text '{2}' was added.\n", adGroupCriterionResult.adGroupId,
                                                  adGroupCriterionResult.criterion.id,
                                                  ((Keyword)adGroupCriterionResult.criterion).text);
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("No keywords were added.");
                    }

                    // Display the partial failure errors.
                    if (result != null && result.partialFailureErrors != null)
                    {
                        foreach (ApiError apiError in result.partialFailureErrors)
                        {
                            int operationIndex = apiError.GetOperationIndex();
                            if (operationIndex != -1)
                            {
                                AdGroupCriterion adGroupCriterion = operations[operationIndex].operand;
                                Console.WriteLine("Keyword with ad group id '{0}' and text '{1}' "
                                                  + "triggered a failure for the following reason: '{2}'.\n",
                                                  adGroupCriterion.adGroupId, ((Keyword)adGroupCriterion.criterion).text,
                                                  apiError.errorString);
                            }
                            else
                            {
                                Console.WriteLine("A failure for the following reason: '{0}' has occurred.\n",
                                                  apiError.errorString);
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to add keywords in partial failure mode.",
                                                          e);
                }
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="gmbEmailAddress">The email address for Google My Business
        /// account.</param>
        /// <param name="gmbAccessToken">The OAuth2 access token for Google
        /// My Business account.</param>
        /// <param name="businessAccountIdentifier">The account identifier for
        /// Google My Business account.</param>
        public void Run(AdWordsUser user, string gmbEmailAddress, string gmbAccessToken,
                        string businessAccountIdentifier)
        {
            FeedService feedService = (FeedService)user.GetService(AdWordsService.v201409.FeedService);

            CustomerFeedService customerFeedService = (CustomerFeedService)user.GetService(
                AdWordsService.v201409.CustomerFeedService);

            // Create a feed that will sync to the Google My Business account
            // specified by gmbEmailAddress. Do not add FeedAttributes to this object,
            // as AdWords will add them automatically because this will be a
            // system generated feed.
            Feed gmbFeed = new Feed();

            gmbFeed.name = String.Format("Google My Business feed #{0}",
                                         ExampleUtilities.GetRandomString());

            PlacesLocationFeedData feedData = new PlacesLocationFeedData();

            feedData.emailAddress = gmbEmailAddress;
            feedData.businessAccountIdentifier = businessAccountIdentifier;

            OAuthInfo oAuthInfo = new OAuthInfo();

            oAuthInfo.httpMethod = "GET";

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

            gmbFeed.systemFeedGenerationData = feedData;

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

            // Create an operation to add the feed.
            FeedOperation feedOperation = new FeedOperation();

            feedOperation.operand   = gmbFeed;
            feedOperation.@operator = Operator.ADD;

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

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

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

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

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

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

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

                        Console.WriteLine("Added CustomerFeed for feed ID {0} and placeholder type {1}",
                                          addedCustomerFeed.feedId, addedCustomerFeed.placeholderTypes[0]);
                        break;
                    } catch (AdWordsApiException e) {
                        ApiException apiException = (ApiException)e.ApiException;
                        foreach (ApiError error in apiException.errors)
                        {
                            if (error is CustomerFeedError)
                            {
                                if ((error as CustomerFeedError).reason ==
                                    CustomerFeedErrorReason.MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE)
                                {
                                    errorHandler.DoExponentialBackoff();
                                    errorHandler.IncrementRetriedAttempts();
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                    }
                } while (errorHandler.HaveMoreRetryAttemptsLeft());

                // OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at
                // the Campaign level.  This will be similar to the CampaignFeed in the
                // AddSiteLinks example, except you can also filter based on the
                // business name and category of each FeedItem by using a
                // FeedAttributeOperand in your matching function.

                // OPTIONAL: Create an AdGroupFeed for even more fine grained control
                // over which feed items are used at the AdGroup level.
            } catch (Exception ex) {
                throw new System.ApplicationException("Failed to create customer feed.", ex);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="campaignId">Id of the campaign to which ad groups are
        /// added.</param>
        public void Run(AdWordsUser user, long campaignId)
        {
            // Get the AdGroupService.
            AdGroupService adGroupService =
                (AdGroupService)user.GetService(AdWordsService.v201402.AdGroupService);

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

            for (int i = 0; i < NUM_ITEMS; i++)
            {
                // Create the ad group.
                AdGroup adGroup = new AdGroup();
                adGroup.name = string.Format("Earth to Mars Cruises #{0}",
                                             ExampleUtilities.GetRandomString());
                adGroup.status     = AdGroupStatus.ENABLED;
                adGroup.campaignId = campaignId;

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

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

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

                adGroup.biddingStrategyConfiguration = biddingConfig;

                // Optional: Set targeting restrictions.
                // These setting only affect serving for the Display Network.
                TargetingSetting targetingSetting = new TargetingSetting();

                TargetingSettingDetail placementDetail = new TargetingSettingDetail();
                placementDetail.criterionTypeGroup = CriterionTypeGroup.PLACEMENT;
                placementDetail.targetAll          = true;

                TargetingSettingDetail verticalDetail = new TargetingSettingDetail();
                verticalDetail.criterionTypeGroup = CriterionTypeGroup.VERTICAL;
                verticalDetail.targetAll          = false;

                targetingSetting.details = new TargetingSettingDetail[] { placementDetail, verticalDetail };

                adGroup.settings = new Setting[] { targetingSetting };

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

                operations.Add(operation);
            }

            try {
                // Create the ad group.
                AdGroupReturnValue retVal = adGroupService.mutate(operations.ToArray());

                // Display the results.
                if (retVal != null && retVal.value != null && retVal.value.Length > 0)
                {
                    foreach (AdGroup newAdGroup in retVal.value)
                    {
                        Console.WriteLine("Ad group with id = '{0}' and name = '{1}' was created.",
                                          newAdGroup.id, newAdGroup.name);
                    }
                }
                else
                {
                    Console.WriteLine("No ad groups were created.");
                }
            } catch (Exception ex) {
                throw new System.ApplicationException("Failed to create ad groups.", ex);
            }
        }
        /// <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)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionService adGroupCriterionService =
                (AdGroupCriterionService)user.GetService(AdWordsService.v201705.AdGroupCriterionService);

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

            WebpageParameter parameter = new WebpageParameter();

            parameter.criterionName = "Test criterion";
            webpage.parameter       = parameter;

            // Add a condition for label=specified_label_name.
            WebpageCondition condition = new WebpageCondition();

            condition.operand    = WebpageConditionOperand.CUSTOM_LABEL;
            condition.argument   = labelName;
            parameter.conditions = new WebpageCondition[] { condition };

            BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();

            criterion.adGroupId = adGroupId;
            criterion.criterion = webpage;

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

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

            criterion.biddingStrategyConfiguration = biddingStrategyConfiguration;

            AdGroupCriterionOperation operation = new AdGroupCriterionOperation();

            operation.operand   = criterion;
            operation.@operator = Operator.ADD;

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

                Console.WriteLine("Web page criterion with ID = {0} and status = {1} was created.",
                                  newCriterion.criterion.id, newCriterion.userStatus);

                return(newCriterion);
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to create webpage criterion for " +
                                                      "custom page feed label.", e);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="campaignId">Id of the campaign to which sitelinks will
        /// be added.</param>
        public void Run(AdWordsUser user, long campaignId)
        {
            // Get the CampaignExtensionSettingService.
            CampaignExtensionSettingService campaignExtensionSettingService =
                (CampaignExtensionSettingService)user.GetService(
                    AdWordsService.v201509.CampaignExtensionSettingService);

            CustomerService customerService = (CustomerService)user.GetService(
                AdWordsService.v201509.CustomerService);
            Customer customer = customerService.get();

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

            // Show the Thanksgiving specials link only from 20 - 27 Nov.
            SitelinkFeedItem sitelink2 = new SitelinkFeedItem()
            {
                sitelinkText      = "Thanksgiving Specials",
                sitelinkFinalUrls = new string[] { "http://www.example.com/thanksgiving" },
                startTime         = string.Format("{0}1120 000000 {1}", DateTime.Now.Year, customer.dateTimeZone),
                endTime           = string.Format("{0}1127 235959 {1}", DateTime.Now.Year, customer.dateTimeZone)
            };

            // Show the wifi details primarily for high end mobile users.
            SitelinkFeedItem sitelink3 = new SitelinkFeedItem()
            {
                sitelinkText      = "Wifi available",
                sitelinkFinalUrls = new string[] { "http://www.example.com/mobile/wifi" },
                devicePreference  = new FeedItemDevicePreference()
                {
                    // See https://developers.google.com/adwords/api/docs/appendix/platforms
                    // for device criteria IDs.
                    devicePreference = 30001
                }
            };

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

            // Create your campaign extension settings. This associates the sitelinks
            // to your campaign.
            CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting();

            campaignExtensionSetting.campaignId       = campaignId;
            campaignExtensionSetting.extensionType    = FeedType.SITELINK;
            campaignExtensionSetting.extensionSetting = new ExtensionSetting()
            {
                extensions = new ExtensionFeedItem[] {
                    sitelink1, sitelink2, sitelink3, sitelink4
                }
            };

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

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

                // Display the results.
                if (retVal.value != null && retVal.value.Length > 0)
                {
                    CampaignExtensionSetting newExtensionSetting = retVal.value[0];
                    Console.WriteLine("Extension setting with type = {0} was added to campaign ID {1}.",
                                      newExtensionSetting.extensionType, newExtensionSetting.campaignId);
                }
                else
                {
                    Console.WriteLine("No extension settings were created.");
                }
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to create extension settings.", e);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group from which expanded text ads
        /// are retrieved.</param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupAdService.
            AdGroupAdService service =
                (AdGroupAdService)user.GetService(AdWordsService.v201609.AdGroupAdService);

            // Create a selector.
            Selector selector = new Selector()
            {
                fields = new string[] {
                    ExpandedTextAd.Fields.Id, AdGroupAd.Fields.Status, ExpandedTextAd.Fields.HeadlinePart1,
                    ExpandedTextAd.Fields.HeadlinePart2, ExpandedTextAd.Fields.Description
                },
                ordering   = new OrderBy[] { OrderBy.Asc(ExpandedTextAd.Fields.Id) },
                predicates = new Predicate[] {
                    // Restrict the fetch to only the selected ad group id.
                    Predicate.Equals(AdGroupAd.Fields.AdGroupId, adGroupId),

                    // Retrieve only expanded text ads.
                    Predicate.Equals("AdType", "EXPANDED_TEXT_AD"),

                    // By default disabled ads aren't returned by the selector. To return
                    // them include the DISABLED status in the statuses field.
                    Predicate.In(AdGroupAd.Fields.Status, new string[] {
                        AdGroupAdStatus.ENABLED.ToString(),
                        AdGroupAdStatus.PAUSED.ToString(),
                        AdGroupAdStatus.DISABLED.ToString()
                    })
                },
                paging = Paging.Default
            };

            AdGroupAdPage page = new AdGroupAdPage();

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

                    // Display the results.
                    if (page != null && page.entries != null)
                    {
                        int i = selector.paging.startIndex;

                        foreach (AdGroupAd adGroupAd in page.entries)
                        {
                            ExpandedTextAd expandedTextAd = (ExpandedTextAd)adGroupAd.ad;
                            Console.WriteLine("{0} : Expanded text ad with ID '{1}', headline '{2} - {3}' " +
                                              "and description '{4} was found.", i + 1, expandedTextAd.id,
                                              expandedTextAd.headlinePart1, expandedTextAd.headlinePart2,
                                              expandedTextAd.description);
                            i++;
                        }
                    }
                    selector.paging.IncreaseOffset();
                } while (selector.paging.startIndex < page.totalNumEntries);
                Console.WriteLine("Number of expanded text ads found: {0}", page.totalNumEntries);
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to get expanded text ads", e);
            }
        }
Example #22
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="businessId">The AdWords Express business id.</param>
        public void Run(AdWordsUser user, long businessId)
        {
            // Get the ExpressBusinessService.
            ExpressBusinessService businessService = (ExpressBusinessService)
                                                     user.GetService(AdWordsService.v201402.ExpressBusinessService);

            // Get the PromotionService
            PromotionService promotionService = (PromotionService)
                                                user.GetService(AdWordsService.v201402.PromotionService);

            // Get the business for the businessId. We will need its geo point to
            // create a Proximity criterion for the new Promotion.
            Selector businessSelector = new Selector();

            Predicate predicate = new Predicate();

            predicate.field             = "Id";
            predicate.@operator         = PredicateOperator.EQUALS;
            predicate.values            = new string[] { businessId.ToString() };
            businessSelector.predicates = new Predicate[] { predicate };

            businessSelector.fields = new string[] { "Id", "GeoPoint" };

            ExpressBusinessPage businessPage = businessService.get(businessSelector);

            if (businessPage == null || businessPage.entries == null ||
                businessPage.entries.Length == 0)
            {
                Console.WriteLine("No business was found.");
                return;
            }

            // Set the business ID to the service.
            promotionService.RequestHeader.expressBusinessId = businessId;

            // First promotion
            Promotion marsTourPromotion = new Promotion();
            Money     budget            = new Money();

            budget.microAmount                    = 1000000L;
            marsTourPromotion.name                = "Mars Tour Promotion " + ExampleUtilities.GetShortRandomString();
            marsTourPromotion.status              = PromotionStatus.PAUSED;
            marsTourPromotion.destinationUrl      = "http://www.example.com";
            marsTourPromotion.budget              = budget;
            marsTourPromotion.callTrackingEnabled = true;

            // Criteria

            // Criterion - Travel Agency product service
            ProductService productService = new ProductService();

            productService.text = "Travel Agency";

            // Criterion - English language
            // The ID can be found in the documentation:
            // https://developers.google.com/adwords/api/docs/appendix/languagecodes
            Language language = new Language();

            language.id = 1000L;

            // Criterion - Within 15 miles
            Proximity proximity = new Proximity();

            proximity.geoPoint            = businessPage.entries[0].geoPoint;
            proximity.radiusDistanceUnits = ProximityDistanceUnits.MILES;
            proximity.radiusInUnits       = 15;

            marsTourPromotion.criteria = new Criterion[] { productService, language, proximity };

            // Creatives

            Creative creative1 = new Creative();

            creative1.headline = "Standard Mars Trip";
            creative1.line1    = "Fly coach to Mars";
            creative1.line2    = "Free in-flight pretzels";

            Creative creative2 = new Creative();

            creative2.headline = "Deluxe Mars Trip";
            creative2.line1    = "Fly first class to Mars";
            creative2.line2    = "Unlimited powdered orange drink";

            marsTourPromotion.creatives = new Creative[] { creative1, creative2 };

            PromotionOperation operation = new PromotionOperation();

            operation.@operator = Operator.ADD;
            operation.operand   = marsTourPromotion;

            try {
                Promotion[] addedPromotions = promotionService.mutate(
                    new PromotionOperation[] { operation });

                Console.WriteLine("Added promotion ID {0} with name {1} to business ID {2}.",
                                  addedPromotions[0].id, addedPromotions[0].name, businessId);
            } catch (Exception ex) {
                throw new System.ApplicationException("Failed to add promotions.", ex);
            }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            using (BatchJobService batchJobService = (BatchJobService)user.GetService(
                       AdWordsService.v201802.BatchJobService)) {
                try {
                    // Create a BatchJob.
                    BatchJobOperation addOp = new BatchJobOperation()
                    {
                        @operator = Operator.ADD,
                        operand   = new BatchJob()
                    };

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

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

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

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

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

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

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

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

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

                    BatchJobUtilities batchJobUploadHelper = new BatchJobUtilities(user);

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

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

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

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

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

                    if (batchJob.downloadUrl != null && batchJob.downloadUrl.url != null)
                    {
                        BatchJobMutateResponse mutateResponse = batchJobUploadHelper.Download(
                            batchJob.downloadUrl.url);
                        Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url);
                        foreach (MutateResult mutateResult in mutateResponse.rval)
                        {
                            String outcome = mutateResult.errorList == null ? "SUCCESS" : "FAILURE";
                            Console.WriteLine("  Operation [{0}] - {1}", mutateResult.index, outcome);
                        }
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to add campaigns using batch job.", e);
                }
            }
        }
Example #24
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Get the TrafficEstimatorService.
            TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService)user.GetService(
                AdWordsService.v201609.TrafficEstimatorService);

            // Create keywords. Refer to the TrafficEstimatorService documentation for the maximum
            // number of keywords that can be passed in a single request.
            //   https://developers.google.com/adwords/api/docs/reference/latest/TrafficEstimatorService
            // [START createKeywordEstimateRequest] MOE:strip_line
            Keyword keyword1 = new Keyword();

            keyword1.text      = "mars cruise";
            keyword1.matchType = KeywordMatchType.BROAD;

            Keyword keyword2 = new Keyword();

            keyword2.text      = "cheap cruise";
            keyword2.matchType = KeywordMatchType.PHRASE;

            Keyword keyword3 = new Keyword();

            keyword3.text      = "cruise";
            keyword3.matchType = KeywordMatchType.EXACT;

            Keyword[] keywords = new Keyword[] { keyword1, keyword2, keyword3 };

            // Create a keyword estimate request for each keyword.
            List <KeywordEstimateRequest> keywordEstimateRequests = new List <KeywordEstimateRequest>();

            foreach (Keyword keyword in keywords)
            {
                KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest();
                keywordEstimateRequest.keyword = keyword;
                keywordEstimateRequests.Add(keywordEstimateRequest);
            }

            // Create negative keywords.
            Keyword negativeKeyword1 = new Keyword();

            negativeKeyword1.text      = "moon walk";
            negativeKeyword1.matchType = KeywordMatchType.BROAD;

            KeywordEstimateRequest negativeKeywordEstimateRequest = new KeywordEstimateRequest();

            negativeKeywordEstimateRequest.keyword    = negativeKeyword1;
            negativeKeywordEstimateRequest.isNegative = true;
            keywordEstimateRequests.Add(negativeKeywordEstimateRequest);
            // [END createKeywordEstimateRequest] MOE:strip_line

            // [START createAdGroupEstimateRequest] MOE:strip_line
            // Create ad group estimate requests.
            AdGroupEstimateRequest adGroupEstimateRequest = new AdGroupEstimateRequest();

            adGroupEstimateRequest.keywordEstimateRequests = keywordEstimateRequests.ToArray();
            adGroupEstimateRequest.maxCpc             = new Money();
            adGroupEstimateRequest.maxCpc.microAmount = 1000000;
            // [END createAdGroupEstimateRequest] MOE:strip_line

            // [START createCampaignEstimateRequest] MOE:strip_line
            // Create campaign estimate requests.
            CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest();

            campaignEstimateRequest.adGroupEstimateRequests = new AdGroupEstimateRequest[] {
                adGroupEstimateRequest
            };

            // Optional: Set additional criteria for filtering estimates.
            // See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
            // for a detailed list of country codes.
            Location countryCriterion = new Location();

            countryCriterion.id = 2840; //US

            // See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
            // for a detailed list of language codes.
            Language languageCriterion = new Language();

            languageCriterion.id = 1000; //en

            campaignEstimateRequest.criteria = new Criterion[] { countryCriterion, languageCriterion };
            // [END createCampaignEstimateRequest] MOE:strip_line

            try {
                // [START makeRequest] MOE:strip_line
                // Create the selector.
                TrafficEstimatorSelector selector = new TrafficEstimatorSelector()
                {
                    campaignEstimateRequests = new CampaignEstimateRequest[] { campaignEstimateRequest },

                    // Optional: Request a list of campaign level estimates segmented by platform.
                    platformEstimateRequested = true
                };

                // Get traffic estimates.
                TrafficEstimatorResult result = trafficEstimatorService.get(selector);
                // [END makeRequest] MOE:strip_line

                // [START displayEstimates] MOE:strip_line
                // Display traffic estimates.
                if (result != null && result.campaignEstimates != null &&
                    result.campaignEstimates.Length > 0)
                {
                    CampaignEstimate campaignEstimate = result.campaignEstimates[0];

                    // Display the campaign level estimates segmented by platform.
                    if (campaignEstimate.platformEstimates != null)
                    {
                        foreach (PlatformCampaignEstimate platformEstimate in
                                 campaignEstimate.platformEstimates)
                        {
                            string platformMessage = string.Format("Results for the platform with ID: " +
                                                                   "{0} and name : {1}.", platformEstimate.platform.id,
                                                                   platformEstimate.platform.platformName);

                            DisplayMeanEstimates(platformMessage, platformEstimate.minEstimate,
                                                 platformEstimate.maxEstimate);
                        }
                    }

                    // Display the keyword estimates.
                    if (campaignEstimate.adGroupEstimates != null &&
                        campaignEstimate.adGroupEstimates.Length > 0)
                    {
                        AdGroupEstimate adGroupEstimate = campaignEstimate.adGroupEstimates[0];

                        if (adGroupEstimate.keywordEstimates != null)
                        {
                            for (int i = 0; i < adGroupEstimate.keywordEstimates.Length; i++)
                            {
                                Keyword         keyword         = keywordEstimateRequests[i].keyword;
                                KeywordEstimate keywordEstimate = adGroupEstimate.keywordEstimates[i];

                                if (keywordEstimateRequests[i].isNegative)
                                {
                                    continue;
                                }
                                string kwdMessage = string.Format("Results for the keyword with text = '{0}' " +
                                                                  "and match type = '{1}':", keyword.text, keyword.matchType);
                                DisplayMeanEstimates(kwdMessage, keywordEstimate.min, keywordEstimate.max);
                            }
                        }
                    }
                }
                else
                {
                    Console.WriteLine("No traffic estimates were returned.");
                }
                // [END displayEstimates] MOE:strip_line
            } catch (Exception e) {
                throw new System.ApplicationException("Failed to retrieve traffic estimates.", e);
            }
        }
Example #25
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group to which placements are added.
        /// </param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionService adGroupCriterionService =
                (AdGroupCriterionService)user.GetService(AdWordsService.v201409.AdGroupCriterionService);

            // Create the placement.
            Placement placement1 = new Placement();

            placement1.url = "http://mars.google.com";

            // Create biddable ad group criterion.
            AdGroupCriterion placementCriterion1 = new BiddableAdGroupCriterion();

            placementCriterion1.adGroupId = adGroupId;
            placementCriterion1.criterion = placement1;

            // Create the placement.
            Placement placement2 = new Placement();

            placement2.url = "http://venus.google.com";

            // Create biddable ad group criterion.
            AdGroupCriterion placementCriterion2 = new BiddableAdGroupCriterion();

            placementCriterion2.adGroupId = adGroupId;
            placementCriterion2.criterion = placement2;

            // Create the operations.
            AdGroupCriterionOperation placementOperation1 = new AdGroupCriterionOperation();

            placementOperation1.@operator = Operator.ADD;
            placementOperation1.operand   = placementCriterion1;

            AdGroupCriterionOperation placementOperation2 = new AdGroupCriterionOperation();

            placementOperation2.@operator = Operator.ADD;
            placementOperation2.operand   = placementCriterion2;

            try {
                // Create the placements.
                AdGroupCriterionReturnValue retVal = adGroupCriterionService.mutate(
                    new AdGroupCriterionOperation[] { placementOperation1, placementOperation2 });

                // Display the results.
                if (retVal != null && retVal.value != null)
                {
                    foreach (AdGroupCriterion adGroupCriterion in retVal.value)
                    {
                        // If you are adding multiple type of criteria, then you may need to
                        // check for
                        //
                        // if (adGroupCriterion is Placement) { ... }
                        //
                        // to identify the criterion type.
                        Console.WriteLine("Placement with ad group id = '{0}, placement id = '{1}, url = " +
                                          "'{2}' was created.", adGroupCriterion.adGroupId,
                                          adGroupCriterion.criterion.id, (adGroupCriterion.criterion as Placement).url);
                    }
                }
                else
                {
                    Console.WriteLine("No placements were added.");
                }
            } catch (Exception ex) {
                Console.WriteLine("Failed to create placements.", ex);
            }
        }
Example #26
0
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            using (ConversionTrackerService conversionTrackerService =
                       (ConversionTrackerService)user.GetService(AdWordsService.v201802.
                                                                 ConversionTrackerService)) {
                List <ConversionTracker> conversionTrackers = new List <ConversionTracker>();

                // Create an Adwords conversion tracker.
                AdWordsConversionTracker adWordsConversionTracker = new AdWordsConversionTracker();
                adWordsConversionTracker.name = "Earth to Mars Cruises Conversion #" +
                                                ExampleUtilities.GetRandomString();
                adWordsConversionTracker.category = ConversionTrackerCategory.DEFAULT;

                // Set optional fields.
                adWordsConversionTracker.status = ConversionTrackerStatus.ENABLED;
                adWordsConversionTracker.viewthroughLookbackWindow    = 15;
                adWordsConversionTracker.defaultRevenueValue          = 23.41;
                adWordsConversionTracker.alwaysUseDefaultRevenueValue = true;
                conversionTrackers.Add(adWordsConversionTracker);

                // Create an upload conversion for offline conversion imports.
                UploadConversion uploadConversion = new UploadConversion();
                // Set an appropriate category. This field is optional, and will be set to
                // DEFAULT if not mentioned.
                uploadConversion.category = ConversionTrackerCategory.LEAD;
                uploadConversion.name     = "Upload Conversion #" + ExampleUtilities.GetRandomString();
                uploadConversion.viewthroughLookbackWindow = 30;
                uploadConversion.ctcLookbackWindow         = 90;

                // Optional: Set the default currency code to use for conversions
                // that do not specify a conversion currency. This must be an ISO 4217
                // 3-character currency code such as "EUR" or "USD".
                // If this field is not set on this UploadConversion, AdWords will use
                // the account's currency.
                uploadConversion.defaultRevenueCurrencyCode = "EUR";

                // Optional: Set the default revenue value to use for conversions
                // that do not specify a conversion value. Note that this value
                // should NOT be in micros.
                uploadConversion.defaultRevenueValue = 2.50;

                // Optional: To upload fractional conversion credits, mark the upload conversion
                // as externally attributed. See
                // https://developers.google.com/adwords/api/docs/guides/conversion-tracking#importing_externally_attributed_conversions
                // to learn more about importing externally attributed conversions.

                // uploadConversion.isExternallyAttributed = true;

                conversionTrackers.Add(uploadConversion);

                try {
                    // Create operations.
                    List <ConversionTrackerOperation> operations = new List <ConversionTrackerOperation>();
                    foreach (ConversionTracker conversionTracker in conversionTrackers)
                    {
                        operations.Add(new ConversionTrackerOperation()
                        {
                            @operator = Operator.ADD,
                            operand   = conversionTracker
                        });
                    }

                    // Add conversion tracker.
                    ConversionTrackerReturnValue retval = conversionTrackerService.mutate(
                        operations.ToArray());

                    // Display the results.
                    if (retval != null && retval.value != null)
                    {
                        foreach (ConversionTracker conversionTracker in retval.value)
                        {
                            Console.WriteLine("Conversion with ID {0}, name '{1}', status '{2}' and " +
                                              "category '{3}' was added.", conversionTracker.id, conversionTracker.name,
                                              conversionTracker.status, conversionTracker.category);
                            if (conversionTracker is AdWordsConversionTracker)
                            {
                                AdWordsConversionTracker newAdWordsConversionTracker =
                                    (AdWordsConversionTracker)conversionTracker;
                                Console.WriteLine("Google global site tag:\n{0}\nGoogle event snippet:\n{1}",
                                                  newAdWordsConversionTracker.googleGlobalSiteTag,
                                                  newAdWordsConversionTracker.googleEventSnippet
                                                  );
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("No conversion trackers were added.");
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to add conversion trackers.", e);
                }
            }
        }
        /// <summary>
        /// Creates the keywords.
        /// </summary>
        /// <param name="user">The Google Ads user.</param>
        /// <param name="adGroupId">The ad group ID.</param>
        /// <param name="keywords">The keywords to create.</param>
        /// <returns>The newly created ad group criteria.</returns>
        public aw::AdGroupCriterion[] CreateKeywords(AdWordsUser user, long adGroupId,
                                                     string[] keywords)
        {
            // Get the AdGroupCriterionService.
            using (aw::AdGroupCriterionService adGroupCriterionService =
                       (aw::AdGroupCriterionService)user.GetService(AdWordsService.v201809
                                                                    .AdGroupCriterionService))
            {
                List <aw::AdGroupCriterionOperation> operations =
                    new List <aw::AdGroupCriterionOperation>();

                foreach (string keywordText in keywords)
                {
                    // Create the keyword.
                    aw::Keyword keyword = new aw::Keyword
                    {
                        text      = keywordText,
                        matchType = aw::KeywordMatchType.BROAD
                    };

                    // Create the biddable ad group criterion.
                    aw::BiddableAdGroupCriterion keywordCriterion =
                        new aw::BiddableAdGroupCriterion
                    {
                        adGroupId = adGroupId,
                        criterion = keyword,

                        // Optional: Set the user status.
                        userStatus = aw::UserStatus.PAUSED,

                        // Optional: Set the keyword destination url.
                        finalUrls = new aw::UrlList()
                        {
                            urls = new string[]
                            {
                                "http://example.com/mars/cruise/?kw=" +
                                HttpUtility.UrlEncode(keywordText)
                            }
                        }
                    };

                    // Create the operations.
                    aw::AdGroupCriterionOperation operation = new aw::AdGroupCriterionOperation
                    {
                        @operator = aw::Operator.ADD,
                        operand   = keywordCriterion
                    };

                    operations.Add(operation);
                }

                // Create the keywords.
                aw::AdGroupCriterionReturnValue retVal =
                    adGroupCriterionService.mutate(operations.ToArray());

                // Display the results.
                foreach (aw::AdGroupCriterion adGroupCriterion in retVal.value)
                {
                    Console.WriteLine(
                        "Keyword with ad group id = '{0}', keyword id = '{1}', text = " +
                        "'{2}' and match type = '{3}' was created.",
                        adGroupCriterion.adGroupId, adGroupCriterion.criterion.id,
                        (adGroupCriterion.criterion as aw::Keyword).text,
                        (adGroupCriterion.criterion as aw::Keyword).matchType);
                }

                // Return the newly created keywords.
                return(retVal.value);
            }
        }
Example #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="KeywordThread" /> class.
 /// </summary>
 /// <param name="threadIndex">Index of the thread.</param>
 /// <param name="adGroupId">The ad group id.</param>
 /// <param name="user">The AdWords user who owns the ad group.</param>
 public KeywordThread(AdWordsUser user, int threadIndex, long adGroupId)
 {
     this.user        = user;
     this.threadIndex = threadIndex;
     this.adGroupId   = adGroupId;
 }
Example #29
0
        /// <summary>
        /// Checks a list of keywords for policy violations, and add the errors to
        /// a list of traffic estimates.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="trafficEstimates">The list of keywords and their traffic
        /// estimates.</param>
        /// <param name="adGroupId">The ad group ID.</param>
        /// <remarks>Users can use the policy violation details to decide whether
        /// to pick a keyword and submit an exemption request, or skip the
        /// violating keyword and scout for other keywords that are policy
        /// compliant.</remarks>
        private void CheckPolicyViolations(AdWordsUser user, List <TrafficEstimate> trafficEstimates,
                                           long adGroupId)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionService adGroupCriterionService =
                (AdGroupCriterionService)user.GetService(
                    AdWordsService.v201705.AdGroupCriterionService);

            adGroupCriterionService.RequestHeader.validateOnly = true;

            for (int i = 0; i < trafficEstimates.Count; i += Settings.AGCS_KEYWORDS_LIST_SIZE)
            {
                List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>();

                for (int j = i; j < i + Settings.AGCS_KEYWORDS_LIST_SIZE &&
                     j < trafficEstimates.Count; j++)
                {
                    AdGroupCriterionOperation operation = new AdGroupCriterionOperation()
                    {
                        @operator = Operator.ADD,
                        operand   = new BiddableAdGroupCriterion()
                        {
                            adGroupId = adGroupId,
                            criterion = new Keyword()
                            {
                                text      = trafficEstimates[i].Keyword.KeywordText,
                                matchType = trafficEstimates[i].MatchType,
                            },
                            userStatus = UserStatus.ENABLED
                        }
                    };

                    operations.Add(operation);
                }

                try {
                    adGroupCriterionService.mutate(operations.ToArray());
                } catch (AdWordsApiException e) {
                    ApiException innerException = e.ApiException as ApiException;
                    if (innerException == null)
                    {
                        throw new Exception("Failed to retrieve ApiError. See inner exception for more " +
                                            "details.", e);
                    }

                    // Examine each ApiError received from the server.
                    foreach (ApiError apiError in innerException.errors)
                    {
                        int index = apiError.GetOperationIndex();
                        if (index == -1)
                        {
                            // This API error is not associated with an operand, so we cannot
                            // recover from this error by removing one or more operations.
                            // Rethrow the exception for manual inspection.
                            throw;
                        }

                        // Handle policy violation errors.
                        if (apiError is PolicyViolationError)
                        {
                            PolicyViolationError policyError = (PolicyViolationError)apiError;
                            trafficEstimates[i + index].Errors.Add(policyError);
                        }
                    }
                }
            }
            return;
        }
Example #30
0
        /// <summary>
        /// Invokes the run method.
        /// </summary>
        /// <param name="codeExample">The code example.</param>
        /// <param name="user">The user.</param>
        private static void InvokeRun(object codeExample, AdWordsUser user)
        {
            MethodInfo methodInfo = codeExample.GetType().GetMethod("Run");

            methodInfo.Invoke(codeExample, GetParameters(user, codeExample));
        }
Example #31
0
        /// <summary>
        /// Gets the traffic estimates for a list of keywords.
        /// </summary>
        /// <param name="user">The user for which keyword ideas are generated.</param>
        /// <param name="keywords">The keywords for which traffic estimates are
        ///  done.</param>
        /// <param name="matchType">Type of the keyword match to apply when making
        /// traffic estimates.</param>
        /// <param name="maxCpc">The maximum CPC to consider for the traffic.</param>
        /// <param name="campaignId">The campaign ID whose settings should be used
        /// for traffic estimation.</param>
        /// <returns>A list of traffic estimates for the keywords.</returns>
        private List <TrafficEstimate> GetTrafficEstimates(AdWordsUser user,
                                                           List <KeywordIdea> keywords, KeywordMatchType matchType, long maxCpc, long campaignId)
        {
            // Get the TrafficEstimatorService.
            TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService)user.GetService(
                AdWordsService.v201705.TrafficEstimatorService);

            List <Criterion>       trafficCriteria = GetTrafficEstimateCriteria();
            List <TrafficEstimate> retval          = new List <TrafficEstimate>();

            // Eliminate duplicate keywords in the keyword suggestion list so that
            // TrafficEstimatorService doesn't complain about them.
            Dictionary <string, KeywordIdea> uniqueEntries = new Dictionary <string, KeywordIdea>();

            for (int i = 0; i < keywords.Count; i++)
            {
                if (!uniqueEntries.ContainsKey(keywords[i].KeywordText))
                {
                    uniqueEntries[keywords[i].KeywordText] = keywords[i];
                }
            }

            keywords = new List <KeywordIdea>(uniqueEntries.Values);

            for (int i = 0; i < keywords.Count; i += Settings.TES_KEYWORDS_LIST_SIZE)
            {
                List <KeywordEstimateRequest> keywordEstimateRequests = new List <KeywordEstimateRequest>();

                for (int j = i; j < i + Settings.TES_KEYWORDS_LIST_SIZE && j < keywords.Count; j++)
                {
                    KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest()
                    {
                        keyword = new Keyword()
                        {
                            text      = keywords[j].KeywordText,
                            matchType = matchType
                        }
                    };
                    keywordEstimateRequests.Add(keywordEstimateRequest);
                }

                // Create campaign estimate requests.
                CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest()
                {
                    adGroupEstimateRequests = new AdGroupEstimateRequest[] {
                        new AdGroupEstimateRequest()
                        {
                            keywordEstimateRequests = keywordEstimateRequests.ToArray(),
                            maxCpc = new Money()
                            {
                                microAmount = maxCpc
                            }
                        }
                    }
                };

                campaignEstimateRequest.criteria   = trafficCriteria.ToArray();
                campaignEstimateRequest.campaignId = campaignId;

                // Create the selector.
                TrafficEstimatorSelector selector = new TrafficEstimatorSelector();
                selector.campaignEstimateRequests = new CampaignEstimateRequest[] {
                    campaignEstimateRequest
                };

                try {
                    // Get traffic estimates.
                    TrafficEstimatorResult result = trafficEstimatorService.get(selector);

                    // Display traffic estimates.
                    if (result != null && result.campaignEstimates != null &&
                        result.campaignEstimates.Length > 0)
                    {
                        CampaignEstimate campaignEstimate = result.campaignEstimates[0];
                        if (campaignEstimate.adGroupEstimates != null &&
                            campaignEstimate.adGroupEstimates.Length > 0)
                        {
                            AdGroupEstimate adGroupEstimate = campaignEstimate.adGroupEstimates[0];

                            if (adGroupEstimate.keywordEstimates != null)
                            {
                                for (int k = 0; k < adGroupEstimate.keywordEstimates.Length; k++)
                                {
                                    Keyword         keyword         = keywordEstimateRequests[k].keyword;
                                    KeywordEstimate keywordEstimate = adGroupEstimate.keywordEstimates[k];

                                    if (keywordEstimateRequests[k].isNegative)
                                    {
                                        continue;
                                    }

                                    // Find the mean of the min and max values.
                                    long   meanAverageCpc      = 0;
                                    double meanAveragePosition = 0;
                                    long   meanClicks          = 0;
                                    long   meanImpressions     = 0;
                                    long   meanTotalCost       = 0;

                                    if (keywordEstimate.min != null && keywordEstimate.max != null)
                                    {
                                        if (keywordEstimate.min.averageCpc != null &&
                                            keywordEstimate.max.averageCpc != null)
                                        {
                                            meanAverageCpc = (long)Math.Round(
                                                (double)(keywordEstimate.min.averageCpc.microAmount
                                                         + keywordEstimate.max.averageCpc.microAmount) / 2, Settings.ACCURACY,
                                                MidpointRounding.AwayFromZero);
                                        }
                                        meanAveragePosition = Math.Round((keywordEstimate.min.averagePosition
                                                                          + keywordEstimate.max.averagePosition) / 2, Settings.ACCURACY,
                                                                         MidpointRounding.AwayFromZero);

                                        meanClicks = (long)Math.Round((keywordEstimate.min.clicksPerDay +
                                                                       keywordEstimate.max.clicksPerDay) / 2, MidpointRounding.AwayFromZero);

                                        meanImpressions = (long)Math.Round((keywordEstimate.min.impressionsPerDay
                                                                            + keywordEstimate.max.impressionsPerDay) / 2,
                                                                           MidpointRounding.AwayFromZero);

                                        if (keywordEstimate.min.totalCost != null &&
                                            keywordEstimate.max.totalCost != null)
                                        {
                                            meanTotalCost = (keywordEstimate.min.totalCost.microAmount
                                                             + keywordEstimate.max.totalCost.microAmount) / 2;
                                        }
                                    }

                                    TrafficEstimate trafficEstimate = new TrafficEstimate()
                                    {
                                        Keyword         = keywords[i + k],
                                        MatchType       = keyword.matchType,
                                        Clicks          = meanClicks,
                                        Impressions     = meanImpressions,
                                        Cost            = meanTotalCost,
                                        AverageCpc      = meanAverageCpc,
                                        AveragePosition = meanAveragePosition
                                    };
                                    retval.Add(trafficEstimate);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new System.ApplicationException("Failed to retrieve traffic estimates.", e);
                }
            }

            return(retval);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="UseSandbox"></param>
        /// <param name="Name"></param>
        /// <param name="Countries"></param>
        /// <param name="Languages"></param>
        /// <param name="BudgetPeriod"></param>
        /// <param name="BudgetAmount"></param>
        /// <param name="MaxAdGroups"></param>
        /// <param name="DisplayUrl"></param>
        /// <param name="destinationUrlPrefix"></param>
        public void CreateCampaignByKeywordDensityContentMatch(bool UseSandbox, Guid AffiliateSiteRefId, int BudgetPeriod,
            Moneyv200906 BudgetAmount, AdGroupCriterionMoneyv200906 KeywordMaxCpc, string DisplayUrl, int MaxAdGroups, int AdKeywordType, int MinKeywordDensity,
            int MaxKeywordDensity, int MinContentMatch, decimal maxApiUsageDollars)
        {
            // Create a user (reads headers from App.config file).
            AdWordsUser user = new AdWordsUser();
            if (UseSandbox)
                user.UseSandbox();	// use sandbox

            AccountService accountService = (AccountService)user.GetService(ApiServices.v13.AccountService);
            string[] accounts = accountService.getClientAccounts();

            try
            {
                #region Create Campaign

                PpcNetwork ppcNetwork = DataRepository.PpcNetworkProvider.GetByName("AdWords");

                TList<PpcCampaign> Campaigns =
                    DataRepository.PpcCampaignProvider.GetByPpcNetworkRefId(ppcNetwork.PpcNetworkRefId);

                foreach (PpcCampaign campaign in Campaigns)
                {
                    // Target the campaign at
                    CampaignServicev200906 campaignService =
                        (com.google.api.adwords.v200906.CampaignService.CampaignService)
                        user.GetService(ApiServices.v200906.CampaignService);

                    // Create a new campaign with an ad group.  First create a
                    // campaign, so we can get its id.
                    Campaignv200906 newCampaign = new Campaignv200906();

                    // The campaign name is optional.  An error results if a campaign
                    // of the same name already exists.
                    newCampaign.name = campaign.CampaignName + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();

                    // Set the campaign status to paused, we don't want to start
                    // paying for this test.
                    // Required: Set the campaign status.
                    newCampaign.status = CampaignStatusv200906.ACTIVE;
                    newCampaign.statusSpecified = true;

                    // Required: Specify the currency and budget amount.
                    Budget budget = new Budget();
                    BudgetAmount.microAmountSpecified = true;
                    budget.amount = BudgetAmount;

                    // Required: Specify the bidding strategy.
                    newCampaign.biddingStrategy = new ManualCPC();

                    // Optional: Specify the budget period and delivery method.
                    budget.periodSpecified = true;
                    budget.period = BudgetBudgetPeriod.DAILY;
                    budget.deliveryMethodSpecified = true;
                    budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
                    newCampaign.budget = budget;

                    // Optional: Specify an endDate for the campaign.
                    newCampaign.endDate = DateTime.Now.AddDays(campaign.DurationInDays).ToString("yyyyMMdd");

                    // Define an Add operation to add the campaign.
                    CampaignOperation campaignOperation = new CampaignOperation();

                    campaignOperation.operatorSpecified = true;
                    campaignOperation.@operator = CampaignOperatorv200906.ADD;
                    campaignOperation.operand = newCampaign;

                    try
                    {
                        CampaignReturnValue results =
                            campaignService.mutate(new CampaignOperation[] { campaignOperation });
                        if (results != null && results.value != null && results.value.Length > 0)
                        {
                            newCampaign.id = results.value[0].id;
                            newCampaign.idSpecified = true;
                            Trace.TraceInformation(
                                "New campaign with name = \"{0}\" and id = " + "\"{1}\" was created.",
                                results.value[0].name, results.value[0].id);
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error:" + ex.Message);
                        throw new Exception("Failed to create campaign. " + ex.Message);
                    }

                #endregion

                    #region Targeting

                    CampaignTargetService service =
                        (CampaignTargetService)user.GetService(ApiServices.v200906.CampaignTargetService);

                    // Create a language target - for English language.
                    LanguageTargetv200906 languageTarget = new LanguageTargetv200906();
                    languageTarget.languageCode = "en"; //TODO: Add as property
                    LanguageTargetList languageTargetList = new LanguageTargetList();
                    languageTargetList.targets = new LanguageTargetv200906[] { languageTarget };
                    languageTargetList.campaignId = newCampaign.id;
                    languageTargetList.campaignIdSpecified = true;

                    // Create a country target - include US, exclude metrocode 743.
                    CountryTargetv200906 countryTarget = new CountryTargetv200906();
                    countryTarget.countryCode = campaign.TargetCountry;
                    countryTarget.excludedSpecified = true;
                    countryTarget.excluded = false;
                    MetroTargetv200906 metroTarget = new MetroTargetv200906();
                    metroTarget.excludedSpecified = true;
                    metroTarget.excluded = true;
                    metroTarget.metroCode = campaign.ExcludeMetroTarget;

                    GeoTargetList geoTargetList = new GeoTargetList();
                    geoTargetList.targets = new GeoTargetv200906[] { countryTarget, metroTarget };
                    geoTargetList.campaignId = newCampaign.id;
                    geoTargetList.campaignIdSpecified = true;

                    // Create a network target - Google Search.
                    NetworkTargetv200906 networkTarget1 = new NetworkTargetv200906();
                    networkTarget1.networkCoverageTypeSpecified = true;
                    networkTarget1.networkCoverageType = NetworkCoverageTypev200906.GOOGLE_SEARCH;
                    NetworkTargetv200906 networkTarget2 = new NetworkTargetv200906();
                    networkTarget2.networkCoverageTypeSpecified = true;
                    networkTarget2.networkCoverageType = NetworkCoverageTypev200906.SEARCH_NETWORK;

                    NetworkTargetList networkTargetList = new NetworkTargetList();
                    networkTargetList.targets = new NetworkTargetv200906[] { networkTarget1, networkTarget2 };
                    networkTargetList.campaignId = newCampaign.id;
                    networkTargetList.campaignIdSpecified = true;

                    TargetList[] targets =
                        new TargetList[] { languageTargetList, geoTargetList, networkTargetList };

                    ArrayList campaignTargetOperations = new ArrayList();

                    foreach (TargetList target in targets)
                    {
                        CampaignTargetOperation ops = new CampaignTargetOperation();
                        ops.operatorSpecified = true;
                        ops.@operator = CampaignTargetOperatorv200906.SET;
                        ops.operand = target;
                        campaignTargetOperations.Add(ops);
                    }

                    try
                    {
                        service.mutate((CampaignTargetOperation[])
                                       campaignTargetOperations.ToArray(typeof(CampaignTargetOperation)));
                        Trace.TraceInformation("Geo, language, and network targeting were " +
                                               "successfully added to campaign id = \"{0}\".", newCampaign.id);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Failed to create campaign targeting. " +
                                         "Exception says \"{0}\"", ex.Message);
                    }

                    #endregion

                    #region Create your Services

                    //create your services
                    List<SeedKeyword> keywords = new List<SeedKeyword>();

                    AdGroupAdServicev200906 adService =
                        (AdGroupAdServicev200906)user.GetService(ApiServices.v200906.AdGroupAdService);
                    KeywordToolService keywordToolService =
                        (KeywordToolService)user.GetService(ApiServices.v13.KeywordToolService);
                    AdGroupServicev200906 adgroupService =
                        (AdGroupServicev200906)user.GetService(ApiServices.v200906.AdGroupService);
                    TrafficEstimatorService trafficEstimatorService =
                        (TrafficEstimatorService)user.GetService(ApiServices.v13.TrafficEstimatorService);

                    #endregion

                    #region Enumerate thru all the keywords by category

                    AdGroupv200906 newAdGroup = null;

                    foreach (
                        SiteCategory siteCategory in
                            DataRepository.SiteCategoryProvider.GetByAffiliateSiteRefId(AffiliateSiteRefId))
                    {
                        int adGroupCnt = 1;
                        //enumerate thru all the keywords
                        foreach (
                            KeywordUrLsDistinct keywordUrLsDistinct in
                                DataRepository.KeywordUrLsDistinctProvider.GetBySiteCategoryRefId(
                                    siteCategory.SiteCategoryRefId))
                        {
                            VList<KeywordDensity> keywordDensityList =
                                DataRepository.KeywordDensityProvider.GetURLKeywordDensity(keywordUrLsDistinct.Url,
                                                                                           MinKeywordDensity,
                                                                                           MaxKeywordDensity).
                                    FindAllDistinct("SiteContent");

                            int GroupAdCount = 0;

                            //check the avg keyword density
                            if (keywordDensityList.Count >= MinContentMatch)
                            {
                                if (adGroupCnt == 1)
                                {
                                    #region Ad AdGroup

                                    if (GroupAdCount >= MaxAdGroups)
                                        break;

                                    //Create an ad group by site category
                                    newAdGroup = new AdGroupv200906();
                                    newAdGroup.name = siteCategory.Name;

                                    newAdGroup.campaignId = newCampaign.id;
                                    newAdGroup.campaignIdSpecified = true;
                                    //newAdGroup.campaignName = newCampaign.name;

                                    // Optional: set the status of adgroup.
                                    newAdGroup.statusSpecified = true;
                                    newAdGroup.status = AdGroupStatus.ENABLED;

                                    // Optional: Create a Manual CPC Bid.
                                    ManualCPCAdGroupBids bids = new ManualCPCAdGroupBids();

                                    // Set the keyword content max cpc.
                                    bids.keywordContentMaxCpc = new Bid();

                                    Money kwdContentMaxCpc = new Money();
                                    kwdContentMaxCpc.microAmountSpecified = true;
                                    kwdContentMaxCpc.microAmount = KeywordMaxCpc.microAmount;
                                    bids.keywordContentMaxCpc.amount = kwdContentMaxCpc;

                                    // Set the keyword max cpc.
                                    bids.keywordMaxCpc = new Bid();
                                    Money kwdMaxCpc = new Money();
                                    kwdMaxCpc.microAmountSpecified = true;
                                    kwdMaxCpc.microAmount = KeywordMaxCpc.microAmount;
                                    bids.keywordMaxCpc.amount = kwdMaxCpc;

                                    // Set the manual bid to the adgroup.
                                    newAdGroup.bids = bids;

                                    AdGroupOperation adGroupOperation = new AdGroupOperation();
                                    adGroupOperation.operatorSpecified = true;
                                    adGroupOperation.@operator = AddGroupOperatorv200906.ADD;
                                    adGroupOperation.operand = newAdGroup;

                                    try
                                    {
                                        AdGroupReturnValue results =
                                            adgroupService.mutate(new AdGroupOperation[] { adGroupOperation });
                                        if (results != null && results.value != null && results.value.Length > 0)
                                        {
                                            newAdGroup.id = results.value[0].id;
                                            newAdGroup.idSpecified = true;
                                            Trace.TraceInformation(
                                                "New ad group with name = \"{0}\" and id = \"{1}\" was created.",
                                                results.value[0].name, results.value[0].id);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Trace.TraceError("Failed to create ad group. Exception says \"{0}\"", ex.Message);
                                    }

                                    adGroupCnt++;

                                    #endregion
                                }

                                Trace.TraceInformation(keywordUrLsDistinct.Url);

                                //Create an add for each product
                                //
                                // IMPORTANT: create an ad before adding keywords!  Else the
                                // minCpc will have a higher value.
                                TList<PpcAdTemplate> ppcAdTemplateList =
                                    DataRepository.PpcAdTemplateProvider.GetByPpcCampaignRefId(campaign.PpcCampaignRefId);
                                foreach (var ppcAdTemplate in ppcAdTemplateList)
                                {

                                    TextAdv200906 newTextAd = new TextAdv200906();
                                    Product prod =
                                        DataRepository.ProductProvider.GetByProductRefId(
                                            (Guid)keywordUrLsDistinct.ProductRefId);
                                    newTextAd.headline = StringUtils.ScrubProdName(prod.Name);

                                    while (newTextAd.headline.Length > 25)
                                    {
                                        // if one word longer than 25 chars
                                        if (newTextAd.headline.LastIndexOf(" ") < 0)
                                            continue;

                                        newTextAd.headline =
                                            newTextAd.headline.Substring(0, newTextAd.headline.LastIndexOf(" ")).
                                                Substring(
                                                0,
                                                newTextAd.headline.Substring(0, newTextAd.headline.LastIndexOf(" "))
                                                    .
                                                    LastIndexOf(" "));
                                    }

                                    newTextAd.description1 = ppcAdTemplate.AdLine1.Replace(KeywordToken,
                                                                                           keywordDensityList[0].Keywords).Replace(ProductNameToken, newTextAd.headline);
                                    newTextAd.description2 = ppcAdTemplate.AdLine2;

                                    //}

                                    newTextAd.displayUrl = DisplayUrl;
                                    newTextAd.url = keywordUrLsDistinct.Url;
                                    //don't add it yet, there is a check below to see if it meets criteria

                                    //SeedKeyword[] keywordsArray = new SeedKeyword[] { new SeedKeyword() };
                                    //keywordsArray = keywords.ToArray();

                                    // Associate this ad group with the newly created campaign.  Send
                                    // the request to add the new ad group.

                                    try
                                    {
                                        //we found a keyword that meets criteria so ad the new Ad.
                                        AdGroupAd adGroupAd = new AdGroupAd();
                                        adGroupAd.adGroupId = newAdGroup.id;
                                        adGroupAd.adGroupIdSpecified = true;
                                        adGroupAd.ad = newTextAd;

                                        AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation();
                                        adGroupAdOperation.operatorSpecified = true;
                                        adGroupAdOperation.@operator = AddGroupAdOperatorv200906.ADD;
                                        adGroupAdOperation.operand = adGroupAd;

                                        AdGroupAdReturnValue result = null;
                                        try
                                        {
                                            result = adService.mutate(new AdGroupAdOperation[] { adGroupAdOperation });

                                            if (result.value != null && result.value.Length > 0)
                                            {
                                                foreach (AdGroupAd tempAdGroupAd in result.value)
                                                {
                                                    Trace.TraceInformation(
                                                        String.Format(
                                                            "New text ad with headline = \"{0}\" and id = \"{1}\" was created.",
                                                            ((TextAdv200906)tempAdGroupAd.ad).headline,
                                                            tempAdGroupAd.ad.id));
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Trace.TraceError("Failed to create Ad(s). Exception says \"{0}\"",
                                                             ex.Message);
                                        }

                                        GroupAdCount++;
                                        Trace.TraceInformation("Text ad" + GroupAdCount + ": " + newTextAd.headline +
                                                               " Text Line1:" +
                                                               newTextAd.description1 + " Text Line2:" +
                                                               newTextAd.description2);

                                        //Trace.TraceInformation("Text ad: " + newTextAd.headline + " Text Line1:" + newTextAd.description1 + " Text Line2:" + newTextAd.description2);
                                    }
                                    catch
                                    {
                                        //do nothing
                                        Trace.TraceError("***Text ad Failed:" + newTextAd.headline + " Text Line1:" +
                                                         newTextAd.description1 + " Text Line2:" +
                                                         newTextAd.description2);
                                    }

                                }

                                //Add the Product name as a whole phrase
                                AdGroupCriterionServicev200906 criterionService =
                                    (AdGroupCriterionServicev200906)
                                    user.GetService(ApiServices.v200906.AdGroupCriterionService);

                                foreach (KeywordDensity kd in keywordDensityList)
                                {
                                    try
                                    {
                                        Keywordv200906 newKeyword = new Keywordv200906();
                                        newKeyword.matchTypeSpecified = true;
                                        newKeyword.matchType =
                                            com.google.api.adwords.v200906.AdGroupCriterionService.KeywordMatchType.
                                                BROAD;
                                        newKeyword.text = kd.Keywords;

                                        BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
                                        criterion.adGroupId = newAdGroup.id;
                                        criterion.adGroupIdSpecified = true;
                                        criterion.criterion = newKeyword;
                                        criterion.destinationUrl = kd.Url;

                                        //TODO: Use the Traffic Estimator to determine the
                                        // the maxCpc to use
                                        //newKeyword.maxCpc = KeywordMaxCpc;
                                        //newKeyword.maxCpcSpecified = true;

                                        var adGroupCriterionBids =
                                            new com.google.api.adwords.v200906.AdGroupCriterionService.
                                                ManualCPCAdGroupCriterionBids();

                                        adGroupCriterionBids.maxCpc =
                                            new com.google.api.adwords.v200906.AdGroupCriterionService.Bid();
                                        adGroupCriterionBids.maxCpc.amount = KeywordMaxCpc;
                                        criterion.bids = adGroupCriterionBids;

                                        AdGroupCriterionOperation adGroupCriterionOperation =
                                            new AdGroupCriterionOperation();
                                        adGroupCriterionOperation.@operator =
                                            com.google.api.adwords.v200906.AdGroupCriterionService.Operator.ADD;
                                        adGroupCriterionOperation.operatorSpecified = true;
                                        adGroupCriterionOperation.operand = criterion;

                                        try
                                        {
                                            AdGroupCriterionReturnValue results =
                                                criterionService.mutate(new AdGroupCriterionOperation[] { adGroupCriterionOperation });
                                            if (results != null && results.value != null && results.value.Length > 0)
                                            {
                                                Keywordv200906 result = results.value[0].criterion as Keywordv200906;
                                                Trace.TraceInformation(
                                                    String.Format(
                                                        "New keyword with text = \"{0}\" and id = \"{1}\" was created.",
                                                        result.text, result.id));
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            Trace.TraceError(
                                                String.Format(
                                                    "Failed to create keyword at Ad group level. Exception says \"{0}\"",
                                                    ex.Message));
                                        }

                                    }
                                    catch
                                    {
                                        //do nothing
                                        Trace.TraceError("***Add Criteria Failed: Keyword" + kd.Keywords);
                                    }
                                }

                                if (GroupAdCount >= MaxAdGroups)
                                    break;
                            }
                        }
                    }

                    #endregion
                }

                #region Check api usage
                // check api usage
                ApiUsage apiUsage = new ApiUsage();
                APIQuotaValues aPIQuotaValues = apiUsage.GetApiUsage(UseSandbox);

                Trace.TraceInformation("FreeQuotaUsed:" + aPIQuotaValues.FreeQuotaUsed.ToString() + " FreeUnitsRemaining:" + aPIQuotaValues.FreeUnitsRemaining.ToString() + " SysDefinesQuotaCap:" + aPIQuotaValues.SysDefinesQuotaCap.ToString() + " TotalUsed:" + aPIQuotaValues.TotalUsed.ToString());

                #endregion

                #region Log everything created
                //AdGroup[] adGroups = adgroupService.getAllAdGroups(campaignId);

                //foreach (AdGroup adGroup in adGroups)
                //{
                //    Trace.TraceInformation("Ad group: " + adGroup.name);

                //    Ad[] ads = adService.getAllAds(new long[] { adGroup.id });

                //    foreach (Ad ad in ads)
                //    {
                //        if (ad is TextAd)
                //        {
                //            TextAd textAd = (TextAd)ad;
                //            Trace.TraceInformation("Text ad: " + textAd.headline + " Text Line1:" + textAd.description1 + " Text Line2:" + textAd.description2);
                //        }
                //    }
                //}

                #endregion

            }
            catch (Exception ex)
            {
                Trace.TraceError("Error:" + ex.Message);
                throw ex;
            }
        }