public async override Task RunAsync(AuthorizationData authorizationData) { try { AdInsightService = new ServiceClient <IAdInsightService>(authorizationData); CampaignService = new ServiceClient <ICampaignManagementService>(authorizationData); // To get started with dynamic search ads, first you'll need to add a new Campaign // with its type set to DynamicSearchAds. When you create the campaign, you'll need to // include a DynamicSearchAdsSetting that specifies the target website domain and language. var campaigns = new[] { new Campaign { CampaignType = CampaignType.DynamicSearchAds, Settings = new [] { new DynamicSearchAdsSetting { DomainName = "contoso.com", Language = "English" } }, Name = "Women's Shoes " + DateTime.UtcNow, Description = "Red shoes line.", // You must choose to set either the shared budget ID or daily amount. // You can set one or the other, but you may not set both. BudgetId = null, DailyBudget = 50, BudgetType = Microsoft.BingAds.V10.CampaignManagement.BudgetLimitType.DailyBudgetStandard, // You can set your campaign bid strategy to Enhanced CPC (EnhancedCpcBiddingScheme) // and then, at any time, set an individual ad group bid strategy to // Manual CPC (ManualCpcBiddingScheme). BiddingScheme = new EnhancedCpcBiddingScheme { }, TimeZone = "PacificTimeUSCanadaTijuana", DaylightSaving = true, // Used with CustomParameters defined in lower level entities such as ads. TrackingUrlTemplate = "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}" }, }; AddCampaignsResponse addCampaignsResponse = await AddCampaignsAsync(authorizationData.AccountId, campaigns); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); Microsoft.BingAds.V10.CampaignManagement.BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray(); OutputCampaignsWithPartialErrors(campaigns, campaignIds, campaignErrors); // Next, create a new AdGroup within the dynamic search ads campaign. var adGroups = new[] { new AdGroup { Name = "Women's Red Shoe Sale", AdDistribution = AdDistribution.Search, BiddingModel = BiddingModel.Keyword, PricingModel = PricingModel.Cpc, StartDate = null, EndDate = new Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, SearchBid = new Bid { Amount = 0.09 }, Language = "English", // For ad groups you can use either of the InheritFromParentBiddingScheme or ManualCpcBiddingScheme objects. // If you do not set this element, then InheritFromParentBiddingScheme is used by default. BiddingScheme = new ManualCpcBiddingScheme { }, } }; AddAdGroupsResponse addAdGroupsResponse = await AddAdGroupsAsync((long)campaignIds[0], adGroups); long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray(); Microsoft.BingAds.V10.CampaignManagement.BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray(); OutputAdGroupsWithPartialErrors(adGroups, adGroupIds, adGroupErrors); // You can add one or more Webpage criterion to each ad group that helps determine // whether or not to serve dynamic search ads. var adGroupCriterions = new List <AdGroupCriterion>(); var adGroupWebpagePositivePageContent = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Bid = new Bid { Amount = 0.50 } }, Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = "flowers", Operand = WebpageConditionOperand.PageContent, } }, CriterionName = "Ad Group Webpage Positive Page Content Criterion" }, }, // DestinationUrl and FinalUrls are not supported with Webpage criterion. // The Final URL is dynamically created at the ad level. DestinationUrl = null, FinalUrls = null, // You could use a tracking template which would override the campaign level // tracking template. Tracking templates defined for lower level entities // override those set for higher level entities. // In this example we are using the campaign level tracking template. TrackingUrlTemplate = null, // Set custom parameters that are specific to this webpage criterion, // and can be used by the criterion, ad group, campaign, or account level tracking template. // In this example we are using the campaign level tracking template. UrlCustomParameters = new CustomParameters { Parameters = new[] { new CustomParameter() { Key = "promoCode", Value = "PROMO1" }, new CustomParameter() { Key = "season", Value = "summer" }, } } }; adGroupCriterions.Add(adGroupWebpagePositivePageContent); // To discover the categories that you can use for Webpage criterion (positive or negative), // use the GetDomainCategories operation with the Ad Insight service. var getDomainCategoriesResponse = await GetDomainCategoriesAsync(DOMAIN_NAME, LANGUAGE); var categories = getDomainCategoriesResponse.Categories; // If any categories are available let's use one as a condition. if (categories.Count > 0) { var adGroupWebpagePositiveCategory = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Bid = new Bid { Amount = 0.50 } }, Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = categories[0].CategoryName, Operand = WebpageConditionOperand.Category, } }, CriterionName = "Ad Group Webpage Positive Category Criterion" }, } }; adGroupCriterions.Add(adGroupWebpagePositiveCategory); } // If you want to exclude certain portions of your website, you can add negative Webpage // criterion at the campaign and ad group level. var adGroupWebpageNegativeUrl = new NegativeAdGroupCriterion { AdGroupId = (long)adGroupIds[0], Criterion = new Webpage { Parameter = new WebpageParameter { // You can choose whether you want the criterion argument to match partial URLs, // page content, page title, or categories that Bing thinks applies to your website. Conditions = new[] { new WebpageCondition { Argument = DOMAIN_NAME, Operand = WebpageConditionOperand.Url, } }, // If you do not specify any name, then it will be set to a concatenated list of conditions. CriterionName = null } }, }; adGroupCriterions.Add(adGroupWebpageNegativeUrl); OutputStatusMessage("Adding Ad Group Webpage Criterion . . . \n"); OutputAdGroupCriterions(adGroupCriterions); AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await AddAdGroupCriterionsAsync(adGroupCriterions, CriterionType.Webpage); long?[] adGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray(); OutputStatusMessage("New Ad Group Criterion Ids:\n"); OutputIds(adGroupCriterionIds); BatchErrorCollection[] adGroupCriterionErrors = addAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("\nAddAdGroupCriterions Errors:\n"); OutputBatchErrorCollections(adGroupCriterionErrors); // The negative Webpage criterion at the campaign level applies to all ad groups // within the campaign; however, if you define ad group level negative Webpage criterion, // the campaign criterion is ignored for that ad group. var campaignCriterions = new List <CampaignCriterion>(); var campaignWebpageNegative = new NegativeCampaignCriterion { CampaignId = (long)campaignIds[0], Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = DOMAIN_NAME + "\\seattle", Operand = WebpageConditionOperand.Url, } }, CriterionName = "Campaign Negative Webpage Url Criterion" } } }; campaignCriterions.Add(campaignWebpageNegative); OutputStatusMessage("Adding Campaign Webpage Criterion . . . \n"); OutputCampaignCriterions(campaignCriterions); AddCampaignCriterionsResponse addCampaignCriterionsResponse = await AddCampaignCriterionsAsync(campaignCriterions, CampaignCriterionType.Webpage); long?[] campaignCriterionIds = addCampaignCriterionsResponse.CampaignCriterionIds.ToArray(); OutputStatusMessage("\nNew Campaign Criterion Ids:\n"); OutputIds(campaignCriterionIds); BatchErrorCollection[] campaignCriterionErrors = addCampaignCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("\nAddCampaignCriterions Errors:\n"); OutputBatchErrorCollections(campaignCriterionErrors); // Finally you can add a DynamicSearchAd into the ad group. The ad title and display URL // are generated automatically based on the website domain and language that you want to target. var ads = new Ad[] { new DynamicSearchAd { Text = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.", Path1 = "seattle", Path2 = "shoe sale", // You cannot set FinalUrls. The Final URL will be a dynamically selected landing page. // The final URL is distinct from the path that customers will see and click on in your ad. FinalUrls = null, // You could use a tracking template which would override the campaign level // tracking template. Tracking templates defined for lower level entities // override those set for higher level entities. // In this example we are using the campaign level tracking template. TrackingUrlTemplate = null, // Set custom parameters that are specific to this ad, // and can be used by the ad, webpage, ad group, campaign, or account level tracking template. // In this example we are using the campaign level tracking template. UrlCustomParameters = new CustomParameters { Parameters = new[] { new CustomParameter() { Key = "promoCode", Value = "PROMO1" }, new CustomParameter() { Key = "season", Value = "summer" }, } } }, }; AddAdsResponse addAdsResponse = await AddAdsAsync((long)adGroupIds[0], ads); long?[] adIds = addAdsResponse.AdIds.ToArray(); Microsoft.BingAds.V10.CampaignManagement.BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray(); OutputAdsWithPartialErrors(ads, adIds, adErrors); // Retrieve the Webpage criterion for the campaign. var getCampaignCriterionsByIdsResponse = await GetCampaignCriterionsByIdsAsync( (long)campaignIds[0], null, CampaignCriterionType.Webpage ); OutputStatusMessage("Retrieving the Campaign Webpage Criterions that we added . . . \n"); campaignCriterions = getCampaignCriterionsByIdsResponse.CampaignCriterions.ToList(); OutputCampaignCriterions(campaignCriterions); // Retrieve the Webpage criterion for the ad group and then test some update scenarios. var getAdGroupCriterionsByIdsResponse = await GetAdGroupCriterionsByIdsAsync( (long)adGroupIds[0], null, CriterionType.Webpage ); OutputStatusMessage("Retrieving the Ad Group Webpage Criterions that we added . . . \n"); adGroupCriterions = getAdGroupCriterionsByIdsResponse.AdGroupCriterions.ToList(); OutputAdGroupCriterions(adGroupCriterions); // You can update the bid for BiddableAdGroupCriterion var updateBid = new FixedBid { Bid = new Bid { Amount = 0.75 } }; // You can update the Webpage criterion name but cannot update the conditions. // To update the conditions you must delete the criterion and add a new criterion. // This update attempt will return an error. var updateCriterionAttemptFailure = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = "Books", Operand = WebpageConditionOperand.PageContent, } }, CriterionName = "Update Attempt Failure" }, }; var updateCriterionAttemptSuccess = new Webpage { Parameter = new WebpageParameter { CriterionName = "Update Attempt Success" }, }; foreach (var adGroupCriterion in adGroupCriterions) { var biddableAdGroupCriterion = adGroupCriterion as BiddableAdGroupCriterion; if (biddableAdGroupCriterion != null) { ((BiddableAdGroupCriterion)(adGroupCriterion)).CriterionBid = updateBid; ((BiddableAdGroupCriterion)(adGroupCriterion)).Criterion = updateCriterionAttemptSuccess; } else { var negativeAdGroupCriterion = adGroupCriterion as NegativeAdGroupCriterion; if (negativeAdGroupCriterion != null) { ((NegativeAdGroupCriterion)(adGroupCriterion)).Criterion = updateCriterionAttemptFailure; } } } OutputStatusMessage("Updating Ad Group Webpage Criterion . . . \n"); OutputAdGroupCriterions(adGroupCriterions); UpdateAdGroupCriterionsResponse updateAdGroupCriterionsResponse = await UpdateAdGroupCriterionsAsync(adGroupCriterions, CriterionType.Webpage); adGroupCriterionErrors = updateAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("UpdateAdGroupCriterions Errors:\n"); OutputBatchErrorCollections(adGroupCriterionErrors); // Delete the campaign, ad group, criterion, and ad that were previously added. // You should remove this operation if you want to view the added entities in the // Bing Ads web application or another tool. await DeleteCampaignsAsync(authorizationData.AccountId, new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("\nDeleted Campaign Id {0}\n", campaignIds[0])); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Campaign Management service exceptions catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.ApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V10.CampaignManagement.EditorialApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment; CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper( OutputStatusMessageDefault: this.OutputStatusMessage); CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>( authorizationData: authorizationData, environment: environment); // Create an Audience campaign with one ad group. var campaigns = new[] { new Campaign { BudgetType = BudgetLimitType.DailyBudgetStandard, // CampaignType must be set for Audience campaigns CampaignType = CampaignType.Audience, DailyBudget = 50, Description = "Red shoes line.", // Languages must be set for Audience campaigns Languages = new string[] { "All" }, Name = "Women's Shoes " + DateTime.UtcNow, TimeZone = "PacificTimeUSCanadaTijuana", }, }; OutputStatusMessage("-----\nAddCampaigns:"); AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync( accountId : authorizationData.AccountId, campaigns : campaigns, includeDynamicSearchAdsSource : false); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray(); OutputStatusMessage("CampaignIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors); // Add an ad group within the campaign. var adGroups = new[] { new AdGroup { Name = "Women's Red Shoe Sale", StartDate = null, EndDate = new Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, CpcBid = new Bid { Amount = 0.09 }, // Network cannot be set for ad groups in Audience campaigns Network = null, Settings = new[] { new TargetSetting { // Sets the "target and bid" option for CompanyName, Industry, and JobFunction. // Microsoft will only deliver ads to people who meet at least one of your criteria. // By default the "bid only" option is set for Audience, Age, and Gender. // Microsoft will deliver ads to all audiences, ages, and genders, if they meet // your company name, industry, or job function criteria. Details = new [] { new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.CompanyName, TargetAndBid = true }, new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.Industry, TargetAndBid = true }, new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.JobFunction, TargetAndBid = true }, } } }, } }; OutputStatusMessage("-----\nAddAdGroups:"); AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync( campaignId : (long)campaignIds[0], adGroups : adGroups, returnInheritedBidStrategyTypes : false); long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray(); BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray(); OutputStatusMessage("AdGroupIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors); // Whether or not the "target and bid" option has been set for a given // criterion type group, you can set bid adjustments for specific criteria. var adGroupCriterions = new List <AdGroupCriterion>(); var adGroupCompanyNameCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new BidMultiplier { Multiplier = 15 }, Criterion = new ProfileCriterion { ProfileId = 808251207, // Microsoft ProfileType = ProfileType.CompanyName }, }; adGroupCriterions.Add(adGroupCompanyNameCriterion); var adGroupIndustryCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new BidMultiplier { Multiplier = 20 }, Criterion = new ProfileCriterion { ProfileId = 807658654, // Computer & Network Security ProfileType = ProfileType.Industry }, }; adGroupCriterions.Add(adGroupIndustryCriterion); var adGroupJobFunctionCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new BidMultiplier { Multiplier = 25 }, Criterion = new ProfileCriterion { ProfileId = 807658477, // Engineering ProfileType = ProfileType.JobFunction }, }; adGroupCriterions.Add(adGroupJobFunctionCriterion); // Exclude ages twenty-five through thirty-four. var adGroupNegativeAgeCriterion = new NegativeAdGroupCriterion { AdGroupId = (long)adGroupIds[0], Criterion = new AgeCriterion { AgeRange = AgeRange.TwentyFiveToThirtyFour }, }; adGroupCriterions.Add(adGroupNegativeAgeCriterion); OutputStatusMessage("-----\nAddAdGroupCriterions:"); CampaignManagementExampleHelper.OutputArrayOfAdGroupCriterion(adGroupCriterions); AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await CampaignManagementExampleHelper.AddAdGroupCriterionsAsync( adGroupCriterions : adGroupCriterions, criterionType : AdGroupCriterionType.Targets); long?[] adGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray(); OutputStatusMessage("AdGroupCriterionIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupCriterionIds); BatchErrorCollection[] adGroupCriterionErrors = addAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("NestedPartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(adGroupCriterionErrors); // Delete the campaign and everything it contains e.g., ad groups and ads. OutputStatusMessage("-----\nDeleteCampaigns:"); await CampaignManagementExampleHelper.DeleteCampaignsAsync( accountId : authorizationData.AccountId, campaignIds : new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0])); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Campaign Management service exceptions catch (FaultException <AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <ApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <EditorialApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment; AdInsightExampleHelper AdInsightExampleHelper = new AdInsightExampleHelper( OutputStatusMessageDefault: this.OutputStatusMessage); AdInsightExampleHelper.AdInsightService = new ServiceClient <IAdInsightService>( authorizationData: authorizationData, environment: environment); CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper( OutputStatusMessageDefault: this.OutputStatusMessage); CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>( authorizationData: authorizationData, environment: environment); // To get started with dynamic search ads, first you'll need to add a new Campaign // with its type set to DynamicSearchAds. When you create the campaign, you'll need to // include a DynamicSearchAdsSetting that specifies the target website domain and language. var campaigns = new[] { new Campaign { BudgetType = Microsoft.BingAds.V13.CampaignManagement.BudgetLimitType.DailyBudgetStandard, DailyBudget = 50, CampaignType = CampaignType.DynamicSearchAds, Languages = new string[] { "All" }, Name = "Women's Shoes " + DateTime.UtcNow, TimeZone = "PacificTimeUSCanadaTijuana", Settings = new [] { new DynamicSearchAdsSetting { DomainName = "contoso.com", Language = "English" } }, }, }; OutputStatusMessage("-----\nAddCampaigns:"); AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync( accountId : authorizationData.AccountId, campaigns : campaigns); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); Microsoft.BingAds.V13.CampaignManagement.BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray(); OutputStatusMessage("CampaignIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors); // Create a new ad group within the dynamic search ads campaign. var adGroups = new[] { new AdGroup { Name = "Women's Red Shoe Sale", StartDate = null, EndDate = new Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, CpcBid = new Bid { Amount = 0.09 }, } }; OutputStatusMessage("-----\nAddAdGroups:"); AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync( campaignId : (long)campaignIds[0], adGroups : adGroups, returnInheritedBidStrategyTypes : false); long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray(); Microsoft.BingAds.V13.CampaignManagement.BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray(); OutputStatusMessage("AdGroupIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors); // You can add one or more Webpage criteria to each ad group that helps determine // whether or not to serve dynamic search ads. var adGroupCriterions = new List <AdGroupCriterion>(); var adGroupWebpagePositivePageContent = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Amount = 0.50 }, Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = "flowers", Operand = WebpageConditionOperand.PageContent, } }, CriterionName = "Ad Group Webpage Positive Page Content Criterion" }, }, }; adGroupCriterions.Add(adGroupWebpagePositivePageContent); // To discover the categories that you can use for Webpage criteria (positive or negative), // use the GetDomainCategories operation with the Ad Insight service. OutputStatusMessage("-----\nGetDomainCategories:"); var getDomainCategoriesResponse = await AdInsightExampleHelper.GetDomainCategoriesAsync( categoryName : null, domainName : DOMAIN_NAME, language : LANGUAGE); var categories = getDomainCategoriesResponse.Categories; OutputStatusMessage("Categories:"); AdInsightExampleHelper.OutputArrayOfDomainCategory(categories); // If any categories are available let's use one as a condition. if (categories.Count > 0) { var adGroupWebpagePositiveCategory = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Amount = 0.50 }, Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = categories[0].CategoryName, Operand = WebpageConditionOperand.Category, } }, CriterionName = "Ad Group Webpage Positive Category Criterion" }, } }; adGroupCriterions.Add(adGroupWebpagePositiveCategory); } // If you want to exclude certain portions of your website, you can add negative Webpage // criterion at the campaign and ad group level. var adGroupWebpageNegativeUrl = new NegativeAdGroupCriterion { AdGroupId = (long)adGroupIds[0], Criterion = new Webpage { Parameter = new WebpageParameter { // You can choose whether you want the criterion argument to match partial URLs, // page content, page title, or categories that Bing thinks applies to your website. Conditions = new[] { new WebpageCondition { Argument = DOMAIN_NAME, Operand = WebpageConditionOperand.Url, } }, // If you do not specify any name, then it will be set to a concatenated list of conditions. CriterionName = null } }, }; adGroupCriterions.Add(adGroupWebpageNegativeUrl); OutputStatusMessage("-----\nAddAdGroupCriterions:"); CampaignManagementExampleHelper.OutputArrayOfAdGroupCriterion(adGroupCriterions); AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await CampaignManagementExampleHelper.AddAdGroupCriterionsAsync( adGroupCriterions : adGroupCriterions, criterionType : AdGroupCriterionType.Webpage); long?[] adGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray(); OutputStatusMessage("AdGroupCriterionIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupCriterionIds); BatchErrorCollection[] adGroupCriterionErrors = addAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("NestedPartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(adGroupCriterionErrors); // The negative Webpage criterion at the campaign level applies to all ad groups // within the campaign; however, if you define ad group level negative Webpage criterion, // the campaign criterion is ignored for that ad group. var campaignCriterions = new List <CampaignCriterion>(); var campaignWebpageNegative = new NegativeCampaignCriterion { CampaignId = (long)campaignIds[0], Criterion = new Webpage { Parameter = new WebpageParameter { Conditions = new[] { new WebpageCondition { Argument = DOMAIN_NAME + "\\seattle", Operand = WebpageConditionOperand.Url, } }, CriterionName = "Campaign Negative Webpage Url Criterion" } } }; campaignCriterions.Add(campaignWebpageNegative); OutputStatusMessage("-----\nAddCampaignCriterions:"); CampaignManagementExampleHelper.OutputArrayOfCampaignCriterion(campaignCriterions); AddCampaignCriterionsResponse addCampaignCriterionsResponse = await CampaignManagementExampleHelper.AddCampaignCriterionsAsync( campaignCriterions : campaignCriterions, criterionType : CampaignCriterionType.Webpage); long?[] campaignCriterionIds = addCampaignCriterionsResponse.CampaignCriterionIds.ToArray(); OutputStatusMessage("CampaignCriterionIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(campaignCriterionIds); BatchErrorCollection[] campaignCriterionErrors = addCampaignCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("NestedPartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(campaignCriterionErrors); // Finally you must add at least one DynamicSearchAd into the ad group. The ad title and display URL // are generated automatically based on the website domain and language that you want to target. var ads = new Ad[] { new DynamicSearchAd { Text = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.", Path1 = "seattle", Path2 = "shoe sale", // You cannot set FinalUrls for dynamic search ads. // The Final URL will be a dynamically selected landing page. // The final URL is distinct from the path that customers will see and click on in your ad. FinalUrls = null, }, }; OutputStatusMessage("-----\nAddAds:"); AddAdsResponse addAdsResponse = await CampaignManagementExampleHelper.AddAdsAsync( adGroupId : (long)adGroupIds[0], ads : ads); long?[] adIds = addAdsResponse.AdIds.ToArray(); Microsoft.BingAds.V13.CampaignManagement.BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray(); OutputStatusMessage("AdIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(adErrors); // Delete the campaign and everything it contains e.g., ad groups and ads. OutputStatusMessage("-----\nDeleteCampaigns:"); await CampaignManagementExampleHelper.DeleteCampaignsAsync( accountId : authorizationData.AccountId, campaignIds : new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0])); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Campaign Management service exceptions catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment; CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper( OutputStatusMessageDefault: this.OutputStatusMessage); CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>( authorizationData: authorizationData, environment: environment); // Before you can track conversions or target audiences using a remarketing list // you need to create a UET tag, and then add the UET tag tracking code to every page of your website. // For more information, please see Universal Event Tracking at https://go.microsoft.com/fwlink/?linkid=829965. // First you should call the GetUetTagsByIds operation to check whether a tag has already been created. // You can leave the TagIds element null or empty to request all UET tags available for the customer. OutputStatusMessage("-----\nGetUetTagsByIds:"); var uetTags = (await CampaignManagementExampleHelper.GetUetTagsByIdsAsync( tagIds: null))?.UetTags; // If you do not already have a UET tag that can be used, or if you need another UET tag, // call the AddUetTags service operation to create a new UET tag. If the call is successful, // the tracking script that you should add to your website is included in a corresponding // UetTag within the response message. if (uetTags == null || uetTags.Count < 1) { var uetTag = new UetTag { Description = "My First Uet Tag", Name = "New Uet Tag", }; OutputStatusMessage("-----\nAddUetTags:"); uetTags = (await CampaignManagementExampleHelper.AddUetTagsAsync( uetTags: new[] { uetTag })).UetTags; } if (uetTags == null || uetTags.Count < 1) { OutputStatusMessage( string.Format("You do not have any UET tags registered for CustomerId {0}.", authorizationData.CustomerId) ); return; } OutputStatusMessage("List of all UET Tags:"); CampaignManagementExampleHelper.OutputArrayOfUetTag(uetTags); // After you retreive the tracking script from the AddUetTags or GetUetTagsByIds operation, // the next step is to add the UET tag tracking code to your website. // We will use the same UET tag for the remainder of this example. var tagId = uetTags[0].Id; // Add remarketing lists that depend on the UET Tag Id retreived above. var addAudiences = new[] { new RemarketingList { Description = "New list with CustomEventsRule", MembershipDuration = 30, Name = "Remarketing List with CustomEventsRule " + DateTime.UtcNow, ParentId = authorizationData.AccountId, // The rule definition is translated to the following logical expression: // (Category Equals video) and (Action Equals play) and (Label Equals trailer) // and (Value Equals 5) Rule = new CustomEventsRule { // The type of user interaction you want to track. Action = "play", ActionOperator = StringOperator.Equals, // The category of event you want to track. Category = "video", CategoryOperator = StringOperator.Equals, // The name of the element that caused the action. Label = "trailer", LabelOperator = StringOperator.Equals, // A numerical value associated with that event. // Could be length of the video played etc. Value = 5.00m, ValueOperator = NumberOperator.Equals, }, Scope = EntityScope.Account, TagId = tagId }, new RemarketingList { Description = "New list with PageVisitorsRule", MembershipDuration = 30, Name = "Remarketing List with PageVisitorsRule " + DateTime.UtcNow, ParentId = authorizationData.AccountId, // The rule definition is translated to the following logical expression: // ((Url Contains X) and (ReferrerUrl DoesNotContain Z)) or ((Url DoesNotBeginWith Y)) // or ((ReferrerUrl Equals Z)) Rule = new PageVisitorsRule { RuleItemGroups = new [] { new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.Contains, Value = "X" }, new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.DoesNotContain, Value = "Z" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.DoesNotBeginWith, Value = "Y" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.Equals, Value = "Z" }, } }, }, }, Scope = EntityScope.Account, TagId = tagId }, new RemarketingList { Description = "New list with PageVisitorsWhoDidNotVisitAnotherPageRule", MembershipDuration = 30, Name = "Remarketing List with PageVisitorsWhoDidNotVisitAnotherPageRule " + DateTime.UtcNow, ParentId = authorizationData.AccountId, // The rule definition is translated to the following logical expression: // (((Url Contains X) and (ReferrerUrl DoesNotContain Z)) or ((Url DoesNotBeginWith Y)) // or ((ReferrerUrl Equals Z))) // and not (((Url BeginsWith A) and (ReferrerUrl BeginsWith B)) or ((Url Contains C))) Rule = new PageVisitorsWhoDidNotVisitAnotherPageRule { ExcludeRuleItemGroups = new [] { new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.BeginsWith, Value = "A" }, new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.BeginsWith, Value = "B" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.Contains, Value = "C" }, } }, }, IncludeRuleItemGroups = new [] { new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.Contains, Value = "X" }, new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.DoesNotContain, Value = "Z" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.DoesNotBeginWith, Value = "Y" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.Equals, Value = "Z" }, } }, }, }, Scope = EntityScope.Account, TagId = tagId }, new RemarketingList { Description = "New list with PageVisitorsWhoVisitedAnotherPageRule", MembershipDuration = 30, Name = "Remarketing List with PageVisitorsWhoVisitedAnotherPageRule " + DateTime.UtcNow, ParentId = authorizationData.AccountId, // The rule definition is translated to the following logical expression: // (((Url Contains X) and (ReferrerUrl NotEquals Z)) or ((Url DoesNotBeginWith Y)) or // ((ReferrerUrl Equals Z))) // and (((Url BeginsWith A) and (ReferrerUrl BeginsWith B)) or ((Url Contains C))) Rule = new PageVisitorsWhoVisitedAnotherPageRule { AnotherRuleItemGroups = new [] { new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.BeginsWith, Value = "A" }, new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.BeginsWith, Value = "B" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.Contains, Value = "C" }, } }, }, RuleItemGroups = new [] { new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.Contains, Value = "X" }, new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.DoesNotContain, Value = "Z" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "Url", Operator = StringOperator.DoesNotBeginWith, Value = "Y" }, } }, new RuleItemGroup { Items = new [] { new StringRuleItem { Operand = "ReferrerUrl", Operator = StringOperator.Equals, Value = "Z" }, } }, }, }, Scope = EntityScope.Account, TagId = tagId }, }; // RemarketingList extends the Audience base class. // We manage remarketing lists with Audience operations. OutputStatusMessage("-----\nAddAudiences:"); var addAudiencesResponse = await CampaignManagementExampleHelper.AddAudiencesAsync( audiences : addAudiences); long?[] audienceIds = addAudiencesResponse.AudienceIds.ToArray(); BatchError[] audienceErrors = addAudiencesResponse.PartialErrors.ToArray(); OutputStatusMessage("AudienceIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(audienceIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(audienceErrors); // Add an ad group in a campaign. The ad group will later be associated with remarketing lists. var campaigns = new[] { new Campaign { BudgetType = BudgetLimitType.DailyBudgetStandard, DailyBudget = 50, Description = "Red shoes line.", Languages = new string[] { "All" }, Name = "Women's Shoes " + DateTime.UtcNow, TimeZone = "PacificTimeUSCanadaTijuana", }, }; OutputStatusMessage("-----\nAddCampaigns:"); AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync( accountId : authorizationData.AccountId, campaigns : campaigns, includeDynamicSearchAdsSource : false); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray(); OutputStatusMessage("CampaignIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors); var adGroups = new[] { new AdGroup { Name = "Women's Red Shoe Sale", StartDate = null, EndDate = new Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, CpcBid = new Bid { Amount = 0.09 }, // Applicable for all remarketing lists that are associated with this ad group. TargetAndBid indicates // that you want to show ads only to people included in the remarketing list, with the option to change // the bid amount. Ads in this ad group will only show to people included in the remarketing list. Settings = new[] { new TargetSetting { Details = new [] { new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.Audience, TargetAndBid = true } } } }, } }; OutputStatusMessage("-----\nAddAdGroups:"); AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync( campaignId : (long)campaignIds[0], adGroups : adGroups, returnInheritedBidStrategyTypes : false); long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray(); BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray(); OutputStatusMessage("AdGroupIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors); // Associate all of the remarketing lists created above with the new ad group. var adGroupRemarketingListAssociations = new List <AdGroupCriterion>(); foreach (var audienceId in audienceIds) { if (audienceId != null) { var biddableAdGroupCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], Criterion = new AudienceCriterion { AudienceId = audienceId, AudienceType = AudienceType.RemarketingList, }, CriterionBid = new BidMultiplier { Multiplier = 20.00, }, Status = AdGroupCriterionStatus.Active, }; adGroupRemarketingListAssociations.Add(biddableAdGroupCriterion); } } OutputStatusMessage("-----\nAddAdGroupCriterions:"); CampaignManagementExampleHelper.OutputArrayOfAdGroupCriterion(adGroupRemarketingListAssociations); AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await CampaignManagementExampleHelper.AddAdGroupCriterionsAsync( adGroupCriterions : adGroupRemarketingListAssociations, criterionType : AdGroupCriterionType.Audience); long?[] nullableAdGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray(); OutputStatusMessage("AdGroupCriterionIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(nullableAdGroupCriterionIds); BatchErrorCollection[] adGroupCriterionErrors = addAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("NestedPartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(adGroupCriterionErrors); // Delete the campaign and everything it contains e.g., ad groups and ads. OutputStatusMessage("-----\nDeleteCampaigns:"); await CampaignManagementExampleHelper.DeleteCampaignsAsync( accountId : authorizationData.AccountId, campaignIds : new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0])); // Delete the remarketing lists. OutputStatusMessage("-----\nDeleteAudiences:"); await CampaignManagementExampleHelper.DeleteAudiencesAsync( audienceIds : new[] { (long)audienceIds[0] }); OutputStatusMessage(string.Format("Deleted Audience Id {0}", audienceIds[0])); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Campaign Management service exceptions catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.ApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.EditorialApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage); CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>(authorizationData); // Setup an Audience campaign with one ad group and a responsive ad. var campaigns = new[] { new Campaign { // CampaignType must be set for Audience campaigns CampaignType = CampaignType.Audience, // Languages must be set for Audience campaigns Languages = new string[] { "All" }, Name = "Women's Shoes " + DateTime.UtcNow, Description = "Red shoes line.", DailyBudget = 50, BudgetType = BudgetLimitType.DailyBudgetStandard, TimeZone = "PacificTimeUSCanadaTijuana", }, }; var adGroups = new[] { new AdGroup { Name = "Women's Red Shoe Sale", StartDate = null, EndDate = new Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, CpcBid = new Bid { Amount = 0.09 }, // Language cannot be set for ad groups in Audience campaigns Language = null, // Network cannot be set for ad groups in Audience campaigns Network = null, Settings = new[] { new TargetSetting { // By including the corresponding TargetSettingDetail, // this example sets the "target and bid" option for // CompanyName, Industry, and JobFunction. We will only deliver ads to // people who meet at least one of your criteria. // By default the "bid only" option is set for Audience, Age, and Gender. // We will deliver ads to all audiences, ages, and genders, if they meet // your company name, industry, or job function criteria. Details = new [] { new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.CompanyName, TargetAndBid = true }, new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.Industry, TargetAndBid = true }, new TargetSettingDetail { CriterionTypeGroup = CriterionTypeGroup.JobFunction, TargetAndBid = true }, } } }, } }; var ads = new Ad[] { new ResponsiveAd { // Not applicable for responsive ads AdFormatPreference = null, BusinessName = "Contoso", CallToAction = CallToAction.AddToCart, // Not applicable for responsive ads DevicePreference = null, EditorialStatus = null, FinalAppUrls = null, FinalMobileUrls = new[] { "http://mobile.contoso.com/womenshoesale" }, FinalUrls = new[] { "http://www.contoso.com/womenshoesale" }, ForwardCompatibilityMap = null, Headline = "Fast & Easy Setup", Id = null, LandscapeImageMediaId = LandscapeImageMediaId, LandscapeLogoMediaId = LandscapeLogoMediaId, LongHeadline = "Find New Customers & Increase Sales!", SquareImageMediaId = SquareImageMediaId, SquareLogoMediaId = SquareLogoMediaId, Status = null, Text = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.", TrackingUrlTemplate = null, Type = null, UrlCustomParameters = null, } }; // Add the campaign, ad group, and ad AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(authorizationData.AccountId, campaigns); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray(); CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds); CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors); AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync( (long)campaignIds[0], adGroups, false); long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray(); BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray(); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds); CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors); AddAdsResponse addAdsResponse = await CampaignManagementExampleHelper.AddAdsAsync((long)adGroupIds[0], ads); long?[] adIds = addAdsResponse.AdIds.ToArray(); BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray(); CampaignManagementExampleHelper.OutputArrayOfLong(adIds); CampaignManagementExampleHelper.OutputArrayOfBatchError(adErrors); // Whether or not the "target and bid" option has been set for a given // criterion type group, you can set bid adjustments for specific criteria. var adGroupCriterions = new List <AdGroupCriterion>(); var adGroupCompanyNameCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Amount = 0.50 }, Criterion = new ProfileCriterion { ProfileId = 808251207, // Microsoft ProfileType = ProfileType.CompanyName }, }; adGroupCriterions.Add(adGroupCompanyNameCriterion); var adGroupIndustryCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Amount = 0.50 }, Criterion = new ProfileCriterion { ProfileId = 807658654, // Computer & Network Security ProfileType = ProfileType.Industry }, }; adGroupCriterions.Add(adGroupIndustryCriterion); var adGroupJobFunctionCriterion = new BiddableAdGroupCriterion { AdGroupId = (long)adGroupIds[0], CriterionBid = new FixedBid { Amount = 0.50 }, Criterion = new ProfileCriterion { ProfileId = 807658477, // Engineering ProfileType = ProfileType.JobFunction }, }; adGroupCriterions.Add(adGroupJobFunctionCriterion); // Exclude ages twenty-five through thirty-four. var adGroupNegativeAgeCriterion = new NegativeAdGroupCriterion { AdGroupId = (long)adGroupIds[0], Criterion = new AgeCriterion { AgeRange = AgeRange.TwentyFiveToThirtyFour }, }; adGroupCriterions.Add(adGroupNegativeAgeCriterion); OutputStatusMessage("Adding Ad Group Criteria . . . \n"); CampaignManagementExampleHelper.OutputArrayOfAdGroupCriterion(adGroupCriterions); AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await CampaignManagementExampleHelper.AddAdGroupCriterionsAsync( adGroupCriterions, AdGroupCriterionType.Targets); long?[] adGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray(); OutputStatusMessage("New Ad Group Criterion Ids:\n"); CampaignManagementExampleHelper.OutputArrayOfLong(adGroupCriterionIds); BatchErrorCollection[] adGroupCriterionErrors = addAdGroupCriterionsResponse.NestedPartialErrors.ToArray(); OutputStatusMessage("\nAddAdGroupCriterions Errors:\n"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(adGroupCriterionErrors); // Delete the campaign, ad group, criteria, and ad that were previously added. // You should remove this line if you want to view the added entities in the // Bing Ads web application or another tool. await CampaignManagementExampleHelper.DeleteCampaignsAsync(authorizationData.AccountId, new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("\nDeleted Campaign Id {0}\n", campaignIds[0])); } // Catch authentication exceptions catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Campaign Management service exceptions catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.ApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.CampaignManagement.EditorialApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }