public async override Task RunAsync(AuthorizationData authorizationData) { try { CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage); CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient <ICampaignManagementService>(authorizationData); // Add a campaign that will later be associated with ad extensions. var campaigns = new[] { new Campaign { 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 = BudgetLimitType.DailyBudgetStandard, BiddingScheme = new EnhancedCpcBiddingScheme(), TimeZone = "PacificTimeUSCanadaTijuana", // Used with FinalUrls shown in the sitelinks that we will add below. TrackingUrlTemplate = "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}" } }; AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(authorizationData.AccountId, campaigns); long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray(); CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds); CampaignManagementExampleHelper.OutputArrayOfBatchError(addCampaignsResponse?.PartialErrors); // Specify the extensions. var adExtensions = new AdExtension[] { //new AppAdExtension //{ // AppPlatform = "Windows", // AppStoreId = "AppStoreIdGoesHere", // DestinationUrl = "DestinationUrlGoesHere", // DisplayText = "Contoso", //}, new CallAdExtension { CountryCode = "US", PhoneNumber = "2065550100", IsCallOnly = false, Scheduling = new Schedule { // For this example assume the call center is open Monday - Friday from 9am - 9pm // in the account's time zone. UseSearcherTimeZone = false, DayTimeRanges = new[] { new DayTime { Day = Day.Monday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Tuesday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Wednesday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Thursday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Friday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, }, StartDate = null, EndDate = new Microsoft.BingAds.V11.CampaignManagement.Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, } }, new CalloutAdExtension { Text = "Callout Text" }, new LocationAdExtension { PhoneNumber = "206-555-0100", CompanyName = "Contoso Shoes", Address = new Microsoft.BingAds.V11.CampaignManagement.Address { StreetAddress = "1234 Washington Place", StreetAddress2 = "Suite 1210", CityName = "Woodinville", ProvinceName = "WA", CountryCode = "US", PostalCode = "98608" }, Scheduling = new Schedule { // For this example assume you want to drive traffic every Saturday morning // in the search user's time zone. UseSearcherTimeZone = true, DayTimeRanges = new[] { new DayTime { Day = Day.Saturday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 12, EndMinute = Minute.Zero, }, }, StartDate = null, EndDate = new Microsoft.BingAds.V11.CampaignManagement.Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, } }, new PriceAdExtension { Language = "English", TableRows = new PriceTableRow[] { new PriceTableRow { CurrencyCode = "USD", Description = "Come to the event", FinalUrls = new string[] { "https://contoso.com" }, Header = "New Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, new PriceTableRow { CurrencyCode = "USD", Description = "Come to the next event", FinalUrls = new string[] { "https://contoso.com" }, Header = "Next Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, new PriceTableRow { CurrencyCode = "USD", Description = "Come to the final event", FinalUrls = new string[] { "https://contoso.com" }, Header = "Final Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, }, PriceExtensionType = PriceExtensionType.Events, TrackingUrlTemplate = "http://tracker.com?url={lpurl}&matchtype={matchtype}", UrlCustomParameters = new CustomParameters { // Each custom parameter is delimited by a semicolon (;) in the Bulk file Parameters = new[] { new CustomParameter() { Key = "promoCode", Value = "PROMO1" }, new CustomParameter() { Key = "season", Value = "summer" }, } }, }, new ReviewAdExtension { IsExact = true, Source = "Review Source Name", Text = "Review Text", Url = "http://review.contoso.com" // The Url of the third-party review. This is not your business Url. }, new StructuredSnippetAdExtension { Header = "Brands", Values = new [] { "Windows", "Xbox", "Skype" } } }; // Get adExtensions = adExtensions.Concat(GetSampleSitelink2AdExtensions()).ToArray(); // Add all extensions to the account's ad extension library var addAdExtensionsResponse = (await CampaignManagementExampleHelper.AddAdExtensionsAsync( authorizationData.AccountId, adExtensions )); var adExtensionIdentities = addAdExtensionsResponse?.AdExtensionIdentities; CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(addAdExtensionsResponse?.NestedPartialErrors); OutputStatusMessage("Added ad extensions.\n"); // DeleteAdExtensionsAssociations, SetAdExtensionsAssociations, and GetAdExtensionsEditorialReasons // operations each require a list of type AdExtensionIdToEntityIdAssociation. var adExtensionIdToEntityIdAssociations = new List <AdExtensionIdToEntityIdAssociation>(); // GetAdExtensionsByIds requires a list of type long. var adExtensionIds = new List <long>(); // Loop through the list of extension IDs and build any required data structures // for subsequent operations. foreach (var adExtensionIdentity in adExtensionIdentities) { if (adExtensionIdentity != null) { adExtensionIdToEntityIdAssociations.Add(new AdExtensionIdToEntityIdAssociation { AdExtensionId = adExtensionIdentity.Id, EntityId = (long)campaignIds[0] }); adExtensionIds.Add(adExtensionIdentity.Id); } } // Associate the specified ad extensions with the respective campaigns or ad groups. await CampaignManagementExampleHelper.SetAdExtensionsAssociationsAsync( authorizationData.AccountId, adExtensionIdToEntityIdAssociations, AssociationType.Campaign ); OutputStatusMessage("Set ad extension associations.\n"); // Get editorial rejection reasons for the respective ad extension and entity associations. var getAdExtensionsEditorialReasonsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsEditorialReasonsAsync( authorizationData.AccountId, adExtensionIdToEntityIdAssociations, AssociationType.Campaign )); var adExtensionEditorialReasonCollection = (AdExtensionEditorialReasonCollection[])getAdExtensionsEditorialReasonsResponse?.EditorialReasons; CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsEditorialReasonsResponse?.PartialErrors); AdExtensionsTypeFilter adExtensionsTypeFilter = AdExtensionsTypeFilter.AppAdExtension | AdExtensionsTypeFilter.CallAdExtension | AdExtensionsTypeFilter.CalloutAdExtension | AdExtensionsTypeFilter.ImageAdExtension | AdExtensionsTypeFilter.LocationAdExtension | AdExtensionsTypeFilter.Sitelink2AdExtension | // You should remove this flag if your customer is not enabled for price ad extensions. AdExtensionsTypeFilter.PriceAdExtension | AdExtensionsTypeFilter.ReviewAdExtension | AdExtensionsTypeFilter.StructuredSnippetAdExtension; // Get all ad extensions added above. var getAdExtensionsByIdsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync( authorizationData.AccountId, adExtensionIds, adExtensionsTypeFilter )); adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray(); CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsByIdsResponse?.PartialErrors); OutputStatusMessage("List of ad extensions that were added above:\n"); CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions); // Get only the location extensions and remove scheduling. adExtensionsTypeFilter = AdExtensionsTypeFilter.LocationAdExtension; getAdExtensionsByIdsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync( authorizationData.AccountId, adExtensionIds, adExtensionsTypeFilter )); adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray(); // In this example partial errors will be returned for indices where the ad extensions // are not location ad extensions because we only requested AdExtensionsTypeFilter.LocationAdExtension. // This is an example, and ideally you would only send the required ad extension IDs. CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsByIdsResponse?.PartialErrors); var updateExtensions = new List <AdExtension>(); var updateExtensionIds = new List <long>(); foreach (var extension in adExtensions) { // GetAdExtensionsByIds will return a nil element if the request filters / conditions were not met. if (extension != null && extension.Id != null) { // Remove read-only elements that would otherwise cause the update operation to fail. var updateExtension = SetReadOnlyAdExtensionElementsToNull(extension); // If you set the Scheduling element null, any existing scheduling set for the ad extension will remain unchanged. // If you set this to any non-null Schedule object, you are effectively replacing existing scheduling // for the ad extension. In this example, we will remove any existing scheduling by setting this element // to an empty Schedule object. updateExtension.Scheduling = new Schedule { }; updateExtensions.Add(updateExtension); updateExtensionIds.Add((long)updateExtension.Id); } } OutputStatusMessage("Removing scheduling from the location ad extensions..\n"); await CampaignManagementExampleHelper.UpdateAdExtensionsAsync(authorizationData.AccountId, updateExtensions); // Get only the location extensions to output the result. getAdExtensionsByIdsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync( authorizationData.AccountId, updateExtensionIds, adExtensionsTypeFilter )); adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray(); CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsByIdsResponse?.PartialErrors); OutputStatusMessage("List of ad extensions that were updated above:\n"); CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions); // Delete the ad extension associations, ad extensions, and campaign, that were previously added. // At this point the ad extensions are still available in the account's ad extensions library. await CampaignManagementExampleHelper.DeleteAdExtensionsAssociationsAsync( authorizationData.AccountId, adExtensionIdToEntityIdAssociations, AssociationType.Campaign ); OutputStatusMessage("Deleted ad extension associations.\n"); // Delete the ad extensions from the account’s ad extension library. await CampaignManagementExampleHelper.DeleteAdExtensionsAsync( authorizationData.AccountId, adExtensionIds ); OutputStatusMessage("Deleted ad extensions.\n"); await CampaignManagementExampleHelper.DeleteCampaignsAsync(authorizationData.AccountId, new[] { (long)campaignIds[0] }); OutputStatusMessage(string.Format("Deleted Campaign Id {0}\n", (long)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.V11.CampaignManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V11.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.V11.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 Customer Management service exceptions catch (FaultException <Microsoft.BingAds.V11.CustomerManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V11.CustomerManagement.ApiFault> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.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); // Add a campaign to associate with ad extensions. 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); // Create media for the image ad extension that we'll add later. var imageAdExtensionMedia = GetImageMedia( "Image15x10", MediaFilePath + ImageAdExtensionMediaFileName, System.Drawing.Imaging.ImageFormat.Png); var media = new Media[] { imageAdExtensionMedia }; // Add the media to the account's library. OutputStatusMessage("-----\nAddMedia:"); AddMediaResponse addMediaResponse = await CampaignManagementExampleHelper.AddMediaAsync( accountId : authorizationData.AccountId, media : media); long[] mediaIds = addMediaResponse.MediaIds.ToArray(); OutputStatusMessage("MediaIds:"); CampaignManagementExampleHelper.OutputArrayOfLong(mediaIds); // Add the extensions to the account's library. var adExtensions = new AdExtension[] { new ActionAdExtension { ActionType = ActionAdExtensionActionType.ActNow, FinalUrls = new string[] { "http://www.contoso.com/womenshoesale" }, Language = "English", Status = AdExtensionStatus.Active, }, //new AppAdExtension //{ // AppPlatform = "Windows", // AppStoreId = "AppStoreIdGoesHere", // DestinationUrl = "DestinationUrlGoesHere", // DisplayText = "Contoso", //}, new CallAdExtension { CountryCode = "US", PhoneNumber = "2065550100", IsCallOnly = false, // Include the call extension Monday - Friday from 9am - 9pm // in the account's time zone. Scheduling = new Schedule { UseSearcherTimeZone = false, DayTimeRanges = new[] { new DayTime { Day = Day.Monday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Tuesday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Wednesday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Thursday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, new DayTime { Day = Day.Friday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 21, EndMinute = Minute.Zero, }, }, StartDate = null, EndDate = new Microsoft.BingAds.V12.CampaignManagement.Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, } }, new CalloutAdExtension { Text = "Callout Text" }, new ImageAdExtension { AlternativeText = "Image Extension Alt Text", ImageMediaIds = mediaIds }, new LocationAdExtension { PhoneNumber = "206-555-0100", CompanyName = "Contoso Shoes", Address = new Microsoft.BingAds.V12.CampaignManagement.Address { StreetAddress = "1234 Washington Place", StreetAddress2 = "Suite 1210", CityName = "Woodinville", ProvinceName = "WA", CountryCode = "US", PostalCode = "98608" }, // Include the location extension every Saturday morning // in the search user's time zone. Scheduling = new Schedule { UseSearcherTimeZone = true, DayTimeRanges = new[] { new DayTime { Day = Day.Saturday, StartHour = 9, StartMinute = Minute.Zero, EndHour = 12, EndMinute = Minute.Zero, }, }, StartDate = null, EndDate = new Microsoft.BingAds.V12.CampaignManagement.Date { Month = 12, Day = 31, Year = DateTime.UtcNow.Year + 1 }, } }, new PriceAdExtension { Language = "English", PriceExtensionType = PriceExtensionType.Events, TableRows = new PriceTableRow[] { new PriceTableRow { CurrencyCode = "USD", Description = "Come to the event", FinalUrls = new string[] { "https://contoso.com" }, Header = "New Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, new PriceTableRow { CurrencyCode = "USD", Description = "Come to the next event", FinalUrls = new string[] { "https://contoso.com" }, Header = "Next Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, new PriceTableRow { CurrencyCode = "USD", Description = "Come to the final event", FinalUrls = new string[] { "https://contoso.com" }, Header = "Final Event", Price = 9.99, PriceQualifier = PriceQualifier.From, PriceUnit = PriceUnit.PerDay, }, }, }, new ReviewAdExtension { IsExact = true, Source = "Review Source Name", Text = "Review Text", // The Url of the third-party review. This is not your business Url. Url = "http://review.contoso.com" }, new SitelinkAdExtension { Description1 = "Simple & Transparent.", Description2 = "No Upfront Cost.", DisplayText = "Women's Shoe Sale", FinalUrls = new[] { "http://www.contoso.com/womenshoesale" }, }, new StructuredSnippetAdExtension { Header = "Brands", Values = new [] { "Windows", "Xbox", "Skype" } } }; OutputStatusMessage("-----\nAddAdExtensions:"); var addAdExtensionsResponse = await CampaignManagementExampleHelper.AddAdExtensionsAsync( accountId : authorizationData.AccountId, adExtensions : adExtensions); OutputStatusMessage("AdExtensionIdentities:"); var adExtensionIdentities = addAdExtensionsResponse?.AdExtensionIdentities; OutputStatusMessage("NestedPartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(addAdExtensionsResponse?.NestedPartialErrors); // DeleteAdExtensionsAssociations, SetAdExtensionsAssociations, and GetAdExtensionsEditorialReasons // operations each require a list of type AdExtensionIdToEntityIdAssociation. var adExtensionIdToEntityIdAssociations = new List <AdExtensionIdToEntityIdAssociation>(); // GetAdExtensionsByIds requires a list of type long. var adExtensionIds = new List <long>(); // Loop through the list of extension IDs and build any required data structures // for subsequent operations. foreach (var adExtensionIdentity in adExtensionIdentities) { if (adExtensionIdentity != null) { adExtensionIdToEntityIdAssociations.Add(new AdExtensionIdToEntityIdAssociation { AdExtensionId = adExtensionIdentity.Id, EntityId = (long)campaignIds[0] }); adExtensionIds.Add(adExtensionIdentity.Id); } } // Associate the ad extensions with the campaign. OutputStatusMessage("-----\nSetAdExtensionsAssociations:"); var setAdExtensionsAssociationsResponse = await CampaignManagementExampleHelper.SetAdExtensionsAssociationsAsync( accountId : authorizationData.AccountId, adExtensionIdToEntityIdAssociations : adExtensionIdToEntityIdAssociations, associationType : AssociationType.Campaign); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(setAdExtensionsAssociationsResponse?.PartialErrors); // Get editorial rejection reasons for the ad extension and entity associations. OutputStatusMessage("-----\nGetAdExtensionsEditorialReasons:"); var getAdExtensionsEditorialReasonsResponse = await CampaignManagementExampleHelper.GetAdExtensionsEditorialReasonsAsync( accountId : authorizationData.AccountId, adExtensionIdToEntityIdAssociations : adExtensionIdToEntityIdAssociations, associationType : AssociationType.Campaign); OutputStatusMessage("EditorialReasons:"); var adExtensionEditorialReasonCollection = (AdExtensionEditorialReasonCollection[])getAdExtensionsEditorialReasonsResponse?.EditorialReasons; CampaignManagementExampleHelper.OutputArrayOfAdExtensionEditorialReasonCollection(adExtensionEditorialReasonCollection); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsEditorialReasonsResponse?.PartialErrors); // Get only the location ad extensions and then remove scheduling. AdExtensionsTypeFilter adExtensionsTypeFilter = AdExtensionsTypeFilter.LocationAdExtension; // In this example partial errors will be returned for indices where the ad extensions // are not location ad extensions. // This is an example, and ideally you would only send the required ad extension IDs. OutputStatusMessage("-----\nGetAdExtensionsByIds:"); var getAdExtensionsByIdsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync( accountId: authorizationData.AccountId, adExtensionIds: adExtensionIds, adExtensionType: adExtensionsTypeFilter)); adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray(); BatchError[] getAdExtensionErrors = getAdExtensionsByIdsResponse?.PartialErrors.ToArray(); OutputStatusMessage("AdExtensions:"); CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionErrors); var updateExtensions = new List <AdExtension>(); var updateExtensionIds = new List <long>(); foreach (var extension in adExtensions) { // GetAdExtensionsByIds will return a nil element if the request conditions were not met. if (extension != null && extension.Id != null) { // Remove read-only elements that would otherwise cause the update operation to fail. var updateExtension = SetReadOnlyAdExtensionElementsToNull(extension); // If you set the Scheduling element null, any existing scheduling set for the ad extension will remain unchanged. // If you set this to any non-null Schedule object, you are effectively replacing existing scheduling // for the ad extension. In this example, we will remove any existing scheduling by setting this element // to an empty Schedule object. updateExtension.Scheduling = new Schedule { }; updateExtensions.Add(updateExtension); updateExtensionIds.Add((long)updateExtension.Id); } } OutputStatusMessage("-----\nUpdateAdExtensions:"); await CampaignManagementExampleHelper.UpdateAdExtensionsAsync( accountId : authorizationData.AccountId, adExtensions : updateExtensions); OutputStatusMessage("Removed scheduling from the location ad extensions."); // Get only the location extensions to output the result. OutputStatusMessage("-----\nGetAdExtensionsByIds:"); getAdExtensionsByIdsResponse = await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync( accountId : authorizationData.AccountId, adExtensionIds : updateExtensionIds, adExtensionType : adExtensionsTypeFilter); adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray(); getAdExtensionErrors = getAdExtensionsByIdsResponse?.PartialErrors.ToArray(); OutputStatusMessage("AdExtensions:"); CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions); OutputStatusMessage("PartialErrors:"); CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionErrors); // Delete the ad extension associations, ad extensions, and campaign, that were previously added. // At this point the ad extensions are still available in the account's ad extensions library. OutputStatusMessage("-----\nDeleteAdExtensionsAssociations:"); await CampaignManagementExampleHelper.DeleteAdExtensionsAssociationsAsync( authorizationData.AccountId, adExtensionIdToEntityIdAssociations, AssociationType.Campaign); OutputStatusMessage("Deleted ad extension associations."); // Delete the ad extensions from the account's ad extension library. OutputStatusMessage("-----\nDeleteAdExtensions:"); await CampaignManagementExampleHelper.DeleteAdExtensionsAsync( authorizationData.AccountId, adExtensionIds); OutputStatusMessage("Deleted ad extensions."); // Delete the account's media that was used for the image ad extension. OutputStatusMessage("-----\nDeleteMedia:"); await CampaignManagementExampleHelper.DeleteMediaAsync( accountId : authorizationData.AccountId, mediaIds : mediaIds); foreach (var id in mediaIds) { OutputStatusMessage(string.Format("Deleted Media Id {0}", id)); } // 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.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 Customer Management service exceptions catch (FaultException <Microsoft.BingAds.V12.CustomerManagement.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.CustomerManagement.ApiFault> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }